使用KNN预测电影评分-python3

0. 理论

在散点图上找出k个最近邻居,让他们投票确定分类,类别判定为离它最近的k个观察值中所占比例最大的分类。

1.用KNN预测电影评分

import pandas as pd
import numpy as np
# 读取电影评分数据
r_cols = ['user_id', 'movie_id', 'rating']
ratings = pd.read_csv('E:/python/python数据科学与机器学习/《Python数据科学与机器学习:从入门到实践》源代码/ml-100k/u.data', sep='\t', names=r_cols, usecols=range(3))
ratings.head()
user_idmovie_idrating
00505
101725
201331
31962423
41863023
# 将movie_id分组汇总,求每个movie_id的评价数量和打分均值

movieProperties = ratings.groupby('movie_id')['rating'].agg(['size', 'mean']).reset_index()
movieProperties.head()
movie_idsizemean
014523.878319
121313.206107
23903.033333
342093.550239
45863.302326
# 将评价数量标准化, 范围在[0, 1]
movieProperties['size'] = (movieProperties['size'] - movieProperties['size'].min())/(movieProperties['size'].max() - movieProperties['size'].min())
movieProperties.head()
movie_idsizemean
010.7735853.878319
120.2229853.206107
230.1526593.033333
340.3567753.550239
450.1457983.302326
movieProperties.tail()
movie_idsizemean
167716780.01.0
167816790.03.0
167916800.02.0
168016810.03.0
168116820.03.0
# 读取电影类型数据
movieDict = {}
i = 0
with open(r'E:/python/python数据科学与机器学习/《Python数据科学与机器学习:从入门到实践》源代码/ml-100k/u.item',encoding = 'ISO-8859-1') as f:    
    for line in f:
        fields = line.rstrip('\n').split('|')
        movieID = int(fields[0])
        name = fields[1]
        # 类型
        genres = fields[5:25]
        # 将类型转为int列表
        genres = map(int, genres)
        # 标准化后的尺寸
        size = movieProperties.loc[movieProperties.movie_id == movieID, 'size'].values[0]
        # 均值
        mean = movieProperties.loc[movieProperties.movie_id == movieID, 'mean'].values[0]
        # 将数据存入字典
        movieDict[movieID] = (name, np.array(list(genres)), size, mean)
print(movieDict[1])
('Toy Story (1995)', array([0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]), 0.7735849056603774, 3.8783185840707963)
from scipy import spatial

# 计算两个电影之间的相似度距离
def ComputeDistance(a, b):
    genresA = a[1]
    genresB = b[1]
    # 用余弦距离作为类型的相似度
    genreDistance = spatial.distance.cosine(genresA, genresB)
    popularityA = a[2]
    popularityB = b[2]
    # 用尺寸的绝对值之差作为流行度的相似度
    popularityDistance = abs(popularityA - popularityB)
    return genreDistance + popularityDistance
    
ComputeDistance(movieDict[2], movieDict[4])
0.8004574042309892
def getNeighbors(movieID, k):
    distances = []
    for movie in movieDict:
        if (movie != movieID):
            dist = ComputeDistance(movieDict[movieID], movieDict[movie])
            distances.append((movie, dist))
    # 按相似度距离正序排列,越相似的电影距离越小
    distances.sort(key= lambda x: x[1])
    # k个近邻
    neighbors = []
    for x in range(k):
        neighbors.append(distances[x][0])
    # 查找k个近邻在字典的评分均值,并计算总体均值
    print('前{}个近邻的名称和打分为:\n'.format(k))
    avgRating = 0
    for neighbor in neighbors:
        avgRating += movieDict[neighbor][3]   
        print('{:<45s}{}'.format(movieDict[neighbor][0], movieDict[neighbor][3]))
    avgRating /= k   
    print('\n{}个近邻的总体打分均值为:{}'.format(k, avgRating))
    print('ID为{}的电影的实际评分为:{}'.format(movieID, movieDict[movieID][3]))
     
getNeighbors(1, 10)    
前10个近邻的名称和打分为:

Liar Liar (1997)                             3.156701030927835
Aladdin (1992)                               3.8127853881278537
Willy Wonka and the Chocolate Factory (1971) 3.6319018404907975
Monty Python and the Holy Grail (1974)       4.0664556962025316
Full Monty, The (1997)                       3.926984126984127
George of the Jungle (1997)                  2.685185185185185
Beavis and Butt-head Do America (1996)       2.7884615384615383
Birdcage, The (1996)                         3.4436860068259385
Home Alone (1990)                            3.0875912408759123
Aladdin and the King of Thieves (1996)       2.8461538461538463

10个近邻的总体打分均值为:3.3445905900235564
ID为1的电影的实际评分为:3.8783185840707963

2. 参考资料

Python数据科学与机器学习:从入门到实践
作者:
[美]弗兰克•凯恩(Frank Kane)

源代码下载:
https://www.ituring.com.cn/book/2426

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
加权KNN算法可以用于电影评分预测。假设我们有一个用户-电影评分矩阵,其中每行代表一个用户,每列代表一个电影,矩阵中的元素为用户对电影评分。我们可以使用加权KNN算法来预测用户对某个电影评分。 具体来说,我们可以将每个用户的评分向量作为训练数据,使用加权KNN算法来预测用户对某个电影评分。具体步骤如下: 1. 对于要预测评分电影,计算它与所有用户评分的距离。 2. 对距离进行排序,选取前k个最近的用户。 3. 对于每个用户,计算其权重,可以使用距离的倒数或者高斯核函数等方法来计算权重。 4. 对于要预测评分的用户,计算其对该电影的加权评分。 5. 输出预测评分。 下面是一个用于预测用户对某个电影评分的加权KNN算法的Python实现: ```python import numpy as np def euclidean_distance(x1, x2): return np.sqrt(np.sum((x1 - x2)**2)) class WeightedKNN: def __init__(self, k=3): self.k = k def fit(self, X, y): self.X_train = X self.y_train = y def predict(self, x): distances = [euclidean_distance(x, x_train) for x_train in self.X_train] k_indices = np.argsort(distances)[:self.k] k_distances = distances[k_indices] k_ratings = self.y_train[k_indices] weights = 1 / (k_distances + 1e-8) # add small number to avoid division by zero weights = weights / np.sum(weights) y_pred = np.dot(weights, k_ratings) return y_pred ``` 在上述代码中,我们通过`fit`方法传入训练数据,其中`X`是评分矩阵,每行代表一个用户,每列代表一个电影,`y`是电影列表。在`predict`方法中,我们传入要预测电影评分向量`x`,计算它与所有用户评分的距离,并选取前k个最近的用户。然后,对于每个用户,计算其权重,并计算其对该电影的加权评分。最后,输出预测评分。 需要注意的是,当对新用户进行评分预测时,由于其评分向量为空,我们可以使用该用户评分矩阵中其他用户对该电影评分来代替其评分向量,即将其评分向量设为该电影的列向量。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值