目录
1、将文本数据进行特征提取
1.1英文文本---直接用CountVectorizer
1.2中文文本---先用结巴分词工具进行分词
2、将分词转为数组
2.1 基本词袋模型
2.2 改善词袋模型---n-Gram
3、进一步优化处理
3.1 tf-idf模型
3.2 删除文本中的停用词
4、如何深入自然语言处理
CountVectorizer是属于常见的特征数值计算类,是一个文本特征提取方法。对于每一个训练文本,它只考虑每种词汇在该训练文本中出现的频率。用法:
sklearn.feature_extraction.text(input=’content’,encoding=’utf8’, decode_error=’strict’,strip_accents=None, lowercase=True, preprocessor=None, tokenizer=None, stop_words=None, token_pattern=’(?u)\b\w\w+\b’, ngram_range=(1, 1), analyzer=’word’, max_df=1.0, min_df=1, max_features=None, vocabulary=None,binary=False, dtype=
参数设置见https://zhuanlan.zhihu.com/p/37644086
##处理英文文本
#导入文本向量化工具CountVectorizer
from sklearn.feature_extraction.text import CountVectorizer
#引入算法
vect = CountVectorizer()
#导入文本数据(注意这里是文本list)
text_data = ['The quick brown fox jumps over a lazy dog']
#用CountVectorizer算法拟合文本数据
vect.fit(text_data)
#打印结果
print('单词数:{}'.format(len(vect.vocabulary_)))
print('分词:{}'.format(vect.vocabulary_))
单词数:8
分词:{'the': 7, 'quick': 6, 'brown': 0, 'fox': 2, 'jumps': 3, 'over': 5, 'lazy': 4, 'dog': 1}
这里的0-7是给每一个分词进行了编码
注意CountVectorize默认不统计只有一个字母的单词,如a,因此只有8个单词;CountVectorize无法对中文语句进行特征提取,需要先用其它工具
##处理中文文本
#使用前请先安装 pip install jieba
#导入结巴分词工具
import jieba
#导入文本数据(注意这里是文本元组)
text_data = ('那只敏捷的棕色狐狸跳过了一只懒惰的狗')
#用结巴分词对中文文本进行分词
cn = jieba.cut(text_data)
#使用空格作为词与词之间的分界线
cn = [' '.join(cn)]
#打印结果
print(cn)
#用CountVectorizer算法拟合文本数据
vect.fit(cn)
print('单词数:{}'.format(len(vect.vocabulary_)))
print('分词:{}'.format(vect.vocabulary_))
['那 只 敏捷 的 棕色 狐狸 跳过 了 一只 懒惰 的 狗']
单词数:6
分词:{'敏捷': 2, '棕色': 3, '狐狸': 4, '跳过': 5, '一只': 0, '懒惰': 1}
这里的0-5是给每一个分词进行了编码
上面的实验中,对于一个由字符串构成的数组,每个元素可能是一个以空格分割的句子(sentence),CountVectorizer.fit的功能是将它们分割,为每一个单词(word)编码,在这个过程中会自动滤除停止词(stop words),例如英文句子中的”a”,”.”之类的长度为1的字符串。接下来,CountVectorizer.transform的功能则是将输入的数组中每个元素进行分割,然后使用fit中生成的编码字典,将原单词转化成编码,数据以csr_matrix的形式返回。
#使用.transform功能
bag_of_words = vect.transform(cn)
print('转化为词袋的特征:\n{}'.format(repr(bag_of_words)))
print(bag_of_words)
print('词袋的密度表达:\n{}'.format(bag_of_words.toarray()))
转化为词袋的特征:
<1x6 sparse matrix of type ''
with 6 stored elements in Compressed Sparse Row format>
(0, 0) 1
(0, 1) 1
(0, 2) 1
(0, 3) 1
(0, 4) 1
(0, 5) 1
词袋的密度表达:
[[1 1 1 1 1 1]]
词袋的特征变成了一个numpy数组
打印词袋:每一个编码的计数情况
词袋的密度表达就只打印计数情况
但是词袋模型的一个缺点是只记录各个分词的数量,忽略文本的词序列,那么比如'道士看见和尚亲吻了尼姑的嘴唇’,‘尼姑看见道士的嘴唇亲吻了和尚’最后的统计结果会一样,为了处理这个问题,我们需要对词袋模型进行优化
#导入结巴分词工具
import jieba
#导入文本数据(注意这里是文本元组)
text_data1 = ('道士看见和尚亲吻了尼姑的嘴唇')
text_data2 = ('尼姑看见道士的嘴唇亲吻了和尚')
#用结巴分词对中文文本进行分词
text_data1 = jieba.cut(text_data1)
text_data2 = jieba.cut(text_data2)
#使用空格作为词与词之间的分界线
text_data1 = [' '.join(text_data1)]
text_data2 = [' '.join(text_data2)]
#打印分词后结果
print('text_data1分词后结果:{}'.format(text_data1))
print('text_data2分词后结果:{}'.format(text_data2))
#用CountVectorizer算法提取文本特征---传入CountVectorizer方法
vect = CountVectorizer()
#用CountVectorizer算法提取文本特征---用.fit方法拟合分词,为每一个分词进行编码
cv1 = vect.fit(text_data1)
cv2 = vect.fit(text_data2)
#用CountVectorizer算法提取文本特征---根据编码,用.transform转换成数组
joke_feature_1 = cv1.transform(text_data1)
joke_feature_2 = cv2.transform(text_data2)
#打印分词数组的统计结果
print('joke_feature_1特征表达:{}'.format(joke_feature_1.toarray()))
print('joke_feature_2特征表达:{}'.format(joke_feature_2.toarray()))
#用CountVectorizer算法提取文本特征,并使用ngram_range参数关注词序---传入CountVectorizer方法
vect = CountVectorizer(ngram_range=(2,2))
#用CountVectorizer算法提取文本特征---用.fit方法拟合分词,为每一个分词进行编码
cv11 = vect.fit(text_data1)
cv22 = vect.fit(text_data2)
#用CountVectorizer算法提取文本特征---根据编码,用.transform转换成数组
joke_feature_11 = cv11.transform(text_data1)
joke_feature_22 = cv22.transform(text_data2)
#打印分词数组的统计结果
print('joke_feature_11特征表达:{}'.format(joke_feature_11.toarray()))
print('joke_feature_22特征表达:{}'.format(joke_feature_22.toarray()))
text_data1分词后结果:['道士 看见 和尚 亲吻 了 尼姑 的 嘴唇']
text_data2分词后结果:['尼姑 看见 道士 的 嘴唇 亲吻 了 和尚']
joke_feature_1特征表达:[[1 1 1 1 1 1]]
joke_feature_2特征表达:[[1 1 1 1 1 1]]
joke_feature_11特征表达:[[0 0 0 0 0]]
joke_feature_22特征表达:[[1 1 1 1 1]]
TF-IDF(term frequency–inverse document frequency)是一种用于信息检索与数据挖掘的常用加权技术。TF意思是词频(Term Frequency),IDF意思是逆文本频率指数(Inverse Document Frequency)。TF-IDF是一种统计方法,用以评估一字词对于一个文件集或一个语料库中的其中一份文件的重要程度。字词的重要性随着它在文件中出现的次数成正比增加,但同时会随着它在语料库中出现的频率成反比下降。
TFIDF的主要思想是:如果某个词或短语在一篇文章中出现的频率TF高,并且在其他文章中很少出现,则认为此词或者短语具有很好的类别区分能力,适合用来分类。
例子:有很多不同的数学公式可以用来计算TF-IDF。这边的例子以公式来计算。词频 (TF) 是一词语出现的次数除以该文件的总词语数。假如一篇文件的总词语数是100个,而词语“母牛”出现了3次,那么“母牛”一词在该文件中的词频就是3/100=0.03。一个计算文件频率 (IDF) 的方法是文件集里包含的文件总数除以测定有多少份文件出现过“母牛”一词。所以,如果“母牛”一词在1,000份文件出现过,而文件总数是10,000,000份的话,其逆向文件频率就是 lg(10,000,000 / 1,000)=4。最后的TF-IDF的分数为0.03 * 4=0.12。
##方法1
from sklearn.feature_extraction.text import TfidfTransformer
from sklearn.feature_extraction.text import CountVectorizer
data=['this is the first document','this is the second document','and the third on','is this the first document?']
words=CountVectorizer().fit_transform(data)
tfidf1=TfidfTransformer().fit_transform(words)
print(tfidf1)
print('/n')
##方法2
from sklearn.feature_extraction.text import TfidfVectorizer
tfidf2=TfidfVectorizer().fit_transform(data)
print(tfidf2)
(0, 8) 0.4387767428592343 (0, 6) 0.35872873824808993 (0, 3) 0.4387767428592343 (0, 2) 0.5419765697264572 (0, 1) 0.4387767428592343 (1, 8) 0.4041289471327509 (1, 6) 0.3304018949358262 (1, 5) 0.6331460890591821 (1, 3) 0.4041289471327509 (1, 1) 0.4041289471327509 (2, 7) 0.5528053199908667 (2, 6) 0.2884767487500274 (2, 4) 0.5528053199908667 (2, 0) 0.5528053199908667 (3, 8) 0.4387767428592343 (3, 6) 0.35872873824808993 (3, 3) 0.4387767428592343 (3, 2) 0.5419765697264572 (3, 1) 0.4387767428592343
TF-IDF是非常常用的文本挖掘的预处理几本步骤,使用TF-IDF并进行标准化后,就可以使用各个文本的词特征向量作文文本的特征,进行分类或者聚类分析。
另外一个python工具包---NLTK;
关注话题建模和文档聚类;
word2vec库;
很多学者使用Tensorflow建立循环神经网络在自然语言处理方面取得了重大突破。