Предупреждение об источнике данных
Источник данных находится по адресу https://www.kaggle.com/jealousleopard/goodreadsbooks (https://www.kaggle.com/jealousleopard/goodreadsbooks). Мне неизвестна процедура, которую применял автор для сбора данных. Поэтому всегда надо помнить, что особенности именно данного набора могут оказать влияние на выводы. Идеально было бы самостоятельно собрать данные или использовать дополнительно иные сборки данных, но пока в этой методичке такая задача не стоит. Кроме того, сайт Goodreads с конца 2020 ограничил использование API и получение данных.
Почему при таких ограничениях я выбрал именно данный набор? Как я указывал выше, прежде всего, надо основываться на действительности, чтобы понять данные. А значит я должен разбираться или хотя бы понимать те объекты, тот предмет, которого касаются данные. Так как я много читаю, полагаю, что неплохо понимаю, за что можно поставить книге ту или иную оценку, как на это влияет количество страниц и прочее. Поэтому я выбрал именно эти данные.
Вижу, что данные можно разбить на две категории:
1) сведения о книге (название, автор, isbn, язык, количество страниц, дата публикации и издательство);
2) сведения о реакции читателей (средний рейтинг, количество отзывов, количество оценок).
Данные рассказывают не просто про книгу и не просто про реакцию на книгу, а про реакцию читателей, измеренную конкретными признаками, на книгу, также измеренную конкретными признаками. Если у меня нет специального задания по анализу, то я могу наметить стратегию исследования по имеющимся признакам. Так, например, может быть интересно, каким книгам чаще ставят положительные оценки? как зависит оценка книги от количества страниц в ней?
Сформулирую для себя общую цель – изучить от чего зависит оценка книги.
Таблица задает две оси: вертикальная – наблюдения, горизонтальная – признаки.
Метка для наблюдений – индекс, метка для признаков – название признаков (название столбцов). Поэтому, естественно, что подготовка данных должна начинаться с обследования меток. Однако индекс формируется автоматически в порядке возрастания от 0 до n (это поведение по умолчанию можно изменить). Названия столбцов были предоставлены вместе с данными, поэтому их-то отдельно и надо обследовать.
Вижу, что есть 12 признаков (нумерация начинается с 0 и продолжается до 11) и 11123 наблюдений (строк). Пропусков нет (количество объектов по столбцам одинаковое). Индекс у нас это RangeIndex. По типам данных заметно две проблемы. isbn помечен как объект, а isbn13 как int64. Кроме того, publication_date помечен как объект, хотя это очевидно дата. Изменю тип данных.
Вижу, что в publication_date появилось два пропущенных значения. Так как подобных строк всего две, я могу их удалить.
Запись выше надо читать так. В таблице db выбрать только те строки, у которых в столбце «publication_date» нет значения NaT. Значок тильды ~ означает «не». Метод isin проверяет наличие указанных данных в ячейке.
Здесь также важно, что я могу взять изначальную таблицу, отфильтровать ее, как мне это необходимо, а затем заменить изначальную таблицу отфильтрованной. Другими словами, изначально у меня была таблица db, после изменений я получаю таблицу с тем же названием db, но уже отфильтрованную.
Теперь я должен заняться дубликатами строк. Я могу искать либо полные дубликаты (данные в каждом столбце для строки полностью совпадают), либо искать дубликаты выборочно. Здесь надо обратить внимание, что isbn является уникальным идентификатором каждой изданной книги. Поэтому логично искать дубликаты только по этому признаку, так как книги вполне могут совпадать по иным признакам и это нормально.
Дубликатов по isbn13 нет. Но все-таки посмотрю дубликаты по названию и имени автора.
Такой подход позволяет понять, почему могут совпадать имя автора и название при различных isbn. Вижу, что, как правило, такие дубликаты – это аудиокниги. С этим придется разобраться отдельно. Для начала посмотрю, есть ли нулевое количество страниц у книг.
Таких книг 76. Что их объединяет? Посмотрю издательства.
Вижу, что в основном это издательства, которые выпускают аудиокниги. Это логично. Если у книги нет страниц, то это просто аудиокнига. Но посмотрим количество страниц для тех книг, которые выпускали эти издательства.
Код выше весьма любопытен. Как его прочитать? Берем таблицу db. В этой таблице ищем такие строки, в которых столбец равен 0. Далее, в отфильтрованной таким образом таблице, берем столбец ’publisher’. После этого вызываем value_counts для подсчета количества и head для ограничения вывода результатов.
Вижу, что аудиоиздательства издают нечто, что имеет страницы, даже 1162 страницы! Посмотрю на это.
*Заметка к коду*
Код выше очень похож на предыдущий и может быть аналогично прочитан. Однако обращает внимание, что при первоначальной фильтрации таблицы я могу добавить дополнительные методы, например str и т. п.
В интернете, например, на сайте Amazon, можно обнаружить эту книгу. И она оказывается аудиокнигой! Таким образом, количество «страниц» еще не говорит нам, что это бумажная книга. Это может быть, например, вес дисков. Более верный признак – это именно издательство. Как же поступить? Ведь сравнить книги аудио и бумажные по количеству страниц не получится. Следовательно, в одном признаке смешаны различные числа – количество страниц и вес дисков. Удалю все аудиокниги, но сначала сравню оценки по бумажным и аудиокнигам.
Вижу, что медиана не отличается, хотя разброс оценок для бумажных книг больше, чем для аудиокниг. Удалю вспомогательный признак, а также все аудиокниги. Надо учитывать, что такой подход, когда сравниваются две категории книг по графикам, является довольно грубым. Здесь бы стоило применить, например, t-тест. Но у меня нет специальной задачи исследовать аудио- и бумажные книги, поэтому ограничусь графиками.
*Заметка к коду*
Как прочитать np. where? Здесь я беру исходные данные признака, нахожу один из них, например названия с «audio», и присваиваю значение «audio», а если это не выполняется, то присваиваю значение «paper».
Еще раз посмотрю на таблицу, но выберу только количество страниц до 10. Посмотрю издательства.
Если изучить полный список, то можно заметить, что там есть издательства Listening Library и ряд других, которые очевидно выпускают аудиокниги. Прихожу к выводу, что книги с количеством страниц 10 – это аудиокниги. Удалю их.
Добавлю два дополнительных признака в таблицу:
1) десятилетие, в котором вышла книга,
2) квартал, в котором вышла книга.
Это называется конструированием признаков, исходя из целей исследования. Специальных целей передо мной не ставили, я ищу их для себя сам. Меня будет интересовать, как распределяются книги по десятилетиям и в какой квартал их чаще выпускают. Почему именно эти признаки? Потому что десятилетия отражают развитие рынка книготорговли, изменение форматов и т. п. Кварталы же зависят от праздников, сезонности, что также может оказывать влияние на оценку книги.
Конструирование признаков возможно двумя путями:
1) самостоятельно определить новый признак,
2) признак создается автоматически, например простым возведением каждого числового признака в квадрат или перемножением каждой пары таких признаков.
Если затруднительно самостоятельно определить признаки, которые было бы интересно изучить, то можно применить второй метод. В этом случае можно и не создавать признаки на этапе обработки данных, можно использовать специальные методы, например полиномиальную регрессию.
Теперь посмотрю на признак authors. Вижу, что здесь есть случаи, когда указано несколько имен через /. Сколько таких случаев?
*Заметка к коду*
Чтобы получить значение десятилетия, я использовал код 10 * (db. loc [:, «publication_date»].dt. year // 10). Почему? В этом коде я сначала делю год на 10, причем оставляю только целую часть. Например, если год 2001, то получаю 200. А затем уже умножаю на 10 это «целое» число, что и дает декаду.
Из примеров видно, что, как правило, через слеш указаны переводчики. Однако возможны и другие ситуации. Это могут быть соавторы или вариант написания имени. Без дополнительного исследования внешних источников это определить нельзя. В этой ситуации можно сделать следующее. Заменю слеш на запятую. Создам колонку tra_co (переводчик или соавтор) и присвою 1 тем случаям, где есть запятая, и 0 остальным.
Теперь разберусь с книгами, у которых слишком большие значения количества страниц. Посмотрю на них повнимательнее.
Как правило, книги с количеством страниц больше 1000 – это многотомные издания. Очевидно, что просто убрать такие книги, как я сделал с книгами, у которых было 0 страниц, нельзя. Что же тогда? Я должен найти все такие книги и пометить их. Для этого надо определить маркеры, которые позволят найти многотомные издания. Уже представленный выше список дает идеи:
1) книги с наличием знака #,
2) книги со словами Boxed Set.
Кроме того, под подозрением все книги со словами «books», «vol.», «volume», «series».
См. хорошее руководство по регулярным выражениям https://developers.google.com/edu/python/regular-expressions (https://developers.google.com/edu/python/regular-expressions).
Минимальная оценка это 0. Но на сайте нельзя поставить такую оценку. Поэтому 0 означает отсутствие оценки, то есть это категориальный признак, который «пробрался» в числовой. Посмотрю количество и удалю, так как такое смешение недопустимо. Однако, если оценка 0, но количество оценок не 0, то это просто ошибка. Проверю это.
Удалю редкие категории. Для этого можно применить следующий код к каждой категориальной переменной.
Здесь не привожу вывод по каждой категории. Однако общий вывод такой: редкие категории встречаются в **decade**, поэтому объединю все года, у которых менее 20 значений в год 1940.