NLP学习1——文本分类(spacy的初步使用)

本文学习自这篇文章

import spacyfrom sklearn.datasets 
import fetch_20newsgroupsfrom sklearn.pipeline 
import Pipeline
import numpy as np
# 下载数据集,20个类别
twenty_train = fetch_20newsgroups(subset='train', shuffle=True, download_if_missing=True)  
twenty_test = fetch_20newsgroups(subset='test', shuffle=True, download_if_missing=True)

from sklearn.feature_extraction.text import CountVectorizer
count_vect = CountVectorizer()
X_train_counts = count_vect.fit_transform(twenty_train.data)   # 创建词袋模型
print(f'Shape of Term Frequency Matrix: {X_train_counts.shape}')  # 输出词频矩阵
	# Shape of Term Frequency Matrix: (11314, 130107)

关于词袋模型的解释:
首先给出两个句子:1.“The cat sat on the hat”
2.“The dog ate the cat and the hat”
然后提取出词汇表:{ the, cat, sat, on, hat, dog, ate, and }
于是第一个句子的词袋模型就是:{ 2, 1, 1, 1, 1, 0, 0, 0 },它的意义是词汇表中的每个单词在句子中出现的次数,例如the在第一个句子中出现了2次,所以词袋模型的第一个位置就是2。类似可以得到第二个句子的词袋模型。

from sklearn.feature_extraction.text import TfidfTransformer
tfidf_transformer = TfidfTransformer()
X_train_tfidf = tfidf_transformer.fit_transform(X_train_counts) # TF-IDF算法对词进行加权
print(f'Shape of TFIDF Matrix: {X_train_tfidf.shape}')
	# Shape of TFIDF Matrix: (11314, 130107)

TF-IDF算法:
在一个大型的文本语料库中,一些单词会非常常见(例如英语中的“the”、“a”、“is”),而对于文档的实际内容来说,它们几乎没有什么有意义的信息。这样的词在上面是描述的词袋模型中,出现次数多,所占比重就多,所以TF-IDF算法就是要尽可能降低这些词的比重。以下结合TfidfTransformer()方法描述该算法,首先我们知道了通过CountVectorizer()方法得出一个词频矩阵,行代表文本个数 d d d,列代表词的个数 t t t,则,
t f i d f ( t , d ) = t f ( t , d ) × i d f ( t ) tfidf(t,d)=tf(t,d)\times idf(t) tfidf(t,d)=tf(t,d)×idf(t)
其中, t f ( t , d ) tf(t,d) tf(t,d)是第 t t t个词在第 d d d个文本中出现的次数,也即词频矩阵中的某个数。 i d f ( t ) idf(t) idf(t)计算如下,当TfidfTransformer(norm=‘l2’, use_idf=True, smooth_idf=True, sublinear_tf=False)时,
i d f ( t ) = l o g n 1 + d f ( t ) idf(t)=log\frac{n}{1+df(t)} idf(t)=log1+df(t)n
其中 d f ( t ) df(t) df(t)是第t个词在整个语料库中出现的次数,比如上面的两个句子(给出的语料库只有两个句子)中,以the为例,它在两个句子中都出现了(不考虑它在某个句子中出现的次数),则 d f ( t ) = 2 df(t)=2 df(t)=2
当smooth_idf=False时,
i d f ( t ) = l o g n d f ( t ) + 1 idf(t)=log\frac{n}{df(t)}+1 idf(t)=logdf(t)n+1
最后计算完成后,要计算每个文本的L2范数,
v n o r m = [ v 1 , v 2 , . . . , v t ] v 1 2 + v 2 2 + . . . + v t 2 v_{norm}=\frac{[v_1, v_2,...,v_t]}{\sqrt{v_1^2+v_2^2+...+v_t^2}} vnorm=v12+v22+...+vt2 [v1,v2,...,vt]
即把词频矩阵中每一行的词经过TF-IDF运算后在进行L2范数计算,最后求出最终的tf-idf矩阵。

from sklearn.naive_bayes import MultinomialNB
# 用朴素贝叶斯法训练模型
clf = MultinomialNB().fit(X_train_tfidf, twenty_train.target)

下面介绍一种方法可以将以上过程结合起来,

text_nb_clf = Pipeline([('vect', CountVectorizer()), ('tfidf', TfidfTransformer()), ('clf', MultinomialNB())])
text_nb_clf = text_nb_clf.fit(twenty_train.data, twenty_train.target)

测试模型

predicted = text_nb_clf.predict(twenty_test.data)
naivebayes_clf_accuracy = np.mean(predicted == twenty_test.target) * 100.
	# Test Accuracy is 77.38980350504514 %

下面介绍一下spacy的一些使用方法,

nlp = spacy.load('en')  # 加载语言模型'en'
from spacy.lang.en.stop_words import STOP_WORDS  # 加载停用词    
doc = nlp("I am learning the most important ideas Natural Language Processing ideas using Python")  # 将字符串转换为文档    
for token in doc:  # 对文档进行分词
    print(token)
    	# I
	# am
	# learning
	# the
	# most
	# important
	# ideas
	# Natural
	# Language
	# Processing
	# ideas
	# using
	# Python    
simplified_doc = [token for token in doc if not token.is_punct | token.is_stop]
	# 去除停用词和标点符号以后的词
# 构建分词器	    
from spacy.lang.en import English
tokenizer = English().Defaults.create_tokenizer(nlp)
def spacy_tokenizer(document):
    return [token.orth_ for token in tokenizer(document)]
    # token.orth_属性可以保留标点符号
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值