您的位置:首页 > 其它

特征抽取(复习14)

2018-01-20 17:51 176 查看
本文是个人学习笔记,内容主要基于DictVectorizer对字典存储的数据进行特征抽取和向量化,对sklearn内置的fetch_20newsgroups——新闻数据抓取器从互联网上即时下载的新闻文本数据进行去停用词、构建词表、CountVectorizer和TfidfVectorizer词向量化等处理后,再利用MultinomialNB分类器进行多类分类。

前面的实验都是从标准的训练数据中,依靠学习器的默认配置学习到模型的参数,然后利用这组参数构建的模型在测试数据集上进行测试,最后对模型的表现性能进行评价。这么做不能保证:(1)所有用于训练的数据特征都是最好的(2)学习得到的参数一定是最优的(3)默认配置下的模型总是最佳的。

对症下药,可以从以下角度对模型进行性能提升:对数据预处理、控制参数训练、优化模型配置。

对数据的预处理包括:(a.)对数据特征的抽取——将原始数据逐条转化为特征向量,这个过程同时涉及对数据特征的量化表示;(b.)对数据特征的筛选——在高维度、已量化的特征向量中,选择对指定任务更有效的特征组合,进一步提升模型性能。

原始数据的种类:数字化的信号数据(声纹、图像),符号化的文本。要想利用文本信息进行计算,需要将文本预先进行向量化处理。

(一)DictVectorizer对字典存储的数据进行特征抽取和向量化

measurements=[{'city':'Dubai','temperature':33.},{'city':'London','temperature':12.},
{'city':'San Fransisco','temperature':18.}]

from sklearn.feature_extraction import DictVectorizer
vec=DictVectorizer()   #初始化DictVectorizer()特征抽取器
print(vec.fit_transform(measurements).toarray())   #输出转化后的特征矩阵
print(vec.get_feature_names())   #输出各个维度特征含义




DictVectorizer()特征抽取器对类别型特征进行了one-hot处理,对数值型特征没做进一步处理。

(二)一些更原始的文本数据,几乎没使用特殊的数据结构进行存储,只是一系列字符串。比较常用的文本特征表示方法是词袋法(Bag of Words)。即不考虑词语出现的顺序,只是将训练文本中的每个出现过的词单独视作一列特征,将这种不重复的词汇集合成为词表(Vocabulary),基于词表,每条训练文本都可以在高维度的词表上映射出一个特征向量

特征数值化的两种计算方法:(a.)CountVectorizer——每个词(Term)在该训练文本中出现的频率(Term Frequency);(b.)TfidfVectorizer——除了考量某一词汇在当前文本中出现的频率(Term Frequency)外,还要关注包含这个词汇的文本条数的倒数(Inverse Document Frequency)。训练文本的条目越多,TfidfVectorizer这种特征量化的方式就更有优势,因为计算词频(Term Frequency)的目的在于找出对所在文本的含义更有贡献的重要词汇,如果一个词几乎在每篇文章中都出现,说明这个词是常用词,不会帮助模型对文本进行分类。此外,在每条文本中都出现的常用词汇成为停用词(Stop Words),停用词在文本特征抽取时需要过滤掉。

from sklearn.datasets import fetch_20newsgroups
news=fetch_20newsgroups(subset='all')


from sklearn.cross_validation import train_test_split
X_train,X_test,y_train,y_test=train_test_split(news.data,news.target,test_size=0.25,random_state=33)


from sklearn.feature_extraction.text import CountVectorizer
count_vec=CountVectorizer()   #默认形式初始化词频统计器(不去停用词)
X_count_train=count_vec.fit_transform(X_train)
X_count_test=count_vec.transform(X_test)

from sklearn.naive_bayes import MultinomialNB
mnb_count=MultinomialNB()
mnb_count.fit(X_count_train,y_train)   #用朴素贝叶斯分类器对词频统计器(不去停用词)处理后的样本进行参数学习
print('The accuracy of classifying 20newsgroups using Naive Bayes(CountVectorizer without filtering stopwords):',
mnb_count.score(X_count_test,y_test))

y_count_predict=mnb_count.predict(X_count_test)
from sklearn.metrics import classification_report
print(classification_report(y_test,y_count_predict,target_names=news.target_names))




from sklearn.feature_extraction.text import TfidfVectorizer
tfidf_vec=TfidfVectorizer()   #默认形式初始化tfidf统计器(不去停用词)
X_tfidf_train=tfidf_vec.fit_transform(X_train)
X_tfidf_test=tfidf_vec.transform(X_test)

mnb_tfidf=MultinomialNB()
mnb_tfidf.fit(X_tfidf_train,y_train)   #用朴素贝叶斯分类器对tfidf统计器(不去停用词)处理后的样本进行参数学习
print('The accuracy of classifying 20news with Naive Bayes(TfidfVectorizer without filtering stopwords):',
mnb_tfidf.score(X_tfidf_test,y_test))

y_tfidf_predict=mnb_tfidf.predict(X_tfidf_test)
print(classification_report(y_test,y_tfidf_predict,target_names=news.target_names))
#在训练文本量较多的时候,利用TfidfVectorizer压制一些常用词汇对分类决策的干扰




count_filter_vec=CountVectorizer(analyzer='word',stop_words='english')   #初始化词频统计器(去停用词)
X_count_filter_train=count_filter_vec.fit_transform(X_train)
X_count_filter_test=count_filter_vec.transform(X_test)

mnb_count_filter=MultinomialNB()
mnb_count_filter.fit(X_count_filter_train,y_train)
print('The accuarcy of classifying 20newsgroups using Naive Bayes(CountVetorizer by filtering stopwords):',
mnb_count_filter.score(X_count_filter_test,y_test))

y_count_filter_predict=mnb_count_filter.predict(X_count_filter_test)
from sklearn.metrics import classification_report
print(classification_report(y_test,y_count_filter_predict,target_names=news.target_names))




tfidf_filter_vec=TfidfVectorizer(analyzer='word',stop_words='english')   #初始化tfidf统计器(去停用词)
X_tfidf_filter_train=tfidf_filter_vec.fit_transform(X_train)
X_tfidf_filter_test=tfidf_filter_vec.transform(X_test)

mnb_tfidf_filter=MultinomialNB()
mnb_tfidf_filter.fit(X_tfidf_filter_train,y_train)
print('The accuracy of classifying 20newsgroups with Naive Bayes(TfidfVectorizer by filtering stopwords):',
mnb_tfidf_filter.score(X_tfidf_filter_test,y_test))

y_tfidf_filter_predict=mnb_tfidf_filter.predict(X_tfidf_filter_test)
print(classification_report(y_test,y_tfidf_filter_predict,target_names=news.target_names))




从上述实验结果可见,对停用词进行过滤的文本特征抽取方法,平均比不过滤停用词的模型综合性能高出3%~4%。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: