[筆記] 機器學習 推薦系統 ( Recommender Systems )
以下例子會用到這些 :
- nu : 使用者人數
- nm : 電影數量
- r(i, j) : 如果使用者 j 有評價電影 i,則 r(i, j) 為 1
- y(i, j) : 使用者 j 對於電影 i 的評價 ( 前提是 r(i, j) 為 1 )
基於內容推薦 ( content based recommendations )
- 使用線性回歸來預測
對於每個使用者 j,訓練出 θ(j) ( 因為有 n + 1 項特徵值,包含 x0 ),使用 $(\theta^{(j)})^Tx^{(i)}$ 預測使用者 j 對於電影 i 的評價
- θ(j) 為使用者 j 對應的參數向量
x(i) 為電影 i 的特徵值 ( 包含 x0 = 1 )
- 例如 : x1 為此電影的愛情成分比率、x2 為此電影的動作成分比率
$(\theta^{(j)})^Tx^{(i)}$ 用來預測使用者 j 對於電影 i 的評價
- m(j) 為使用者 j 評價過的電影數
學習使用者 j 的參數向量 θ(j) ( 以下線性回歸已去掉常數 m )
學習所有使用者的參數向量 θ(1),θ(2),…,θ(nu)
梯度下降更新
協同過濾 CF ( Collaborative Filtering )
- 一種建構推薦系統的方法
- 上述的基於內容推薦方法需要自行設定電影特徵值 ( 愛情成分比率、動作成分比率 ),此方法可以自行學習所要使用的特徵
使用 θ(1),θ(2),…,θ(nu) 學習 x(i)
使用 θ(1),θ(2),…,θ(nu) 學習所有電影的特徵值 x(1),x(2),…,x(nm)
這樣我們究竟要用 x(i) 學習 θ(j),還是用 θ(j) 學習 x(i) 呢
- 可以先猜測出 θ(j)
- 使用此 θ(j) 學習出 x(i)
- 再用上面學習出的 x(i) 優化出新的 θ(j)
- 不斷循環,最後得到收斂
演算法
用 x(1),x(2),…,x(nm) 學習 θ(1),θ(2),…,θ(nu)
用 θ(1),θ(2),…,θ(nu) 學習 x(1),x(2),…,x(nm)
結合上面兩個的代價函數
這樣就不用反覆計算 θ(j) 與 x(i),只需將兩組參數同時化簡
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35function [J, grad] = cofiCostFunc(params, Y, R, num_users, num_movies, ...
num_features, lambda)
X = reshape(params(1:num_movies*num_features), num_movies, num_features);
Theta = reshape(params(num_movies*num_features+1:end), num_users, num_features);
J = 0;
X_grad = zeros(size(X));
Theta_grad = zeros(size(Theta));
predict = (X * Theta') .* R;
J = (1 / 2) * sum(sum((predict - Y) .^ 2)) + (lambda / 2) * sum(sum(Theta .^ 2)) + (lambda / 2) * sum(sum(X .^ 2));
% 梯度下降
for i = 1:num_movies
idx = find(R(i, :) == 1);
Thetatemp = Theta(idx, :);
Ytemp = Y(i, idx);
X_grad(i, :) = (X(i, :) * Thetatemp' - Ytemp) * Thetatemp + lambda * X(i, :);
end
for i=1:num_users
idx = find(R(:, i) == 1);
Xtemp = X(idx, :);
Ytemp = Y(idx, i);
Theta_grad(i, :) = (Xtemp * Theta(i, :)' - Ytemp)' * Xtemp + lambda * Theta(i, :);
end
grad = [X_grad(:); Theta_grad(:)];
end在 Octave 上算出代價函數並梯度下降找最小的函式
而 x0 的固定值也不需要了,因為機器會自行學習特徵值,若需要固定值,機器會自行學習出來
- 既然不需要 x0 了,想當然也就沒有 θ0 了
步驟 :
用小的數值隨機初始化 x(1),…,x(nm),θ(1),…,θ(nu)
- 打破對稱 ( 類似神經網路的隨機初始化 ),確保特徵值彼此不同
使用梯度下降 ( 或高級優化算法 ) 來最小化代價函數
- 若某個使用者具有參數 θ,某個電影也具有了參數 x,假如這個使用者尚未對此電影評分,我們就可以使用 $θ^Tx$ 來預測他的評分
向量化實現 : 低秩矩陣分解 ( Low rank matrix factorization )
Y = $\begin{bmatrix} 5 & 5 & 0 & 0 \ 5 & ? & ? & 0 \ ? & 4 & 0 & ? \ 0 & 0 & 5 & 4 \ 0 & 0 & 5 & 0 \end{bmatrix}$
- 使用者對每部電影的評分
X = $\begin{bmatrix} … & (x^{(1)})^T & … \ … & (x^{(2)})^T & … \ … & … & … \ … & (x^{(1)})^T & … \end{bmatrix}$
- Θ = $\begin{bmatrix} … & (θ^{(1)})^T & … \ … & (θ^{(2)})^T & … \ … & … & … \ … & (θ^{(1)})^T & … \end{bmatrix}$
- XΘT =
如何使用學習到的特徵值找到與電影 i 最相似的電影 j 推薦給使用者呢
- 找出最小值的 $||x^{(i)} - x^{(j)}||$
均值歸一化
使用原因 :
- 當有新的使用者加入時,因為尚未評分任何電影
- 為了最小化代價函數,此使用者的參數 θ 都會是 0 ( 正規化式子 : $\dfrac{\lambda}{2}\sum^{nu}{j = 1}sum^{n}_{k = 1}(\theta_k^{(j)})^2$ 所影響 )
- 這會造成不管甚麼電影經過 θTx 結果都會是 0
- 就沒有任何預測較高評價的電影推薦給他
使用方法 :
Y = $\begin{bmatrix} 5 & 5 & 0 & 0 & ? \ 5 & ? & ? & 0 & ? \ ? & 4 & 0 & ? & ? \ 0 & 0 & 5 & 4 & ? \ 0 & 0 & 5 & 0 & ? \end{bmatrix}$
- 最後一行是新加入的使用者
μ = $\begin{bmatrix} 2.5 \ 2.5 \ 2 \ 2.25 \ 1.25 \end{bmatrix}$
- 將每部電影的所有評分做平均
Y = $\begin{bmatrix} 2.5 & 2.5 & -2.5 & -2.5 & ? \ 2.5 & ? & ? & -2.5 & ? \ ? & 2 & -2 & ? & ? \ -2.25 & -2.25 & 2.75 & 1.75 & ? \ -1.25 & -1.25 & 3.75 & -1.25 & ? \end{bmatrix}$
- 再將 Y 的所有評分減掉他們的平均
- 用此 Y 來學習 θ(j)、x(i)
使用 $(\theta^{(j)})^Tx^{(i)} + \mu_i$ 來預測
新加入的使用者就算 θ 為 0,也有基本的平均評分
- Y = $\begin{bmatrix} 5 & 5 & 0 & 0 & 2.5 \ 5 & ? & ? & 0 & 2.5 \ ? & 4 & 0 & ? & 2 \ 0 & 0 & 5 & 4 & 2.25 \ 0 & 0 & 5 & 0 & 1.25 \end{bmatrix}$