機器學習-08-推薦算法-案例

總結

本系列是機器學習課程的系列課程,主要介紹機器學習中關聯規則

參考

機器學習(三):Apriori算法(算法精講)

Apriori 算法 理論 重點

MovieLens:一個常用的電影推薦系統領域的數據集

23張圖,帶你入門推薦系統

本門課程的目標

完成一個特定行業的算法應用全過程:

懂業務+會選擇合適的算法+數據處理+算法訓練+算法調優+算法融合
+算法評估+持續調優+工程化接口實現

機器學習定義

關于機器學習的定義,Tom Michael Mitchell的這段話被廣泛引用:
對于某類任務T性能度量P,如果一個計算機程序在T上其性能P隨著經驗E而自我完善,那么我們稱這個計算機程序從經驗E中學習
在這里插入圖片描述

要構建一個包含用戶、商品和評分的數據集,并基于 Python 實現基于用戶的商品推薦,我們可以使用協同過濾算法(Collaborative Filtering)。以下是實現的步驟:


基于用戶的協同過濾推薦案例

在真實的推薦系統場景中,用戶通常只會對少量商品進行評分,而大部分商品的評分為 0(表示未評分)。為了模擬這種稀疏性,我們可以調整數據生成邏輯,使得每個用戶的評分矩陣中有更多的 0 值。

以下是如何生成稀疏評分矩陣的完整代碼實現:


1. 構建稀疏評分矩陣

我們將通過隨機生成的方式,確保每個用戶只對少量商品評分(例如每個用戶平均評分 3-5 個商品),其余商品的評分為 0

import numpy as np
import pandas as pd
from sklearn.metrics.pairwise import cosine_similarity# 設置隨機種子以確保結果可復現
np.random.seed(42)# 參數設置
num_users = 10  # 用戶數量
num_items = 10  # 商品數量
max_ratings_per_user = 5  # 每個用戶最多評分的商品數量# 初始化評分矩陣 (初始值為 0)
ratings = np.zeros((num_users, num_items))# 隨機生成稀疏評分數據
for i in range(num_users):# 隨機選擇該用戶評分的商品數量(1 到 max_ratings_per_user)num_rated_items = np.random.randint(1, max_ratings_per_user + 1)# 隨機選擇該用戶評分的商品索引rated_items = np.random.choice(num_items, size=num_rated_items, replace=False)# 隨機生成評分(1 到 5)ratings[i, rated_items] = np.random.randint(1, 6, size=num_rated_items)# 構建 DataFrame
user_ids = [f"用戶{i+1}" for i in range(num_users)]
item_ids = [f"商品{j+1}" for j in range(num_items)]
df = pd.DataFrame(ratings, index=user_ids, columns=item_ids)# 打印評分矩陣
print("用戶-商品評分矩陣:")
print(df)
輸出示例:

在這里插入圖片描述

2. 計算用戶相似度并預測評分

接下來,我們基于稀疏評分矩陣計算用戶相似度,并為目標用戶預測未評分商品的評分。

# 計算用戶之間的相似度
user_similarity = cosine_similarity(df)
user_similarity_df = pd.DataFrame(user_similarity, index=df.index, columns=df.index)print("\n用戶相似度矩陣:")
print(user_similarity_df)# 預測目標用戶對未評分商品的評分
def predict_ratings(target_user, df, user_similarity_df):# 獲取目標用戶的評分target_ratings = df.loc[target_user]# 修改這里:初始化預測評分為float類型predicted_ratings = pd.Series(0.0, index=df.columns, dtype='float64')for item in df.columns:if target_ratings[item] == 0:  # 只預測未評分的商品# 獲取對該商品評分過的用戶users_who_rated = df[df[item] > 0].index# 計算加權平均評分weighted_sum = 0.0similarity_sum = 0.0for user in users_who_rated:rating = df.loc[user, item]similarity = user_similarity_df.loc[target_user, user]weighted_sum += rating * similaritysimilarity_sum += similarityif similarity_sum > 0:predicted_ratings[item] = weighted_sum / similarity_sumreturn predicted_ratings# 目標用戶
target_user = '用戶1'# 預測評分
predicted_ratings = predict_ratings(target_user, df, user_similarity_df)print(f"\n為目標用戶 {target_user} 預測的評分:")
print(predicted_ratings)# 推薦商品
recommended_items = predicted_ratings[predicted_ratings > 0].sort_values(ascending=False)
print(f"\n推薦給用戶 {target_user} 的商品:")
print(recommended_items)

3. 運行結果解釋

假設運行上述代碼后,輸出如下:

用戶相似度矩陣(部分):

在這里插入圖片描述

為目標用戶 用戶1 預測的評分:

