任务8 使用Word2Vec进行推荐

任务8 使用Word2Vec进行推荐

1. 原理

我们有了用户的embedding很容易就可以利用这些embedding来计算用户的相似度. 有了用户的相似度, 我们接下来就可以使用前面任务4的一些函数来直接进行推荐

2. 代码实现

导入相关的包, 有些包是自己手动实现的, 详情见之前的博客

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import torch

import Metirc
from utils import loadData, rating2matrix, Split_Dataset_P
import Similarity

from gensim.models import Word2Vec

读取数据集

ratings = loadData('./data/', 'ml-100k')

划分数据集

train_data, test_data = Split_Dataset_P(ratings)

下面实际上只是把任务7的过程在做了一遍

def rating_splitter(df):
    df['liked'] = np.where(df['rating'] >= 4, 1, 0)
    df['movieid'] = df['movieid'].astype('str')
    gp_movie_like = df.groupby(['liked', 'movieid'])
    return ([gp_movie_like.get_group(gp)['userid'].tolist() for gp in gp_movie_like.groups])
    
splitted_users = rating_splitter(train_data)

import random

for user_list in splitted_users:
    random.shuffle(user_list)
    
model = Word2Vec(sentences=splitted_users
                , epochs=20
                , min_count=1
                , vector_size=100
                , workers=4
                , sg=1
                , hs=0
                , negative=5
                , window=1000)
    
model.wv.save_word2vec_format('train_uservector.txt')
user_vector = pd.read_csv('train_uservector.txt', sep=' ', header=None)
user_vector.rename(columns={0:'userid'}, inplace=True)
user_vector = user_vector.sort_values(by='userid').reset_index(drop=True)
uservec = torch.tensor(user_vector.loc[:, 1:].to_numpy())

下面我们计算用户与用户之间的相似度(函数之前任务4的时候就写过了, 直接拿来用)

simi = Similarity.SimCos(uservec)

取出最相似的前80个用户

sim_user_value, sim_user_index = torch.topk(simi, k=80, dim=1)

下面进行推荐, 步骤和任务4类似

def normalize_e(t):
    """对一个矩阵,按照列进行归一化
    即 行向量的元素/行向量的总和

    Args:
        t (tensor(2d)): 需要进行归一化的矩阵

    Returns:
        tensor: 和输入矩阵形状一样的一个经过归一化之后的矩阵
    """
    return t / t.sum(dim=1).unsqueeze(dim=1)


def predict_score(scores, index, similarity):
    """预测用户的打分

    Args:
        scores (tensor): 完整的打分矩阵
        index (tensor): 相似的前k个用户的索引
        similarity (tensor): 相似程度
        通常index和similary是通过torch.topk得到的
    Returns:
        tensor: 每一行就是一个用户,每个行向量就是预测的用户对物品的打分
    """
    r1 = []
    similarity = normalize_e(similarity)
    for i,j in zip(index, similarity):
        # print(i)
        # print(j)
        selected_score = torch.index_select(input=scores, index=i, dim=0)
        print(selected_score)
        print(j)
        final_score = torch.mm(j.unsqueeze(dim=0), selected_score)
        # print(final_score)
        r1.append(final_score)
    r1 = torch.cat(r1,dim=0)
    return r1


def recommend(score, k = 3):
    """通过预测的物品打分,给用户推荐前k个物品

    Args:
        score (tensor): 这个是预测的打分
        k (int, optional): 推荐前k个物品. Defaults to 3.

    Returns:
        pred, index: pred是推荐的物品对应的打分,index是推荐的物品的索引
    """
    pred, index = torch.topk(input=score, k=k, dim=1)
    return pred, index
    

对数据进行一下处理, 我们之前生成"句子"的时候不小心把train_data的userid变成了str类型的, 现在要转换回来, 之后还要把数据转换成tensor格式的

train_data['movieid'] = train_data['movieid'].astype('int')
train_data = rating2matrix(train_data)
train_data = torch.tensor(train_data)
train_data = train_data.double()

基于之前计算得到的相似度, 来预测一下打分

pred_score = predict_score(train_data, index=sim_user_index, similarity=sim_user_value)
pred_score

tensor([[2.9639, 1.3864, 0.5703, …, 0.0000, 0.0358, 0.0407],
[1.1632, 0.1052, 0.0219, …, 0.0000, 0.0000, 0.0000],
[0.0253, 0.0760, 0.0000, …, 0.0000, 0.0000, 0.0000],
…,
[2.7019, 0.4559, 0.5954, …, 0.0000, 0.0000, 0.0000],
[1.7096, 0.6178, 0.0954, …, 0.0000, 0.0000, 0.0000],
[3.0461, 1.3083, 0.5879, …, 0.0000, 0.0000, 0.0382]],
dtype=torch.float64)

基于预测的打分, 给出打分最高的10个物品

rec_value, rec_index = recommend(pred_score, k=10)

rec_index就是推荐的10个物品的id, rec_value就是对应的预测打分

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值