天天看點

商業分析python實戰(二):電影智能推薦

作者:機器學習養成記

原文連結:商業分析python實戰(二):電影智能推薦

随着企業經營水準的提高,對應網站的通路量逐漸增加,資料資訊也随之大量增長,使得使用者面對海量資訊時無法快速找到想要的内容,降低了資訊使用效率。這時,可以利用相關資料,研究使用者興趣偏好,分析使用者的需求和行為,引導使用者發現需求資訊,将内容準确推薦給使用者。

本例通過943名使用者對1664部電影的評分資料,建構協同過濾模型,進而推薦電影供使用者觀看。通過本例,可以了解協同過濾算法在電子商務智能推薦領域的應用方法,幫助使用者更加便捷的擷取想要的資訊,進而提升使用者體驗、促進推薦轉化。

步驟

1、擷取資料;

2、資料探索分析;

3、建構智能推薦模型;

4、評估推薦系統模型。

商業分析python實戰(二):電影智能推薦

NO.1 擷取資料

資料包含943名使用者對1664部電影的打分,評分在1-5分之間,超出規定範圍的算異常值。

商業分析python實戰(二):電影智能推薦

NO.2 資料探索分析

導入的資料共有99416行,3列,第一列為使用者id,第二列為電影名字,第三列為打分。

商業分析python實戰(二):電影智能推薦

經過基本的資料驗證,發現三列資料均存在缺失的情況(取值為空),且根據打分列,發現資料存在異常值(打分結果不在1-5範圍内),是以将存在缺失值和異常值的行删除,删除後,資料剩下99392行。同時,為了進行每部電影的打分資料探索分析,将movie列中的電影名轉換為列名,轉換後,可觀察每部電影的評分使用者數及分數的基本分布。

商業分析python實戰(二):電影智能推薦

NO.3 建構基于物品的協同過濾推薦模型

基于物品的協同過濾模型(ItemCF)通過分析群體使用者的曆史偏好,找到相似物品,然後根據個體使用者的曆史行為為其進行推薦,主要分為計算物品間相似度和生成推薦清單兩個步驟。ItemCF可以離線計算,進而提高推薦效率,且利用曆史行為進行推薦解釋,結果更容易信服,但是推薦精度相對有限,且對于使用者偏好的變化不敏感,實時推薦能力較弱。關于ItemCF的更多介紹可參考往期文章推薦算法概述。

在實際應用時,使用者的曆史行為包含是否浏覽網頁、是否購買、是否評論、是否轉發點贊等,本例中,僅涉及使用者對電影的打分,是以不存在其他的行為。得到的電影相似度矩陣如下:

商業分析python實戰(二):電影智能推薦

建構ItemCF模型後,得到使用者1.0的推薦清單如下:

商業分析python實戰(二):電影智能推薦

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語言商務資料分析實戰》