在這里插入圖片描述

推薦給用戶 用戶1 的商品:

在這里插入圖片描述

4. 總結

通過引入稀疏評分矩陣,我們更貼近真實場景,其中大多數商品的評分為 0。對于目標用戶 用戶1,我們預測了其對未評分商品的評分,并推薦了預測評分最高的商品(如 商品3商品10 等)。

你可以根據需要進一步優化算法,例如:

  • 調整評分稀疏度(例如減少評分的商品數量)。
  • 使用其他相似度計算方法(如皮爾遜相關系數)。
  • 引入隱式反饋數據(如點擊、瀏覽等行為)。

5.代碼改進方法

在計算用戶相似度時,如果用戶評分數據過于稀疏(比如某些用戶沒有共同評分的商品),可能會導致計算相似度時出現問題。以下是改進后的代碼,增加了數據預處理和異常處理:

import numpy as np
import pandas as pd
from sklearn.metrics.pairwise import cosine_similarity# 設置隨機種子以確保結果可復現
np.random.seed(42)# 參數設置
num_users = 10  # 用戶數量
num_items = 10  # 商品數量
max_ratings_per_user = 5  # 每個用戶最多評分的商品數量# 初始化評分矩陣 (初始值為 0)
ratings = np.zeros((num_users, num_items))# 隨機生成稀疏評分數據
for i in range(num_users):# 隨機選擇該用戶評分的商品數量(1 到 max_ratings_per_user)num_rated_items = np.random.randint(1, max_ratings_per_user + 1)# 隨機選擇該用戶評分的商品索引rated_items = np.random.choice(num_items, size=num_rated_items, replace=False)# 隨機生成評分(1 到 5)ratings[i, rated_items] = np.random.randint(1, 6, size=num_rated_items)# 構建 DataFrame
user_ids = [f"用戶{i+1}" for i in range(num_users)]
item_ids = [f"商品{j+1}" for j in range(num_items)]
df = pd.DataFrame(ratings, index=user_ids, columns=item_ids)# 打印評分矩陣
print("用戶-商品評分矩陣:")
print(df)# 計算用戶之間的相似度(改進版)
def calculate_user_similarity(df):# 填充缺失值為0(如果還沒有填充)df_filled = df.fillna(0)# 計算余弦相似度user_similarity = cosine_similarity(df_filled)# 將對角線設置為0(避免用戶與自己比較)np.fill_diagonal(user_similarity, 0)# 轉換為DataFrameuser_similarity_df = pd.DataFrame(user_similarity, index=df.index, columns=df.index)return user_similarity_dfuser_similarity_df = calculate_user_similarity(df)# 計算用戶之間的相似度
# user_similarity = cosine_similarity(df)
# user_similarity_df = pd.DataFrame(user_similarity, index=df.index, columns=df.index)print("\n用戶相似度矩陣:")
print(user_similarity_df)# 預測目標用戶對未評分商品的評分
# def predict_ratings(target_user, df, user_similarity_df):
#     # 獲取目標用戶的評分
#     target_ratings = df.loc[target_user]#     # 修改這里:初始化預測評分為float類型
#     predicted_ratings = pd.Series(0.0, index=df.columns, dtype='float64')#     for item in df.columns:
#         if target_ratings[item] == 0:  # 只預測未評分的商品
#             # 獲取對該商品評分過的用戶
#             users_who_rated = df[df[item] > 0].index#             # 計算加權平均評分
#             weighted_sum = 0.0
#             similarity_sum = 0.0
#             for user in users_who_rated:
#                 rating = df.loc[user, item]
#                 similarity = user_similarity_df.loc[target_user, user]
#                 weighted_sum += rating * similarity
#                 similarity_sum += similarity#             if similarity_sum > 0:
#                 predicted_ratings[item] = weighted_sum / similarity_sum#     return predicted_ratings# 預測目標用戶對未評分商品的評分(改進版)
def predict_ratings(target_user, df, user_similarity_df, min_similar_users=1):target_ratings = df.loc[target_user]predicted_ratings = pd.Series(0.0, index=df.columns,dtype='float64')for item in df.columns:if target_ratings[item] == 0:users_who_rated = df[df[item] > 0].indexweighted_sum = 0similarity_sum = 0valid_users = 0for user in users_who_rated:similarity = user_similarity_df.loc[target_user, user]# 只考慮正相似度的用戶if similarity > 0:rating = df.loc[user, item]weighted_sum += rating * similaritysimilarity_sum += similarityvalid_users += 1# 至少有min_similar_users個相似用戶才進行預測if valid_users >= min_similar_users and similarity_sum > 0:predicted_ratings[item] = weighted_sum / similarity_sumreturn predicted_ratings# 目標用戶
target_user = '用戶1'# 預測評分
predicted_ratings = predict_ratings(target_user, df, user_similarity_df)print(f"\n為目標用戶 {target_user} 預測的評分:")
print(predicted_ratings)# 推薦商品
recommended_items = predicted_ratings[predicted_ratings > 0].sort_values(ascending=False)
print(f"\n推薦給用戶 {target_user} 的商品:")
print(recommended_items)

