оригинальный автор: Дэн Сюйдун
Оригинальный текст был размещен в личном паблике автора в WeChat: Дэн и его Python (Мы общаемся по номеру:
DaDengAndHisPython), нажмитеПосмотреть исходный текст, НаггетсРазрешение на перепечатку получено. Еще раз спасибо автору.
Вчера я загрузил видео с Youtube, которые мне пригодились, с двух конференций PyCon2018 и PyData2018, Вчера опубликованное «Используйте pandas для улучшения науки о данных» от PyData2018. На написание этой статьи меня вдохновил контент спикера.
Адрес видео:V.QQ.com/small/afraid/i067…
Daniel Pyrathon - A practical guide to Singular Value Decomposition in Python PyCon2018
奇异值分解Python实操
1. Предварительные знания
1.1 Совместная фильтрация
В повседневной жизни крупные интернет-компании, такие как Amazon, Taobao, JD.com и Toutiao, будут постоянно собирать данные о поведении наших пользователей в Интернете и предлагать нам рекомендуемый контент или рекомендуемые продукты на основе накопленных исторических данных о поведении. Это роль рекомендательного алгоритма, существование которого мы никогда не ощущали.Более распространенный метод реализации — Collaborative Filtering. Существует три типа информации от дизайна данных до пользователя, продукта и оценки продукта, данные аналогичны следующему рисунку.
1.2 Похожие люди чаще делают похожие вещи
Основная идея совместной фильтрации заключается в том, что похожие люди склонны делать похожие вещи. Например, A и B — два человека, которые пропагандируют технологии (аналогичная информация поступает из большого количества данных о просмотре фильмов), и B любит смотреть научно-фантастические фильмы, тогда мы предполагаем, что A также любит научно-фантастические фильмы.
1.3 Задавать вопросы
Диаграмма визуализации пользовательского фильма, которую мы показали выше, на самом деле часто используется в алгоритме рекомендации.Матрица оценки пользователей,
Так как же нам рассчитать матрицу, чтобы получить информацию о сходстве?
Имея информацию о сходстве, как мы можем использовать информацию о сходстве, чтобы рекомендовать продукт?
Мы знаем, что два вектора можно аппроксимировать вычислением косинусного подобия, так как же нам получить эти векторы изМатрица оценки пользователейЧто насчет экстракции?
1.4 Разложение по сингулярным числам SVD
При этом используется разложение по сингулярным значениям (Singular Value Decompositon), называемое SVD. Эта статья не посвящена извлечению. Python помог нам в этом. Нам нужно лишь немного разобраться в SVD, чтобы сразу приступить к работе.
Например, у нас сейчасМатрица оценки пользователей
Имея матрицу, мы можем разложить ее, чтобы получить два вида матриц, одна из которых представляет собой матрицу информации о пользователе, а другая — матрицу информации об оценке (продукте). Эти две матрицы используют n_features = 2 в этом примере, то есть длина вектора пользователя или вектора оценки продукта равна 2, на самом деле это могут быть и другие числа (например, 3, 4...)
Тогда симпатию User1 к голубым фильмам можно вычислить по вектору 3,52.
1.5 Сходство пользователей
Как показано на рисунке ниже, мы можем видеть сходство между разными пользователями в двумерных координатах.
2. Боевой проект
Мы будем использовать библиотеку сюрпризов Python для создания простой системы рекомендаций по совместной фильтрации в наборе данных MovieLens.
способ установки:
pip3 install scikit-surprise
Если ваша анаконда поставляется с блокнотом Jupyter. Тогда вам может понадобиться использовать следующий метод установки
conda install -c conda-forge scikit-surprise
Из названия установки мы обнаружили особое отношение других scikit, поэтому студентам, знакомым со scikit, будет легче читать эту статью.
2.1 Подготовка данных
Набор данных MovieLens содержит 100 000 оценок фильмов от 1000 пользователей. где нам нужно использовать только файл u.data в этом наборе данных, который хранится в строках, каждая строка включаетuserID itemID rating timestamp
, и каждое поле начинается с\t
интервал. Часть данных выглядит следующим образом
['196\t242\t3\t881250949\n',
'186\t302\t3\t891717742\n',
'22\t377\t1\t878887116\n',
'244\t51\t2\t880606923\n',
'166\t346\t1\t886397596\n']
2.2 Режимы резания
В неожиданной библиотеке мы можем создать формат ридера Reader. В этом примере мы используем\t
Отделите каждую строку данных и назначьте ее
user item rating timestamp
После определения формата Reader мы используем объект Dataset для чтения данных.
from surprise import Reader, Dataset
#定义数据格式
reader = Reader(line_format='user item rating timestamp', sep='\t')
#使用reader格式从u.data文件中读取数据
data = Dataset.load_from_file('u.data', reader=reader)
2.3 Перекрестная проверка
удивление предоставляет интерфейс для перекрестной проверки Что такое перекрестная проверка?
Давайте посмотрим на картинку, чтобы объяснить
Часть данных делится в среднем на 5 частей, если 4 части используются в качестве обучающей выборки и 1 часть используется в качестве тестовой выборки. Затем, когда мы обучаем модель, остается 1/5 данных, которые наша модель не может изучить, что является пустой тратой 20%.
Но мы не можем взять все данные для обучения один раз, а затем использовать обученные данные для прогнозирования. Потому что это приведет к очень высокому показателю точности а, но на практике точность предсказания этой модели на самом деле ниже, чем а.
Таким образом, существует перекрестная проверка перекрестной проверки. Мы тренируемся 5 раз с одними данными, и каждый раз полные данные делятся на 4 части для обучения и 1 часть для тестирования. Это решает проблему, с которой столкнулись выше. Как показано ниже
#n_folds=5是指数据分成5份,做5次训练预测
data.split(n_folds=5)
2.4 Оптимизация Оптимизация
Как добиться оптимального обучения, то должна быть Оптимизация, то есть должен быть эталон для справки.
Обучение проводится так же, как и другие методы машинного обучения, в том смысле, что алгоритм пытается оптимизировать свою работу.Предполагаемая стоимостькак можно ближереальная стоимость. В приложении для совместной фильтрации наш алгоритм попытается предсказать определенноепользовательский фильмкомбинированный рейтинг иПредполагаемая стоимостьиреальная стоимостьСравнивать. Классические меры ошибок, такие как среднеквадратическая ошибка (RMSE) и средняя абсолютная ошибка (MAE), используются для измерения разницы между прогнозируемыми и истинными значениями.
В библиотеке сюрпризов у нас есть широкий выбор алгоритмов и широкий выбор параметров для каждого алгоритма (SVD, NMF, KNN). В нашем примере мы будем использовать алгоритм SVD. оптимизировать цельmeasures
использоватьRMSE', 'MAE
from surprise import SVD, evaluate
#相当于scikit的机器学习算法的初始化
svd = SVD()
#相当于scikit中的score,模型评估
evaluate(svd, data, measures=['RMSE', 'MAE'])
бегать
Evaluating RMSE, MAE of algorithm SVD.
------------
Fold 1
RMSE: 0.9324
MAE: 0.7346
------------
Fold 2
RMSE: 0.9422
MAE: 0.7423
------------
Fold 3
RMSE: 0.9367
MAE: 0.7398
------------
Fold 4
RMSE: 0.9310
MAE: 0.7323
------------
Fold 5
RMSE: 0.9393
MAE: 0.7422
------------
------------
Mean RMSE: 0.9363
Mean MAE : 0.7382
------------
------------
Судя по приведенным выше результатам, после того, как оптимизатор использует RMSE, средняя точность 5 сеансов обучения достигает 93,63%.
2.5 Прогноз
Наконец, мы все еще хотим увидеть, какова способность предсказания обученной модели.
На этот раз сделаем кросс-валидацию, избавим от всех хлопот и скинем все на СВД для обучения
from surprise import SVD
from surprise import Reader, Dataset
#读取数据
reader = Reader(line_format='user item rating timestamp', sep='\t')
data = Dataset.load_from_file('u.data', reader=reader)
data = data.build_full_trainset()
#初始化svd模型,用data训练模型
svd =SVD()
svd.fit(data)
код выше
data = data.build_full_trainset()
Я не писал эту строку изначально, но когда я закомментировал эту строку. Возникает следующая ошибка,
DatasetAutoFolds' object has no attribute 'global_mean' on python surprise
Наконец, я нашел решение в stackoverflow, которому нужно преобразовать данные в класс trainset, который можно использовать неожиданно.
https://stackoverflow.com/questions/49263964/datasetautofolds-object-has-no-attribute-global-mean-on-python-surprise
Давайте продолжим наш прогноз, идентификатор пользователя — 196, идентификатор элемента — 302, а его истинная оценка — 4.
userid = str(196)
itemid = str(302)
actual_rating = 4
print(svd.predict(userid, 302, 4))
бегать
user: 196 item: 302 r_ui = 4.00 est = 3.41 {'was_impossible': False}
Прогнозируемое значение — 3,41, истинное значение — 4. Еще относительно надежен.