原文:towardsdatascience.com/ai-my-holiday-elf-building-a-gift-recommender-for-the-perfect-christmas-caf163d38e10

假期季节已经到来——是时候点亮灯光、品尝热红酒、享受炸薯条和进行礼物采购了!但说真的,寻找独特、有心思的礼物很快就会变成一项繁琐的任务。厌倦了那些老套的建议,比如男士香水和对所有孩子都适用的普通玩具,我决定给我的礼物采购体验带来一些人工智能的魔力。

在这篇文章中,我将向您展示我是如何使用人工智能和 Streamlit 创建一个有趣的、个性化的礼物推荐器的——这非常适合节省时间和传播节日气氛!文章末尾将添加仓库链接。

目录

  1. 圣诞老人的便条:2024 年最受欢迎的礼物选择

  2. 教会 AI 你的愿望清单

  3. 定制推荐的魅力

  4. 你的礼物指南精灵:Streamlit 实战

  5. 协同过滤:朋友最了解

  6. 挑战

  7. 总结一切

圣诞老人的便条:2024 年最受欢迎的礼物选择

我让 AI 扮演圣诞老人的小助手,并整理了一份 2024 年的流行礼物清单。使用 Perplexity 和 ChatGPT 等工具,我根据人物角色分组礼物——无论是为喜欢喝茶的父亲、好奇的幼儿还是技术娴熟的丈夫。

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/ff48f70a389cf4c04542f0b19fd713a3.png

作者提供的困惑度搜索结果

结果?一个充满创意的数据集,为你的名单上的每个人量身定制。

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/b50bf4b15be518d6a6eeb0d01ba61888.png

作者提供的礼物想法数据集图片

这里是精灵选择的礼物想法的预览:

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/108ab5f9b2a60b253282ef4955289d20.png

作者提供的礼物想法词云

下一步是准备这些数据以供我们的模型使用,并将这些文本转换为机器人的语言。

教会 AI 你的愿望清单

为了教会 AI“说礼物”,我将礼物描述转换成了一种机器人友好的语言,称为嵌入。想象一下,给每个礼物一个 GPS 位置,这样 AI 就知道它在礼物世界中的位置。

我使用了句子嵌入来总结礼物想法的精髓。你可以将这个过程想象成一个教室的学生:

  • 句子中的每个单词就像教室里的一个学生。

  • 每个学生(单词)都有代表其技能(如数学、舞蹈、艺术等)的数字。

  • 每个教室都有固定数量的座位,所以如果学生(单词)不够,空座位(填充)会用可爱的小熊填充,用数字 0 表示。

当我们给模型一个句子,例如:“这是一个美妙的礼物想法。”,每个单词都会被转换成一个描述其技能的数字列表。例如:

  • “This” = [0.5, 0.2, -0.1, …]

  • “is” = [0.3, 0.6, 0.0, …]

即使是空座位(填充)也会得到一个泰迪熊(或一个零的列表):

  • “泰迪熊” = [0.0, 0.0, 0.0, …]

然后,我们将所有这些列表组合起来形成一个大的表格,描述句子:

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/e7534c913c03e35200f93c768f910347.png

礼物嵌入表由作者

现在,我们想找出教室(句子)擅长什么,所以我们取所有技能的平均值:

  • 技能 1 平均:(0.5 + 0.3 + 0.1 - 0.2 + 0.8 + 0.0) ÷ 6 = 0.25

  • 技能 2 平均:(0.2 + 0.6 + 0.4 + 0.7 - 0.1 + 0.0) ÷ 6 = 0.30

最后,我们得到一个代表整个教室(句子)的单一数字列表:

  • 句子 = [0.25, 0.30, 0.10, …]

这个列表被称为句子嵌入。我们不再逐个查看每个单词,现在我们有一个单一的数字列表,它讲述了整个句子的故事

使用Sentence-BERT,我将每个礼物想法、描述和人物编码成嵌入,人工智能可以使用这些嵌入来比较和匹配用户输入,如“爱茶的爸爸”。

# Load a pre-trained Sentence-BERT model
model = SentenceTransformer('all-MiniLM-L6-v2')  # Lightweight and fast model
# Apply the model to gift ideas
df['embedding']=df.apply(
lambda row: model.encode(f"{row['Gift Idea']} {row['Description']} for {row['Persona']}"),axis=1
)

