«Если вы не любите читать, значит, вы не нашли нужную книгу». - J.K. Роулинг

Эта статья сильно отличается от тех, к которым вы, возможно, привыкли. Мне очень понравилось поработать над этим и поделиться им с вами, надеюсь, вам понравится читать об этом 🙂

Если вы хотите узнать больше о проектах, над которыми я работал, загляните на мой сайт!

Недавно я понял, что не трачу достаточно времени на чтение. Итак, в прошлом году я начал заставлять себя читать больше. Примерно в то же время я наткнулся на Goodreads, социальную сеть для книг. Благодаря этой платформе вы можете видеть, что ваши друзья читают, прочитали, как они оценивают различные книги и т. Д. Вы также можете записывать все книги, которые вы прочитали, сохранять книги, которые хотите прочитать, и многое другое.

Несколько недель назад я обнаружил, что могу загрузить свои данные Goodreads. Как энтузиаст данных, я подумал, что было бы весело взглянуть на него и посмотреть, смогу ли я использовать его для создания персональных рекомендаций по книгам! Вот как я это сделал 👇

Часть 1 - Получение удовольствия от данных

Данные, которые я скачал, содержали 441 книгу. В него вошли те, которые я прочитал (265), те, которые я сейчас читаю (3), и те, которые я хочу прочитать (173). Для каждой книги он включал все (или почти все) следующие данные: Идентификатор книги, Название, Автор, ISBN, Моя оценка, Средняя оценка (дана всеми участниками Goodreads), Издатель, Количество страниц, Год публикации.

Так что я начал немного развлекаться с данными. Вот график, показывающий количество книг в моей библиотеке на автора. Как видите, авторы детских книг Рене Госинни (Астерикс), Мэри Поуп Осборн (Волшебный дом на дереве), Роберт Мучамор (CHERUB) и Энтони Горовиц (Алекс Райдер) возглавляют рейтинг. За ними следуют «взрослые» авторы, такие как Кундера, Камю, Мольер и Гексли.

Еще один интересный график, который мне удалось отобразить, - это количество изданных книг в моей библиотеке за год.

Как вы можете видеть, большинство книг в моей библиотеке - недавние, причем режим (наиболее частое значение) - 2004 год. 2004 год также является средним годом публикации книг в моей библиотеке.

Часть 2 - Добавление переменных

Хотя было интересно взглянуть на данные в общих чертах, главная цель заключалась в том, чтобы иметь возможность построить модель, способную предсказывать, как я буду оценивать каждую книгу на основе того, как я оценивал прошлые книги. (Примечание. Я не буду вдаваться в подробности о коде здесь. Я попытался добавить как можно больше пояснений в код, который буду отображать. Вы также можете найти весь код на странице my Github , хотя должен вас предупредить, что это может быть немного запутано).

На каких переменных вы бы сосредоточились, если бы пытались предсказать, какую книгу вы хотели бы прочитать? Название книги? Его автор? Его средний рейтинг на Goodreads? Его жанр? Год его публикации?

Если бы компьютер пытался проделать то же самое упражнение, у него могли бы возникнуть проблемы с использованием некоторых из этих переменных для анализа. В самом деле, хотя название книги может дать читателю много указаний о книге, компьютеру гораздо труднее (хотя и не невозможно, благодаря НЛП и т. П.) Компьютеру понимать слова и особенно то, что может быть привлекательным в названии книги или что может быть показателем качества книги. Это кажется особенно трудным, учитывая, насколько мал наш набор данных и как часто бывают короткие заголовки. С другой стороны, числа и двоичные переменные (например, это поэзия или не-поэзия) гораздо проще использовать для компьютеров при построении модели.

Инстинктивно две переменные кажутся более важными, чем другие. Во-первых, жанр, так как некоторые люди абсолютно ненавидят поэзию, пьесы или документальную литературу… Во-вторых, средняя оценка, по-видимому, является хорошим показателем качества книги и, следовательно, ее вероятность того, что книга понравится или не понравится. Хотя данные Goodreads предоставили название, автора, год публикации, количество страниц и средний рейтинг, они не указали жанр книги.

Поэтому я попытался добавить эту информацию в свой набор данных, прежде чем начал строить свою модель. Тем не менее, это оказалось более сложным, чем я думал (как вы скоро узнаете 😂). Если вы хотите сразу перейти к модели и ее результатам, перейдите к Части 3.

2.1 - Google API

Я быстро обнаружил, что Google разработал API, в котором можно указать ISBN книги (международный стандартный номер книги) и получить доступ к большому количеству информации об этой книге, включая ее жанр. Поэтому я написал код для сбора жанров всех книг в наборе данных.

