电影推荐算法实例代码

# -*- coding=utf-8 -*-

import math
import sys
from texttable import Texttable

#   使用 |A&B|/sqrt(|A || B |)计算余弦距离

def calcCosDistSpe(user1,user2):
    avg_x=0.0
    avg_y=0.0
    for key in user1:
        avg_x+=key[1]
    avg_x=avg_x/len(user1)

    for key in user2:
        avg_y+=key[1]
    avg_y=avg_y/len(user2)

    u1_u2=0.0
    for key1 in user1:
        for key2 in user2:
            if key1[1] > avg_x and key2[1]>avg_y and key1[0]==key2[0]:
                u1_u2+=1
    u1u2=len(user1)*len(user2)*1.0
    sx_sy=u1_u2/math.sqrt(u1u2)
    return sx_sy


#
#   计算余弦距离

def calcCosDist(user1,user2):
    sum_x=0.0
    sum_y=0.0
    sum_xy=0.0
    for key1 in user1:
        for key2 in user2:
            if key1[0]==key2[0] :
                sum_xy+=key1[1]*key2[1]
                sum_y+=key2[1]*key2[1]
                sum_x+=key1[1]*key1[1]

    if sum_xy == 0.0 :
        return 0
    sx_sy=math.sqrt(sum_x*sum_y) 
    return sum_xy/sx_sy



#
#   相似余弦距离

def calcSimlaryCosDist(user1,user2):
    sum_x=0.0
    sum_y=0.0
    sum_xy=0.0
    avg_x=0.0
    avg_y=0.0
    for key in user1:
        avg_x+=key[1]
    avg_x=avg_x/len(user1)

    for key in user2:
        avg_y+=key[1]
    avg_y=avg_y/len(user2)

    for key1 in user1:
        for key2 in user2:
            if key1[0]==key2[0] :
                sum_xy+=(key1[1]-avg_x)*(key2[1]-avg_y)
                sum_y+=(key2[1]-avg_y)*(key2[1]-avg_y)
        sum_x+=(key1[1]-avg_x)*(key1[1]-avg_x)

    if sum_xy == 0.0 :
        return 0
    sx_sy=math.sqrt(sum_x*sum_y) 
    return sum_xy/sx_sy


#
#   读取文件

def readFile(file_name):
    contents_lines=[]
    f=open(file_name,"r")
    contents_lines=f.readlines()
    f.close()
    return contents_lines

#
#   解压rating信息,格式:用户id\t硬盘id\t用户rating\t时间
#   输入:数据集合
#   输出:已经解压的排名信息
#
def getRatingInformation(ratings):
    rates=[]
    for line in ratings:
        rate=line.split("\t")
        rates.append([int(rate[0]),int(rate[1]),int(rate[2])])
    return rates


#
#   生成用户评分的数据结构
#   
#   输入:所以数据 [[2,1,5],[2,4,2]...]
#   输出:1.用户打分字典 2.电影字典
#   使用字典,key是用户id,value是用户对电影的评价,
#   rate_dic[2]=[(1,5),(4,2)].... 表示用户2对电影1的评分是5,对电影4的评分是2

def createUserRankDic(rates):
    user_rate_dic={}
    item_to_user={}
    for i in rates:
        user_rank=(i[1],i[2])
        if i[0] in user_rate_dic:
            user_rate_dic[i[0]].append(user_rank)
        else:
            user_rate_dic[i[0]]=[user_rank]

        if i[1] in item_to_user:
            item_to_user[i[1]].append(i[0])
        else:
            item_to_user[i[1]]=[i[0]]

    return user_rate_dic,item_to_user


#
#   计算与指定用户最相近的邻居
#   输入:指定用户ID,所以用户数据,所以物品数据
#   输出:与指定用户最相邻的邻居列表
#
def calcNearestNeighbor(userid,users_dic,item_dic):
    neighbors=[]
    #neighbors.append(userid)
    for item in users_dic[userid]:
        for neighbor in item_dic[item[0]]:
            if neighbor != userid and neighbor not in neighbors: 
                neighbors.append(neighbor)

    neighbors_dist=[]
    for neighbor in neighbors:
        dist=calcSimlaryCosDist(users_dic[userid],users_dic[neighbor])  #calcSimlaryCosDist  calcCosDist calcCosDistSpe
        neighbors_dist.append([dist,neighbor])
    neighbors_dist.sort(reverse=True)
    #print neighbors_dist
    return  neighbors_dist


#
#   使用UserFC进行推荐
#   输入:文件名,用户ID,邻居数量
#   输出:推荐的电影ID,输入用户的电影列表,电影对应用户的反序表,邻居列表
#
def recommendByUserFC(file_name,userid,k=5):

    #读取文件数据
    test_contents=readFile(file_name)

    #文件数据格式化成二维数组 List[[用户id,电影id,电影评分]...] 
    test_rates=getRatingInformation(test_contents)

    #格式化成字典数据 
    #    1.用户字典:dic[用户id]=[(电影id,电影评分)...]
    #    2.电影字典:dic[电影id]=[用户id1,用户id2...]
    test_dic,test_item_to_user=createUserRankDic(test_rates)

    #寻找邻居
    neighbors=calcNearestNeighbor(userid,test_dic,test_item_to_user)[:k]

    recommend_dic={}
    for neighbor in neighbors:
        neighbor_user_id=neighbor[1]
        movies=test_dic[neighbor_user_id]
        for movie in movies:
            #print movie
            if movie[0] not in recommend_dic:
                recommend_dic[movie[0]]=neighbor[0]
            else:
                recommend_dic[movie[0]]+=neighbor[0]
    #print len(recommend_dic)

    #建立推荐列表
    recommend_list=[]
    for key in recommend_dic:
        #print key
        recommend_list.append([recommend_dic[key],key])


    recommend_list.sort(reverse=True)
    #print recommend_list
    user_movies = [ i[0] for i in test_dic[userid]]

    return [i[1] for i in recommend_list],user_movies,test_item_to_user,neighbors

