原文連結:商業分析python實戰(二):電影智能推薦
随着企業經營水準的提高,對應網站的通路量逐漸增加,資料資訊也随之大量增長,使得使用者面對海量資訊時無法快速找到想要的内容,降低了資訊使用效率。這時,可以利用相關資料,研究使用者興趣偏好,分析使用者的需求和行為,引導使用者發現需求資訊,将内容準确推薦給使用者。
本例通過943名使用者對1664部電影的評分資料,建構協同過濾模型,進而推薦電影供使用者觀看。通過本例,可以了解協同過濾算法在電子商務智能推薦領域的應用方法,幫助使用者更加便捷的擷取想要的資訊,進而提升使用者體驗、促進推薦轉化。
步驟
1、擷取資料;
2、資料探索分析;
3、建構智能推薦模型;
4、評估推薦系統模型。
NO.1 擷取資料
資料包含943名使用者對1664部電影的打分,評分在1-5分之間,超出規定範圍的算異常值。
NO.2 資料探索分析
導入的資料共有99416行,3列,第一列為使用者id,第二列為電影名字,第三列為打分。
經過基本的資料驗證,發現三列資料均存在缺失的情況(取值為空),且根據打分列,發現資料存在異常值(打分結果不在1-5範圍内),是以将存在缺失值和異常值的行删除,删除後,資料剩下99392行。同時,為了進行每部電影的打分資料探索分析,将movie列中的電影名轉換為列名,轉換後,可觀察每部電影的評分使用者數及分數的基本分布。
NO.3 建構基于物品的協同過濾推薦模型
基于物品的協同過濾模型(ItemCF)通過分析群體使用者的曆史偏好,找到相似物品,然後根據個體使用者的曆史行為為其進行推薦,主要分為計算物品間相似度和生成推薦清單兩個步驟。ItemCF可以離線計算,進而提高推薦效率,且利用曆史行為進行推薦解釋,結果更容易信服,但是推薦精度相對有限,且對于使用者偏好的變化不敏感,實時推薦能力較弱。關于ItemCF的更多介紹可參考往期文章推薦算法概述。
在實際應用時,使用者的曆史行為包含是否浏覽網頁、是否購買、是否評論、是否轉發點贊等,本例中,僅涉及使用者對電影的打分,是以不存在其他的行為。得到的電影相似度矩陣如下:
建構ItemCF模型後,得到使用者1.0的推薦清單如下:
NO.4 評估推薦系統模型
模型結果評價主要有三種方式,分别為離線測試、使用者調查和線上實驗。
- 離線測試:通過從實際系統中提取資料,采用各種推薦算法并計算各算法的測評名額。該方法不需真實使用者參與,但結果與實際結果會存在偏差。
- 使用者調查:利用測試的推薦系統調查真實使用者,觀察他們的行為并回答相關問題,通過使用者行為及回報判斷推薦系統好壞。
- 線上實驗:将推薦系統投入實際應用,通過應用的轉化名額評價推薦系統結果。
實作代碼
import pandas as pd
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
import math
import operator
from sklearn import model_selection as ms
#step1:擷取資料
print("#step1:擷取資料")
datafile = pd.read_csv('dataMovieLense.csv')
#print(datafile.head(10))
#step2:資料探索分析
print("#step2:資料探索分析")
datafile.info()#資料基本資訊
datafile.score.isna().sum()#資料缺失值數量
datafile = datafile.dropna(axis=0)#删除存在缺失值的行
datafile.loc[datafile['score'] > 5]#存在異常值
datafile = datafile.drop(datafile[datafile.score >5].index)#删除異常值
#print(datafile.shape)#輸出資料維數
datafile_trans = pd.pivot(datafile, index='user', columns='movie', values='score')#将movie中的電影名轉換為列名
#print(datafile_trans.head())
datafile_trans.describe()
df_index = datafile_trans.index
df_columns = datafile_trans.columns
datafile_trans = datafile_trans.fillna(0).to_numpy()
#step3:建構智能推薦模型
print("#step3:建構智能推薦模型")
from sklearn.metrics.pairwise import cosine_similarity
item_similarity = cosine_similarity(datafile_trans.T)#電影間的相似度矩陣
pd.DataFrame(item_similarity,index=df_columns,columns = df_columns).head()
class ItemCf():
########獲得初始化資料,字典格式
def __init__(self,data):
data_dic = {}
#self.itemSim = dict()
for line in data.itertuples():
if not line[1] in data_dic.keys():
data_dic[line[1]]={line[2]:line[3]}
else:
data_dic[line[1]][line[2]]=line[3]
self.data = data_dic
self.ItemSimilarity()
def ItemSimilarity(self):
self.itemSim = dict()
movie_popular = dict() #item_user_count{item: likeCount} the number of users who like the item
count = dict() #count{i:{j:value}} the number of users who both like item i and j
for user,movies in self.data.items():
for movie in movies:
if movie not in movie_popular:
movie_popular[movie] = 0
movie_popular[movie] += 1
movie_count = len(movie_popular)
print('Total movies: %d'% movie_count)
for user,movies in self.data.items():
for m1 in movies:
for m2 in movies:
if m1 == m2:
continue
self.itemSim.setdefault(m1,{})
self.itemSim[m1].setdefault(m2,0)
self.itemSim[m1][m2] += 1/math.log(1+len(movies))
print('Build co-rated users matrix success!')
for m1,related_movies in self.itemSim.items():
for m2,count in related_movies.items():
if movie_popular[m1] == 0 or movie_popular[m2] == 0:
movie_sim_matrix[m1][m2] = 0
else:
self.itemSim[m1][m2] = count / math.sqrt(movie_popular[m1]*movie_popular[m2])
print('Calculate movie similarity matrix success!')
max_w = 0
for m1,related_movies in self.itemSim.items():
for m2,_ in related_movies.items():
if self.itemSim[m1][m2] > max_w:
max_w = self.itemSim[m1][m2]
for m1,related_movies in self.itemSim.items():
for m2,_ in related_movies.items():
self.itemSim[m1][m2] = self.itemSim[m1][m2]/max_w
def Recomand(self,user,n_sim_movie=10,n_rec_movie=5):
K = n_sim_movie
N = n_rec_movie
rank = {}
watched_movies = self.data[user]
for movie,rating in watched_movies.items():
for related_movie,w in sorted(self.itemSim[movie].items(),key=operator.itemgetter(1),reverse=True)[:K]:
if related_movie in watched_movies:
continue
rank.setdefault(related_movie,0)
rank[related_movie] += w*float(rating)
return sorted(rank.items(),key=operator.itemgetter(1),reverse=True)[0:N]
if __name__=='__main__':
datafile['user']=datafile['user'].astype(str)
print(datafile.head())
itemCf=ItemCf(data=datafile)
recommandList=itemCf.Recomand('1.0',20,10)
print('使用者1.0的推薦結果為:' + str(recommandList))
點選原文(商業分析python實戰(二):電影智能推薦)背景回複“電影推薦”可得本例資料及代碼。
參考内容:
1、《R語言商務資料分析實戰》