Однако, проверив свои результаты, я понял, что, хотя все книги были включены в набор данных Google API, 56,5% не имели жанров. Таким образом, даже несмотря на то, что мне было лучше, чем я начал, мои результаты оказались слишком ограниченными для анализа, как показано ниже 😐

2.2 - Очистка Goodreads

Одна из особенностей Goodreads, которая мне понравилась, заключалась в том, что книги классифицировались не по одному жанру, а по нескольким жанрам, как показано ниже.

Это дало мне больше понимания, когда я просматривал книгу на платформе. Это также пригодилось для моей модели прогнозирования, так как гарантировало, что все книги будут классифицированы как минимум в одном жанре, а еще лучше - в нескольких жанрах. Поэтому я попытался получить эту информацию для каждой книги с помощью «веб-скрапинга».

Для тех, кто не знаком со сканированием веб-страниц, вот краткое описание того, как это работает: Когда вы заходите на веб-сайт, ваш браузер отправляет HTTP-запрос на сервер веб-сайта, который возвращает HTML-документ. Этот документ обрабатывается вашим браузером для отображения эстетичного и удобного веб-сайта, который мы видим и с которым взаимодействуем каждый день. С помощью веб-скрейпинга вы, по сути, создаете программу, которая имитирует этот HTTP-запрос, а затем выполняет поиск в HTML-документе, чтобы найти то, что вы попросили его найти.

Таким образом, всякий раз, когда вы выполняете парсинг, вам нужно найти «трюк» для доступа ко всем интересующим вас URL-адресам. Если сейчас это непонятно, не волнуйтесь! Надеюсь, это будет легче понять с помощью приведенных ниже примеров 🙂 Следовательно, чтобы получить жанры книги, я должен знать URL-адрес веб-сайта этой книги. Ключевым моментом здесь является понимание того, что мы не хотим вручную извлекать все URL-адреса книг. Скорее, мы хотим попытаться найти трюк, чтобы иметь возможность генерировать их все автоматически. Таким образом, соскабливание - это игра, основанная на терпении, творчестве и удаче. Вот почему это обычно считается «методом крайней меры», который вы применяете после того, как не смогли получить данные другими способами (открытые данные, API-интерфейсы и т. Д.).

Как видно на изображении ниже, URL книги Goodreads можно разделить на 3 раздела: основной URL Goodreads (красный), то, что выглядит как случайное число (синий) и название книги (зеленый).

Что произойдет, если я удалил название книги в конце URL-адреса? Как оказалось, все работает нормально! Как показано ниже 🙂

Итак, теперь возникает вопрос, чему соответствует это случайное число и как мы можем найти это число для каждой книги в нашей библиотеке? Возвращаясь к данным, которые мы изначально импортировали из Goodreads, мы обнаруживаем, что первый столбец в нашем наборе данных действительно соответствовал идентификатору Goodreads книги. Это может быть нашим ответом! Попробовав это, мы понимаем, что «Случайное число» на самом деле является идентификатором Goodreads Id.

Это отличная новость, потому что у нас есть все идентификаторы книг Goodreads, и поэтому мы сможем сгенерировать все URL-адреса наших книг и, таким образом, получить все их жанры! Благодаря Python это можно сделать очень легко с помощью нескольких строк кода 👇

Это весь код, который нам нужен! Однако, когда мы смотрим на наши результаты, мы видим, что есть много проблем! Хотя мы получили то, что хотели для наших первых результатов, мы, кажется, получаем только пустые значения для более поздних. 😓

Как придешь? Когда мы смотрим на то, что получаем, «очищая» наши более поздние результаты, мы понимаем, что код HMTL, отправленный сервером, содержал следующие странные результаты:

Похоже, это добровольная защита от парсинга, созданная разработчиками Goodreads для предотвращения слишком частого парсинга Goodreads. Таким образом, хотя мы почти получили все необходимые нам результаты, это, к сожалению, не подходящее решение нашей проблемы. .

2.3 - Goodreads API

Хотя мне было известно, что Goodreads разработал API, на его веб-сайте указано, что API остается активным, но они перестали выдавать токены доступа, необходимые для использования API. Поэтому я изначально искал альтернативные решения, подобные упомянутым выше. К счастью, я наткнулся на запрос API, сделанный одним из пользователей форума. Запрос включал токен доступа, который они использовали, поэтому я смог использовать этот токен доступа и сделать свои собственные запросы API, как показано в приведенном ниже коде!

Это сработало! Теперь у меня было множество жанров в каждой книге, которые помогли мне улучшить мою модель 💪

Часть 3 - Прогнозы

