自然语言处理(NLP)是人工智能的一个分支,它处理人类语言,使系统能够理解和响应语言。在任何数据科学项目中,数据都是最重要的部分,应该以易于理解和建模的方式呈现,尤其是在自然语言处理机器学习中。有人说,如果为不良模型提供非常好的特征,为优化良好的模型提供不良特征,那么不良模型的表现将远远超过优化模型。因此,在本文中,将研究如何从文本数据中提取特征,并在NLP机器学习建模过程中使用它们,以及为什么从文本中提取特征比其他类型的数据要困难一些。
首先出现的问题是什么是从文本中提取特征?特征提取是一个通用术语,也被称为文本表示或文本向量化,这是一个将文本转换为数字的过程。称之为向量化,因为当文本被转换为数字时,它以向量形式存在。
第二个问题是为什么需要特征提取?知道机器只能理解数字,为了使机器能够识别语言,需要将其转换为数字形式。
如果询问任何NLP从业者或经验丰富的数据科学家,答案是肯定的,处理文本数据是困难的。首先,来比较文本特征提取与其他类型数据的特征提取。例如,在图像数据集中,假设数字识别是拥有数字图像,任务是预测数字,所以在图像特征提取中,因为图像已经以数字(像素)的形式存在,所以特征提取是容易的。如果谈论音频特征,假设从语音识别中预测情感,那么拥有的数据是以波形信号的形式,特征可以在某个时间间隔内提取。但是,当说有一句话并想要预测其情感时,将如何用数字来表示它?图像数据集、语音数据集是简单的情况,但在文本数据的情况下,需要稍微思考一下。在本文中,将专门研究这些技术。
这些是将在后续技术中使用的常用术语,所以希望熟悉这四个基本术语:语料库(C)~整个数据集中单词组合的总数被称为语料库。简单地说,将数据集中的所有文本记录连接起来形成语料库。词汇表(V)~构成语料库的不同单词的总数被称为词汇表。文档(D)~数据集中有多个记录,所以单个记录或评论被称为文档。单词(W)~在文档中使用的单词被称为单词。
独热编码意味着将文档中的单词转换为V维向量,通过组合所有这些,得到一个单独的文档,所以最后有一个二维数组。这种技术非常直观,意味着它简单,可以自己编码。这是独热编码的唯一优势。
import numpy as np
import pandas as pd
sentences = ['在Analytics Vidhya上写作', 'Vidhya在Analytics Vidhya上阅读并评论', 'Vidhya赞赏']
df = pd.DataFrame({"text":sentences, "output":[1,1,0]})
现在可以使用sklearn预构建的类来执行所有技术,也可以使用Python实现它。实现后,每个句子将有一个不同的2-D数组,如下所示的单个句子的样本图像。
缺点:
- 稀疏性 - 可以看到,只有一个句子就创建了一个n*m大小的向量,其中n是句子的长度,m是文档中唯一单词的数量,向量中80%的值是零。
- 没有固定大小 - 每个文档的长度不同,这会创建不同大小的向量,不能输入到模型中。
- 不捕获语义 - 核心思想是通过保持句子的实际含义来将文本转换为数字,这在独热编码中没有看到。
这是最常用的文本向量化技术之一。它主要用于文本分类任务。词袋模型与独热编码有点相似,在词袋模型中输入每个单词作为二进制值,并在文档中输入单词的计数。所以,创建一个词汇表,并为单个文档输入一个条目,说明文档中哪些单词出现了多少次。让进入IDE并使用scikit-learn的CountVectorizer类实现词袋模型。
from sklearn.feature_extraction.text import CountVectorizer
cv = CountVectorizer()
bow = cv.fit_transform(df['text'])
现在,要查看它创建的词汇表和向量,可以使用以下代码,如下所示的结果图像。
它如何分配计数,首先它根据单词的字母顺序或词汇创建一个词汇表,然后创建一个数组,并检查每个术语在文档中出现的次数,并将该计数放在数组的相应位置。让讨论这种技术的优缺点。
优点:
- 简单直观 - 实施这种技术只需要几行代码。
- 固定大小的向量 - 在独热编码中看到的问题是无法将数据输入机器学习模型,因为每个句子形成一个不同大小的向量,但在这里它忽略了新单词,只取词汇表中的单词,所以创建了一个固定大小的向量。
缺点:
- 词汇表外的情况 - 它只计算词汇表中的单词,所以如果新单词出现在句子中,它简单地忽略它,并跟踪词汇表中单词的计数。但如果它忽略的单词在预测结果中很重要,那么这是一个缺点,唯一的好处是它不会抛出错误。
- 稀疏性 - 当有一个大词汇表,文档包含一些重复的术语时,它创建了一个稀疏数组。
- 不考虑顺序是一个问题 - 估计文档的语义是困难的。
这种技术与词袋模型类似。到目前为止,所读的所有技术都是由单个单词组成的,无法使用它们或利用它们以更好地理解。所以N-Gram技术解决了这个问题,并构建了包含多个单词的词汇表。当构建N-Gram技术时,需要定义,比如想要二元组、三元组等。所以,当定义N-Gram时,如果不可能,它将抛出一个错误。在情况下,不能构建4或5-gram模型。让尝试二元组并观察输出。
#二元组模型
from sklearn.feature_extraction.text import CountVectorizer
cv = CountVectorizer(ngram_range=[2,2])
bow = cv.fit_transform(df['text'])
可以尝试三元组,范围为[3,3],并尝试N范围,以便对这种技术有更多的了解,并尝试转换一个新文档并观察它的性能。
优点:
- 能够捕获句子的语义含义 - 因为使用二元组或三元组,它采取句子的序列,这使得找到单词关系更容易。
- 直观且易于实施 - N-Gram的实施是直接的,只需对词袋模型进行一点修改。
缺点:
- 当从单词移动到N-Gram时,向量形成或词汇的维度增加,因此它需要更多的时间进行计算和预测。
- 没有解决词汇表外的术语 - 没有其他方法,只能忽略新句子中的新单词。
现在要研究的技术与上述技术的工作方式不同。这种技术为文档中的每个单词分配不同的值(权重)。分配权重的核心思想是,在文档中多次出现的单词但在语料库中很少出现的单词对那个文档非常重要,所以它给那个单词更多的权重。这个权重是通过两个术语计算的,称为TF和IDF。所以,要找到任何单词的权重,找到TF和IDF并将两个术语相乘。
词频(TF) - 一个单词在文档中出现的次数除以文档中的总术语数被称为词频。例如,必须在以下句子中找到people的词频,那么它将是1/5。它说一个特定单词在特定文档中出现的频率。
逆文档频率 - 语料库中的文档总数除以包含术语T的文档总数,并取完整分数的对数是逆文档频率。如果有一个词出现在所有文档中,那么对数的结果输出是零。但在实施中,sklearn使用了一个有点不同的实现,因为如果它变成零,那么单词的贡献就被忽略了,所以他们在结果中加一,这就是为什么可以观察到TFIDF的值有点高。如果一个词只出现一次,IDF会更高。
from sklearn.feature_extraction.text import TfidfVectorizer
tfidf = TfidfVectorizer()
tfidf.fit_transform(df['text']).toarray()
一个术语跟踪术语出现的频率,而另一个跟踪术语出现的频率。
已经阅读并实践了从文本中提取特征的机器学习技术。这些是在进行机器学习建模时使用的技术。还有更多高级的技术,它们属于深度学习技术,用于从文本中提取特征,如编码器-解码器、GloVe编码等,这些技术用于当使用神经网络进行NLP任务时,将在下一篇文章中学习所有深度学习技术。