Саймон Функ против Matlabs SVDS

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

У меня есть матрица с пользователями x элементов, где рейтинг "0" означает, что пользователь не дал оценку этому элементу.

До сих пор я пытался реализовать алгоритм Саймона Функса в Matlab (см. Исходный код) ниже, но он действительно (!) Работает плохо. Случайно я обнаружил, что функция Matdsb SVDS заполняет пустые рейтинги, и она на самом деле работает лучше и быстрее, чем функция моего Саймона Функса.

Может кто-нибудь сказать мне, что может быть причиной этого? Или скажите мне, какую глупую ошибку я допустил в функции Matlab?:П

function ratings = simon_funk(original_ratings, dimensions) % To construct a complete rating matrix

% See: http://www.timelydevelopment.com/demos/NetflixPrize.aspx

% Variables
global max_features;    max_features = dimensions;
global init;            init = 0.1;

min_epochs = 2;
max_epochs = 16;
min_improvement = 0.001;
lrate = 0.01;
k = 0.015;

respondent_count = size(original_ratings, 1);
item_count = size(original_ratings, 2);
rating_count = 0;

data = [];
for r=1:respondent_count
    for i=1:item_count
        rating = original_ratings(r,i);
        if(rating > 0)
            data = [data; [r, i, rating, 0]];
            rating_count = rating_count + 1;
        end    
     end
end
% Now data contain all ratings in the form [user_id, item_id, rating, cache (default 0)]

ratings = zeros(respondent_count, item_count);
global item_features;       item_features = zeros(max_features, item_count);
global respondent_features; respondent_features = zeros(max_features, respondent_count);

% Init
item_features(:,:) = init;
respondent_features(:,:) = init;

% CalcFeatures
rmse_last = 2.0;
rmse = 2.0;

for f=1:max_features
    for e=1:max_epochs
        sq = 0;
        rmse_last = rmse;


        for r=1:rating_count
           % for i=1:item_count

           respondent = data(r,1);
           item = data(r,2);
           rating = data(r,3);

            % Predict rating
            p = simon_funk_predict_rating(data(r,:), f, 1);
            err = (1.0 * rating - p);
            sq = sq + err*err;

            rf = respondent_features(f,respondent);
            mf = item_features(f, item);

            % Cross-train the features
            respondent_features(f, respondent) = respondent_features(f,respondent) + (lrate * (err * mf - k * rf));
            item_features(f, item) = item_features(f, item) + (lrate * (err * rf - k * mf));
           % end
        end

        rmse = sqrt(sq/rating_count);

        %if (e >= min_epochs && rmse > (rmse_last - min_improvement))
        if ((e >= min_epochs) && ((rmse_last - rmse) < min_improvement))
            break;
        end
    end
    % Caching
    for r=1:rating_count
        data(r, 4) = simon_funk_predict_rating(data(r,:), f, 0);
    end 
end

% return new ratings set
for r=1:respondent_count
    for i=1:item_count
        sum = 1;

        for f=1:max_features
            sum = sum + item_features(f,i) * respondent_features(f,r);
            if(sum > 10)
            %    sum = 10;
            end

            if(sum < 1)
             %   sum = 1;
            end

        end
        ratings(r,i) = sum;
    end
end

И функция для прогнозирования индивидуального рейтинга:

function sum = simon_funk_predict_rating(rating, f, bTrailing)
global item_features;
global respondent_features;
global max_features;
global init;
respondent = rating(1,1);
item = rating(1,2);
cache_value = rating(1,4);

sum = 1;
if(cache_value > 0)
    sum = cache_value;
end

sum = sum + (item_features(f,item) * respondent_features(f,respondent));

if (sum > 10) 
    %sum = 10;
end

if (sum < 1) 
    %sum = 1;
end


if (bTrailing == 1)
    sum = sum + (max_features - f - 1) * (init * init);
    if (sum > 10) 
        sum = 10;
    end
    if (sum < 1) 
        sum = 1;
    end
end

Большое спасибо!

0 ответов

Другие вопросы по тегам