文本特征化方法总结

1 概述

        在NLP的任务中,除了去重、分词、去停以及词频分析、词云等定性分析外,如果需要用到机器学习、深度学习等模型就需要对文本进行文本特征化处理。简单来讲,就是将文本转化为计算机能够看懂的数字。这也是NLP进行数值分析的第一步,也是最关键的一步,是文本挖掘通往传统模型步骤的桥梁,这一步搭建好了,之后的所有步骤都可以按照传统做法进行。在这里,总结了4种常见文本特征化方法以及其对应的优缺点、python实现。

2 文本特征话方法

2.1 词袋模型

2.1.1 概述

        词袋模型顾名思义就是讲一句话以为基本单元放入一个袋子里从而实现向量化。这里以4个大学的名称为例,“中国海洋大学”、“中国农业大学”、“中国科学技术大学”、“中国矿业大学”分词后为“中国 海洋 大学”、“中国 农业 大学”、“中国 科学 技术 大学”、“中国 矿业 大学”,那么这4个大学共同的唯一不重复的词(类似集合的交集)组成的词语集合就是词库,词库种包含的词语个数就是词库大小,这里的词库为['中国', '农业', '大学', '技术', '海洋', '矿业', '科学'],对于中国海洋大学,在词库中能够对应上的位置就赋值为1,否则为0,即可以将中国海洋大学转化为[1 0 1 0 1 0 0]。

2.1.2 优缺点

        优点:词袋模型简单易懂。

        缺点:

(1)维度灾难。词袋模型的词库是取所有文本分词后的交集,词语众多,所有词都要囊括进去会造成维度膨胀。

(2)向量稀疏。对于庞大的词库而言,某一条评论或一篇文章包含的词在词库中只是茫茫0海中的少数个1,这样的向量非常稀疏,对之后的建模不利。

(3)忽略了词序。词袋模型以词频为基础,未考虑上下文的关联,即“我爱你”和“你爱我”在词袋模型中是一样的。

(4)以离散的词频来表示文本,丢失了一定信息。

2.1.3 代码实现

#文本数据
data=['中国 海洋 大学','中国 农业 大学','中国 科学 技术 大学','中国 矿业 大学']
#词袋模型
from sklearn.feature_extraction.text import CountVectorizer
cv1 = CountVectorizer(min_df = 1) # 出现5次以上的才纳入
cv_fit1 = cv1.fit_transform(data)
print(cv1.get_feature_names())#得到词袋,即不重复的所有词
array1 = cv_fit1.toarray()#得到各条信息的向量

2.2 ngram模型

2.2.1 概述

        ngram模型在词袋模型的基础上加入了滑动窗口,即在构建词库时考虑了词序,如若两两结合,那么词库为:(在python中设置参数ngram_range=(2,2)) # ngram_range中的数表示词库中组合的词个数的上下限)

['中国 农业', '中国 海洋', '中国 矿业', '中国 科学', '农业 大学', '技术 大学', '海洋 大学', '矿业 大学', '科学 技术']

        或是窗口设置更长和更宽泛,1个词、2个词、3个词一起组合:(ngram_range=(1,3)) )

['中国', '中国 农业', '中国 农业 大学', '中国 海洋', '中国 海洋 大学', '中国 矿业', '中国 矿业 大学', '中国 科学', '中国 科学 技术', '农业', '农业 大学', '大学', '技术', '技术 大学', '海洋', '海洋 大学', '矿业', '矿业 大学', '科学', '科学 技术', '科学 技术 大学']

2.2.2 优缺点

        优点:在一定程度上弥补了词袋模型未考虑词序的缺陷

        缺点:组合变多以后,维度变得更大,向量空间变得更稀疏。

2.2.3 代码实现

#ngram模型
cv2 = CountVectorizer(min_df = 1,ngram_range=(1,3)) # ngram_range中的数表示词库中组合的词个数的上下限
cv_fit2 = cv2.fit_transform(data)
print(cv2.get_feature_names())#得到词袋,即不重复的所有词
array2 = cv_fit2.toarray()

2.3 TF-IDF模型

2.3.1 概述

        TF-IDF是一种关键词抽取方法,使用TF-IDF来对文本进行向量化可以更准确地突出文本的重点。同样以开头的大学名称为例,每一所大学里面都带有“中国”和“大学”两个词,若按照词频的思想,这两个词的重要性最高。然而,这类重复出现的词其实信息量不一定大,我们在都知道研究数据中国的大学的前提下,这两个词就是没有意义的,即他们的区分度不高。在TF-IDF中引入了逆词频,即在考虑词频的前提下还考虑该次的逆词频(见下图),比如“中国”的词频很高,但其逆词频(dfi)很高,那么其作为分母,整体就越小,log是用来调节其程度。

文本特征化方法总结_第1张图片

2.3.2 优缺点

        优点:可以更准确更真实地提取有用信息

        缺点:仍然没有解决词袋模型存在的问题

2.3.3 代码实现

#TF-IDF
from sklearn.feature_extraction.text import TfidfVectorizer
cv3 = TfidfVectorizer()
cv_fit3 = cv3.fit_transform(data)
print(cv3.get_feature_names())
array3=cv_fit3.toarray()

2.4 Word2vec

2.4.1 概述

        word2vec比较好的弥补了上述问题,考虑词序+把词库映射到更低维的向量空间,但与之前不同,word2vec是每个词得出一个向量,而非一整句话得出一个,对于词语级的可以直接用,若是句子级的任务则需要进行处理,如每个句子中的词向量求平均。

2.4.2 代码实现

#word2vec
from gensim.models.word2vec import Word2Vec
list_data=[['中国','海洋','大学'],['中国','农业','大学'],['中国','科学','技术','大学'],['中国','矿业','大学']]
model = Word2Vec(list_data,vector_size=50,sg=0,min_count=1,epochs=5)
model.init_sims(replace=True)
word=CountVectorizer(min_df = 1)
cv_fit4 = word.fit_transform(data)
words=word.get_feature_names()
#得到词库中每个词的词向量
vec=[]
for i in words:
    v=model.wv[i]
    vec.append(v)
import numpy as np
vec=np.array(vec)
#若是以句子级的任务,可以将每个句子里的词语加起来求平均
sum_vec=[]
for i in list_data:
    array=np.zeros((1,50))#存放一个空矩阵,等待累加
    for j in i:
        array+=np.array(model.wv[j])/len(i)
    sum_vec.append(array)

你可能感兴趣的:(NLP,人工智能,nlp,python)