在上一篇文章推荐系统—影视评分预测中提出了,几点思考:
=============================一、theta/x的意义?=============================
首先是模型:以下的model1/model2都把user想简单了
(1)model1:给定x=(romance,action),回归优化theta。
首先模型就给x赋予了意义(movie类型),那么可以认为theta也跟着有了意义(喜欢romance or action?)
(2)model2:给定theta=(0, 5, 0),回归优化x。
此模型也给theta赋予了意义(喜欢romance or action?),那么x也跟着有了意义(movie类型romance or action?)
model1/model2存在什么样的问题呢?——把user想得too simple
喜欢action类型的电影的user就会对所有action类型的电影打高分么?
读者一定不会是这个审美。同样跟演员/导演等等是相关的。
这个质疑就是在质疑模型(不是指回归模型)建得simple了,当然对问题建模可以从简单到精细,这也是按着科学的思路来的。
复杂的模型可能此时求解有困难(没有找到方案or硬件设施跟不上等问题),转而研究简单的模型。
那么总结model1与model2就是:
给定一个参数(theta or x)用回归模型优化另一个(x or theta),我们赋予给定参数的意义就可以用来解释预测参数。
(3)还有model3:就是协同过滤——同时优化x/theta
这个跟机器学习里面我们学的 “线性回归”就有差别了,
ML里面都是model1/model2似的:给定(y, X) or (y, Theta)
现在给了一个y,就要 x/theta,还是头一次见。
从优化上面来看:J(x,theta)的凸性看不出来,使用Ng的优化得到的是否是全局最优?
这个问题应该是明确的,但是对于《推荐系统》书看得不多(本身优秀的参考书籍也不多),目测应该是全局最优。
此问题待以后深入《推荐系统》时再去解决。
现在假设model3得到了正确的求解,但是x/theta的意义是什么呢? 此处x/theta的维数是由我们来给定的,code中用的是feature=10
我觉得看不出来什么意义?
再或者我们“意义是什么”?为什么一定要有意义,我们是不是被model1/model2带坏了?一定要找个意义?
那么仅仅从“为了回归y”的目的上来考虑,可以没有“意义”;
没有意义,我们对未评分的预测算是什么呢?—没有model1/model2的模型解释,model3的预测就显得没有道理(意义。。。)。
写到这想到 杨绛给一个年轻人的回信:“读书太少,想得太多”。
这些问题先不深究,待读读书/看看paper来了解目前对此的研究情况。
=============================二、是否对x-feature添加分量1==============================
我是想做个数值实验来着,code做的是协同过滤,x/theta都是未知的随机变量了。那么也就无法对x-feature添加分量1了。
后来做了行均值化,那么对于model1:给定x=(romance,action),回归优化theta,就有点意思了。
。。。一个结论记错了,刚查了下,木有意思了。
所以问题可以是更一般些了:在机器学习中“线性回归”为什么要对x-feature添加分量1?——我查清楚放到评论里。
=============================三、x-feature的意义=============================
这个在<一>中已经论及,这里再整理下:
- model1/model2的模型对某一参数赋予了意义(不一定是romance/action,还可以是其他),另一参数也就有了意义。
- model3找不出什么意义来。
=============================四、词语意义=============================
"基于内容的推荐":
看过《集体智慧编程》,此书第二章:提供推荐,也是在讲推荐系统。其中提到“基于用户过滤”和“基于物品过滤”,跟这个名字很相似,但是套路好像真不一样。待查。
"协同过滤":
看到这个我想到的是——啤酒和尿布,这个好像跟这里的回归模型差别很多,啤酒尿布那块用贝叶斯来搞的,待查。
=============================五、协同过滤code=============================
%% Machine Learning Online Class
clear,clc
%% Part 1: Entering ratings for a new user
movieList = loadMovieList();
my_ratings = zeros(1682, 1);
my_ratings(1) = 4;
my_ratings(98) = 2;
my_ratings(7) = 3;
my_ratings(12)= 5;
my_ratings(54) = 4;
my_ratings(64)= 5;
my_ratings(66)= 3;
my_ratings(69) = 5;
my_ratings(183) = 4;
my_ratings(226) = 5;
my_ratings(355)= 5;
fprintf('\n\nNew user ratings:\n');
for i = 1:length(my_ratings)
if my_ratings(i) > 0
fprintf('Rated %d for %s\n', my_ratings(i), ...
movieList{i});
end
end
%% Part 2: Learning Movie Ratings
% Now, you will train the collaborative filtering model on a movie rating
% dataset of 1682 movies and 943 users%
fprintf('\nTraining collaborative filtering...\n');
% Load data
load('ex8_movies.mat');
%可见评分比例比较小
fprintf('------用户评分百分比:%f-------\n',sum(R(:))/numel(R))
% Add our own ratings to the data matrix
Y = [my_ratings Y];
R = [(my_ratings ~= 0) R];
% Normalize Ratings
[Ynorm, Ymean] = normalizeRatings(Y, R);
% Useful Values
num_users = size(Y, 2);
num_movies = size(Y, 1);
num_features = 10;
% Set Initial Parameters (Theta, X)
X = randn(num_movies, num_features);
Theta = randn(num_users, num_features);
initial_parameters = [X(:); Theta(:)];
% Set options for fmincg
options = optimset('GradObj', 'on', 'MaxIter', 200);
% Set Regularization
lambda = 10;
%优化部分 计算X Theta使costFunction最小
%原代码 此处有误: 需将Y 改为Ynorm
theta = fmincg (@(t)(cofiCostFunc(t, Ynorm, R, num_users, num_movies, ...
num_features, lambda)), ...
initial_parameters, options);
% Unfold the returned theta back into U and W
X = reshape(theta(1:num_movies*num_features), num_movies, num_features);
Theta = reshape(theta(num_movies*num_features+1:end), ...
num_users, num_features);
fprintf('Recommender system learning completed.\n');
%% Part 3: Recommendation for you
% After training the model, you can now make recommendations by computing
% the predictions matrix.
p = X * Theta';
my_predictions = p(:,1) + Ymean;
movieList = loadMovieList();
[r, ix] = sort(my_predictions, 'descend');
%此处代码有点小误,既然是推荐,那么user评过分的movie应该过滤掉,
%以下代码木有过滤
fprintf('\nTop recommendations for you:\n');
for i=1:10
j = ix(i);
fprintf('Predicting rating %.1f for movie %s\n', my_predictions(j), ...
movieList{j});
end
fprintf('\n\nOriginal ratings provided:\n');
%此处简单修改了下,增加了对比
fprintf('----------Movie------------------初始化评分----------预测评分-------\n')
for i = 1:length(my_ratings)
if my_ratings(i) > 0
fprintf('%-36s %d %4.3d\n', movieList{i}, my_ratings(i), my_predictions(i))
end
end
输出:
Part 1: Entering ratings for a new user
Part 2: Learning Movie Ratings
Part 3: Recommendation for you