定制推荐的魅力

基于内容的过滤就像咖啡店酒吧师注意到你喜欢巧克力,并推荐摩卡或焦糖等风味。

同样,我的应用程序将您的输入(“爱茶的爸爸”)与具有相似“风味”或描述的礼物进行匹配。

我将用户的输入转换为嵌入,并将用户的输入嵌入与礼物嵌入进行比较,以使用余弦相似度找到最合适的礼物想法。

余弦相似度衡量两个礼物想法根据其描述的匹配程度。它们越接近,匹配度就越好!

它忽略了详细的礼物描述,只关注两个礼物想法的方向。如果它们指向同一方向,余弦相似度会说,“这两个礼物匹配!”

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/9edeaac05d90932798d2af9212d371c4.png

余弦相似度 Canva 设计由作者

因此,我计算了用户输入 “爱茶的爸爸” 与礼物嵌入之间的余弦相似度:

# Compute cosine similarity between user input and all gift embeddings
similarity_score=cosine_similarity(user_embedding,gift_embeddings)
# Add similarity scores to the dataframe for reference
df['similarity_score'] = similarity_score.flatten()

并获取前 5 个最佳匹配结果:

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/e526ddfc396baac37532a40569fa9e0f.png

由作者根据余弦相似度模型提供的 Top 5 礼物想法

数据框看起来像这样:

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/5dc69cb2b93c3e34693df8ec470c13a0.png

具有相似度分数的数据集由作者

一旦我找到了匹配的礼物,我还需要考虑我的预算范围。你不想让推荐者总是建议让你在节日季节后破产的礼物!

我定义了一个预算范围函数,它从数据中解析价格范围数据,以确保建议的礼物在指定的预算限制内:

def is_within_budget(price_range, min_budget, max_budget):
    try:
        # Parse price range (e.g., "£50-£100")
        price_values = price_range.replace('£', '').split('-')

        if len(price_values) == 2:
            min_price, max_price = map(float, price_values)
        else:
            min_price = max_price = float(price_values[0])

        return min_price >= min_budget and max_price <= max_budget
    except Exception as e:
        return False  # Handle invalid price range format

您的礼物指南精灵:Streamlit 在行动

在 Streamlit 上构建和分享这个应用程序就像将人工智能变成每个人的圣诞老人助手一样。通过输入一个简单的描述——比如“热爱艺术的丈夫”——应用程序可以在您的预算范围内提出定制的礼物想法。

获取 Streamlit 账户,您可以直接将您的 GitHub 页面链接到您的账户以创建您的应用。如果您是 Streamlit 的新手,您可能需要通过试错来找出您的文件路径,并确保 Streamlit 应用可以正确访问您的 GitHub 文件夹路径。

我创建了一个 app.py 脚本,Streamlit 应用将访问并部署该应用:

# Add the "Get Recommendations" button
if st.button("Get Recommendations"):
    if user_input:
        # Generate user embedding for description (ensure you already have the model and embeddings)
        user_embedding = model.encode(user_input).reshape(1, -1)  # Replace 'model' with your preloaded model
        similarity_scores = cosine_similarity(user_embedding, gift_embeddings)

        # Apply budget filtering
        df['similarity_score'] = similarity_scores.flatten()
        filtered_df = df[df['Budget Range'].apply(lambda x: is_within_budget(x, min_budget, max_budget))]
        filtered_df_sorted = filtered_df.sort_values(by='similarity_score', ascending=False)

哈喽,今年我为我家人找到了完美的圣诞礼物——一个小型冰淇淋机和一套书法套装或 Galaxy 投影仪给老公!

cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fplayer.vimeo.com%2Fvideo%2F1036630572%3Fapp_id%3D122963&dntp=1&display_name=Vimeo&url=https%3A%2F%2Fvimeo.com%2F1036630572&image=https%3A%2F%2Fi.vimeocdn.com%2Fvideo%2F1958389062-36dfc3d953f29a8c8ca5d025e59e01ffa8d539e01b384e1283866f895c3a4d20-d_1280&type=text%2Fhtml&schema=vimeo

