日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

协同滤波模型的推荐算法(ACM暑校-案例学习)

發布時間:2025/3/15 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 协同滤波模型的推荐算法(ACM暑校-案例学习) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

基于協同濾波的推薦技術可以細分為基于用戶的協同過濾方法、基于產品的協同過濾方法、基于模型的協同過濾方法;本博文進行了一一測試。

1. 數據準備、評價指標

由于協同濾波模型需要用到用戶的行為,這里選用MovieLen數據集進行測試研究。

MovieLen是明尼蘇達大學計算機科學系GroupLens研究中心開發和維護的,也是最常用于測試協同濾波算法性能的公開數據集之一。Movielens提供了大量電影的用戶評分。完整的版本包括超過了26000000的電影評分,他們來源于270000用戶觀看45000部電影的體會。GroupLens網站上提供的數據集不再提供用戶人口統計信息。因此,這里使用Prajit-Datta在kaggle上提供的部分數據集。

  • 數據下載

下載地址:https://www.kaggle.com/prajitdatta/movielens-100k-dataset/data?

該數據集包括:1682部電影上943名用戶的100000個評分(1-5)。每個用戶至少為20部電影打分。該數據集也為用戶提供簡單的人口統計信息(年齡、性別、工作等)。這些數據是在1997年9月19日至1998年4月22日的七個月期間通過Movielens網站(movielens.umn.edu)收集的。此數據已被清除-從該數據集中刪除了評分低于20或沒有完整人口統計信息的用戶。

  • 數據瀏覽

在解壓文件中,只需要使用u.date/ u.user/ u.item三個文件。

① 查看用戶圖譜文件

import pandas as pd# load the u.user file into a dataframe u_cols = ['user_id', 'age', 'sex', 'occupation', 'zip_code'] users = pd.read_csv('C:/Users/Administrator/Desktop/RecoSys/data/movielens/u.user', sep='|',names=u_cols, encoding='latin-1') users.head()

可以看到,u.user文件中主要包含的用戶圖譜,如年齡,性別,職業,zip_code。

② 查看電影描述文件

i_cols = ['movie_id', 'title', 'release date', 'video release date', 'IMDB URL', 'unknow', 'Action', 'Adventure', 'Animation', 'Children\'s', 'Comedy', 'Crime', 'Documentary', 'Drama', 'Fantasy', 'Film-Noir', 'Horror', 'Musical', 'Mystery', 'Romance', 'Sci-Fi', 'Thriller', 'War','Western'] movies = pd.read_csv('C:/Users/Administrator/Desktop/RecoSys/data/movielens/u.item',sep='|', names=i_cols, encoding='latin-1') movies.head()

可以看出,u.item文件中主要提供了電影的名字、發行時間、IMDB URL和題材等信息。因為,本編博客主要研究的是協同濾波算法,因此,電影中的題材等是用不到的,只需要保留movie_id和title就好。

movies = movies[['movie_id', 'title']] movies.head()

③ 查看用戶對電影評分文件

r_cols = ['user_id', 'movie_id', 'rating', 'timestamp'] ratings = pd.read_csv('C:/Users/Administrator/Desktop/RecoSys/data/movielens/u.data',sep='\t', names=r_cols, encoding='latin-1') ratings.head()

  • 訓練數據?training data & 測試數據 test data

DataFrame包含從1-5的用戶對電影的評分。因此,可以將該問題建模為監督學習的實例,目的在于預測給定用戶和電影的評分。雖然電影的分數只是1-5的五個離散值,其實質仍為回歸問題。考慮用戶對電影的真實評分是5:分類模型不能區分預測評分為1和4的情況。分類模型會將1-4的評分都視為錯誤分類。然而,回歸模型卻不是這樣子,其對rating=4的懲罰遠遠大于rating=1的情況。

對于監督模型的學習,重要的一步在于訓練集和測試集的劃分。在本次試驗中,用戶評分數據中的75%用作模型訓練,25%用于模型測試

from sklearn.model_selection import train_test_split X = ratings.copy() y = ratings['user_id'] # split into training and test datasets, stratified along user_id X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, stratify=y, random_state=42)>>> X_train.shape = (75000, 3) X_test.shape = (25000, 3)
  • 評估方法

這里選用根均方差(RMSE=root-mean-square-error)對模型的推薦性能進行評估。其Python實現如下所示:

from sklearn.metrics import mean_squared_error from numpy as npdef rmse(y_true, y_pred):return np.sqrt( mean_squared_error(y_true, y_pred) )# Function to compute the RMSE score obtained on the testing set by a model def score(cf_model):# Construct a list of user-movie tuples from the testing datasetid_pairs = zip(X_test['user_id'], X_test['movie_id'])# Predict the rating for every user-movie tupley_pred = np.array([cf_model(user, movie) for (user, movie) in id_pairs])# Extract the actual ratings given by the users in the test datay_true = np.array(X_test['rating'])# Return the final RMSE scorereturn rmse(y_true, y_pred)

