Использование матричного факторизации для рекомендательной системы

Я работаю над рекомендательной системой для ресторанов, используя элементарный совместный фильтр в C# 6.0. Я хочу, чтобы мой алгоритм работал как можно лучше, поэтому я провел некоторые исследования по различным способам прогнозирования рейтингов для ресторанов, которые пользователь еще не рассмотрел.

Я начну с исследования, которое я сделал

сначала я хотел настроить пользовательский совместный фильтр, используя корреляцию Пирсона между пользователями, чтобы иметь возможность видеть какие пользователи хорошо сочетаются.
Основная проблема заключалась в количестве данных, необходимых для расчета этой корреляции. Сначала вам нужно было 4 отзывы на 2 пользователей в одном ресторане. Но мои данные будут очень скудными. Маловероятно, что 2 пользователя рассмотрели бы те же самые 4 ресторана. Я хотел исправить это, расширив условия матча (т. е. не соответствующие пользователям в тех же ресторанах, но в том же типе ресторана), но это дало мне проблему, где это было трудно определить, какие отзывы я бы использовал в корреляции, так как пользователь мог оставить 3 отзыва о ресторане с типом "фаст-фуд". Какой из них лучше всего подходит для обзора другого пользователя в ресторане быстрого питания?

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

теперь моя проблема

Я искал по всему интернету учебники по использованию этого способ, но у меня нет никакого опыта в рекомендательных системах, и мои знания по алгебре, также ограничено. Я понимаю справедливость метода. У вас есть Матрица, где у вас есть 1 сторона пользователей и другая сторона ресторанов. Каждая ячейка-это рейтинг, который пользователь дал в ресторане.
Метод матричного факторизации создает две матрицы этого, одну с весом между пользователями и типом ресторана, а другую между ресторанами и этими типами.

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

Я приведу вам пример того, как данные выглядят в моем приложении:
В этой таблице U1 означает пользователя, а R1 - ресторан. Каждый ресторан имеет свои теги (тип ресторана). Т. е. R1 имеет тег "итальянский", R2 имеет "фаст-фуд"и т. д.

   |  R1  |  R2  |  R3  |  R4  |
U1 |  3   |  1   |  2   |  -   |
U2 |  -   |  3   |  2   |  2   |
U3 |  5   |  4   |  -   |  4   |
U4 |  -   |  -   |  5   |  -   |

кто-нибудь может мне точку в правильном направлении или объяснить, как я должен использовать этот метод на моих данных? Любая помощь будет очень признательна!

1 ответов


матричная факторизация предполагает, что" латентные факторы", такие как предпочтение итальянской кухни пользователем и итальянность продукта питания, связаны с рейтингами в матрице.

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

извлечение скрытых факторов-это другая проблема.

таким образом, реализация GDM может выглядеть так:

public void learnGDM(){
//traverse learnSet
for(int repeat = 0; repeat < this.steps; repeat++){
    for (int i = 0; i < this.learnSet.length; i++){
        for (int j = 0; j < this.learnSet[0].length; j++){
            if(this.learnSet[i][j] > 0.0d){
                double Rij = this.learnSet[i][j];

                for(int f = 0 ; f <= latentFactors; f++){
                    double error = Rij - dotProduct(Q.getRow(i), P.getRow(j));/*estimated_Rij;*/
                    //ieee computer 1.pdf
                    double qif = Q.get(i, f);
                    double pif = P.get(j, f);
                    double Qvalue = qif + gradientGamma * (error * pif - gradientLambda * qif);
                    double Pvalue = pif + gradientGamma * (error * qif - gradientLambda * pif);
                    Q.set(i,f, Qvalue);
                    P.set(j, f, Pvalue);
                }
            }
        }
    }
    //check global error
    if(checkGlobalError() < 0.001d){
        System.out.println("took" + repeat + "steps");
        break;
    }
}

где learnset представляет собой двумерный массив, содержащий Ratingmatrix, как в статье ieee. Алгоритм GDM изменяет векторы рейтинга P и Q бит на каждой итерации, чтобы они приближались к рейтингам в ratingmatrix. Тогда "не дано" рейтинги могут быть рассчитаны по точечному произведению P и Q. самыми высокими оценками для не заданных рейтингов будут рекомендации.

Так что это для начала. Существует множество оптимизаций и других алгоритмов или модифицированных версий GDM, которые также можно запускать параллельно.

некоторые хорошие гласит:

рекомендательные системы в Энциклопедии машинного обучения

презентация на матрицу факторизация

рекомендательные системы