如何解决90%的NLP问题:逐步指导
使用机器学习来理解和利用文本。
文本数据无处不在
无论您是成熟公司还是致力于推出新服务,您始终可以利用文本数据来验证,改进和扩展产品的功能。从文本数据中提取意义和学习的科学是一个活跃的研究主题,称为自然语言处理(NLP)。
每天NLP产生新的和令人兴奋的 结果,是一个非常大的领域。然而,Insight团队与数百家公司合作,看到一些关键的实际应用程序比其他任何公司更频繁地出现:
- 识别不同的用户/客户群(例如预测流失,生命周期价值,产品偏好)
- 准确地检测和提取不同类别的反馈(正面和负面评论/意见,提及特定属性,如服装尺码/合身......)
- 根据意图对文本进行分类(例如请求基本帮助,紧急问题)
虽然许多NLP论文和教程存在于网上,但我们发现很难找到有关如何从头开始有效解决这些问题的指南和技巧。
本文如何提供帮助
在每年领导数百个项目并获得美国各地顶级团队的建议后,我们写了这篇文章来解释如何构建机器学习解决方案来解决上述问题。我们将从最简单的方法开始,然后转向更细微的解决方案,例如特征工程,单词向量和深度学习。
阅读本文后,您将了解如何:
- 收集,准备和检查数据
- 构建简单的模型,并在必要时过渡到深度学习
- 解释和理解您的模型,以确保您实际捕获信息而不是噪音
我们把这篇文章写成了一步一步的指南; 它还可以作为高效标准方法的高级概述。
这篇文章附有一个交互式笔记本,演示和应用所有这些技术。随意运行代码并继续!
第1步:收集您的数据
示例数据源
每个机器学习问题都从数据开始,例如电子邮件,帖子或推文列表。常见的文字信息来源包括:
- 产品评论(在亚马逊,Yelp和各种应用商店)
- 用户生成的内容(推文,Facebook帖子,StackOverflow问题)
- 故障排除(客户请求,支持服务单,聊天记录)
“社交媒体灾难”数据集
对于这篇文章,我们将使用 Figure Eight慷慨提供的数据集,称为“社交媒体上的灾难”,其中:
贡献者查看了超过
条推文,其中包括“点燃”,“隔离”和“混乱”等各种搜索,然后注意到推文是否涉及灾难事件(而不是与单词或电影评论相关的笑话或一些非灾难性的事情)。
我们的任务是检测哪些推文是关于灾难性事件的,而不是像电影那样无关紧要的话题。为什么?一个潜在的应用是完全通知执法官员紧急紧急情况,同时忽略对最近的亚当桑德勒电影的评论。这项任务的一个特殊挑战是两个类都包含用于查找推文的相同搜索词,因此我们必须使用微妙的差异来区分它们。
在本文的其余部分,我们将把关于灾难的推文称为“ disaster(灾难 )”,并将有关其他任何内容的推文称为“ (irrelevant)无关紧要 ”。
标签
我们已经标记了数据,因此我们知道哪些推文属于哪些类别。正如Richard Socher在下面概述的那样,通常更快,更简单,更便宜地找到并标记足够的数据来训练模型,而不是试图优化复杂的无监督方法。
第2步:清理数据
我们遵循的首要规则是:
数据科学家的关键技能之一是了解下一步是应该对模型还是数据进行处理。一个好的经验法则是首先查看数据然后进行清理。一个干净的数据集将允许模型学习有意义的功能,而不是过度匹配无关的噪音。
以下是用于清理数据的清单:( 有关详细信息,请参阅代码):
- 删除所有不相关的字符,例如任何非字母数字字符
- 通过分词将其分割成单个的单词文本
- 删除不相关的单词,例如“@”twitter提及或网址
- 将所有字符转换为小写,以便将诸如“hello”,“Hello”和“HELLO”之类的单词视为相同
- 考虑将拼写错误或交替拼写的单词组合成单个表示(例如“cool”/“kewl”/“cooool”)
- 考虑词形还原(将诸如“am”,“are”和“is”等词语简化为常见形式,例如“be”)
按照这些步骤并检查其他错误后,我们可以开始使用干净的标记数据来训练模型!
第3步:找到一个好的数据表示
机器学习模型将数值作为输入。例如,处理图像的模型采用表示每个颜色通道中每个像素的强度的矩阵。
我们的数据集是一个句子列表,所以为了让我们的算法从数据中提取模式,我们首先需要找到一种方法来表示我们的算法可以理解的方式,即作为数字列表。
one-hot编码(Bag of Words)
表示计算机文本的一种自然方式是将每个字符单独编码为数字(例如ASCII)。如果我们将这个简单的表示提供给分类器,则必须仅根据我们的数据从头学习单词的结构,这对于大多数数据集是不可能的。我们需要使用更高级别的方法。
例如,我们可以在数据集中构建所有唯一单词的词汇表,并将唯一索引与词汇表中的每个单词相关联。然后将每个句子表示为与我们词汇表中不同单词的数量一样长的列表。在此列表中的每个索引处,我们标记给定单词在句子中出现的次数。这被称为Bag of Words模型,因为它是一种完全忽略句子中单词顺序的表示。这如下图所示。
可视化嵌入
我们在“社交媒体灾难”示例中的词汇量大约有20,000个单词,这意味着每个句子都将表示为长度为20,000的向量。向量将主要包含0,因为每个句子只包含我们词汇表的一小部分。
为了查看我们的嵌入是否正在捕获与我们的问题相关的信息(即推文是否与灾难有关),最好将它们可视化并查看类看起来是否分离得很好。由于词汇表通常非常大,并且不可能以20,000维度可视化数据,因此像PCA这样的技术将有助于将数据投影到二维。这个绘制如下。
这两个类看起来分离不是很好,这可能是我们嵌入的一个特征,或者仅仅是我们降维的一个特征。为了查看Bag of Words功能是否有用,我们可以根据它们训练分类器。
第4步:分类
当第一个接近问题时,一般的最佳做法是从可以解决工作的最简单的工具开始。无论何时对数据进行分类,其多功能性和可解释性的共同点都是Logistic回归。训练非常简单,结果可以解释,因为您可以轻松地从模型中提取最重要的系数。
我们将数据分成一个训练集,用于拟合我们的模型和一个测试集,以查看它对未见数据的概括性。经过培训,我们得到75.4%的准确率。不是太寒酸!猜测最频繁的分类(“不相关(irrelevant)”)将只给我们57%。然而,即使75%的精度足以满足我们的需求,我们也绝不应该在不试图了解它的情况下运送模型。
第五步:检查
混乱矩阵
第一步是了解我们的模型所犯的错误类型,以及哪种错误是最不可取的。在我们的示例中,false positives将不相关的推文分类为灾难,而false negatives则将灾难归类为不相关的推文。如果优先考虑对每个潜在事件作出反应,我们会希望降低我们的false negatives。但是,如果我们在资源方面受到限制,我们可能会优先考虑较低的false positives率以减少误报。可视化此信息的一种好方法是使用混淆矩阵,该矩阵将我们的模型预测与真实标签进行比较。理想情况下,矩阵将是从左上角到右下角的对角线(我们的预测完全匹配真相)。
我们的分类器比 false negatives(按比例)产生更多的false positives 。换句话说,我们模型最常见的错误是将灾难分类为不相关。如果false positives代表了执法的高成本,那么这对我们的分类者来说可能是一个很好的偏见。
解释我们的模型
为了验证我们的模型并解释其预测,重要的是要查看它用于做出决策的单词。如果我们的数据有偏差,我们的分类器将对样本数据做出准确的预测,但该模型在现实世界中不会很好地概括。在这里,我们为灾难和无关的分类绘制最重要的单词。使用Bag of Words和Logistic回归绘制单词重要性很简单,因为我们可以提取和排列模型用于其预测的系数。
我们的分类器正确地采用了一些模式(广岛,大屠杀),但显然在某些无意义的术语上过度拟合(heyoo,x1392)。现在,我们的Bag of Words模型正在处理不同单词的巨大词汇并平等对待所有单词。然而,这些词中的一些是非常频繁的,并且只会对我们的预测产生噪音。接下来,我们将尝试一种方法来表示可以解释单词频率的句子,看看我们是否可以从我们的数据中获取更多信号。
第六步:考虑词汇结构
TF-IDF
为了帮助我们的模型更多地关注有意义的单词,我们可以在我们的Bag of Words模型之上使用TF-IDF分数(Term Frequency,Inverse Document Frequency)。TF-IDF根据它们在我们的数据集中的稀有程度对单词进行加权,对过于频繁的单词进行折扣并仅添加噪声。这是我们新嵌入的PCA投影。
我们可以看到上面两种颜色之间有更明确的区别。这应该使我们的分类器更容易 分离两个组。让我们看看这是否会带来更好的性能。在我们的新嵌入体上训练另一个Logistic回归,我们得到76.2%的准确度。
一点点改进。我们的模型是否开始接受更重要的词汇?如果我们在防止我们的模型“作弊”的同时获得更好的结果,那么我们可以真正认为这个模型是升级。
它所拾取的单词看起来更相关!尽管我们的测试集上的指标仅略有增加,但我们对模型使用的术语更有信心,因此在将与客户交互的系统中部署它时会感觉更舒服。
第7步:利用语义
Word2Vec
我们最新模型设法获得高信号词。但是,如果我们部署此模型,我们很可能会遇到以前在训练集中没有看到过的单词。即使在培训期间看到非常相似的单词,之前的模型也无法准确地对这些推文进行分类。
为了解决这个问题,我们需要捕捉词语的语义,这意味着我们需要理解像“好”和“积极”这样的词比“杏”和“大陆”更接近。我们将用来帮助我们捕获意义的工具称为Word2Vec。
使用预先训练过的单词
Word2Vec是一种查找单词连续嵌入的技术。它通过阅读大量文本并记住哪些词语倾向于出现在类似的语境中来学习。在对足够的数据进行训练之后,它为词汇表中的每个单词生成300维向量,其中具有相似含义的单词彼此更接近。
该报告的作者论文开源了一个非常大的语料库,我们可以利用到包括语义一些知识转化成我们的模型这是预先训练的典范。可以在与此帖相关联的存储库中找到预先训练的向量。
句子级别表示
为我们的分类器设置句子嵌入的快速方法是平均句子中所有单词的Word2Vec分数。这是一个像之前一样的Bag of Words方法,但这次我们只丢失了句子的语法,同时保留了一些语义信息。
以下是使用以前技术的新嵌入的可视化:
这两组颜色看起来更加分离,我们的新嵌入应该有助于我们的分类器找到两个类之间的分离。在第三次训练相同模 型(Logistic回归)后,我们得到77.7%的准确度得分,我们的最佳结果呢!是时候检查我们的模型了。
复杂性/可解释性权衡
由于我们的嵌入不像我们之前的模型那样表示为每个单词一维的向量,因此很难看出哪些单词与我们的分类最相关。虽然我们仍然可以访问Logistic回归的系数,但它们与嵌入的300维有关,而不是单词的索引。
对于如此低的准确度增益,失去所有可解释性似乎是一种严厉的权衡。但是,对于更复杂的模型,我们可以利用LIME等黑盒解释器,以便深入了解分类器的工作原理。
LIME
LIME 可通过开源软件包在Github上获得。黑盒解释器允许用户通过扰乱输入(在我们的情况下从句子中删除单词)并查看预测如何变化来解释任何分类器在一个特定示例上的决定。
让我们看一下我们数据集中句子的几个解释。
但是,我们没有时间探索数据集中的数千个示例。我们要做的是在有代表性的测试用例样本上运行LIME,看看哪些词会继续成为强大的贡献者。使用这种方法,我们可以像以前的模型一样获得单词重要性分数,并验证模型的预测。
看起来该模型选择了高度相关的词语,暗示它似乎做出了可以理解的决定。这些似乎是以前所有型号中最相关的词,因此我们更愿意部署到生产中。
步骤8:使用端到端方法利用语法
我们已经介绍了生成紧凑句嵌入的快速有效方法。但是,通过省略单词的顺序,我们将丢弃句子的所有句法信息。如果这些方法不能提供足够的结果,您可以使用更复杂的模型,将整个句子作为输入并预测标签,而无需构建中间表示。要做到这一点的常用方法是把一个句子中的单词矢量序列使用或者Word2Vec或更近的方法,比如GloVe或GoVe。这是我们将在下面做的。
用于句子分类的卷积神经网络训练非常快,并且作为入门级深度学习架构运行良好。虽然卷积神经网络(CNN)主要以其在图像数据上的性能而闻名,但它们在文本相关任务上提供了出色的结果,并且通常比大多数复杂的NLP方法(例如LSTM和编码器/解码器架构)更快地进行训练。该模型保留了单词的顺序,并学习了有关哪些单词序列可以预测目标类的有价值信息。与之前的型号相反,它可以区分“Alex吃植物”和“植物吃Alex”之间的区别。
训练此模型不需要比以前的方法更多的工作(详见代码),并为我们提供了比以前更好的模型,准确度达到79.5%!与上述模型一样,下一步应该是使用我们描述的方法探索和解释预测,以验证它确实是部署到用户的最佳模型。到现在为止,您应该自己解决这个问题。
最后的笔记
以下是我们成功使用的方法的简要回顾:
- 从快速简单的模型开始
- 解释它的预测
- 了解它正在犯的错误
- 使用该知识为下一步提供信息,无论是对您的数据还是更复杂的模型。
这些方法适用于特定的示例案例,使用为理解和利用短文本(如推文)而定制的模型,但这些思想广泛适用于各种问题。我希望这对你有帮助,我们很乐意听到你的意见和问题!
更多文章欢迎访问 http://www.apexyun.com/
联系邮箱:public@space-explore.com
(未经同意,请勿转载)