利用机器学习探索食物配方:通过Word2Vec模型进行菜谱分析

本文涉及的产品
模型训练 PAI-DLC,100CU*H 3个月
模型在线服务 PAI-EAS,A10/V100等 500元 1个月
交互式建模 PAI-DSW,每月250计算时 3个月
简介: 利用机器学习探索食物配方:通过Word2Vec模型进行菜谱分析

介绍

食物是我们生活中不可分割的一部分。据观察,当一个人选择吃东西时,通常会考虑食材和食谱。受食材和烹饪风格的影响,一道菜可能有数百或数千种不同的菜谱。网站上的菜谱展示了做一道菜所需要的食材和烹饪过程。但问题是,用户无法识别哪些菜可以用自己现有的食材烹饪。为了克服这些问题,机器学习方法能够根据用户可用的材料提出菜谱。

因此,在我们进一步研究机器学习如何在食品工业中使用之前,让我们先了解更多关于自然语言处理(NLP)的知识。

NLP是什么

自然语言是指人类用来相互交流的语言。这种交流可以是口头的,也可以是文本的。例如,面对面的对话,推特,博客,电子邮件,网站,短信,都包含自然语言。然而,要使计算机容易地理解和处理这种自然语言,就需要应用规则和算法,以便将非结构化数据转换为计算机能够理解的形式。

句法分析和语义分析是完成自然语言处理任务的主要技术。“句法”指的是词语在句子中的排列,使它们具有语法意义,而“语义”指的是文本所传达的意思

有了这些规则和字嵌入算法,我们将自然语言字转换为计算机可以理解的数字格式。

Word Embedding 字嵌入

单词嵌入是一种单词表示,它允许机器学习算法理解具有相似意思的单词。又称分布式语义模型或语义向量空间或向量空间模型;这意味着在向量空间中对相似单词的向量进行分类或分组。它背后的想法相当简单:你应该通过它的同伴来认识一个单词。因此,有相似邻居的词,即。用法上下文是差不多的,很可能有相同的意思或至少是高度相关的。

Word2Vec -一种单词嵌入方法

Word2Vec是一种单词嵌入方法,由Tomas Mikolov开发,被认为是最先进的。Word2Vec方法利用深度学习和基于神经网络的技术,将单词转换为相应的向量,使语义相似的向量在N维空间中相互接近,其中N表示向量的维数。

究竟为什么我们需要在分析食物配方和配料时嵌入文字呢?嗯,我们需要一些方法来将文本和分类数据转换为数字机器可读的变量,如果我们想比较一个配方和另一个配方。在本教程中,我们将学习如何使用Word2Vec:

  • 暗示相似的概念——在这里,单词嵌入帮助我们暗示与被置于预测模型中的单词相似的成分。
  • 创建一组相关词:用于语义分组,将特征相似的事物聚在一起,不相似的事物远远聚在一起。
  • 找到不相关的概念
  • 计算两个或更多单词之间的相似度

这篇文章的目的是为那些有兴趣进一步探索这一领域的人提供一个参考和起点。

食物的食谱数据集

让Word2Vec真正为您工作的秘密是在相关领域中拥有大量文本数据。在本教程中,我们将使用数据集,该数据集包含大约5000个不同烹饪方法和不同配料的食谱。

数据清理和预处理

让我们首先将菜谱加载到pandas dataframe并删除空行

#load the recipes dataset
filepath = "/kaggle/input/foodrecipes/recipes.csv"
df_recipes = pd.read_csv(filepath, encoding="ISO-8859-1")
#drop rows where cuisine, ingregients are NA
df_recipes.dropna(subset=['cuisine', 'ingredients'],inplace=True)
df_recipes

结果是大约5400个食谱,分别列有食谱名称、等级、课程类型、烹饪方法和每个食谱所需的配料表。

640.png

原始数据在有大量的打字错误、停止字\不必要的间隔、标点、数字等被删除的地方总是容易产生干扰。所涵盖的其他预处理包括,

配料以复数形式表示(例如用tomatoes 代替tomato; potatoes替代potato),需要转换为单数形式,以减少单词的维数。

大多数配料都以形容词作为前缀,例如干番茄、榨柠檬、新鲜香菜等。这些词(干的,压缩的,新鲜的等等)在生成有意义的词嵌入没有用处。因此,可以使用正则表达式函数来删除这些内容。