輸出如下:
在這里插入圖片描述

主要改進點:

增加了calculate_user_similarity函數來封裝相似度計算邏輯
在計算相似度前確保數據已填充缺失值
將對角線相似度設為0(避免用戶與自己比較)
在預測評分時增加了min_similar_users參數,確保有足夠多的相似用戶才進行預測
只考慮正相似度的用戶參與預測
這些改進可以解決以下潛在問題:

處理缺失值問題
避免用戶與自己的相似度影響結果
確保預測時有足夠的參考用戶
提高預測結果的可靠性

基于物品的協同過濾推薦案例

基于物品的協同過濾(Item-Based Collaborative Filtering)是一種推薦算法,其核心思想是:如果兩個商品被相似的用戶評分,那么這兩個商品可能是相似的。我們可以根據商品之間的相似性,為目標用戶推薦他們未評分但可能感興趣的商品。

以下是基于上述稀疏評分矩陣實現基于物品的協同過濾的完整代碼:


1. 數據準備

我們使用之前生成的稀疏評分矩陣 df,其中包含 10 個用戶和 10 個商品。

import numpy as np
import pandas as pd
from sklearn.metrics.pairwise import cosine_similarity# 設置隨機種子以確保結果可復現
np.random.seed(42)# 參數設置
num_users = 10  # 用戶數量
num_items = 10  # 商品數量
max_ratings_per_user = 5  # 每個用戶最多評分的商品數量# 初始化評分矩陣 (初始值為 0)
ratings = np.zeros((num_users, num_items))# 隨機生成稀疏評分數據
for i in range(num_users):# 隨機選擇該用戶評分的商品數量(1 到 max_ratings_per_user)num_rated_items = np.random.randint(1, max_ratings_per_user + 1)# 隨機選擇該用戶評分的商品索引rated_items = np.random.choice(num_items, size=num_rated_items, replace=False)# 隨機生成評分(1 到 5)ratings[i, rated_items] = np.random.randint(1, 6, size=num_rated_items)# 構建 DataFrame
user_ids = [f"用戶{i+1}" for i in range(num_users)]
item_ids = [f"商品{j+1}" for j in range(num_items)]
df = pd.DataFrame(ratings, index=user_ids, columns=item_ids)print("用戶-商品評分矩陣:")
print(df)

輸出如下:
在這里插入圖片描述

2. 計算商品相似度

在基于物品的協同過濾中,我們需要計算商品之間的相似度。可以使用余弦相似度來衡量商品之間的相似性。

# 轉置評分矩陣,使得行表示商品,列表示用戶
item_similarity = cosine_similarity(df.T)  # 對轉置后的矩陣計算相似度
item_similarity_df = pd.DataFrame(item_similarity, index=df.columns, columns=df.columns)print("\n商品相似度矩陣:")
print(item_similarity_df)
輸出示例:

在這里插入圖片描述

3. 基于商品相似度預測評分

對于目標用戶未評分的商品,我們可以利用商品相似度和用戶已評分的商品來預測評分。

def predict_item_based(target_user, df, item_similarity_df):# 獲取目標用戶的評分target_ratings = df.loc[target_user]# 初始化預測評分predicted_ratings = pd.Series(0, index=df.columns)for item in df.columns:if target_ratings[item] == 0:  # 只預測未評分的商品# 獲取與當前商品相似的商品similar_items = item_similarity_df[item]# 計算加權平均評分weighted_sum = 0similarity_sum = 0for other_item in df.columns:if target_ratings[other_item] > 0 and similar_items[other_item] > 0:rating = target_ratings[other_item]similarity = similar_items[other_item]weighted_sum += rating * similaritysimilarity_sum += similarityif similarity_sum > 0:predicted_ratings[item] = weighted_sum / similarity_sumreturn predicted_ratings# 目標用戶
target_user = '用戶1'# 預測評分
predicted_ratings = predict_item_based(target_user, df, item_similarity_df)print(f"\n為目標用戶 {target_user} 預測的評分:")
print(predicted_ratings)# 推薦商品
recommended_items = predicted_ratings[predicted_ratings > 0].sort_values(ascending=False)
print(f"\n推薦給用戶 {target_user} 的商品:")
print(recommended_items)