2. 基于用戶的協同過濾推薦算法實例 Users-based

基于用戶的協同推薦算法把主要的研究精力放在用戶角度,實質上就是具有相同興趣的用戶群體進行聚類,然后對相同類群的用戶進行產品推薦。核心在于對高度稀疏的用戶-產品矩陣進行預測和填充。PANDAS提供了一個非常好用的函數pivot_table去構造rating矩陣:

# Build the ratings matrix using pivot_table function r_matrix = X_train.pivot_table(values='rating', index='user_id', columns='movie_id') r_matrix.head(5)

該矩陣就是推薦領域最最重要的了:①用戶-產品矩陣是高度稀疏的;②實際應用過程中,從用戶和產品兩個維度考慮,評分矩陣是非常非常巨大的。

  • 均值Mean角度初步考慮

首先可以構建一個最簡單的協同過濾算法,只需輸入用戶ID和電影ID,并輸出所有看過的用戶對該電影的平均評分。用戶之間沒有區別。換言之,每個用戶的評分被賦予相等的權重。其中,有一種完全可能異常情況:有些電影只能在測試數據集進行訪問,而在訓練數據集不存在。該情況下,我們直接設置一個baseline,將其默認賦值為3.0。

# User Based Collaborative Filter using MEan Rating def cf_user_mean(user_id, movie_id):# Check if movie_id exists in r_matrixif movie_id in r_matrix:# Compute the mean of all the ratings given to the moviemean_rating = r_matrix[movie_id].mean()else:# Default to a rating of 3.0 in the absence of any informationmean_rating = 3.0return mean_rating# Compute RMSE for the Mean model score(cf_user_mean)>>> 1.0234701463131335

該方法僅僅適合討論研究,是沒有實際應用價值的:一方面,用戶對產品的評分肯定會有偏好;另一方面,大部分少數群體的興趣沒有被認真關注。一種合適的改進方法是采用加權平均weighted mean。

  • 加權均值weighted mean角度考慮

在前面的模型中,我們為每一個用戶分配了等同的權重。然而,與普通用戶相比,對那些評分與所討論問題相似的用戶給予更多的關注。因此,在前面的模型中,比較合適的方案是為每一個用戶分配一個合適的權重系數。數學可以表示為:

其中,r(u,m)表示為用戶u對電影m的評分。對于相似度測量,同樣采用余弦距離。

數據處理:將rating表中的NAN替換成0,然后用scikit-learn中的cosine_similarity函數進行處理。

r_matrix_dummy = r_matrix.copy().fillna(0) r_matrix_dummy.head() r_matrix_dummy.shape>>> (943, 1647)

from sklearn.metrics.pairwise import cosine_similarity cosine_sim = cosine_similarity(r_matrix_dummy, r_matrix_dummy) cosine_sim.shape>>> (943, 943) # Convert into pandas dataframe cosine_sim = pd.DataFrame(cosine_sim, index=r_matrix.index, columns=r_matrix.index) cosine_sim.head()

# User Based Collabrative Filter using Weighted Mean Ratings def cf_user_wmean(user_id, movie_id):# Check if movie_id exists in r_matrixif movie_id in r_matrix:sim_scores = cosine_sim[user_id]m_ratings = r_matrix[movie_id]idx = m_ratings[m_ratings.isnull()].indexm_ratings = m_ratings.dropna()sim_scores = sim_scores.drop(idx)wmean_rating = np.dot(sim_scores, m_ratings)/ sim_scores.sum()else:#Default to a rating of 3.0 in the absence of any informationwmean_rating = 3.0return wmean_ratingscore(cf_user_wmean)>>> 1.0174483808407588
  • 用戶圖譜demographics角度考慮

這是一種相對而言更加精細的處理方式。該算法的核心思想是,具有相同圖譜的用戶傾向于有相似的品味。因此,其有效性取決于這樣的假設:女性、青少年或來自同一地區的人在電影選擇時會有相同的品味。與前面的模型不同,該種算法不考慮用戶對特定電影的評分。相反,算法只關注那些符合特定人群的用戶。

3.?基于產品的協同過濾推薦算法實例 Items-based

Items-based和User-based方法本質是一致的,就相當于將第二節中的User變成Item。在基于產品的協同過濾中,我們計算庫存中產品的成對相似性。然后,根據user_id和movie_id,計算用戶對其所有評分產品的加權平均值。這個模型背后的基本思想是:一個特定的用戶可能會對相似的兩個產品有相似的評分。

