NLP之文本特征提取详解

深度学习入门小菜鸟,希望像做笔记记录自己学的东西,也希望能帮助到同样入门的人,更希望大佬们帮忙纠错啦~侵权立删。

✨NLP系列✨

NLP之文本预处理详解_tt丫的博客-CSDN博客_nlp文本预处理

NLP之文本特征提取详解_tt丫的博客-CSDN博客

目录

一、词袋模型(Bag of Words, BoW)

1、目的

2、主要思想

3、具体算法步骤

4、缺点

5、词袋管理

6、代码实现

二、TF-IDF文本特征提取

1、定义与用途

2、缺点

3、代码实现

三、基于词向量的特征提取模型 —— word2vector

1、word2vector定义介绍

2、基于神经网络语言模型的词向量生成(NNLM)

3、CBoW模型

4、Skip-gram模型

5、两种优化的方法


一、词袋模型(Bag of Words, BoW)

1、目的

将不定长的文本型数据转化为定长的数值型数据,方便用作机器学习模型的输入

2、主要思想

建立一个词典库,其中包含训练语料库的所有词语,每个词语都对应一个唯一识别的编号,利用one-hot文本(即存在的词语用1表示,不存在的用0来表示)来表示;文档的词向量维度与单词向量的维度相同,每个位置的值是对应位置词语在文档中出现的次数。

他是N-gram模型的特例1元模型

3、具体算法步骤

(1)对所有文本进行单词提取,生成词袋

eg:She is a good girl.He is a good boy. It is a pig.

生成的词袋有:she;is;a;good;girl;he;boy;it;pig

(2)将词袋中的单词与词向量中的值一一对应

对应法则:该单词在当前文本中总共出现的次数

即:(所谓的one - hot 编码)

"She is a good girl" = [1,1,1,1,1,0,0,0,0]

"He is a good boy" = [0,1,1,1,1,1,0,0,0]

"It is a pig" = [0,1,1,0,0,0,0,1,1]

4、缺点

(1)仅考虑词语出现的次数,没有考虑句子词语之间的顺序信息,即语义信息未考虑

(2)词袋太大,占用过多

(3)文档(词向量)稀疏(即0值特别多)

5、词袋管理

基于上面所阐述的缺点,我们需要使用合理的方法来压缩词袋的大小

压缩方法有:

(1)忽略人名、地名等对象的名字

(2)忽略高频且无意义的词,如:a,the,的,了(去除停用词)

(3)将单词的变形(如过去式、过去分词)统一转化为词干

(4)用词组来组成词袋,这样不仅减少了词袋的大小,而且会更有意义(N-gram模型)

有关去除停用词和N-gram的介绍可以看博主往期文章NLP之文本预处理详解_tt丫的博客-CSDN博客

6、代码实现

主要通过sklearn.feature_extraction.text中的CountVectorizer类来实现

CountVectorizer是特征数值计算类,对于每个文本通过fit_transform方法来计算每个单词在该文本中出现的频率,形成词频矩阵。
通过get_feature_names可查看所有文本关键字,通过toarray可查看到文本的词袋模型结果

首先导入所需的库

from sklearn.feature_extraction.text import CountVectorizer

提取文本文件中的语料,分句

path = "1.txt"
f = open(path, 'r', encoding= 'utf-8', errors= 'ignore')
text = []
piece = ''
for line in f:
    for uchar in line:
        if uchar == '\n':
            continue
        if uchar == '.' or uchar == '?' or uchar == '!':
            text.append(piece)
            piece = ''
        else:
            piece = piece + uchar

其中1.txt文件是待处理的文本

I have a pen.I love this pen.I have an apple.I love to eat apples.
You have a book.

处理后

['I have a pen', 'I love this pen', 'I have an apple', 'I love to eat apples', 'You have a book']

定义提取特征对象

v = CountVectorizer()

对文本提特征,转为词袋模型

dtext = v.fit_transform(text)
dtext = dtext.toarray()
print(dtext)
feature = v.get_feature_names()
print(feature)

输出

[[0 0 0 0 0 1 0 1 0 0 0]
 [0 0 0 0 0 0 1 1 1 0 0]
 [1 1 0 0 0 1 0 0 0 0 0]
 [0 0 1 0 1 0 1 0 0 1 0]
 [0 0 0 1 0 1 0 0 0 0 1]]
['an', 'apple', 'apples', 'book', 'eat', 'have', 'love', 'pen', 'this', 'to', 'you']


二、TF-IDF文本特征提取

1、定义与用途

TF-IDF(词频-逆向文档频率):可以用来评估单词对于文档的重要程度

顾名思义:TF-IDF由TF和IDF组成。

TF

定义:一个单词在某个文档中出现的频率。

公式:TF = 单词在一篇文章中出现的次数 / 这篇文章的总词汇数

意义:一个单词在一个文档中出现的频率越高,则该单词对于当前文档越重要

注意:一些通用词汇的出现频率同样很高(像“你”,“是”等词)

IDF

定义:IDF代表单词对于文档的区分度(“逆文档频率”)

如果一个单词在一篇文章中出现多次,但在其他文章中很少出现,则认为该单词对于当前文档的区分能力较强,即IDF值较大,否则认为该单词对文档的区分能力较差,IDF值小。

公式:IDF = log(全部文档数/包含该词的文档总数+1)—— 分母加1是为了避免分母为0的情况

意义:为尽量减少上面所说的通用词的干扰,体现词语对当前文本的区分度高低

TF-IDF:将TF值和IDF值做乘法,即可得到一个单词的TF-IDF值

即:TF-IDF = TF *IDF 

然后就能根据TF-IDF提取出关键词了(思路:求出TF-IDF后进行排序,划定阈值,取出前几个TF-IDF值大的作为关键词)

