翻译:Emmanuel Ameisen撰写的《如何解决90%的NLP问题:分步指南》
http://t.cn/RQd3IGq
文本数据无处不在
无论您是一家老牌公司还是致力于推出一项新服务,您都可以始终利用文本数据来验证,改善和扩展产品的功能。从文本数据中提取含义和进行学习的科学是被称为自然语言处理(NLP)的研究活动。
NLP每天都会产生令人兴奋的新结果,并且是一个很大的领域。但是,与数百家公司合作之后,Insight团队发现一些关键的实际应用比其他任何应用都要频繁出现:
- 识别用户/客户的不同群组(例如预测客户流失,生命周期价值,产品偏好),
- 准确地检测和提取不同类别的反馈(正面和负面评论/意见,提及特定属性,例如衣服尺寸/ )
- 根据意图对文本进行分类(例如,请求基本帮助,紧急问题)
尽管在线上存在许多NLP论文和教程,但我们发现很难找到有关如何解决这些问题的指南和技巧。
这篇文章可以提供哪些帮助
在每年领导数百个项目并获得全美顶级团队的建议后,我们写了这篇文章来解释如何构建机器学习解决方案来解决上述问题。我们将从最可行的最简单方法开始,然后继续介绍更细微的解决方案,例如特征工程,词向量和深度学习。
通过这篇文章,你可以知道:
- 收集,准备和检查数据
- 建立简单的模型以开始,并在必要时过渡到深度学习
- 解释和理解您的模型,以确保您实际上捕获的是信息而不是噪音
我们写这篇文章是一个循序渐进的指南。它也可以作为高效标准方法的高级概述
这篇文章还附有一个交互式笔记本,展示并应用了所有这些技术。随意运行代码并继续学习!
第一步:收集数据
数据源
每个机器学习问题都始于数据,例如电子邮件,帖子或推文列表。文本信息的常见来源包括:
- 产品评论(在Amazon,Yelp和各种App Store上)
- 用户生成的内容(推文,Facebook帖子,StackOverflow问题)
- 故障排除(客户请求,支持通知单,聊天记录)
“社交媒体上的灾难”数据集
对于本文,我们将使用CrowdFlower提供的数据集,称为“社交媒体上的灾难”,其中:
我们收集了10,000多个推文,这些推文通过各种搜索(例如“大火”,“隔离”和“ 骚动”)被剔除,然后指出了该推文是否指的是灾难事件(与带有单词或电影评论的笑话或非灾难性的东西)。
我们的任务是检测哪些推文是与灾难性事件有关,而不是与不相关的主题(例如灾难电影)。为什么?一种潜在的应用是专门将紧急情况通知执法人员,而无视最新的亚当·桑德勒灾难电影的评论。此任务面临的一个特殊挑战是,两个类都包含用于查找推文的相同搜索词,因此我们将不得不使用微妙的区别来区分它们。
在本文的其余部分,我们将与灾难有关的推文称为“灾难”,而将其他任何事物的推文称为“无关紧要”。
标签
我们已经标记了数据,因此我们知道哪些推文属于哪些类别。正如Richard Socher在下面概述的那样,查找和标记足够的数据以训练模型通常更快,更简单,也更容易,而不是尝试优化复杂的无监督方法。
第二步 清洗数据
我们遵循的第一条规则是:“您的模型将永远与您的数据一样好。”
数据科学家的一项关键技能就是知道下一步应该对模型还是对数据进行研究。一个好的经验法则是首先查看数据,然后进行清理。干净的数据集将使模型学习有意义的特征,而不会过度夸大无关的噪声。
这是用于清除数据的清单:(有关更多详细信息,请参见代码):
1.删除所有不相关的字符,例如任何非字母数字字符.
2.通过将其分隔为单个单词来对文本进行标记。
3.删除不相关的词,例如“ @”推特提及或网址。
4.将所有字符都转换为小写,以便将“ hello”,“ Hello”和“ HELLO”之类的单词视为相同。
5.考虑将拼写错误或替代拼写的单词组合为单个表示形式(例如“ cool” /“ kewl” /“ cooool”)
6.考虑去词缀化(将诸如“ am”,“ are”和“ is”之类的词简化为诸如“ be”之类的常见形式)
完成上述步骤并检查其他错误之后,我们就可以开始使用带有标签的干净数据来训练模型了!
第三步 寻找良好的数据表示方法
机器学习模型将数值作为输入。例如,处理图像的模型采用代表每个颜色通道中每个像素强度的矩阵。
我们的数据集是一个句子列表,因此为了使我们的算法从数据中提取模式,我们首先需要找到一种以我们的算法可以理解的方式表示它的方式,即作为一个数字列表。
One-hot 编码(Bag of Words)
代表计算机文本的自然方法是将每个字符分别编码为数字(例如ASCII)。如果我们将这种简单表示形式提供给分类器,则必须仅基于我们的数据从头开始学习单词的结构,这对于大多数数据集是不可能的。我们需要使用更高层次的方法。
例如,我们可以为数据集中的所有唯一单词构建词汇表,并将唯一索引与词汇表中的每个单词相关联。
然后,将每个句子表示为一个列表,该列表与我们词汇表中不同单词的数量一样长。在此列表的每个索引处,我们标记给定单词出现在句子中的次数。这被称为“词袋”模型,因为它是一种完全忽略句子中单词顺序的表示形式。如下所示。
可视化嵌入
在“社交媒体的灾难”示例中,词汇表中大约有20,000个单词,这意味着每个句子将被表示为长度为20,000的向量。向量将主要包含0,因为每个句子仅包含我们词汇的很小一部分。
为了查看我们的嵌入是否正在捕获与我们的问题相关的信息(即推文是否与灾难有关),最好将它们可视化并查看类是否看起来分离得很好。由于词汇量通常很大,并且无法在20,000个维度上可视化数据,因此PCA等技术将有助于将数据投影到二维。这在下面绘制。
这两个类看起来并没有很好地分开,这可能是我们嵌入的特征,或者仅仅是我们降维的特征。(The two classes do not look very well separated,which could be a feature of our embeddings or simply of our dimensionality reduction.)
为了查看词袋功能是否有用,我们可以基于它们训练分类器。
第四步 分类
当我们要解决问题时,一般的最佳做法是从可以解决问题的最简单工具开始。每当涉及数据分类时,因其多功能性和可解释性而广受欢迎的是Logistic回归。训练非常简单,结果可以解释,因为您可以轻松地从模型中提取最重要的系数。
我们将数据分为一个用于训练模型的训练集和一个测试集,用来测试在未知数据上的表现。经过训练,我们的准确率为75.4%。结果不算太差!猜到最频繁的类别(“无关”)只会给我们57%的机会。但是,即使75%的精度足以满足我们的需求,我们也应该在不理解模型的情况下发布模型。
第五步 检查
混淆矩阵
第一步是需要了解我们的模型产生的错误类型,以及哪种错误是最不希望的。在我们的示例中,False Positives(假阳性)将不相关的推文归类为灾难,False Negatives(假阴性)将灾难归为不相关的推文。如果优先考虑对每个潜在事件进行响应,我们希望降低False Negatives(假阴性)。但是,如果我们考虑资源的限制,则可以优先考虑较低的False Positives(假阳性),以减少错误警报。
可视化此信息的一种好方法是使用混淆矩阵,该矩阵将我们的模型做出的预测与真实标签进行比较。理想情况下,矩阵应该是从左上角到右下角的对角线(我们的预测与事实完全吻合)。
我们的分类器产生的false negatives(假阴性)要比false positives(假阳性)多。换句话说,我们模型中最常见的错误是将灾难错误地归类为不相关。如果误报会给执法部门带来高昂的成本及风险。
解释和解释我们的模型
为了验证我们的模型并解释其预测,重要的是要查看使用哪个词来做决策。如果我们的数据有偏差,我们的分类器将在样本数据中做出准确的预测,但是该模型在现实世界中无法很好地推广。在这里,我们为灾难和无关的人群绘制了最重要的单词。
使用单词袋和逻辑回归可以很容易地绘制单词的重要性,因为我们可以提取并排序模型用于预测的系数。
我们的分类者正确地选择了一些模式(广岛,屠杀),但显然似乎在一些毫无意义的术语上过拟合(heyoo,x1392)。目前,我们的“词袋”模型正在处理大量不同单词的词汇,并平等对待所有单词。但是,其中一些词非常频繁,只会对我们的预测产生影响。接下来,我们将尝试一种表示可以解释单词出现频率的句子的方法,以查看是否可以从数据中获取更多信号。
第六步:统计意义下的单词表
TF-IDF
为了帮助我们的模型更多地关注有意义的词,我们可以在“词袋”模型的顶部使用TF-IDF分数(词频,文档逆频)。TF-IDF会根据单词在我们的数据集中的稀有程度对单词进行权衡,将过于频繁且只会增加噪音的单词打折。这是我们新嵌入的PCA投影。
我们可以在上面看到两种颜色之间有更清晰的区别。这应该使我们的分类人员更容易将两个组分开。让我们看看这是否可以带来更好的性能。在我们的新嵌入上训练另一个Logistic回归,我们得到76.2%的准确性。
非常轻微的改善。我们的模型是否已开始使用更重要的单词?如果我们在防止模型“作弊”的同时获得了更好的结果,那么我们可以真正地将此模型视为升级。
它所选择的单词看起来更加相关!尽管我们在测试集上的指标仅略有增加,但是我们对模型使用的术语有更多的信心,因此将其部署在与客户互动的系统中会更自在。
第七步 利用语义
Word2Vec
我们的最新模型设法获得高频词。
但是,如果我们部署此模型,则很有可能会遇到以前在训练集中看不到的单词。
以前的模型即使在训练期间看到非常相似的单词,也将无法准确地对这些推文进行分类。
为了解决这个问题,我们需要捕获单词的语义,这意味着我们需要理解“好”和“肯定”等词比“杏”和“大陆”更接近。我们将使用该工具来帮助我们捕获 含义称为Word2Vec。
使用预训练模型
Word2Vec是一种用于查找单词的连续嵌入的技术。它通过阅读大量文本并记住哪些单词倾向于在相似的上下文中学习来学习。经过足够的数据训练后,它会为词汇表中的每个单词生成一个300维的向量,意思相似的单词会彼此靠近。
该论文的作者公开了一个在非常大的语料库上预先训练的模型,我们可以利用该模型将一些语义含义的知识包括到我们的模型中。可以在与此帖子关联的存储库中找到经过预训练的向量。
句子级别的表示
为我们的分类器嵌入句子的一种快速方法是对句子中所有单词的Word2Vec分数求平均。就像以前一样,这是一个“词袋”方法,但是这次我们只丢失了句子的语法,同时保留了一些语义信息。
这是使用先前技术的新嵌入的可视化:
这两组颜色在这里看起来更加分离,我们的新嵌入应有助于我们的分类器找到两个类之间的分离。在第三次训练相同的模型(逻辑回归)之后,我们获得了77.7%的准确性得分,这是我们迄今为止最好的结果!
是时候检查我们的模型了。
复杂性/解释性权衡
由于我们的嵌入不像以前的模型那样被表示为每个单词一维的向量,因此很难确定哪个单词与我们的分类最相关。虽然我们仍然可以使用逻辑回归的系数,但是它们与嵌入的300个维度有关,而不是与单词索引有关。
由于准确性如此之低,因此失去所有可解释性似乎是一项艰巨的代价。但是,对于更复杂的模型,我们可以利用LIME之类的黑匣子解释器来深入了解我们的分类器如何工作。
LIME
LIME可通过开源软件包在Github上使用。黑盒解释器允许用户解释任何分类器在可视化Word2Vec嵌入方面的决定。通过扰动输入(在本例中为从句子中删除单词)并查看预测如何变化,
我们来看看数据集中句子的一些解释。
但是,我们没有时间探索数据集中的数千个示例。我们要做的是在一个有代表性的测试用例样本上运行LIME,然后看看哪些词继续成为强大的贡献者。使用这种方法,我们可以像以前的模型那样获得单词重要性评分,并验证模型的预测。
看起来该模型使用了高度相关的词语,表明它似乎在做出易于理解的决策。这些似乎是所有先前型号中最相关的词,因此我们更愿意将其部署到生产中。
第八步:使用端到端方法
我们已经介绍了快速有效的方法来生成紧凑的句子嵌入。但是,通过忽略单词的顺序,我们将丢弃句子中所有的句法信息。如果这些方法不能提供足够的结果,则可以利用更复杂的模型将整个句子作为输入并预测标签,而无需构建中间表示。常用的方法是使用Word2Vec或更新的方法(例如GloVe或CoVe)将句子视为单个单词向量的序列。这就是我们下面要做的。
用于句子分类的卷积神经网络训练非常迅速,并且可以作为入门级深度学习架构很好地工作。
虽然卷积神经网络(CNN)主要以其在图像数据上的性能而闻名,但它们在与文本有关的任务上一直提供出色的结果,并且通常比大多数复杂的NLP方法(例如LSTM和编码器/解码器体系结构)训练起来要快得多。该模型保留了单词的顺序,并学习了有关哪些单词序列可以预测我们的目标类别的有价值的信息。与以前的模型相反,它可以说出“ Alex食用植物”和“ Plant eat食用Alex”之间的区别。训练该模型不需要比以前的方法做更多的工作(有关详细信息,请参见代码),并且为我们提供了一个模型比以前的要好得多,准确度高达79.5%!与上述模型一样,下一步应该是使用我们描述的方法来探索和解释预测,以验证它确实是部署给用户的最佳模型。到目前为止,您应该可以自己解决这个问题。
最后说明
以下是我们成功使用的方法的简要概述:
- 从快速简单的模型开始
- 解释其预测
- 了解其正在犯的错误
- 使用该知识来告知您的下一步,无论是对数据还是更复杂的模型。
这些方法使用为理解和利用诸如tweet之类的短文本而量身定制的模型应用于特定的示例案例,但是这些思想广泛应用于各种问题。希望对您有所帮助,我们很乐意听到您的评论和问题!