当前位置: 首页 > 科技观察

指南-分步教程解决90%的NLP问题

时间:2023-03-21 19:28:49 科技观察

文本数据无处不在无论您是老牌公司还是开发新服务,您都可以使用文本数据来验证、改进和扩展产品的功能。从文本数据中提取语义和学习的科学是一个活跃的研究课题,称为自然语言处理(NLP)。NLP每天都有新的重要进展,这是一个非常大的领域。然而,在与数百家公司合作后,Insight团队发现一些关键的实际应用比其他应用出现得更频繁:识别不同的用户/客户细分(例如预测流失、生命周期价值、产品偏好)准确检测和提取不同类别的反馈(正面和负面评论/意见,衣服尺寸/合身等属性……)按意图对文本进行分类(例如:请求基本帮助,紧急问题)虽然网络上有很多关于NLP的论文和教程,但我们发现很难找到从根本上有效解决这些问题的指导方针和技巧。这篇文章有什么用?在每年领导数百个项目并获得美国顶级团队的建议后,我们写了这篇文章来解释如何构建机器学习解决方案来解决上述问题。我们将从最简单的可能方法开始,然后转向更精细的解决方案,如特征工程、词向量和深度学习。阅读本文后,您将了解:收集、准备和检查数据构建简单模型以开始和过渡到深度学习,必要时解释和理解您的模型,以确保您实际捕获的是信息而不是噪音分步指南,本文还可以作为高效标准方法的高级概述。第1步:收集数据样本数据源每个机器学习问题都从数据开始,例如电子邮件、帖子或推文列表。文本信息的常见来源包括:产品评论(亚马逊、Yelp、各种应用商店)用户生成的内容(推文、Facebook帖子、StackOverflow问题)故障排除(客户请求、支持票、聊天记录)“社交媒体上的灾难”数据集““社交媒体灾难”数据集对于本文,我们将使用图8中显示的数据集,标题为“社交媒体灾难”,其中:贡献者查看了10,000多条推文,这些推文经过了各种搜索,如“着火”、“隔离”、”和“混乱”,然后表明该推文是否指的是灾难性事件(而不是笑话、电影评论或其他带有该词的非灾难性事件)。我们的任务是检测哪些推文是关于灾难性事件的,而不是相关主题,例如电影。为什么?一个潜在的应用可能是简单地通知执法人员紧急情况,而忽略对亚当桑德勒最新电影的评论。此任务的一个特殊挑战是两个类都包含用于查找推文的相同搜索词,因此我们将不得不使用更细微的差异来区分它们。对于本文的其余部分,我们会将有关灾难的推文称为“灾难”,而将有关其他任何内容的推文称为“无关紧要”。标记我们标记了数据,因此我们知道哪些推文属于哪些类别。正如RichardSocher在下面概述的那样,与尝试优化复杂的无监督方法相比,查找和标记足够的数据来训练模型通常更快、更容易且成本更低。第二步:数据清理我们遵循的第一条规则是:“你的模型永远和你的数据一样好。”数据科学家的一项关键技能是知道下一步应该使用模型还是数据。一个好的经验法则是先查看数据,然后再组织它。干净的数据集将使模型能够学习有意义的特征,而不会过度拟合不相关的噪声。这是您可以用来清理数据的清单:删除所有不相关的字符,例如任何非字母数字字符Tokenize通过将文本分成单独的单词来标记文本删除不相关的单词,例如twitter提到的“@”或url将所有字符转换为小写这样像“hello”、“hello”和“hello”这样的词被平等对待,拼写错误或交替拼写的词被组合成一个表示(例如“cool”/“kewl”/“cooool”)考虑词形还原(简化词如“am","are",and"is"tocommonformslike"be")在执行这些步骤并检查其他错误后,我们可以开始使用干净的、标记的数据来训练模型!第三步:找到一个好的数据表示机器学习模型,以数值作为输入。例如,处理图像的模型采用表示每个颜色通道中每个像素强度的矩阵。由数字矩阵表示的笑脸我们的数据集是一个句子列表,因此为了让我们的算法从数据中提取模式,我们首先需要找到一种以我们的算法可以理解的方式来表示它的方法,即数字列表。单热编码(词袋)表示计算机文本的一种自然方式是将每个字符单独编码为一个数字。如果我们要将这个简单的表示提供给分类器,它就必须仅根据我们的数据从头开始学习单词的结构,这对于大多数数据集来说是不可能的。我们需要使用更高层次的方法。例如,我们可以构建数据集中所有唯一单词的词汇表,并将唯一索引与词汇表中的每个单词相关联。然后将每个句子表示为一个列表,与我们词汇表中不同单词的数量一样长。在此列表中的每个索引处,我们标记给定单词在句子中出现的次数。这被称为词袋模型,因为它是一种完全忽略句子中单词顺序的表示。如下所示。将句子表示为词袋。左边的句子和右边的描述。向量中的每个索引代表一个特定的词。嵌入可视化在“社交媒体灾难”示例中,我们的词汇量约为20,000个单词,这意味着每个句子将表示为长度为20,000的向量。大多数向量都是0,因为每个句子只包含一个非常小的词汇子集。为了查看我们的嵌入是否捕获了与我们的问题相关的信息(即推文是否与灾难相关),最好将它们可视化并查看类之间是否有良好的分离。由于词汇表通常非常大,不可能将20,000维的数据可视化,因此PCA等技术将有助于将数据投影到二维中。如下图所示。词袋嵌入的可视化这两个类似乎没有很好地分离,这可能是我们嵌入的属性,或者仅仅是降维的属性。要查看词袋特征是否有用,我们可以根据词袋特征训练分类器。第四步:分类第一次解决问题时,一般的最佳做法是从可以解决问题的最简单的工具开始。每当谈到数据分类时,最受欢迎的是逻辑回归,因为它具有多功能性和可解释性。它的训练非常简单,而且结果是可解释的,因为您可以轻松地从模型中提取最重要的系数。我们将数据分为两部分,一部分是用于拟合模型的训练集,另一部分是测试集,以查看它对未见数据的泛化能力如何。经过训练,我们得到了75.4%的准确率。足够好!猜测出现次数最多的类别(“无关紧要”)只能给我们57%的答案。然而,即使75%的准确率足以满足我们的需求,我们也不能在不理解模型的情况下发布它。第5步:检查混淆矩阵第一步是了解我们的模型所犯错误的类型,以及哪些错误是最不希望出现的。在我们的示例中,误报将不相关的推文分类为灾难,而漏报将灾难分类为不相关的推文。如果我们的首要任务是对每个潜在事件做出反应,我们就会希望降低漏报率。但是,如果我们资源有限,我们可能会优先考虑较低的误报率以减少误报。可视化此信息的一种好方法是使用混淆矩阵,它将我们的模型所做的预测与真实标签进行比较。理想情况下,矩阵应该是从左上角到右下角的对角线(我们的预测与结果完全一样)。混淆矩阵(绿色代表高比例,蓝色代表低比例)我们的分类器产生的假阴性多于假阳性(按比例)。换句话说,我们的模型最常犯的错误是错误地将灾难归类为微不足道的。如果误报代表执法部门的高成本,那么这可能是我们分类器的一个很好的偏差。解释我们的模型为了验证我们的模型并解释其预测,重要的是要了解它使用哪些词汇来做出决定。如果我们的数据有偏差,我们的分类器将在样本数据中做出准确的预测,但模型在现实世界中的泛化效果不佳。在这里,我们为灾难类和无关类绘制了最重要的词。由于我们只需要提取模型用于预测的系数并对其进行排序,因此使用词袋和逻辑回归绘制单词重要性非常简单。词袋:词的重要性我们的分类器正确地选择了一些模式(广岛、大屠杀),但显然似乎过度拟合了一些无意义的术语(heyoo、x1392)。现在,我们的词袋模型正在处理大量不同单词的词汇表,并平等对待所有单词。然而,其中一些词非常频繁,只会干扰我们的预测。接下来,我们将尝试一种表示句子的方法来说明词频,看看我们是否可以从数据中获取更多信号。第6步:词汇结构计数TF-IDF为了帮助我们的模型更多地关注有意义的词,我们可以在我们的词袋模型上使用TF-IDF分数(词频、逆文档频率)。TF-IDF根据单词在我们的数据集中的稀有程度对单词进行加权,削弱过于频繁且只会增加噪音的单词。这是我们新嵌入的PCA投影。TF-IDFembeddingvisualization从上面我们可以看出这两种颜色的区别比较明显。这将使我们的分类器更容易??将两组分开。让我们看看这是否会带来更好的性能。在我们的新嵌入上训练另一个逻辑回归,我们得到76.2%的准确率。非常轻微的改善。我们的模型是否开始学习更重要的单词?如果我们在防止模型“作弊”的同时取得更好的效果,那么我们就可以真正认为模型是一次升级。TF-IDF:单词重要性所选单词看起来更相关!尽管我们的测试集的准确性只增加了一点点,但我们对我们的模型使用的术语更有信心,因此感觉更舒服地将它部署在与客户交互的系统中。第7步:语义的力量Word2Vec我们最新的模型能够识别高频词。然而,如果我们部署这个模型,我们很有可能会遇到我们以前在训练集中没有见过的词。即使在训练过程中看到非常相似的词,之前的模型也无法准确地对这些推文进行分类。为了解决这个问题,我们需要捕捉词的语义,这意味着我们需要理解像“good”和“positive”这样的词比“apricot”和“continent”更接近。我们用来帮助??我们捕获语义的工具称为Word2Vec。使用预训练词Word2Vec是一种寻找词的连续嵌入的技术。它通过阅读大量文本并记住出现在相似上下文中的单词来学习。在对足够的数据进行训练后,它为词汇表中的每个单词生成一个300维的向量,具有相似含义的单词彼此更接近。这篇论文的作者(https://arxiv.org/abs/1301.3781)公开了一个在非常大的语料库上预训练的模型的源代码,我们可以使用它来将一些语义知识合并到我们的模型中。可以在与本文相关的存储库中找到预训练向量。语义级别表示为我们的分类器获取句子嵌入的一种快速方法是对句子中所有单词的Word2Vec分数求平均。这是一种词袋方法,就像以前一样,但是这次我们只丢失了句子的语法,同时保留了一些语义信息。Word2Vec句子的嵌入我们使用之前的技术可视化的新嵌入:Word2Vec嵌入可视化这两组颜色在这里看起来更加分离,我们的新嵌入应该帮助我们的分类器找到这两个类之间的分离。第三次训练同一个模型(逻辑回归)后,我们得到了77.7%的准确率,这是迄今为止最好的结果!是时候检查我们的模型了。复杂性与可解释性权衡由于我们的嵌入不像以前的模型那样表示为每个词的一维向量,因此很难看出哪些词与我们的分类最相关。虽然我们仍然可以访问逻辑回归的系数,但它们与嵌入的300个维度相关,与单词的索引无关。对于如此低的精度,失去所有可解释性似乎是一个艰难的权衡。然而,对于更复杂的模型,我们可以利用LIME等黑盒解释器来深入了解分类器的工作原理。LIMELIME在Github上作为开源包提供。黑盒解释器允许用户通过扰乱输入(在我们的例子中,从句子中删除单词)并查看预测如何变化来解释任何分类器对特定示例的决定。让我们看一下数据集中一些句子的解释。选择正确的灾难词汇归类为“相关”。在这里,单词对分类的贡献似乎不太明显。但是,我们没有时间研究数据集中的数千个示例。相反,我们所做的是在具有代表性的测试用例样本上运行LIME,并查看哪些词作为重要贡献者不断出现。使用这种方法,我们可以获得单词重要性分数,就像我们之前的模型一样,并验证我们模型的预测。Word2Vec:WordImportance看起来这个模型选择了高度相关的词,这意味着它似乎做出了可以理解的决定。在之前的所有模型中,这些似乎是最相关的词,因此我们更愿意将它们部署到生产环境中。第8步:利用语义,使用端到端的方法我们已经引入了快速有效的方法来生成密集的句子嵌入。然而,通过忽略单词的顺序,我们丢弃了句子的所有语法信息。如果这些方法不能提供足够的结果,您可以使用更复杂的模型,将整个句子作为输入并预测标签,而无需构建中间表示。一种常见的方法是使用Word2Vec或更新的方法(如GloVe或CoVe)将句子视为一系列单独的词向量。这就是我们接下来要做的。Efficientend-to-endstructureConvolutionalNeuralNetworksforSentenceClassification训练速度非常快,是入门级的深度学习架构。虽然卷积神经网络(CNN)主要以其在图像数据上的性能而著称,但它们也可以在与文本相关的任务上提供出色的结果。通常,最复杂的NLP训练方法(如[LSTM]和编码器/解码器架构)速度更快。该模型保留了单词的顺序并学习了关于哪些单词序列可以预测我们的目标类别的有价值信息。相比之前的,它可以区分“Alexeatsplants”和“PlantseatAlex”。训练这个模型不需要比以前的方法更多的工作,并且给了我们一个更好的模型,达到了79.5%的准确率!与上面的模型一样,下一步应该是使用我们描述的方法探索和解释预测,以验证它确实是部署给用户的最佳模型。到现在为止,您应该已经习惯了自己处理这个问题。关键点总结以下是我们成功使用的方法的快速回顾:从一个快速简单的模型开始解释它的预测理解它所犯的错误使用这些知识来指导下一步,无论是处理数据还是更复杂的模型。