2、缺点

TF-IDF只考虑词频对于文本的重要程度,却没有考虑词语在文本中出现的位置。而事实上,一个单词的重要程度与它在文本中出现的位置是有关系的(比如出现在摘要和段落首行的单词等一般都具有总结性作用,因此应该被赋予更高的权重)。

3、代码实现

在python中可以利用TfidfVectorizer这个工具

首先导入所需的库

from sklearn.feature_extraction.text import TfidfVectorizer

提取文本文件中的语料,分句

path = "1.txt"
f = open(path, 'r', encoding= 'utf-8', errors= 'ignore')
text = []
piece = ''
for line in f:
    for uchar in line:
        if uchar == '\n':
            continue
        if uchar == '.' or uchar == '?' or uchar == '!':
            text.append(piece)
            piece = ''
        else:
            piece = piece + uchar

其中1.txt文件是待处理的文本

I have a pen.I love this pen.I have an apple.I love to eat apples.
You have a book.

处理后

['I have a pen', 'I love this pen', 'I have an apple', 'I love to eat apples', 'You have a book']

定义提取特征对象

tf = TfidfVectorizer(ngram_range=(1,2),analyzer='word',smooth_idf=1) 
# 按照 word 来做特征,最大范围是两个单词,最小是一个单词

对文本提特征,求TF-IDF,并生成对应的矩阵

discuss_tf = tf.fit_transform(text)
discuss_tf = discuss_tf.toarray()
print(discuss_tf)

输出

[[0.         0.         0.         0.         0.         0.
  0.         0.4622077  0.         0.         0.69015927 0.
  0.         0.         0.55681615 0.         0.         0.
  0.         0.         0.        ]
 [0.         0.         0.         0.         0.         0.
  0.         0.         0.         0.         0.         0.38898761
  0.48214012 0.         0.38898761 0.48214012 0.48214012 0.
  0.         0.         0.        ]
 [0.47412465 0.47412465 0.47412465 0.         0.         0.
  0.         0.3175268  0.47412465 0.         0.         0.
  0.         0.         0.         0.         0.         0.
  0.         0.         0.        ]
 [0.         0.         0.         0.38775666 0.         0.38775666
  0.38775666 0.         0.         0.         0.         0.31283963
  0.         0.38775666 0.         0.         0.         0.38775666
  0.38775666 0.         0.        ]
 [0.         0.         0.         0.         0.47412465 0.
  0.         0.3175268  0.         0.47412465 0.         0.
  0.         0.         0.         0.         0.         0.
  0.         0.47412465 0.47412465]]

输出矩阵大小

size_matrix = discuss_tf.shape
print(size_matrix)

结果为:(5, 21)

5——总共5个句子;21——提出21个特征词/词组

输出相应特征词/词组

feature = tf.get_feature_names()
print(feature)

输出

['an', 'an apple', 'apple', 'apples', 'book', 'eat', 'eat apples', 'have', 'have an', 'have book', 'have pen', 'love', 'love this', 'love to', 'pen', 'this', 'this pen', 'to', 'to eat', 'you', 'you have']

即刚刚输出的矩阵,我们来看第一句话“I have a pen”

[0.         0.         0.         0.         0.         0.
  0.         0.4622077  0.         0.         0.69015927 0.
  0.         0.         0.55681615 0.         0.         0.
  0.         0.         0.        ]

即:第8个特征词have :0.4622077;第11个特征词have pen:0.69015927;

第15个特征词pen:0.55681615


三、基于词向量的特征提取模型 —— word2vector

上面介绍的两种方法都有共同的缺点:如果文本很长,提取到的特征词/词组会很多,表示一个句子的向量会更长。

基于词向量的特征提取模型可以解决这个问题。

即基于大量的文本语料库,通过类似神经网络模型训练,将每个词语映射成一个定维度的向量。

1、word2vector定义介绍

word2vector有时又被称为词嵌入。

【补充:NLP中的文本表示形式有以下几类:

(1)one - hot 编码;(2)整数编码(比如词语一共有“你,我,他”这3个,那么用1表示你,2表示我,3表示他;但是对于模型解释而言,整数编码可能具有挑战性)

(3)词嵌入(Word Embedding)—— 包括word2vector和GloVe】

他是一群用来产生词向量的相关模型,并且这些模型通常为浅而双层的神经网络,网络以词来表现,并且需要猜测相邻位置的输入词,借以用来训练以重新构建语言学之词文本,训练完后,word2vec模型可用来映射每个词到一个向量,可用来表示词与词之间的关系,该向量是神经网络之隐藏层

即word2vector模型实际上分为了两个部分,第一部分是建立模型,第二部分是通过模型获取嵌入词向量。

word2vector有两种形式——CBoW 和 Skip-gram

在这里先介绍前期背景——基于神经网络语言模型的词向量生成(NNLM)

2、基于神经网络语言模型的词向量生成(NNLM)

详见往期文章基于神经网络语言模型的词向量生成(NNLM)详解_tt丫的博客-CSDN博客

3、CBoW模型

word2vector之CBoW模型详解_tt丫的博客-CSDN博客

4、Skip-gram模型

word2vector之Skip_Gram模型详解_tt丫的博客-CSDN博客

5、两种优化的方法

分层softmax+负采样

原先的做法中,导致计算量大的原因有:

(1)词表维度大;

(2)softmax计算量大;

详情请看往期博文

基于分层softmax的CBoW模型详解_tt丫的博客-CSDN博客

基于高频词抽样+负采样的CBOW模型_tt丫的博客-CSDN博客

(Skip-gram与CBOW类似)


欢迎大家在评论区批评指正,谢谢~

你可能感兴趣的:(NLP,深度学习,自然语言处理,人工智能,nlp,中文分词,python)