輸出如下:
在這里插入圖片描述

4. 總結

通過基于物品的協同過濾算法,我們成功為目標用戶 用戶1 推薦了未評分但可能感興趣的商品(如 商品3商品10 等)。這種算法的核心在于計算商品之間的相似性,并利用相似商品的評分來預測目標用戶對未評分商品的興趣。

你可以根據需要進一步優化算法,例如:

  • 使用其他相似度計算方法(如皮爾遜相關系數)。
  • 引入隱式反饋數據(如點擊、瀏覽等行為)。
  • 結合基于用戶的協同過濾和基于物品的協同過濾,形成混合推薦系統。

推薦算法流程優化版本-召回過濾精排混排強規則

import numpy as np
import pandas as pd
from sklearn.metrics.pairwise import cosine_similarity# 設置隨機種子以確保結果可復現
np.random.seed(42)# 參數設置
num_users = 10  # 用戶數量
num_items = 10  # 商品數量
max_ratings_per_user = 5  # 每個用戶最多評分的商品數量# 初始化評分矩陣 (初始值為 0)
ratings = np.zeros((num_users, num_items))# 隨機生成稀疏評分數據
for i in range(num_users):# 隨機選擇該用戶評分的商品數量(1 到 max_ratings_per_user)num_rated_items = np.random.randint(1, max_ratings_per_user + 1)# 隨機選擇該用戶評分的商品索引rated_items = np.random.choice(num_items, size=num_rated_items, replace=False)# 隨機生成評分(1 到 5)ratings[i, rated_items] = np.random.randint(1, 6, size=num_rated_items)# 構建 DataFrame
user_ids = [f"用戶{i+1}" for i in range(num_users)]
item_ids = [f"商品{j+1}" for j in range(num_items)]
df = pd.DataFrame(ratings, index=user_ids, columns=item_ids)# 打印評分矩陣
print("用戶-商品評分矩陣:")
print(df)# 計算用戶之間的相似度(改進版)
def calculate_user_similarity(df):# 填充缺失值為0(如果還沒有填充)df_filled = df.fillna(0)# 計算余弦相似度user_similarity = cosine_similarity(df_filled)# 將對角線設置為0(避免用戶與自己比較)np.fill_diagonal(user_similarity, 0)# 轉換為DataFrameuser_similarity_df = pd.DataFrame(user_similarity, index=df.index, columns=df.index)return user_similarity_dfuser_similarity_df = calculate_user_similarity(df)print("\n用戶相似度矩陣:")
print(user_similarity_df)# 預測目標用戶對未評分商品的評分(改進版)
def predict_ratings(target_user, df, user_similarity_df, min_similar_users=1):target_ratings = df.loc[target_user]predicted_ratings = pd.Series(0.0, index=df.columns,dtype='float64')for item in df.columns:if target_ratings[item] == 0:users_who_rated = df[df[item] > 0].indexweighted_sum = 0similarity_sum = 0valid_users = 0for user in users_who_rated:similarity = user_similarity_df.loc[target_user, user]# 只考慮正相似度的用戶if similarity > 0:rating = df.loc[user, item]weighted_sum += rating * similaritysimilarity_sum += similarityvalid_users += 1# 至少有min_similar_users個相似用戶才進行預測if valid_users >= min_similar_users and similarity_sum > 0:predicted_ratings[item] = weighted_sum / similarity_sumreturn predicted_ratings# 目標用戶
target_user = '用戶1'# 預測評分
predicted_ratings = predict_ratings(target_user, df, user_similarity_df)print(f"\n為目標用戶 {target_user} 預測的評分:")
print(predicted_ratings)# 推薦商品
recommended_items = predicted_ratings[predicted_ratings > 0].sort_values(ascending=False)
print(f"\n推薦給用戶 {target_user} 的商品:")
print(recommended_items)# 評估推薦系統
def evaluate_recommendation(df, user_similarity_df, test_ratio=0.2):from sklearn.model_selection import train_test_split# 轉換為長格式melted_df = df.reset_index().melt(id_vars='index', var_name='item', value_name='rating')melted_df.columns = ['user', 'item', 'rating']# 分割訓練集和測試集train_df, test_df = train_test_split(melted_df[melted_df['rating'] > 0], test_size=test_ratio)# 重建訓練矩陣train_matrix = pd.pivot_table(train_df, values='rating', index='user', columns='item').fillna(0)# 計算用戶相似度train_similarity = calculate_user_similarity(train_matrix)# 評估每個測試用戶mae = 0test_users = test_df['user'].unique()for user in test_users:# 獲取測試用戶的實際評分actual_ratings = test_df[test_df['user'] == user].set_index('item')['rating']# 預測評分predicted = predict_ratings(user, train_matrix, train_similarity)# 計算MAEcommon_items = actual_ratings.index.intersection(predicted.index)if len(common_items) > 0:mae += np.mean(np.abs(actual_ratings[common_items] - predicted[common_items]))mae /= len(test_users)print(f"\n推薦系統評估結果(MAE): {mae:.4f}")# 運行評估
evaluate_recommendation(df, user_similarity_df)# ... 已有代碼保持不變 ...# 1. 召回階段 - 多種召回策略
def recall_strategies(target_user, df, user_similarity_df):# 策略1: 基于用戶的協同過濾召回cf_recall = predict_ratings(target_user, df, user_similarity_df)cf_items = cf_recall[cf_recall > 0].index.tolist()# 策略2: 熱門商品召回popular_items = df.sum().sort_values(ascending=False).head(5).index.tolist()# 策略3: 新商品召回new_items = df.columns[-3:].tolist()  # 假設最后3個是新商品# 合并召回結果并去重recalled_items = list(set(cf_items + popular_items + new_items))return recalled_items# 2. 過濾階段 - 過濾掉不合適的商品
def filter_items(target_user, recalled_items, df):# 獲取用戶已購買/已評價的商品rated_items = df.loc[target_user][df.loc[target_user] > 0].index.tolist()# 過濾掉用戶已經購買/評價過的商品filtered_items = [item for item in recalled_items if item not in rated_items]# 強規則過濾示例:過濾掉特定商品blacklist = ['商品5']  # 假設商品5被列入黑名單filtered_items = [item for item in filtered_items if item not in blacklist]return filtered_items# 3. 精排階段 - 對過濾后的商品進行精細排序
def ranking(target_user, filtered_items, df, user_similarity_df):# 計算每個商品的預測評分predicted_ratings = predict_ratings(target_user, df, user_similarity_df)# 計算商品熱度item_popularity = df.sum()# 綜合評分 = 預測評分 * 0.7 + 熱度 * 0.3 (加權得分)ranked_items = {}for item in filtered_items:score = predicted_ratings[item] * 0.7 + item_popularity[item] * 0.3ranked_items[item] = score# 按得分排序ranked_items = sorted(ranked_items.items(), key=lambda x: x[1], reverse=True)return ranked_items# 4. 混排階段 - 結合多種策略生成最終推薦列表
def mixed_sorting(ranked_items):final_list = []# 強規則:確保特定商品排在前面promoted_item = '商品2'  # 假設商品2是推廣商品for i, (item, score) in enumerate(ranked_items):if item == promoted_item:final_list.insert(0, (item, score))  # 推廣商品置頂else:final_list.append((item, score))# 多樣性控制:避免同類型商品扎堆# 這里簡化為限制連續出現相似商品diversified_list = []prev_item_type = Nonefor item, score in final_list:current_type = item[-1]  # 假設商品類型由商品ID最后一位決定if current_type == prev_item_type:score *= 0.9  # 相似類型商品降權diversified_list.append((item, score))prev_item_type = current_typereturn sorted(diversified_list, key=lambda x: x[1], reverse=True)# 5. 完整推薦流程
def full_recommendation_pipeline(target_user, df, user_similarity_df):print(f"\n開始為用戶 {target_user} 生成推薦...")# 召回recalled_items = recall_strategies(target_user, df, user_similarity_df)print(f"\n召回階段結果: {recalled_items}")# 過濾filtered_items = filter_items(target_user, recalled_items, df)print(f"過濾后結果: {filtered_items}")# 精排ranked_items = ranking(target_user, filtered_items, df, user_similarity_df)print(f"精排后結果: {ranked_items}")# 混排final_recommendations = mixed_sorting(ranked_items)print(f"最終推薦列表: {final_recommendations}")return final_recommendations# 運行完整推薦流程
final_recommendations = full_recommendation_pipeline(target_user, df, user_similarity_df)# 輸出最終推薦結果
print("\n=== 最終推薦結果 ===")
for item, score in final_recommendations:print(f"{item}: {score:.2f}")