下面是清理和预处理配料数据的脚本:

#convert to lower case
df_recipes['ingredients'] = df_recipes['ingredients'].apply(lambda x: x.lower())
total_ingredients = []
all_receipes_ingredients = []
for i in range(len(df_recipes)):
    all_ingredients = list()
    #split each recipe into different ingredients
    ingred = df_recipes.loc[i, "ingredients"][1:-1]
    for ing in (ingred.split(',')):
        ing = remove_stopwords(ing)
        ing = strip_numeric(ing)
        ing = re.sub(r'\(.*oz.\)|(®)|(.*ed)|(.*ly)|boneless|skinless|chunks|fresh|large|cook drain|green|frozen|ground','',ing).strip()
        ing = strip_short(ing,2)
        ing = strip_multiple_whitespaces(ing)
        ing = strip_punctuation(ing)
        ing = strip_non_alphanum(ing)
        #convert plurals to singular e.g. tomatoes --> tomato
        ing = (" ".join(TextBlob(ing).words.singularize()))
        all_ingredients.append(ing)
        total_ingredients.append(ing)
    all_receipes_ingredients.append(all_ingredients)
counts_ingr = collections.Counter(total_ingredients)
print('Size Ingredients dataset (with repetition): \t{}'.format((len(total_ingredients))))
print('Unique Ingredients dataset: \t\t\t{}'.format((len(counts_ingr.values()))))
print('Size Receipes dataset: \t{}'.format((len(all_receipes_ingredients))))

640.png

从调查结果可以看出,5400多份食谱总共使用了5万种食材,其中2600多种食材经过预处理后看起来是独一无二的。

#add cleaned ingredients back to original dataframe
df_recipes['clean_ingredients'] = pd.Series(all_receipes_ingredients)
#record the number of ingredients for each recipe
df_recipes['ingredient_count'] = df_recipes.apply(lambda row: len(row['clean_ingredients']), axis = 1)
#convert time in seconds to minutes
df_recipes['timeMins'] = df_recipes.totalTimeInSeconds.apply(lambda x: x/60)

现在,让我们来探讨一下最常见和最不常见的配料。

#find the most common ingredients used across all recipes
print ("---- Most Common Ingredients ----")
print (counts_ingr.most_common(10))print ("\n")#find the most common ingredients used across all recipes
print ("---- Least Common Ingredients ----")
print (counts_ingr.most_common()[-10:])

640.png

让我们用词云可视化技术来可视化它。

#visualize the ingredients in WordCloud
from wordcloud import WordCloud
def plot_wordcloud(text, title=None, max = 1000, size=(12,8), title_size=16):
    """plots wordcloud"""
    wordcloud = WordCloud(max_words=max).generate(text)
    plt.figure(figsize=size)
    plt.title(title, size=title_size)
    plt.imshow(wordcloud, interpolation='bilinear')
    plt.axis("off")
plot_wordcloud(' '.join(total_ingredients), title='Ingredients')

640.png

训练Word2Vec

使用Gensim,创建Word2Vec模型非常简单。成分列表被传递给gensim的Word2Vec类。模型包。Word2Vec使用所有这些标记在内部创建词汇表。

#Train the Word2Vec model
num_features = 300    
# Word vector dimensionality - The size of the dense vector to represent each token or word
#(i.e. the context or neighboring words). If you have limited data, then size should be a much smaller value
#since you would only have so many unique neighbors for a given word
min_word_count = 4                        
# Minimium frequency count of words. The model would ignore words that do not satisfy the min_count.
num_workers = 4       # How many threads to use behind the scenes?
context = 10          
# The maximum distance between the target word and its neighboring word.  
downsampling = 1e-2  
# threshold for configuring which higher-frequency words are randomly downsampled
# Initialize and train the model
model = word2vec.Word2Vec(all_receipes_ingredients, workers=num_workers, \
            size=num_features, min_count = min_word_count, \
            window = context,sample = downsampling, iter=20)
# If you don't plan to train the model any further, calling
# init_sims will make the model much more memory-efficient.
model.init_sims(replace=True)

在上面的步骤中,使用成分列表构建词汇表,并开始训练Word2Vec模型。在幕后,我们训练一个具有单一隐含层的神经网络来基于上下文预测当前的单词。目标是学习隐含层的权值。这些权重就是我们要学习的单词向量。所得到的学习向量称为嵌入。