Теперь, когда у нас есть вся необходимая информация, пора построить модель! Я не буду здесь разбирать код пошагово, помните, что он доступен здесь.

Когда дело доходит до построения модели, важно помнить, что мы пытаемся предсказать. В нашем случае мы пытаемся предсказать рейтинг, который я бы поставил книге. Поэтому мы будем использовать тип машинного обучения, называемый обучением с учителем. Основная идея состоит в том, чтобы позволить нашей модели находить шаблоны для книг, которые мы уже оценили, чтобы он мог понять, что нам нравится в книге и что нам не нравится » t, что важно и что нет и т. д., чтобы затем он мог прогнозировать оценки книг, которые я не читал .

Я начал с использования самой простой модели - линейной регрессии. Вот «закономерности», которые он определил!

Как видите, моя модель основывалась главным образом на двух вещах: средней оценке (от 1 до 5) и жанрах книг. Вы можете видеть, что в соответствии с этой линейной регрессией кажется, что я не люблю художественную литературу (если в книге есть художественная литература в своем жанре, прогнозируемый рейтинг будет понижаться на 1,4 балла). С другой стороны, если книга принадлежит к жанру романа или классики, то прогнозируемый рейтинг увеличится на 1,2–1,3 балла.

Единственным небинарным результатом в модели был результат среднего рейтинга, значения которого находятся в диапазоне от 1 до 5. Идея состоит в том, что за каждую 1, которую вы добавляете к среднему рейтингу, он добавляет 0,522… пункта к прогнозируемому рейтингу.

Теперь, когда мы успешно запустили нашу модель, мы можем проверить, какие книги из моей библиотеки «Хочу прочитать», по мнению модели, я бы предпочел. Вот результаты! Мы можем четко заметить, что, хотя средний рейтинг, по-видимому, оказывает некоторое влияние на наш прогнозируемый рейтинг, поскольку все наши лучшие книги имеют средний рейтинг 3,5+, лучшие книги не обязательно имеют лучший средний рейтинг .

Чтобы было точнее, я стал использовать другие модели. Одним из них была логистическая регрессия. Прочтите эту статью, если хотите узнать больше о разнице между линейной регрессией и логистической регрессией. Основная идея заключается в том, что в то время как линейные регрессии создают линейное уравнение, которое описывает отношения между зависимыми и независимыми переменными, логистические регрессии классифицируют элементы набора на две группы (или более), вычисляя вероятность каждого элемента набора.

В нашем случае модель могла бы найти шаблоны, чтобы попытаться понять, почему определенные книги имеют оценку 1, 2 или 3 ... Затем для каждой книги она будет вычислять вероятность того, что книга попадет в категорию 1 или 2 и т. Д. До 5, и сделает свой прогноз на основе категории с наибольшей вероятностью.

Я также использовал модели Регрессия K-ближайших соседей (KNN) и Классификация KNN. Затем я вычислил среднее значение результатов четырех моделей, чтобы определить мой окончательный рейтинг. 15 лучших результатов можно увидеть ниже, при этом автор Джон Макфи занял 1-е и 2-е места ! Смотрите полные результаты на моем сайте или в Таблицах 🚀

Часть 4 - Что будет дальше?

Краткосрочный

Как вы понимаете, многое можно улучшить. Во-первых, я хотел бы улучшить свою модель, добавив другие переменные, такие как количество оценок, количество страниц и т. Д.

Во-вторых, если бы вы взглянули на код, вы, вероятно, увидели бы, насколько он плохо организован. Поэтому я хотел бы структурировать его, чтобы сделать его более подходящим для развертывания или, по крайней мере, чтобы облегчить воспроизведение. Идея в том, что время от времени я буду повторно загружать свои данные из Goodreads и смотреть, как меняются результаты благодаря дополнительным оценкам, которые я поставил книгам. У меня также много друзей, которые используют Goodreads. Так что я также с нетерпением жду получения их данных, чтобы дать им персональные рекомендации!

Долгосрочный

В конечном итоге целью будет создание мини-веб-сайта, на котором люди смогут загружать свои данные Goodreads (или оценивать определенное количество книг) и получать персональные рекомендации по книгам. Другой возможностью может быть создание расширения Chrome, чтобы сделать работу пользователя еще лучше и проще.

Если у вас есть какие-либо идеи, предложения или отзывы (они всегда очень благодарны!) Или вы хотите помочь мне с краткосрочными и / или долгосрочными целями для этого проекта, не стесняйтесь оставлять комментарии ниже или связываться со мной по Twitter @the_simonpastor!

Мне очень понравилось работать над этим проектом и делиться им с вами, надеюсь, вам понравилось читать об этом 🙂

Первоначально опубликовано на https://simonpastor.substack.com.