輸出如下:

在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述

基于scikit-surprise實現推薦

scikit-surprise 是一個用于構建推薦系統的 Python 庫,專注于協同過濾(Collaborative Filtering)算法。以下是基于 scikit-surprise 實現一個簡單的推薦系統的完整代碼示例。


1. 安裝依賴

首先,確保你已經安裝了 scikit-surprise

pip install scikit-surprise==1.1.4

2. 數據準備

我們使用 scikit-surprise 提供的內置數據集(例如 MovieLens 數據集),或者自定義數據集。

示例:加載 MovieLens 數據集
from surprise import Dataset
from surprise import Reader
from surprise.model_selection import train_test_split# 加載內置的 MovieLens 數據集
data = Dataset.load_builtin('ml-100k')# 將數據劃分為訓練集和測試集
trainset, testset = train_test_split(data, test_size=0.2, random_state=42)

如果你有自己的數據集(例如用戶、物品、評分),可以按照以下方式加載:

import pandas as pd
from surprise import Dataset, Reader# 假設你的數據是一個 Pandas DataFrame
ratings_dict = {"user_id": [1, 1, 1, 2, 2, 3, 3, 3],"item_id": [101, 102, 103, 101, 104, 102, 103, 104],"rating": [5, 3, 4, 4, 2, 5, 3, 1],
}
df = pd.DataFrame(ratings_dict)# 定義評分范圍
reader = Reader(rating_scale=(1, 5))# 加載自定義數據集
data = Dataset.load_from_df(df[["user_id", "item_id", "rating"]], reader)# 劃分訓練集和測試集
trainset, testset = train_test_split(data, test_size=0.2, random_state=42)

