一、FunkSVD算法原理
FunkSVD 算法是一種基於矩陣分解模型的協同過濾算法,其核心思想是基於用戶和物品之間的關聯關係,將用戶-物品矩陣分解為用戶和物品兩個矩陣的乘積,再通過矩陣乘法計算出每個用戶對每個物品的評分得分,從而實現推薦系統的效果。
假設有 m 個用戶 u1, u2, … , um,n 個物品 i1, i2, … , in,用戶-物品矩陣為 R(mxn),其中 R[i][j] 表示用戶 i 對物品 j 的評分得分,分值為 1~5 分。FunkSVD 算法採用矩陣分解模型,通過分解用戶-物品矩陣,得到兩個分解矩陣:用戶特徵矩陣 P(mxr) 和物品特徵矩陣 Q(nxr),其中 r 為低維特徵向量的個數,P 矩陣表示用戶對各個特徵的喜好程度,Q 矩陣表示各個物品在不同的特徵上的得分表現。則用戶 i 對物品 j 的預測得分可以通過式子計算:R[i][j] ≈ P[i,:]Q[j,:].T
二、FunkSVD 算法優劣性分析
FunkSVD 算法是一種有效的協同過濾推薦算法,具有如下優劣性:
1、優點:
(1)可用於處理高維、稀疏的用戶數據,能夠處理較大規模的用戶-物品評分矩陣,適用於大數據場景;
(2)和其他算法相比,FunkSVD 算法在準確性上有一定優勢,可以提供較為精確的推薦結果;
2、缺點:
(1)需要對矩陣分解中的超參數進行調整,才能夠獲得最佳的分解效果;
(2)FunkSVD 算法在處理冷啟動問題(新物品和新用戶)時,表現較差。
三、基於 Python 實現 FunkSVD 算法
import pandas as pd import numpy as np class FunkSVD: def __init__(self, learning_rate=0.01, reg_rate=0.1, n_epochs=100, n_factors=15, verbose=True): """ FunkSVD算法的初始化方法 :param learning_rate: 學習率 :param reg_rate: 正則化係數 :param n_epochs: 迭代次數 :param n_factors: 隱特徵向量維度 :param verbose: 是否打印訓練過程log """ self.learning_rate = learning_rate self.reg_rate = reg_rate self.n_epochs = n_epochs self.n_factors = n_factors self.verbose = verbose def fit(self, X, val_data=None): """ FunkSVD算法的訓練方法 :param X: 用戶-物品評分矩陣 :param val_data: 驗證數據,用於退出訓練 :return: 用戶特徵矩陣P和物品特徵矩陣Q的乘積 """ # 初始化變量 n_users, n_items = X.shape self.P = np.random.normal(size=(n_users, self.n_factors)) self.Q = np.random.normal(size=(n_items, self.n_factors)) # 訓練模型 for epoch in range(self.n_epochs): for i in range(n_users): for j in range(n_items): if X[i][j] > 0: error = X[i][j] - np.dot(self.P[i, :], self.Q[j, :].T) self.P[i, :] += self.learning_rate * (error * self.Q[j, :] - self.reg_rate * self.P[i, :]) self.Q[j, :] += self.learning_rate * (error * self.P[i, :] - self.reg_rate * self.Q[j, :]) # 計算驗證集誤差 if val_data is not None: y_true, y_pred = self.evaluate(val_data) val_loss = np.sqrt(np.mean(np.power(y_true - y_pred, 2))) if self.verbose: print('epoch %d, val_loss=%.4f' % (epoch + 1, val_loss)) return np.dot(self.P, self.Q.T) def predict(self, u, i): """ 預測用戶對物品的評分 :param u: 用戶ID :param i: 物品ID :return: 預測評分得分 """ return np.dot(self.P[u, :], self.Q[i, :].T) def evaluate(self, test_data): """ 評估算法效果 :param test_data: 測試數據 :return: 真實值和預測值 """ y_true = test_data['rating'] y_pred = [self.predict(row['userId'], row['movieId']) for i, row in test_data.iterrows()] return y_true, y_pred
四、FunkSVD 算法在電影推薦系統中應用實例
FunkSVD 算法可以應用於電影推薦系統中,根據用戶對電影的評分得分,建立用戶-電影評分矩陣,然後使用 FunkSVD 算法對評分矩陣進行分解,得到用戶和電影的特徵矩陣 P 和 Q,進而計算出每個用戶對未評價電影的評分得分,根據得分得齣電影推薦結果。以下是基於 FunkSVD 算法實現的推薦系統代碼示例:
import pandas as pd import numpy as np from sklearn.model_selection import train_test_split from FunkSVD import FunkSVD # 讀取數據 ratings = pd.read_csv('ratings.csv') # 將評分矩陣轉換為二維矩陣形式 R = ratings.pivot_table(values='rating', index='userId', columns='movieId').fillna(0) # 劃分訓練集和測試集 train, test = train_test_split(ratings, test_size=0.2) # 初始化 FunkSVD 模型 funk_svd = FunkSVD(n_epochs=50, n_factors=30, verbose=True) # 訓練模型 funk_svd.fit(train.pivot_table(values='rating', index='userId', columns='movieId').fillna(0), val_data=test) # 電影推薦 user_id = 1 user_ratings = ratings[ratings['userId'] == user_id] user_unseen_movies = ratings[~ratings['movieId'].isin(user_ratings['movieId'])]['movieId'].unique() recommendations = [] for movie_id in user_unseen_movies: rating = funk_svd.predict(user_id - 1, movie_id - 1) recommendations.append((movie_id, rating)) # 推薦電影排序並輸出 recommendations = sorted(recommendations, key=lambda x: x[1], reverse=True)[:10] recommended_movie_ids = [rec[0] for rec in recommendations] recommended_movies = ratings[ratings['movieId'].isin(recommended_movie_ids)]['title'].unique() print('為用戶推薦的電影有:') for movie in recommended_movies: print(movie)
五、小結
FunkSVD 算法是一種有效的協同過濾推薦算法,能夠對稀疏高維的用戶-物品評分矩陣進行分解,得到用戶和物品的特徵矩陣,進而計算出每個用戶對所有物品的評分得分,用於電影推薦、商品推薦等領域。通過 Python 實現 FunkSVD 算法,並結合電影推薦應用案例,進一步深化了該算法的理解,有助於進一步掌握協同過濾算法的基本原理和應用。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/286496.html