结果

第一个例子显示了与其他配料相似或至少相关的单词的简单查找(例如配料,如paneer, egg, mango, bread, rice)

# check the similar ingredients returned by the model for search_termssimilar_words = {search_term: [item[0] for item in model.wv.most_similar([search_term], topn=5)]
                  for search_term in ['paneer','egg','mango','bread', 'rice']}
similar_words

640.png

哇,看起来不错。让我们看看更多的配料

成分“巧克力”的类似或相关成分

model.wv.most_similar('chocolate')

640.png

这种相似性把所有和“巧克力”密切相关的单词都显示出来了,比如黑巧克力,香草豆等等

原料“蛋黄酱”的类似或相关成分

model.wv.most_similar('mayonnaise')

640.png

配料“鸡”中类似或相关的配料

model.wv.most_similar(‘chicken’)

640.png

总的来说,这些结果是有意义的。所有相关的词都在相似的上下文中使用。现在让我们使用Word2Vec来计算词汇表中两个成分之间的相似性,方法是调用similarity(…)函数并传入相关的单词。

model.wv.similarity(‘paneer’, ‘chicken’)

640.png

在底层,模型使用每个指定单词的单词向量(嵌入)计算两个指定单词之间的余弦相似度。由此得出的分数是有意义的,因为“paneer”主要用于素食,而“chicken”用于非素食

另一个有趣的事情是识别食物类比,类似于单词类比。对于“面包是奶酪”这个类比,我们的目标是预测一个合理的类比“鸡肉是……”

x = ‘chicken’
b= ‘cheese’
a = ‘bread’
predicted = model.wv.most_similar([x, b], [a])[0][0]
print(“ {} is to {} as {} is to {} “.format(a, b, x, predicted))

640.png

评估Word2Vec

我们已经用word2vec创建了300个维度的嵌入。幸运的是,当我们想要可视化高维字嵌入时,我们可以使用降维技术。下面,我们可以看到t-SNE将常见成分投影到二维上的一些向量嵌入。下列成分的位置代表概率分布,而不是实际的空间位置。t-SNE图可能很难解释为超参数,可以大幅改变簇之间的大小和距离。然而,我们并没有试图解释簇,而是希望评估我们的模型是否从我们的菜谱中学到了一些有用的东西。

#visualization with Tsne
from sklearn.manifold import TSNE
words = sum([[k] + v for k, v in similar_words.items()], [])
wvs = model.wv[words]
tsne = TSNE(n_components=2, random_state=0, n_iter=1000, perplexity=2)
np.set_printoptions(suppress=True)
T = tsne.fit_transform(wvs)
labels = words
plt.figure(figsize=(14, 8))
plt.scatter(T[:, 0], T[:, 1], c='orange', edgecolors='r')
for label, x, y in zip(labels, T[:, 0], T[:, 1]):
    plt.annotate(label, xy=(x+1, y+1), xytext=(0, 0), textcoords='offset points')

你可以看到,素食“奶酪”的原料就在附近,包括马萨拉,大蒜和生姜酱。这绝对是有道理的。同样,所有的食材,如“鸡蛋”、“芒果”也都在眼前。

640.png

接下来是什么?

上面的教程只讨论了食谱的配料部分。还有许多其他可以进一步实现的用例或探索想法。下面是一些问题,我将尝试在后面的文章中构建并得到答案。

  • 根据所提供的食材进行烹饪分类/预测
  • 给定一个菜谱,从语料库中查找相似的菜谱
  • 根据所提供的食材推荐食谱。
  • 使用一组给定的配料,什么食谱可以准备。

总结

在识别文本中的信息时,抓住单词之间的意义和关系是非常重要的。这些嵌入为自然语言处理和机器学习中更复杂的任务和模型提供了基础。试着找到一些你可以输入的有趣的数据集和你可以找出的关于关系的东西——在这里随意评论你发现的任何有趣的东西。

你可以在这里找到我的Kaggle笔记本/kernel:

