推荐系统
1、协同过滤–找出电影的相似度
2、基于项目的协同过滤应用–向人们推荐电影
# 读入数据
import pandas as pd
r_cols=['user_id','movie_id','rating']
ratings=pd.read_csv('./u.data',sep='\\t',names=r_cols,usecols=range(3),encoding="ISO-8859-1") # 我们只使用文件的前三列
ratings.head()
m_cols=['movie_id','title']
movies=pd.read_csv('./u.item',sep='|',names=m_cols,usecols=range(2),encoding="ISO-8859-1") # 只用u.item文件的前两列
movies.head()
# 将上面的两个数据框合并
ratings=pd.merge(movies,ratings)
ratings.head()
# 得到根据看了每部影片的用户所得到的两部影片之间的关系
movieRatings=ratings.pivot_table(index=['user_id'],columns=['title'],values='rating')
movieRatings.head()
# 得到的结果既适用于基于用户的协同过滤,也适用于基于项目的协同过滤
# 接下来,我们进行基于项目的协同过滤
starWarsRatings=movieRatings['Star Wars (1977)']
starWarsRatings.head()
# 我们发现很多人都看过Star Wars 且评分也很高
similarMovies=movieRatings.corrwith(starWarsRatings) # 计算出星球大战与其他电影之间的相关系数
similarMovies.dropna() # 删除缺失值
df=pd.DataFrame(similarMovies) # 新建一个数据框
df.head()
# 对结果进行一下排序,看看那些相似度比较高
similarMovies.sort_values(ascending=False).head(10)
# 结果发现一些冷门电影也同样被推荐了,这显然不符合,所以需要找到那些只有少数人评分的电影,将其丢弃掉
import numpy as np
movieStats=ratings.groupby('title').agg({'rating':[np.size,np.mean]})
movieStats.head()
# 然后我们将评分人数少于100的丢弃掉
popularMovies=movieStats['rating']['size']>=100
movieStats[popularMovies].sort_values([('rating','mean')],ascending=False)[:15]
df.sort_values(['similarity'],ascending=False)[:15]
# 最后我们得到一个比较满意的效果
# 接下来我们来建立一个推荐电影的完整系统
ratings.head()
userRatings=ratings.pivot_table(index=['user_id'],columns=['title'],values='rating')
userRatings.head()
# 计算出整个矩阵中任意两列之间的相关系数
corrMatrix=userRatings.corr()
corrMatrix.head()
# 继续将少于100人评分的给过滤掉
corrMtrix=userRatings.corr(method='pearson',min_periods=100)
corrMatrix.head()
myRatings=userRatings.loc[0].dropna()
myRatings
simCandidates = pd.Series()
for i in range(0, len(myRatings.index)):
print ("Adding sims for " + myRatings.index[i] + "...")
# 找出我评价过的电影
sims = corrMatrix[myRatings.index[i]].dropna()
# 通过我对电影的评分放大相似度
sims = sims.map(lambda x: x * myRatings[i])
# 将分数添加到相似度候选列表中
simCandidates = simCandidates.append(sims)
# 看一下目前的结果
print ("sorting...")
simCandidates.sort_values(inplace = True, ascending = False)
print (simCandidates.head(10))
simCandidates = simCandidates.groupby(simCandidates.index).sum()
simCandidates.sort_values(inplace = True, ascending = False)
simCandidates.head(10)
filteredSims = simCandidates.drop(myRatings.index)
filteredSims.head(10)
# 好了,推荐系统完成