# [筆記] 機器學習 推薦系統 ( Recommender Systems )
* 以下例子會用到這些 :
* n<sub>u</sub> : 使用者人數
* n<sub>m</sub> : 電影數量
* r(i, j) : 如果使用者 j 有評價電影 i,則 r(i, j) 為 1
* y<sup>(i, j)</sup> : 使用者 j 對於電影 i 的評價 ( 前提是 r(i, j) 為 1 )
### 基於內容推薦 ( content based recommendations )
* 使用線性回歸來預測
* 對於每個使用者 j,訓練出 θ<sup>(j)</sup> ( 因為有 n + 1 項特徵值,包含 x<sub>0</sub> ),使用 $(\theta^{(j)})^Tx^{(i)}$ 預測使用者 j 對於電影 i 的評價
* θ<sup>(j)</sup> 為使用者 j 對應的參數向量
* x<sup>(i)</sup> 為電影 i 的特徵值 ( 包含 x<sub>0</sub> = 1 )
* 例如 : x<sub>1</sub> 為此電影的愛情成分比率、x<sub>2</sub> 為此電影的動作成分比率
* $(\theta^{(j)})^Tx^{(i)}$ 用來預測使用者 j 對於電影 i 的評價
* m<sup>(j)</sup> 為使用者 j 評價過的電影數
* 學習使用者 j 的參數向量 θ<sup>(j)</sup> ( 以下線性回歸已去掉常數 m )
* 
* 學習所有使用者的參數向量 θ<sup>(1)</sup>,θ<sup>(2)</sup>,...,θ<sup>(n<sub>u</sub>)</sup>
* 
* 梯度下降更新
* 
### 協同過濾 CF ( Collaborative Filtering )
* 一種建構推薦系統的方法
* 上述的基於內容推薦方法需要自行設定電影特徵值 ( 愛情成分比率、動作成分比率 ),此方法可以自行學習所要使用的特徵
* 使用 θ<sup>(1)</sup>,θ<sup>(2)</sup>,...,θ<sup>(n<sub>u</sub>)</sup> 學習 x<sup>(i)</sup>
* 
* 使用 θ<sup>(1)</sup>,θ<sup>(2)</sup>,...,θ<sup>(n<sub>u</sub>)</sup> 學習所有電影的特徵值 x<sup>(1)</sup>,x<sup>(2)</sup>,...,x<sup>(n<sub>m</sub>)</sup>
* 
* 這樣我們究竟要用 x<sup>(i)</sup> 學習 θ<sup>(j)</sup>,還是用 θ<sup>(j)</sup> 學習 x<sup>(i)</sup> 呢
* 可以先猜測出 θ<sup>(j)</sup>
* 使用此 θ<sup>(j)</sup> 學習出 x<sup>(i)</sup>
* 再用上面學習出的 x<sup>(i)</sup> 優化出新的 θ<sup>(j)</sup>
* 不斷循環,最後得到收斂
#### 演算法
* 用 x<sup>(1)</sup>,x<sup>(2)</sup>,...,x<sup>(n<sub>m</sub>)</sup> 學習 θ<sup>(1)</sup>,θ<sup>(2)</sup>,...,θ<sup>(n<sub>u</sub>)</sup>
* 
* 用 θ<sup>(1)</sup>,θ<sup>(2)</sup>,...,θ<sup>(n<sub>u</sub>)</sup> 學習 x<sup>(1)</sup>,x<sup>(2)</sup>,...,x<sup>(n<sub>m</sub>)</sup>
* 
* 結合上面兩個的代價函數
* 
* 這樣就不用反覆計算 θ<sup>(j)</sup> 與 x<sup>(i)</sup>,只需將兩組參數同時化簡
```Octave=
function [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 上算出代價函數並梯度下降找最小的函式
* 而 x<sub>0</sub> 的固定值也不需要了,因為機器會自行學習特徵值,若需要固定值,機器會自行學習出來
* 既然不需要 x<sub>0</sub> 了,想當然也就沒有 θ<sub>0</sub> 了
* 步驟 :
1. 用小的數值隨機初始化 x<sup>(1)</sup>,...,x<sup>(n<sub>m</sub>)</sup>,θ<sup>(1)</sup>,...,θ<sup>(n<sub>u</sub>)</sup>
* 打破對稱 ( 類似神經網路的隨機初始化 ),確保特徵值彼此不同
2. 使用梯度下降 ( 或高級優化算法 ) 來最小化代價函數
3. 若某個使用者具有參數 θ,某個電影也具有了參數 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Θ<sup>T</sup> = 
如何使用學習到的特徵值找到與電影 i 最相似的電影 j 推薦給使用者呢
* 找出最小值的 $||x^{(i)} - x^{(j)}||$
#### 均值歸一化
* 使用原因 :
* 當有新的使用者加入時,因為尚未評分任何電影
* 為了最小化代價函數,此使用者的參數 θ 都會是 0 ( 正規化式子 : $\dfrac{\lambda}{2}\sum^{n_u}_{j = 1}sum^{n}_{k = 1}(\theta_k^{(j)})^2$ 所影響 )
* 這會造成不管甚麼電影經過 θ<sup>T</sup>x 結果都會是 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 來學習 θ<sup>(j)</sup>、x<sup>(i)</sup>
* 使用 $(\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}$
###### tags: `筆記` `機器學習` `推薦系統` `協同過濾`