我们基于训练集计算用户和产品嵌入,并在未见过的测试集上评估结果。我们将通过绘制用户和产品相似度与评分的关系来评估结果。数据集在 Get_embeddings_from_dataset Notebook 中创建。
我们基于训练集计算用户和产品嵌入,并在未见过的测试集上评估结果。我们将通过绘制用户和产品相似度与评分的关系来评估结果。数据集在 Get_embeddings_from_dataset Notebook 中创建。
我们通过简单地平均训练集中关于同一产品或由同一用户编写的所有评论来计算这些嵌入。
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 | 评分 | 摘要 | 文本 | 组合 | n_tokens | 嵌入 | |
---|---|---|---|---|---|---|---|---|
0 | B003XPF9BO | A3R7JR3FMEBXQB | 5 | 从哪里开始...又在哪里停止...一棵树... | 想保存一些带给我芝加哥的家人... | 标题:从哪里开始...又在哪里停止... ... | 52 | [0.03599238395690918, -0.02116263099014759, -0... |
297 | B003VXHGPK | A21VWSCGW7UUAR | 4 | 好,但不如沃尔夫冈·帕克的好 | 老实说,我不得不承认我期待一个更... | 标题:好,但不如沃尔夫冈·帕克的好;内容... | 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 万个示例中只出现一次。
为了评估推荐结果,我们查看未见过的测试集中评论中用户和产品嵌入的相似性。我们计算用户和产品嵌入之间的余弦距离,这为我们提供了一个介于 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)
我们按评分对余弦相似度评分进行分组,并绘制每个评分的余弦相似度评分分布。
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%
我们可以观察到一个微弱的趋势,表明用户和产品嵌入之间的相似度评分越高,评分也越高。因此,用户和产品嵌入可以微弱地预测评分 - 甚至在用户收到产品之前!
因为这种信号的工作方式与更常用的协同过滤不同,它可以作为额外的特征来稍微提高现有问题的性能。