Скрытая матричная факторизация - невероятно мощный метод, который можно использовать при создании рекомендательной системы. С тех пор, как в конкурсе рекомендаций Netflix было показано, что латентная матричная факторизация превосходит другие методы рекомендаций, она стала краеугольным камнем в создании рекомендательных систем. Эта статья призвана дать вам некоторую интуицию относительно того, когда использовать латентную матричную факторизацию для рекомендаций, а также дать некоторое представление о том, почему она работает. Если вы хотите увидеть полную реализацию, вы можете перейти к моему ядру Kaggle: Вероятностная матричная факторизация.

Перед тем как начать, давайте сначала рассмотрим проблему, которую мы пытаемся решить. Скрытая матричная факторизация - это алгоритм, решающий проблему рекомендаций: данный набор m пользователей и n элементов, а также набор оценок пользователей для некоторых предметы, постарайтесь порекомендовать каждому пользователю самые популярные. Есть много разновидностей и альтернативных отклонений от этой проблемы, большинство из которых добавляют к проблеме дополнительные измерения, такие как добавление тегов. Что делает скрытую матричную факторизацию мощной, так это то, что она дает действительно сильные результаты от основной проблемы и может быть хорошей основой для построения.

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

Алгебра разреженных и неполных матриц:

Традиционная линейная алгебра - это основа машинного обучения, и это потому, что в большинстве приложений машинного обучения есть то, чего нет в рекомендательных системах: набор данных без NaN (неполные записи данных). Например, всякий раз, когда вы создаете модель, NaN или отсутствующие данные удаляются на этапе предварительной обработки данных, поскольку большинство функций не могут работать с незаполненными значениями. Такие функции, как Анализ главных компонентов, не определены, если есть пропущенные значения. Однако рекомендательные системы не могут работать, если вы избавитесь от NaN. Эти NaN существуют по какой-то причине: не каждый пользователь оценил каждый элемент, и ожидать от них этого немного бессмысленно. Работа с разреженными данными может быть очень разной, и это делает рекомендацию интересной проблемой.

Редкость усложняет дело. Разложение по сингулярным значениям, факторизация матрицы m x n на ее сингулярные и ортогональные значения, не определено, если какие-либо элементы в матрице не определены. Это означает, что мы не можем явно факторизовать матрицу таким образом, чтобы мы могли найти, какие диагональные (или скрытые) факторы имеют наибольший вес в наборе данных.

Вместо этого мы собираемся аппроксимировать наилучшую факторизацию матрицы, используя технику, которая называется вероятностная факторизация матрицы. Этот метод аккредитован Саймоном Функом, который использовал его в своем алгоритме FunkSVD, чтобы добиться большого успеха в конкурсе Netflix. Для получения дополнительной информации ознакомьтесь с оригинальным постом Саймона.

Подход:

Я объясню алгоритм, а затем объясню интуицию.

Сначала мы инициализируем две матрицы из распределения Гаусса (в качестве альтернативы, инициализируем их случайным образом). Первая будет матрицей P m x k ​​, а вторая - матрицей Q k x n. Когда эти две матрицы умножаются друг на друга, в результате получается матрица m x n, которая в точности совпадает с размером нашей матрицы рейтинга, которую мы пытаемся предсказать. Параметр k - это один из наших гиперпараметров, который представляет количество скрытых факторов, которые мы используем для оценки матрицы рейтингов. Обычно k составляет от 10 до 250, но не верьте мне на слово - используйте линейный поиск (или поиск по сетке), чтобы найти оптимальное значение для вашего приложения.

С помощью наших матриц P, Q, мы оптимизируем их значения, используя Стохастический градиентный спуск. Таким образом, у вас будет еще два гиперпараметра для оптимизации: скорость обучения и эпохи. Для каждой эпохи мы будем перебирать все известные рейтинги в нашей исходной матрице m x n.

Тогда мы получим ошибку или остаточное значение e, вычтя исходное значение рейтинга на скалярное произведение строки исходного рейтинга пользователя в P и столбца его элемента в Q.

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

Вот он на питоне. Полностью его можно посмотреть в моем Kaggle Kernel.

#randomly initialize user/item factors from a Gaussian
        P = np.random.normal(0,.1,(train.n_users,self.num_factors))
        Q = np.random.normal(0,.1,(train.n_items,self.num_factors))
        #print('fit')
for epoch in range(self.num_epochs):
            for u,i,r_ui in train.all_ratings():
                residual = r_ui - np.dot(P[u],Q[i])
                temp = P[u,:] # we want to update them at the same time, so we make a temporary variable. 
                P[u,:] +=  self.alpha * residual * Q[i]
                Q[i,:] +=  self.alpha * residual * temp
self.P = P
        self.Q = Q
self.trainset = train

Теперь, когда у нас есть алгоритм, почему он работает и как мы интерпретируем его результаты?

Скрытые факторы представляют категории, которые присутствуют в данных. Для k = 5 скрытых факторов для набора данных фильма они могут представлять боевик, романтику, научную фантастику, комедию и ужасы. Чем выше k, тем более конкретные категории. Что происходит? Мы пытаемся предсказать рейтинг элемента i пользователем u. Поэтому мы смотрим на P, чтобы найти вектор, представляющий пользователя u, и его предпочтения или «привязанность» ко всем скрытым факторам. Затем мы смотрим на Q, чтобы найти вектор, представляющий элемент i, и его «сродство» ко всем скрытым факторам. Мы получаем скалярное произведение этих двух векторов, которое вернет нам ощущение того, насколько пользователю нравится элемент в контексте скрытых факторов.

Источники и дополнительная информация:

Большой объем информации и вдохновения был почерпнут из этой статьи Вероятностная матричная факторизация и из главы 3 книги Рекомендательные системы: Учебник Чару Аггарвала.

Вы можете найти реализацию Python здесь.