📜  特征提取技术 - NLP

📅  最后修改于: 2022-05-13 01:54:24.356000             🧑  作者: Mango

特征提取技术 - NLP

本文重点介绍 NLP 中的基本特征提取技术,以分析文本之间的相似性。自然语言处理 (NLP) 是计算机科学和机器学习的一个分支,它处理训练计算机以处理大量人类(自然)语言数据。简而言之,NLP 是计算机理解人类语言的能力。

需要特征提取技术
机器学习算法从训练数据中的一组预定义特征中学习,以生成测试数据的输出。但是使用语言处理的主要问题是机器学习算法不能直接处理原始文本。因此,我们需要一些特征提取技术来将文本转换为特征矩阵(或向量)。
一些最流行的特征提取方法是:

  • 词袋
  • 特遣部队

词袋:
Bag-of-Words 是将标记转换为一组特征的最基本方法之一。 BoW 模型用于文档分类,其中每个单词都用作训练分类器的特征。
例如,在基于评论的情感分析任务中, “fabulous”、“excellent”等词的存在表示正面评论,而“annoying”、“poor”等词则表示负面评论。
创建 BoW 模型有 3 个步骤:

  1. 第一步是文本预处理,包括:
    1. 将整个文本转换为小写字符。
    2. 删除所有标点符号和不必要的符号。
  2. 第二步是从语料库中创建一个包含所有唯一单词的词汇表。假设,我们有一个酒店评论文本。
    让我们考虑其中的 3 条评论,如下所示:

    现在,我们考虑上述评论集中的所有独特词来创建一个词汇表,如下所示:

  3. 在第三步中,我们通过为每个单词分配一个单独的列来创建一个特征矩阵,而每一行对应一个评论。此过程称为文本矢量化。矩阵中的每个条目都表示评论中单词的存在(或不存在)。如果该词出现在评论中,我们将其设为1 ,如果该词不存在,我们将其设为0

对于上面的例子,特征矩阵如下:

goodmovienotadidlike
110000
111100
001011

使用这个模型的一个主要缺点是单词的出现顺序丢失了,因为我们创建了一个随机顺序的标记向量。但是,我们可以通过考虑N-gram (主要是二元组)而不是单个单词来解决这个问题(即一元组)。这可以保留单词的本地顺序。如果我们从给定的评论中考虑所有可能的二元组,上表将如下所示:

good moviemoviedid nota
1100
1101
0010

然而,这个表会变得非常大,因为考虑到所有可能的连续词对,可能会有很多可能的二元组。此外,如果词汇量很大,使用 N-gram 可能会导致一个巨大的稀疏(有很多 0)矩阵,使计算非常复杂!
因此,我们必须根据它们的频率删除一些 N-gram。就像,我们总是可以删除高频 N-gram ,因为它们几乎出现在所有文档中。这些高频 N-gram 通常是冠词、限定词等,最常被称为StopWords
同样,我们也可以删除低频 N-gram,因为它们非常罕见(即通常出现在 1 或 2 条评论中)!!这些类型的 N-gram 通常是拼写错误(或打字错误)。
通常,中频 N-gram 被认为是最理想的。
然而,有一些 N-gram 在我们的语料库中非常罕见,但可以突出一个特定的问题。
假设,有一条评论说—— “Wi-Fi 经常中断”。

在这里,N-gram 'Wi-Fi 中断不能太频繁,但它突出了一个需要关注的主要问题。
我们的 BoW 模型不会捕获这样的 N-gram,因为它的频率非常低。为了解决这类问题,我们需要另一个模型,即TF-IDF Vectorizer ,我们将在接下来研究它。

代码:用于创建 BoW 模型的Python代码是:

# Creating the Bag of Words model 
word2count = {} 
for data in dataset: 
    words = nltk.word_tokenize(data) 
    for word in words: 
        if word not in word2count.keys(): 
            word2count[word] = 1
        else: 
            word2count[word] += 1