#
#   获取电影的列表

def getMoviesList(file_name):
    #print sys.getdefaultencoding()
    movies_contents=readFile(file_name)
    movies_info={}
    for movie in movies_contents:
        movie_info=movie.split("|")
        movies_info[int(movie_info[0])]=movie_info[1:]
    return movies_info

#
#主程序
#输入 : 测试数据集合
if __name__ == '__main__':
    reload(sys)
    sys.setdefaultencoding('utf-8')
    movies=getMoviesList("/Users/wuyinghao/Downloads/ml-100k/u.item")
    recommend_list,user_movie,items_movie,neighbors=recommendByUserFC("/Users/wuyinghao/Downloads/ml-100k/u.data",179,80)
    neighbors_id=[ i[1] for i in neighbors]
    table = Texttable()
    table.set_deco(Texttable.HEADER)
    table.set_cols_dtype(['t',  # text 
                          't',  # float (decimal)
                          't']) # automatic
    table.set_cols_align(["l", "l", "l"])
    rows=[]
    rows.append([u"movie name",u"release", u"from userid"])
    for movie_id in recommend_list[:20]:
        from_user=[]
        for user_id in items_movie[movie_id]:
            if user_id in neighbors_id:
                from_user.append(user_id)
        rows.append([movies[movie_id][0],movies[movie_id][1],""])
    table.add_rows(rows)
    print table.draw()
结果
movie name                release     
=======================================================
Contact (1997)                11-Jul-1997               
Scream (1996)                 20-Dec-1996               
Liar Liar (1997)              21-Mar-1997               
Saint, The (1997)             14-Mar-1997               
English Patient, The (1996)   15-Nov-1996               
Titanic (1997)                01-Jan-1997               
Air Force One (1997)          01-Jan-1997               
Star Wars (1977)              01-Jan-1977               
Conspiracy Theory (1997)      08-Aug-1997               
Toy Story (1995)              01-Jan-1995               
Fargo (1996)                  14-Feb-1997   
您好,我可以为您提供一些关于协同过滤推荐算法的 Python 和 Vue 实现代码示例。但是在这里聊天窗口中添加大量的代码可能会有一些不便,如果您需要,我可以发送给您一个链接,其中包含这段代码并且详情十分全面。在这里,让我简要介绍一下实现协同过滤推荐算法的步骤: 1. 收集数据:需要有一个用户评分数据集,通常这个数据集包含着一组用户和他们对某些项目的评分。 2. 构建项目数量矩阵:由于有多种协同过滤算法,此处不再赘述,这里将会使用经典的基于用户的协同过滤算法。该算法需要使用一个项目数量矩阵,该矩阵包含着所有项目项和它们在用户评分数据集中出现的次数。 3. 计算相似度矩阵:对于每个用户,在用户评分数据集中找到它们共同评分的项目项,并计算这些项目的相似程度。通常使用皮尔逊相关系数或余弦相似度计算相似度。 4. 为每个用户做出预测:对于没有评分的项目,通过相似度矩阵和用户评分数据集来预测它们的评分。 下面是 Python 中实现基于用户的协同过滤推荐算法的示例代码: ```python import pandas as pd import numpy as np # 收集数据 ratings_data = pd.read_csv('path/to/ratings.csv') movies_data = pd.read_csv('path/to/movies.csv') # 构建项目数量矩阵 ratings_data['movie_title'] = ratings_data.merge(movies_data, on='movieId')['title'] item_matrix = ratings_data.pivot_table(index='userId', columns='movie_title', values='rating') # 计算相似度矩阵 item_sim_matrix = item_matrix.corr(method='pearson', min_periods=50) # make recommendations def recommendation_engine(user_id): # 获取该用户对电影的评分 user_ratings = item_matrix.loc[user_id].dropna() # 获取与该用户评分过的电影相似的其他电影 similar_items = pd.DataFrame() for title, rating in user_ratings.iteritems(): similar_items = similar_items.append(item_sim_matrix[title].dropna().apply(lambda x: (x, rating)), ignore_index=True) # 计算加权平均分,并过滤掉该用户已评分的电影 sim_sums = similar_items.groupby(similar_items.index).apply(lambda x: sum(x[0] * x[1]) / x[0].sum()) sim_sums = sim_sums[~sim_sums.index.isin(user_ratings.index)] # 获取前 5 个推荐电影并返回电影名称列表 top_sims = sim_sums.sort_values(ascending=False).head(5) top_movies = movies_data.loc[movies_data['title'].isin(top_sims.index)]['title'].tolist() return top_movies ``` 下面是 Vue 中实现基于用户的协同过滤推荐算法的示例代码: ```javascript <script> import axios from 'axios' export default { data () { return { userId: '', recommendedMovies: [] } }, methods: { makeRecommendation () { axios.get('/recommendation', { params: { user_id: this.userId } }).then(res => { this.recommendedMovies = res.data.movies }) } } } </script> ``` 上面的 Vue 模板中定义了一个 userId 属性和一个 recommendedMovies 属性,并且定义了一个 makeRecommendation 方法去获取推荐电影。该方法会向后端发送一个 GET 请求,该请求会带有用户 ID 信息。后端代码会接收到该请求,进而调用相应的协同过滤推荐函数,然后将电影名字列表返回给前端。 希望这些代码例子可以帮助您学习协同过滤推荐算法的实现。
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值