3. 構建推薦模型

scikit-surprise 提供了多種協同過濾算法,例如 SVD(奇異值分解)、KNN(最近鄰算法)等。以下以 SVD 為例:

from surprise import SVD
from surprise import accuracy# 初始化 SVD 模型
model = SVD()# 在訓練集上訓練模型
model.fit(trainset)# 在測試集上進行預測
predictions = model.test(testset)# 計算 RMSE(均方根誤差)
rmse = accuracy.rmse(predictions)
print(f"RMSE: {rmse}")

4. 推薦物品

我們可以為特定用戶生成推薦物品列表。以下是一個示例函數,用于獲取某個用戶的前 N 個推薦物品:

def get_top_n_recommendations(model, user_id, items, n=5):# 預測用戶對所有物品的評分predictions = [(item, model.predict(user_id, item).est) for item in items]# 按評分排序predictions.sort(key=lambda x: x[1], reverse=True)# 返回前 N 個推薦物品return predictions[:n]# 獲取所有物品 ID
items = df["item_id"].unique()# 為用戶 1 生成推薦
user_id = 1
top_n_recommendations = get_top_n_recommendations(model, user_id, items, n=5)
print(f"為用戶 {user_id} 推薦的物品:")
for item, score in top_n_recommendations:print(f"物品 ID: {item}, 預測評分: {score:.2f}")

5. 使用 KNN 算法

如果你想使用 KNN 算法(基于用戶的協同過濾或基于物品的協同過濾),可以按照以下方式實現:

from surprise import KNNBasic# 初始化 KNN 模型(基于用戶的協同過濾)
sim_options = {"name": "cosine",       # 相似度計算方法"user_based": True      # 基于用戶(True)還是基于物品(False)
}
model = KNNBasic(sim_options=sim_options)# 在訓練集上訓練模型
model.fit(trainset)# 在測試集上進行預測
predictions = model.test(testset)# 計算 RMSE
rmse = accuracy.rmse(predictions)
print(f"RMSE: {rmse}")

6. 完整代碼整合

以下是完整的代碼示例,包含數據加載、模型訓練、評估和推薦:

import pandas as pd
from surprise import Dataset, Reader, SVD, accuracy
from surprise.model_selection import train_test_split# 自定義數據集
ratings_dict = {"user_id": [1, 1, 1, 2, 2, 3, 3, 3],"item_id": [101, 102, 103, 101, 104, 102, 103, 104],"rating": [5, 3, 4, 4, 2, 5, 3, 1],
}
df = pd.DataFrame(ratings_dict)# 定義評分范圍
reader = Reader(rating_scale=(1, 5))# 加載數據集
data = Dataset.load_from_df(df[["user_id", "item_id", "rating"]], reader)# 劃分訓練集和測試集
trainset, testset = train_test_split(data, test_size=0.2, random_state=42)# 初始化 SVD 模型
model = SVD()# 在訓練集上訓練模型
model.fit(trainset)# 在測試集上進行預測
predictions = model.test(testset)# 計算 RMSE
rmse = accuracy.rmse(predictions)
print(f"RMSE: {rmse}")# 獲取所有物品 ID
items = df["item_id"].unique()# 為用戶生成推薦
def get_top_n_recommendations(model, user_id, items, n=5):predictions = [(item, model.predict(user_id, item).est) for item in items]predictions.sort(key=lambda x: x[1], reverse=True)return predictions[:n]# 為用戶 1 生成推薦
user_id = 1
top_n_recommendations = get_top_n_recommendations(model, user_id, items, n=5)
print(f"為用戶 {user_id} 推薦的物品:")
for item, score in top_n_recommendations:print(f"物品 ID: {item}, 預測評分: {score:.2f}")