要亲自尝试,请点击此处 – 圣诞应用链接

协同过滤:朋友最了解

当基于内容的过滤查看礼物描述并将其与用户的输入匹配时,协同过滤更进一步。它通过学习其他用户的偏好添加了一个社交层。

协同过滤就像向一个口味相似的朋友寻求建议。如果你的朋友喜欢科幻电影,而你也是,那么他们的推荐很可能会受欢迎。

如果你搜索“喜欢阅读的妈妈”,基于内容的过滤会根据其与输入的相似性推荐类似烘焙套装等物品。对于协同过滤,如果具有相似偏好的用户也喜欢 HelloFresh 订阅盒,它也会建议这一点——即使它与你的输入没有直接关系。

我使用 ChatGPT 创建了合成用户-项目矩阵,其中每个用户对每个礼物想法的评分从 1 到 5:

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/1b2d3ce35759ec9d6a44d184dec9e53d.png

作者的用户-项目矩阵数据

然后,我应用了 SVD 矩阵分解模型来训练数据集并预测用户的评分:

# Load user-item interaction data into Surprise's format
reader = Reader(rating_scale=(1, 5))
data=Dataset.load_from_df(user_matrix_cleaned,reader)

# Split the data into training and testing sets
trainset, testset = train_test_split(data, test_size=0.2, random_state=42)

# Build and train the SVD (matrix factorization) model
model = SVD()
model.fit(trainset)

# Test the model
predictions = model.test(testset)
svd_rmse=accuracy.rmse(predictions)

在第一次尝试中,RMSE(均方根误差)为 1.42,这意味着平均而言,预测评分与实际评分相差大约1.42个单位。

对于我的评分来说,这还不够,我的评分范围是 1 到 5!

经过进一步检查,我发现模型在预测极端评分方面表现不佳:

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/f453f00c8b03ac595f236a1fa22f2ea5.png

作者的错误分布图

错误可能是由于模型可能过度拟合训练数据,导致极端评分(1 和 5)生成不良。

我重新定义了具有正则化参数的模型:

# Define the model with regularization parameter
svd = SVD(reg_all=0.1)  # You can try different values for reg_all (e.g., 0.05, 0.2)

# Train the model
trainset = data.build_full_trainset()
svd.fit(trainset)

这将均方根误差降低到1.1355,太好了!

下一步是使用这个模型根据协同过滤预测特定用户的礼物:

# Predict ratings for unrated gifts
predictions = [
        (gift, model.predict(user_id, gift).est)
        for gift in all_gifts
        if gift not in rated_gifts
    ]

# Sort by predicted ratings in descending order
predictions.sort(key=lambda x: x[1], reverse=True)

给定用户 0 的示例,模型根据用户的评分推荐了前 5 个礼物想法:

https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/f5fc31cf84cd1a684a57ee6a92457794.png

Top 5 Gift Ideas for User 0 by Author

挑战

在这个项目中遇到了几个挑战:

  1. 理解嵌入让我了解到 AI 如何将语言分解成数字——就像给单词一个 GPS 位置。这很棘手,但值得!

  2. 需要更系统的方法来创建针对每个角色和接收者类型的礼物想法列表。我的当前礼物想法是根据流行趋势精心挑选的。就像圣诞老人更新他的坏孩子和好孩子名单一样,我的礼物推荐器需要定期更新以跟上潮流。

  3. 在 Streamlit 上部署需要很多耐心和反复试验,以确保正确实现文件夹目录,让应用访问你的应用代码。部署应用让我更加重视用户友好设计和稳健的调试。

  4. 训练模型处理极端评分(1 和 5)并避免过拟合花费了一些时间。通过调整参数和重新训练,我找到了一个提高准确性的平衡点。

总结

构建和部署我第一个真正的实时应用令人兴奋!即使你的应用只有一个功能,小步骤也能积累动力。

这个项目让我看到 AI 如何为假日季节带来欢乐。现在轮到你了——这个圣诞节你将构建什么有趣的项目?

Git Repo for those curious minds


*👉 担心你错过了 AI 的机会?*🤖 我为你准备了我们完全免费的 A. I have a Kickstarter email course! 完美适合想要了解更多关于 AI 的初学者。立即行动,不要犹豫!

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