基于hadoop的商品推荐系统_书籍商品推荐系统

本文介绍了如何使用Surprise库中的MatrixFactorization实现个性化书籍推荐系统,通过矩阵分解技术和梯度下降法,结合用户评分数据,解决千人千面的问题,并与Surprise内置的KNN和SVD方法进行了对比。
摘要由CSDN通过智能技术生成

书籍商品推荐系统

使用矩阵分解, 根据用户给书籍商品的评分数据, 做一个千人千面的个性化推荐系统

需要安装推荐系统库surprise, 使用如下命令安装: pip install scikit-surprise

# 导入 nunpy 和 surprise 辅助库
import numpy as np
import surprise  

Surprise库本身没有提供纯粹的矩阵分解的算法, 在这里我们自己实现了基于Alternating Least Squares的矩阵分解, 使用梯度下降法优化

矩阵分解类MatrixFactorization继承了surprise.AlgoBase, 方便我们使用surpise库提供的其它功能

class MatrixFactorization(surprise.AlgoBase):
    '''基于矩阵分解的推荐.'''
    
    def __init__(self, learning_rate, n_epochs, n_factors, lmd):
        
        self.lr = learning_rate  # 梯度下降法的学习率
        self.n_epochs = n_epochs  # 梯度下降法的迭代次数
        self.n_factors = n_factors  # 分解的矩阵的秩(rank)
        self.lmd = lmd # 防止过拟合的正则化的强度
        
    def fit(self, trainset):
        '''通过梯度下降法训练, 得到所有 u_i 和 p_j 的值'''
        
        print('Fitting data with SGD...')
        
        # 随机初始化 user 和 item 矩阵.
        u = np.random.normal(0, .1, (trainset.n_users, self.n_factors))
        p = np.random.normal(0, .1, (trainset.n_items, self.n_factors))
        
        # 梯度下降法
        for _ in range(self.n_epochs):
            for i, j, r_ij in trainset.all_ratings():
                err = r_ij - np.dot(u[i], p[j])
                #TODO
                # 利用梯度调整 u_i 和 p_j
                u[i] -= -self.lr * err * p[j] + self.lr * self.lmd * u[i]
                p[j] -= -self.lr * err * u[i] + self.lr * self.lmd * p[j]
                # 注意: 修正 p_j 时, 安装严格定义, 我们应该使用 u_i 修正之前的值, 但是实际上差别微乎其微
        
        self.u, self.p = u, p
        self.trainset = trainset

    def estimate(self, i, j):
        '''预测 user i 对 item j 的评分.'''
        
        # 如果用户 i 和物品 j 是已知的值, 返回 u_i 和 p_j 的点击
        # 否则使用全局平均评分rating值(cold start 冷启动问题)
        if self.trainset.knows_user(i) and self.trainset.knows_item(j):
            # 返回 u_i 和 p_j 的点击
            return np.dot(self.u[i], self.p[j])
        else:
            # 返回 全局平均评分rating值
            return self.trainset.global_mean

演示如何调用以上定义的矩阵分解类实现书籍商品的推荐

from surprise import BaselineOnly
from surprise import Dataset
from surprise import Reader
from surprise import accuracy
from surprise.model_selection import cross_validate
from surprise.model_selection import train_test_split
import os

file_path = os.path.expanduser('./book_crossing/book_ratings.dat')

# 创建 reader 对象
reader = Reader(line_format='user item rating', sep='t', rating_scale=(1, 5))
data = Dataset.load_from_file(file_path, reader=reader)

# 将数据随机分为训练和测试数据集
trainset, testset = train_test_split(data, test_size=.25)

# 初始化以上定义的矩阵分解类.
algo = MatrixFactorization(learning_rate=.015, n_epochs=60, n_factors=2, lmd = 0.2)

# 训练
algo.fit(trainset)

# 预测
predictions = algo.test(testset)

# 计算平均绝对误差
accuracy.mae(predictions)

Fitting data with SGD... MAE: 3.0879

Out[32]:
3.087916709895363

# 使用 surpise 内建的基于最近邻的方法做比较
algo = surprise.KNNBasic()
algo.fit(trainset)
predictions = algo.test(testset)
accuracy.mae(predictions)

Computing the msd similarity matrix... Done computing similarity matrix. MAE: 3.0747

Out[33]:
3.0746869394684526

# 使用 surpise 内建的基于 SVD 的方法做比较
algo = surprise.SVD()
algo.fit(trainset)
predictions = algo.test(testset)
accuracy.mae(predictions)

MAE: 3.0632

Out[34]:
3.063175741427142

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值