7. 輸出結果

運行上述代碼后,你會得到以下輸出:

  1. RMSE:模型在測試集上的均方根誤差。
  2. 推薦列表:為指定用戶生成的前 N 個推薦物品及其預測評分。

8. 擴展功能

  1. 超參數調優

    • 使用 GridSearchCV 或手動調整模型參數(如 n_factorslr_all 等)來優化模型性能。
  2. 交叉驗證

    • 使用 cross_validate 函數評估模型的穩定性和泛化能力。
  3. 其他算法

    • 嘗試其他算法(如 NMF、SlopeOne 或 CoClustering)并比較效果。

通過上述代碼,你可以快速構建一個基于協同過濾的推薦系統!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/77197.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/77197.shtml
英文地址,請注明出處:http://en.pswp.cn/web/77197.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

OpenCV 圖形API(63)圖像結構分析和形狀描述符------計算圖像中非零像素的邊界框函數boundingRect()

操作系統:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 編程語言:C11 算法描述 計算點集或灰度圖像非零像素的 upright(不旋轉)邊界矩形。 該函數計算并返回指定點集或灰度圖像非零像素的最小 upright …

Redis ⑥-string | hash | list

string類型基本介紹 Redis 中的字符串,是直接按照二進制的方式進行存儲的。也就是說,在存取的過程中,是不會做任何編碼轉換的。存的是啥,取的時候就是啥。 Redis 的這個機制,就使得 Redis 非常適合用來存儲各種各樣的…

星火燎原:大數據時代的Spark技術革命在數字化浪潮席卷全球的今天,海量數據如同奔涌不息的洪流,傳統的數據處理方式已難以滿足實時、高效的需求。

星火燎原:大數據時代的Spark技術革命 在數字化浪潮席卷全球的今天,海量數據如同奔涌不息的洪流,傳統的數據處理方式已難以滿足實時、高效的需求。Apache Spark作為大數據領域的璀璨明星,憑借其卓越的性能和強大的功能&#xff0c…

通信算法之273 : 循環自相關函數和自相關函數

一、循環自相關函數定義與計算流程 ?定義式?: 循環自相關函數為時間平均自相關函數的傅里葉變換: Rxα(τ)=1T∫?T/2T/2Rx(t+τ2,t?τ2)e?j2παtdtRxα?(τ)=T1?∫?T/2T/2?Rx?(t+2τ?,t?2τ?)e?j2παtdt 其中,Rx(t,τ)Rx?(t,τ) 是信號的自相關函數,α為循…

使用 VMware 安裝一臺 Linux 系統之Centos

使用 VMware 安裝一臺 Linux 系統之Centos 想體驗一下 Linux 的魅力,又不想在現有電腦上進行大刀闊斧的改動?使用 VMware 虛擬機是一個絕佳的選擇。它能讓你在 Windows 或 macOS 系統中輕松創建一個獨立的 Linux 環境。本文將手把手帶你完成從下載 VMwa…

uniapp-商城-36-shop 購物車 選好了 進行訂單確認2 支付方式顏色變化和顏色濾鏡filter

顏色濾鏡&#xff0c;在好多網頁都這樣使用&#xff0c;濾掉彩色&#xff0c;顯示黑白&#xff0c;這在一些關鍵的日子中都這樣使用。 1、依然回到訂單確認頁面 看到支付的顏色了嘛&#xff1f; <view class"payType"><view class"box" :class&q…

gerbera文件轉PCB文件-Altium Designer

gerbera文件轉PCB文件-Altium Designer 1. 新建 CAM 文檔2. 導入 Gerber 文件和鉆孔文件導入 Gerber 文件導入鉆孔文件&#xff08;NC Drill&#xff09; 3. 提取網絡表4. 檢查并設置層映射5. 導出為 PCB 文件 1. 新建 CAM 文檔 打開 Altium Designer&#xff0c;執行以下操作…

Flask 請求數據獲取方法詳解

一、工作原理 在 Flask 中&#xff0c;所有客戶端請求的數據都通過全局的 request 對象訪問。該對象是 請求上下文 的一部分&#xff0c;僅在請求處理期間存在。Flask 在收到請求時自動創建 request 對象&#xff0c;并根據請求類型&#xff08;如 GET、POST&#xff09;和內容…

隊列基礎和例題

基礎 #include <queue> #include <iostream>/*** 入隊*/ void Test01() {std::queue<int> q;q.push(1);q.push(2);q.push(3);q.push(4);q.push(777);std::cout << "隊列大小:" << q.size() << std::endl;std::cout << &q…