4. 基于模型的方法 Model-based

到目前為止,上面的協同過濾算法被稱為memory-based的過濾。因為他們只利用相似性度量來得出結果,并沒有從數據中學習任何參數,或者為數據分配類/集群。并沒有用到機械學習算法的威力。

  • 以聚類為核心的協同過濾算法 - Clustering

weighted mean-based 的濾波算法,考慮到了每一位用戶的評分,最后進行加權;相反,demographic-based濾波算法僅僅考慮了‘某個圈子’的用戶,最后進行平均。通常來說,weighted mean-based取得的結果會好于demographic-based,因為考慮的相對來說更廣一點。但是,這兩種方法僅僅用到了最直接、最粗淺的信息,一種解決方案是進行多維度用戶刻畫,進行利用機器學習算法解決高緯度數據處理問題。簡單說,精準的推薦結果不一定唯一依賴考慮所有用戶的感受!

demographic-based算法的缺點來源于他的假設:來自某個相同圖譜的用戶具有相同的想法和評分。這種極端的思考模式造成了算法的粗淺。Clustering-based方法,如k-means, 就是為了改善這種情況:將用戶分組到一個群集中,然后在預測評分時只考慮來自同一個群集中的用戶。下面以KNN-based clustering為例,構建相關的協同過濾算法。步驟如下 ①找出與用戶u對電影m評分最相似的k個最近鄰;②輸出k個用戶對電影m評分的平均值。

可以直接采用Python中的surprise(Simple Python Recommandation System Engine)庫實現。Windows 平臺下下載方式為:pip install scikit-surprise.

# Import the required classes and methods from the surprise library from surprise import Reader, Dataset, KNNBasic, evaluate # Define a Reader object - The Reader object helps in parsing the file or dataframe containing ratings reader = Reader() # Create the dataset to be used for building the filter data = Dataset.load_from_df(ratings, reader) # Define the algorithm object knn = KNNBasic() # Evaluate the performance in terms of RMSE evaluate(knn, data, measures=['RMSE'])

從輸出結果中,我們能夠看出來。surprise庫將所有的評分數據劃分為5個文件包,其中4個文件包用于算法訓練,第5個文件包用于模型測試。這樣的過程重復了5次。

  • 監督學習和降維方法

對于mxn大小的評分矩陣,每一行代表m個用戶中的一個對所有電影的評分;每一列代表n個電影中的一個接受所有用戶的評分。前面已經看到了,該評分矩陣是非常稀疏的。通過監督學習的方法,我們可以嘗試將這個高度稀疏的矩陣補全。

最簡單的思考是,我們可以利用mx(n-1)的評分矩陣進行模型的監督訓練,然后對m*1的未知評分進行預測。如此重復n次,那么評分矩陣將有可能完全被填充。理想是豐滿的,現實的骨感的。因為,一開始我們用的mx(n-1)的模型訓練矩陣就是高度稀疏的~~~(目前也沒辦法解決這個事,工程上的一種處理手段是用所屬的列的均值或中值來填充缺失值,但是考慮到rating矩陣高達90%的系數,計算的均值和中位數一定會引進很大的偏差;同時降維技術,PCA/SVD也不能處理如此稀疏的情況

可以借鑒的一種思路是,Simon Funk在處理Netflix Problem時,將mx(n-1)的模型訓練矩陣壓縮到了更低的維度mxd (d << n),這種處理方式稱為SVD-like,其實效果也比較一般。

  • 火極一時的推薦算法-奇異值分解 Singular-value decomposition

本質上,奇異值分解是一種矩陣因子技術,其輸入為大型矩陣A,輸出為小矩陣U和V。其中,Σ為對角矩陣用于吃調整數據的尺度。對于U矩陣,其實質表征的是用戶主成分,英文專有名詞對應user-embedding矩陣;V矩陣,其實質表征的是產品主成分,英文專有名詞對應item-embedding矩陣。

和大多數機器學習算法一樣,傳統的SVD矩陣對極其稀疏的評分矩陣是沒有效益的。然而,SimonFunk找到了解決這個問題的方法,他的解決方案(SVD++)促成了了推薦系統領域最著名的算法之一。該方法可以利用高度稀疏的評分矩陣A,生成兩個非常稠密的user-embedding矩陣U和item-embedding矩陣V。這些稠密的矩陣(U,V)直接解決了原始數據A高度稀疏的難題。surprise庫也集成了該算法,調用如下:

#Import SVD from surprise import SVD #Define the SVD algorithm object svd = SVD() #Evaluate the performance in terms of RMSE evaluate(svd, data, measures=['RMSE'])

?

總結

以上是生活随笔為你收集整理的协同滤波模型的推荐算法(ACM暑校-案例学习)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。