TF-IDF 矢量化器:
TF-IDF 代表词频-逆文档频率。它突出了一个在我们的语料库中可能不太常见但非常重要的特定问题。 TF-IFD 值与单词在文档中出现的次数成比例增加,并随着语料库中包含该单词的文档数量而减小。它由 2 个子部分组成,它们是:

  1. 词频 (TF)
  2. 逆向文档频率 (IDF)

词频(TF):
词频指定一个词在整个文档中出现的频率。可以认为是在文档中找到一个词的概率。它计算一个词出现的次数w_i发生在审查中r_j ,相对于评论中的总字数r_j . 它被制定为:

    \[tf(w_i, r_j)=\frac{No.\, of \, times \, w_i \, occurs \, in \, r_j}{Total \, no. \, of \, words \, in \, r_j}\]

计算 tf 的另一种方案是对数归一化。它被制定为:

    \[tf(t, d)=1 + \log{\(f_{t, d}\)}\]

在哪里,
f_{t, D}是文档 D 中术语 t 的频率。

逆文档频率(IDF):
逆文档频率是衡量一个词在整个语料库中的文档中是稀有还是频繁的度量。它突出显示在整个语料库中很少出现的文档中的那些单词,或者在简单的语言中,很少见的单词具有较高的 IDF 分数。 IDF 是一个对数归一化的值,它是由文档总数除以得到的D在语料库中按包含该术语的文档数量t ,并取总项的对数。

    \[idf(d, D)=\log{\frac{|D|}{\{d \epsilon D:t \epsilon D\}}}\]

在哪里,
f_{t, D}是文档 D 中术语 t 的频率。
|D|是语料库中的文档总数。
\{d \epsilon D:t \epsilon D\}是语料库中文档的计数,其中包含术语 t。

由于 IDF 的 log函数内的比率必须始终大于或等于 1,因此 IDF(以及因此 tf-idf)的值大于或等于 0。当一个术语出现在大量文档中时,对数内的比率接近 1,IDF 更接近于 0。

词频-逆文档频率(TF-IDF)
TF-IDF 是 TF 和 IDF 的产物。它被制定为:

    \[tfidf(t, d, D) = tf(t, d)*idf(d, D)\]

高 TF-IDF 分数是由在文档中具有高频率和在语料库中的低文档频率的术语获得的。对于一个几乎出现在所有文档中的词,IDF值接近0,使得tf-idf也更接近于0。当IDF和TF值都高时,TF-IDF值高,即该词在整个文档中很少见但经常出现在文档中。

让我们用同样的例子来更好地理解这一点:

在此示例中,每个句子都是一个单独的文档。

考虑到二元模型,我们计算每个二元模型的 TF-IDF 值:

good moviemoviedid not
good movie1*log(3/2) = 0.171*log(3/2) = 0.170*log(3/1) = 0
not a good movie1*log(3/2) = 0.171*log(3/2) = 0.170*log(3/1) = 0
did not like0*log(3/2) = 00*log(3/2) = 01*log(3/1) = 0.47

在这里,我们观察到与其他标记相比,二元组并不罕见(即仅出现在一个文档中),因此具有更高的 tf-idf 分数。

代码:使用Python内置函数TfidfVectorizer计算任何语料库的 tf-idf 分数

# calculating tf-idf values
from sklearn.feature_extraction.text import TfidfVectorizer
import pandas as pd
  
texts = {
"good movie", "not a good movie", "did not like"
}
  
tfidf = TfidfVectorizer(min_df = 2, max_df = 0.5, ngram_range = (1, 2))
features = tfidf.fit_transform(texts)
  
pd.Dataframe{
     features.todense(),
     columns = tfidf.get_feature_names()
}

最后,我们可以说,尽管词袋是特征提取和文本向量化中最基本的方法之一,但它无法捕捉到文本中的某些问题。然而,这个问题被 TF-IDF Vectorizer 解决了,它也是一种特征提取方法,它捕获了整个语料库中不太常见的一些主要问题。