手把手教你解决自然语言处理 90%的问题
Posted AI职通车
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了手把手教你解决自然语言处理 90%的问题相关的知识,希望对你有一定的参考价值。
文本数据无处不在
无论您是一家老牌公司还是致力于推出一项新服务,您都可以始终利用文本数据来验证,改善和扩展产品的功能。从文本数据中提取含义和进行学习的科学是被称为自然语言处理(NLP)的研究活动。NLP每天都会产生令人兴奋的新结果,并且是一个很大的领域。但是,与数百家公司合作之后,Insight团队发现一些关键的实际应用比其他任何应用都要频繁出现:
-
识别用户/客户的不同群组(例如预测客户流失,生命周期价值,产品偏好),
-
准确地检测和提取不同类别的反馈(正面和负面评论/意见,提及特定属性,例如衣服尺寸/ )
-
根据意图对文本进行分类(例如,请求基本帮助,紧急问题)尽管在线上存在许多NLP论文和教程,但我们发现很难找到有关如何解决这些问题的指南和技巧。
在每年领导数百个项目并从全美顶尖团队那里获得建议之后,我们写了这篇文章来解释如何构建机器学习解决方案来解决上述问题。我们将从最简单的可行方法开始,然后继续讨论更细微的解决方案,如特征工程、词向量和深度学习。
阅读本文后,您将知道如何:
1.收集、准备和检查数据
2.建立简单的模型开始,必要时过渡到深度学习
3.解释并理解你的模型,以确保你确实捕捉到了信息而不是噪音
我们写这篇文章是作为一个循序渐进的指南;它也可以作为一个高效标准方法的高效概述。
步骤一:数据收集
数据源示例:
每一个机器学习问题都是从数据开始的,比如电子邮件、帖子或推特的列表。文本信息的常见来源包括:
1.产品评论(亚马逊、Yelp和各种应用商店)
2.用户生成的内容(Tweets、Facebook帖子、StackOverflow问题)
3.故障排除(客户请求、支持票证、聊天日志)
“社交媒体上的灾难”数据集
在本文中,我们将使用“Figure Eight”平台慷慨提供的数据集,称为“社交媒体上的灾难”,其中:
贡献者查看了10000多条经过“ablaze”、“quarantine”和“pandemonium”等多种搜索筛选出来的推文,然后指出该推文是否指灾难事件(而不是用这个词玩笑、电影评论或其他非灾难性的文章)。
我们的任务是检测哪些tweet
是关于灾难性事件的,而不是像电影这样的无关话题。为什么?一个潜在的应用是,只向执法人员通报紧急情况,而忽略对最近Adam Sandler电影的评论。这项任务的一个特殊挑战是,两个类都包含用于查找tweets的相同搜索词,因此我们必须使用更细微的差异来区分它们。
在这篇文章的其余部分,我们将把关于灾难的tweets称为“灾难”,将关于其他任何事情的tweets称为“无关”。
我们已经标记了数据,所以我们知道哪些tweets属于哪些类别。正如Richard Socher在下面概述的那样,找到并标记足够的数据来训练模型通常比试图优化复杂的无监督方法更快、更简单、更便宜。
我们遵循的第一条规则是:“你的模型只会和你的数据一样好"
数据科学家的一项关键技能是知道下一步是处理模型还是数据。一个好的经验法则是先看数据,然后再清理它。一个干净的数据集将允许模型学习有意义的特征,而不是过度适应不相关的噪声。
下面是用于清理数据的检查表:(有关详细信息,请参见代码):
1.删除所有不相关的字符,如任何非字母数字字符
3.删除不相关的词,例如“@”twitter提到或url
4.将所有字符转换为小写,以便将“hello”、“hello”和“hello”等字视为相同的
5.考虑将拼写错误或交替拼写的单词组合成单个表示(例如“cool“/”kewl“/”coool“)
6.考虑规范化(将诸如“am”、“are”和“is”之类的词简化为诸如“be”之类的常见形式)
在遵循这些步骤并检查其他错误之后,我们可以开始使用干净的标记数据来训练模型!
步骤三:找到一个好的数据表示
机器学习模型是以数值作为输入。例如,处理图像的模型采用表示每个颜色通道中每个像素强度的矩阵。
我们的数据集是一个句子列表,因此为了让我们的算法从数据中提取模式,我们首先需要找到一种方法,以我们的算法能够理解的方式来表示它,即作为一个数字列表。
独热编码(词袋)
表示计算机文本的一种朴素方法是将每个字符单独编码为一个数字(例如ASCII)。如果我们将这个简单的表示形式输入到分类器中,它将不得不根据我们的数据从头学习单词的结构,这对于大多数数据集来说是不可能的。我们需要用更高层次的方法。
例如,我们可以构建数据集中所有唯一单词的词汇表,并将唯一索引关联到词汇表中的每个单词。然后,每个句子都被表示为一个列表,其长度与我们词汇表中不同单词的数量相同。在这个列表中的每个索引处,我们标记给定单词在句子中出现的次数。这被称为词袋模型,因为它完全忽略了句子中单词的顺序。如下所示。
句子在左边,表示在右边。向量中的每个索引表示一个特定的词。
在“社交媒体上的灾难”的例子中,我们的词汇中大约有20000个单词,这意味着每一个句子都将被表示为长度为20000的向量。向量将主要包含0,因为每个句子只包含我们词汇表的小部分词汇。
为了查看我们的嵌入是否捕获了与我们的问题相关的信息(即tweets是否与灾难有关),最好将它们可视化,并查看类之间的分隔是否良好。由于词汇表通常非常庞大,不可能在20000维中可视化数据,因此PCA等技术将有助于将数据投影到二维。结果如下图:
这两个类看起来并没有很好地分离,这可能是我们嵌入的一个特点,也可能只是我们维度缩减的一个特点。为了验证词袋特征是否有用,我们可以根据词袋特征进行训练分类器。
当第一次处理问题时,一般的最佳实践是从能够解决工作的最简单的工具开始。每当涉及到数据分类时,逻辑回归是一种通用性和可解释性很强的常用方法。这是非常简单的训练和结果是可以解释的,因为你可以很容易地提取最重要系数从模型。
我们将数据分为一个训练集和一个测试集,分别用来拟合模型和测试集,以查看它对未看到的数据的泛化程度。经过训练,我们得到了75.4%的准确率。并不是太寒酸!猜测最频繁的类(“不相关”)只会给我们57%。然而,即使75%的精度足以满足我们的需求,我们也不应该在不努力理解的情况下发布一个模型。
第一步是了解我们的模型产生的错误类型,以及哪种错误是最不可取的。在我们的示例中,假阳性将不相关的tweet归类为灾难,而假阴性将灾难归类为不相关的tweet。如果我们的首要任务是对每一个潜在的事件做出反应,我们会希望降低我们的假阴性。但是,如果我们在资源上受到限制,我们可能会优先考虑较低的误报率,以减少误报。可视化这些信息的一个好方法是使用一个混淆矩阵,它将我们的模型做出的预测与真实的标签进行比较。理想情况下,矩阵是从左上角到右下角的对角线(我们的预测完全符合事实)。
混淆矩阵
我们的分类器产生的假阴性比假阳性多(按比例)。换句话说,我们的模型最常见的错误是错误地将灾难分类为不相关的。如果假阳性代表了执法的高成本,这可能是我们分类器的一个好的偏见。
为了验证我们的模型,并解释它的预测,重要的是看看它是用什么词来做决定的。如果我们的数据是有偏差的,我们的分类器会在样本数据中做出准确的预测,但是模型在现实世界中不会很好的推广。在这里,我们为灾难类和不相关类绘制最重要的单词。由于我们只需提取模型用于预测的系数并对其进行排序,因此用词袋和Logistic回归来绘制单词重要性很简单。
我们的分类器正确地提取了一些模式(hiroshima, massacre),但显然似乎在一些无意义的术语(heyoo,x1392)上过于合适。现在,我们的词袋模型正在处理大量不同单词的词汇,并平等地处理所有单词。然而,这些词中的一些词是非常高频的,只会给我们的预测带来噪音。接下来,我们将尝试用一种方法来表示能够解释单词频率的句子,看看我们能否从数据中提取更多的信息。
TF-IDF
为了帮助我们的模型更加关注有意义的单词,我们可以在我们的词袋模型上使用TF-IDF分数(术语频率,文档反向频率)。TF-IDF根据单词在我们的数据集中的稀有程度来衡量单词,对过于频繁且只会增加噪音的单词进行折扣。这是我们新嵌入的主成分分析投影。
从上面我们可以看出这两种颜色有着更清楚的区别。这将使我们的分类器更容易分离这两个组。让我们看看这是否会带来更好的性能。在新的嵌入上训练另一个Logistic回归,我们得到了76.2%的准确率。
稍有改善。我们的模型是否已经开始学习更重要的单词?如果我们在防止模型“作弊”的同时获得更好的结果,那么我们就可以真正地将此模型视为一种升级。
这些词似乎看起来更有意义,更相关!尽管我们在测试集上的指标只略有增加,但我们对模型使用会有更多的信心,因此在与客户交互的系统中部署它会感觉更舒服。
Word2Vec
我们的最新型号设法接收到高信息词。但是,如果我们部署这个模型,我们很可能会遇到以前在我们的训练集中没有见过的单词。模型在训练期间看到了非常相似的单词,之前模型也将无法准确地对这些推文进行分类。
要解决这个问题,我们需要捕获单词的语义,这意味着我们需要理解像“good”和“positive”这样的单词比“apricot”和“contain”更接近,我们将使用的帮助我们捕获语义的工具叫做Word2Vec。
使用预先训练过的单词
Word2Vec是一种寻找单词连续嵌入的技术。它通过阅读大量的文本和记忆在相似的上下文中出现的单词来学习。在经过足够的数据训练后,它为词汇表中的每个单词生成一个300维向量,具有相似含义的单词彼此更接近。
Word2Vec作者开放了一个模型,该模型是在一个非常大的语料库上预先训练的,我们可以利用这个语料库将一些语义知识包含到我们的模型中。可以在与本文相关联的存储库中找到预先训练过的向量。
句子级表示
一个快速获取句子嵌入的方法是平均我们句子中所有单词的Word2Vec分数。这是一个和以前的词袋方法很像的方式,但是这次我们只丢失了句子的语法结构,同时保留了一些语义信息。
此处使用之前的嵌入可视化技术,对新的嵌入进行可视化:
这两组颜色在这里看起来更加分离,我们的新嵌入应该帮助我们的分类器找到两个类之间的分离。第三次训练同一个模型(Logistic回归)后,我们得到了77.7%的准确率分数,这是我们迄今为止最好的成绩!是时候检查我们的模型了。
由于我们的嵌入并不像以前的模型那样用每个单词一维的向量来表示,所以很难看出哪个单词与我们的分类最相关。虽然我们仍然可以获得Logistic回归系数,但它们与嵌入的300个维度有关,而不是与单词的索引有关。
对于如此低的准确性,失去所有可解释性似乎是一个严酷的权衡。然而,对于更复杂的模型,我们可以利用诸如LIME这样的黑盒解释程序来了解我们的分类器是如何工作的。
Github上提供了一个开源软件包。黑盒解释程序允许用户通过扰动输入(在我们的例子中,从句子中删除单词)并查看预测如何变化,来解释任何分类器对一个特定示例的决策。
让我们看看对数据集中句子的一些解释。
正确的灾难词被挑选出来归类为“相关的”。
在这里,单词对分类的贡献似乎不太明显。
然而,我们没有时间去探索数据集中的成千上万的例子。相反,我们要做的是在一个有代表性的测试用例样本上运行LIME,看看哪些单词会成为强有力的贡献者。使用这种方法,我们可以得到单词重要性的分数,就像我们以前的模型一样,并验证我们的模型的预测。
看起来这个模型提取了高度相关的词语,暗示它似乎做出了可以理解的决定。这些似乎是所有以前的模型中最相关的词,因此我们更愿意将其部署到生产中。
我们已经介绍了生成紧凑语句嵌入的快速有效方法。然而,通过省略单词的顺序,我们丢弃了句子的所有句法信息。如果这些方法不能提供足够的好的结果,则可以使用更复杂的模型,该模型将整个句子作为输入并预测标签,而无需构建中间表示。一种常见的方法是使用Word2Vec或更新的方法(如GloVe或CoVe)将句子视为单个词向量的序列。这就是我们下面要做的。
卷积神经网络用于句子分类训练速度非常快,工作良好,是一种入门级的深度学习框架。虽然卷积神经网络(CNN)主要以其在图像数据上的性能而闻名,但它们在与文本相关的任务上也提供了优异的结果,并且通常比大多数复杂的NLP方法(例如LSTMs和编解码器架构)训练快得多。该模型保留了单词的顺序,并学习到有价值的信息,其中单词序列可以预测我们的目标类。与之前的模型相反,它可以区分“Alex eats plants”和“Plants eat Alex.”
训练这个模型比以前的方法不需要太多的工作(详见代码),并且给了我们一个比以前的模型好得多的性能,得到了79.5%的准确率!与上面的模型一样,下一步应该是使用我们描述的方法来探索和解释预测,以验证它确实是为用户部署的最佳模型。到现在为止,你应该觉得自己处理这个问题很舒服。
1.从一个简单快捷的模型开始
2.预测解释
3.了解它所犯的错误
4.使用知识来告知您下一步的工作,无论是处理数据还是更复杂的模型。
这些方法已经被应用到一个特定的例子中,使用了专门为理解和利用短文本(如tweets)而定制的模型,但是这些思想广泛适用于各种问题。我希望这对你有所帮助,我们很高兴听到你的评论和问题!
请在下面发表评论,或在这里或Twitter上联系@EmmanuelAmeisen。
投稿、转载、媒介合作联系微信号 | bajiaojiao-sz
商务合作联系微信号 | LJ18825253481
以上是关于手把手教你解决自然语言处理 90%的问题的主要内容,如果未能解决你的问题,请参考以下文章
干货教程自然语言处理入门:手把手教你解决90%的NLP问题
手把手教您解决90%的自然语言处理问题
手把手:自然语言处理太难?按这个套路走,就是砍瓜切菜!(附Python代码)
专访丨一学就会的自然语言处理系统书
一文助你解决90%的自然语言处理问题(附代码)
手把手教你用 PyTorch 辨别自然语言(附代码)