我们基于训练集计算用户和产品嵌入向量,并在未见过的测试集上评估结果。我们将通过绘制用户与产品相似度与评分的对比图来评估结果。该数据集是在Get_embeddings_from_dataset Notebook中创建的。
1. 计算用户和产品嵌入向量
我们通过简单平均训练集中同一产品或同一用户的所有评论来计算这些嵌入向量。
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from ast import literal_eval
df = pd.read_csv('data/fine_food_reviews_with_embeddings_1k.csv', index_col=0) # note that you will need to generate this file to run the code below
df.head(2)| 产品ID | 用户ID | 评分 | 摘要 | 文本内容 | 组合字段 | 令牌数量 | 嵌入向量 | |
|---|---|---|---|---|---|---|---|---|
| 0 | B003XPF9BO | A3R7JR3FMEBXQB | 5 | 从哪里开始...又在哪里结束...关于一棵树... | 想留一些带去芝加哥给家人... | 标题:从哪里开始...又在哪里结束...关于一棵树... | 52 | [0.03599238395690918, -0.02116263099014759, -0... |
| 297 | B003VXHGPK | A21VWSCGW7UUAR | 4 | 不错,但比不上Wolfgang Puck的水平 | 说实话,我必须承认我原本期待... | 标题:不错,但比不上Wolfgang Puck的水平;内容... | 178 | [-0.07042013108730316, -0.03175969794392586, -... |
df['babbage_similarity'] = df["embedding"].apply(literal_eval).apply(np.array)
X_train, X_test, y_train, y_test = train_test_split(df, df.Score, test_size = 0.2, random_state=42)
user_embeddings = X_train.groupby('UserId').babbage_similarity.apply(np.mean)
prod_embeddings = X_train.groupby('ProductId').babbage_similarity.apply(np.mean)
len(user_embeddings), len(prod_embeddings)
(577, 706)
我们可以看到,大多数用户和产品在5万条示例中仅出现一次。
2. 评估嵌入向量
为了评估推荐效果,我们查看了未见测试集中评论的用户和产品嵌入之间的相似性。我们计算用户和产品嵌入之间的余弦距离,得出0到1之间的相似度分数。然后,我们通过计算该相似度分数在所有预测分数中的百分位数,将分数标准化为0到1之间的均匀分布。
from utils.embeddings_utils import cosine_similarity
# evaluate embeddings as recommendations on X_test
def evaluate_single_match(row):
user_id = row.UserId
product_id = row.ProductId
try:
user_embedding = user_embeddings[user_id]
product_embedding = prod_embeddings[product_id]
similarity = cosine_similarity(user_embedding, product_embedding)
return similarity
except Exception as e:
return np.nan
X_test['cosine_similarity'] = X_test.apply(evaluate_single_match, axis=1)
X_test['percentile_cosine_similarity'] = X_test.cosine_similarity.rank(pct=True)
2.1 按评论分数可视化余弦相似度
我们按评论分数对余弦相似度得分进行分组,并绘制每个评论分数的余弦相似度得分分布图。
import matplotlib.pyplot as plt
import statsmodels.api as sm
correlation = X_test[['percentile_cosine_similarity', 'Score']].corr().values[0,1]
print('Correlation between user & vector similarity percentile metric and review number of stars (score): %.2f%%' % (100*correlation))
# boxplot of cosine similarity for each score
X_test.boxplot(column='percentile_cosine_similarity', by='Score')
plt.title('')
plt.show()
plt.close()
Correlation between user & vector similarity percentile metric and review number of stars (score): 29.56%
我们可以观察到一个微弱的趋势,显示用户与产品嵌入之间的相似度得分越高,评论分数也越高。因此,用户和产品嵌入可以微弱地预测评论分数——甚至在用户收到产品之前!
由于该信号的工作方式与更常用的协同过滤不同,它可以作为附加特征来略微提升现有问题的性能。