U-Mail郵件加速服務:全球鏈路加速,安全穩定收發

由于跨國網絡擁堵、帶寬不穩定等因素&#xff0c;導致海外用戶在使用企業郵箱收發郵件時&#xff0c;經常出現郵件收發不暢的問題。針對這種情況&#xff0c;U-Mail正式推出了郵件加速服務&#xff0c;U-Mail郵件加速服務依托全球優質加速鏈路和轉發集群服務器&#xff0c;為海…

從工作到娛樂:Codigger Desktop 讓桌面環境更智能

在數字化時代&#xff0c;我們的桌面環境幾乎成了第二個家。Codigger Desktop 就像是這個家的設計師&#xff0c;幫你打造一個既實用又舒適的數字空間。無論你是想放松娛樂&#xff0c;還是高效工作&#xff0c;Codigger Desktop 都能滿足你的需求。 想象一下&#xff0c;你有一…

用python進行OCR識別

原文鏈接&#xff1a;https://www.bilibili.com/opus/1036675560501149699 我擔心原作者刪除&#xff0c;所以重新拷貝了一遍 1.下載tesseract 鏈接&#xff1a;https://github.com/UB-Mannheim/tesseract/wiki 這里示例安裝最新版本 點擊下載tesseract安裝包 2.安裝tess…

區間和數量統計 之 前綴和+哈希表

文章目錄 1512.好數對的數目2845.統計趣味子數組的數目1371.每個元音包含偶數次的最長子字符串 區間和的數量統計是一類十分典型的問題&#xff1a;記錄左邊&#xff0c;枚舉右邊策略前置題目&#xff1a;統計nums[j]nums[i]的對數進階版本&#xff1a;統計子數組和%modulo k的…

PCB 制造流程分步指南

最近的一次PCB打板經歷&#xff0c;板廠工程人員告知絲印偏到焊盤上了&#xff0c;內部讓我評估是否可以繼續貼片。 于是發一期文章&#xff0c;介紹一下PCB制造流程。 PCB制造工藝 PCB設計獲得批準且制造商收到最終制造文件后&#xff0c;PCB制造或生產就開始了。此時&…

python實現簡單的UI交互

文章目錄 1. 基礎打印 覆蓋同一行2. 多行動畫效果3. 彩色文本&#xff08;Windows/macOS/Linux&#xff09;4. 輸入交互5. 異步輸入與非阻塞顯示6. 高級控制臺 UI 庫 可以通過控制臺打印實現簡單的「偽UI交互」&#xff0c;尤其適合展示進度、動態文本或輕量級狀態反饋。以下是…

AI與思維模型【77】——PDCA思維模型

一、定義 PDCA思維模型是一種用于持續改進和優化工作流程、項目實施以及問題解決的科學管理方法。它由四個英文字母組成&#xff0c;分別代表計劃&#xff08;Plan&#xff09;、執行&#xff08;Do&#xff09;、檢查&#xff08;Check&#xff09;和處理&#xff08;Act&…

10天學會嵌入式技術之51單片機-day-3

第九章 獨立按鍵 按鍵的作用相當于一個開關&#xff0c;按下時接通&#xff08;或斷開&#xff09;&#xff0c;松開后斷開&#xff08;或接通&#xff09;。實物圖、原理圖、封裝 9.2 需求描述 通過 SW1、SW2、SW3、SW4 四個獨立按鍵分別控制 LED1、LED2、LED3、LED4 的亮…

vite+vue2+elementui構建之 package.json

webpack版本太低&#xff0c;構建依賴太多&#xff0c;頭大。 各種查閱資料&#xff0c;弄了一份直通構建vite構建elementUi核心文件&#xff0c; 構建基于開源若依vue2vue3版本改造&#xff0c;感謝開源&#xff0c;感謝若依。 vitevue2elementui構建之 vite.config.js-CSD…

提升變電站運維效率:安科瑞無線測溫系統創新應用

一、引言 變電站作為電力系統的關鍵樞紐&#xff0c;承擔著變換電壓、分配電能以及控制電力流向等重要任務。在變電站的運行過程中&#xff0c;電氣設備的接點溫度監測至關重要。過熱問題可能由多種因素引發&#xff0c;如電阻過大、接頭質量欠佳、銜接不緊密、物理老化等&…

DMA的三種傳輸功能

①內存到內存 #include "dma.h" #include "stdio.h"#define BUF_SIZE 16uint32_t src_buf[BUF_SIZE] {0x00000000,0x11111111,0x22222222,0x33333333,0x44444444,0x55555555,0x66666666,0x77777777,0x88888888,0x99999999,0xAAAAAAAA,0xBBBBBBBB,0xCCCCCCC…