目录
相关文章
|
1月前
|
人工智能 JSON 算法
Qwen2.5-Coder 系列模型在 PAI-QuickStart 的训练、评测、压缩及部署实践
阿里云的人工智能平台 PAI,作为一站式、 AI Native 的大模型与 AIGC 工程平台,为开发者和企业客户提供了 Qwen2.5-Coder 系列模型的全链路最佳实践。本文以Qwen2.5-Coder-32B为例,详细介绍在 PAI-QuickStart 完成 Qwen2.5-Coder 的训练、评测和快速部署。
Qwen2.5-Coder 系列模型在 PAI-QuickStart 的训练、评测、压缩及部署实践
|
7天前
|
机器学习/深度学习 数据可视化 大数据
机器学习与大数据分析的结合:智能决策的新引擎
机器学习与大数据分析的结合:智能决策的新引擎
75 15
|
12天前
|
机器学习/深度学习 数据采集 运维
机器学习在运维中的实时分析应用:新时代的智能运维
机器学习在运维中的实时分析应用:新时代的智能运维
63 12
|
15天前
|
编解码 机器人 测试技术
技术实践 | 使用 PAI+LLaMA Factory 微调 Qwen2-VL 模型快速搭建专业领域知识问答机器人
Qwen2-VL是一款具备高级图像和视频理解能力的多模态模型,支持多种语言,适用于多模态应用开发。通过PAI和LLaMA Factory框架,用户可以轻松微调Qwen2-VL模型,快速构建文旅领域的知识问答机器人。本教程详细介绍了从模型部署、微调到对话测试的全过程,帮助开发者高效实现定制化多模态应用。
|
1月前
|
机器学习/深度学习 PyTorch API
优化注意力层提升 Transformer 模型效率:通过改进注意力机制降低机器学习成本
Transformer架构自2017年被Vaswani等人提出以来,凭借其核心的注意力机制,已成为AI领域的重大突破。该机制允许模型根据任务需求灵活聚焦于输入的不同部分,极大地增强了对复杂语言和结构的理解能力。起初主要应用于自然语言处理,Transformer迅速扩展至语音识别、计算机视觉等多领域,展现出强大的跨学科应用潜力。然而,随着模型规模的增长,注意力层的高计算复杂度成为发展瓶颈。为此,本文探讨了在PyTorch生态系统中优化注意力层的各种技术,
65 6
优化注意力层提升 Transformer 模型效率:通过改进注意力机制降低机器学习成本
|
24天前
|
机器学习/深度学习 人工智能 算法
人工智能浪潮下的编程实践:构建你的第一个机器学习模型
在人工智能的巨浪中,每个人都有机会成为弄潮儿。本文将带你一探究竟,从零基础开始,用最易懂的语言和步骤,教你如何构建属于自己的第一个机器学习模型。不需要复杂的数学公式,也不必担心编程难题,只需跟随我们的步伐,一起探索这个充满魔力的AI世界。
44 12
|
1月前
|
机器学习/深度学习 Python
机器学习中评估模型性能的重要工具——混淆矩阵和ROC曲线。混淆矩阵通过真正例、假正例等指标展示模型预测情况
本文介绍了机器学习中评估模型性能的重要工具——混淆矩阵和ROC曲线。混淆矩阵通过真正例、假正例等指标展示模型预测情况,而ROC曲线则通过假正率和真正率评估二分类模型性能。文章还提供了Python中的具体实现示例,展示了如何计算和使用这两种工具来评估模型。
55 8
|
1月前
|
机器学习/深度学习 Python
机器学习中模型选择和优化的关键技术——交叉验证与网格搜索
本文深入探讨了机器学习中模型选择和优化的关键技术——交叉验证与网格搜索。介绍了K折交叉验证、留一交叉验证等方法,以及网格搜索的原理和步骤,展示了如何结合两者在Python中实现模型参数的优化,并强调了使用时需注意的计算成本、过拟合风险等问题。
53 6
|
1月前
|
机器学习/深度学习 数据采集 算法
从零到一:构建高效机器学习模型的旅程####
在探索技术深度与广度的征途中,我深刻体会到技术创新既在于理论的飞跃,更在于实践的积累。本文将通过一个具体案例,分享我在构建高效机器学习模型过程中的实战经验,包括数据预处理、特征工程、模型选择与优化等关键环节,旨在为读者提供一个从零开始构建并优化机器学习模型的实用指南。 ####
|
1月前
|
人工智能 边缘计算 JSON
DistilQwen2 蒸馏小模型在 PAI-QuickStart 的训练、评测、压缩及部署实践
本文详细介绍在 PAI 平台使用 DistilQwen2 蒸馏小模型的全链路最佳实践。

热门文章

最新文章

相关产品

  • 人工智能平台 PAI