特征提升之特征抽取

来源:互联网 发布:矩阵理论 张跃辉答案 编辑:程序博客网 时间:2024/05/16 15:02
之前都是一旦确定使用某个模型,程序库就可以帮助我们从标准的训练数据中,依靠默认的配置学习到模型所需要的参数,然后利用这组得来的参数指导模型在测试数据集上进行预测,进而对模型的表现性能进行评价。
这套方案不能保证:
1)所有用于训练的数据特征都是最好的
2)学习得到的参数一定是最优的
3)默认配置下的模型总是最佳的
所以,可以从多个角度对前面所使用过的模型进行性能提升,包括预处理数据/控制参数训练以及优化模型配置等方法。

下面介绍 特征抽取:
原始数据的种类很多,除了数字化的信号数据(声纹,图像),还有大量的符号化的文本。但是,无法直接将符号化的文字本身用于计算任务,而是需要通过某些处理手段,预先将文本量化为特征向量。
有些用符号表示的数据特征已经相对结构化,并且以字典的数据结构进行存储。这时,用DictVectorizer对特征进行抽取和向量化。
Python源码:
#coding=utf-8from sklearn.feature_extraction import DictVectorizermeasurements=[{'city':'Dubai','temperature':'33.'},{'city':'London','temperature':'12.'},{'city':'San Fransisco','temperature':'18.'}]vec=DictVectorizer()print vec.fit_transform(measurements).toarray()print vec.get_feature_names()

Result:



可以看到,DictVectorizer对于类别型(Categorical)与数值型(Numerical)特征的处理方式有很大差异。数值型特征转化一般维持原始特征值。类别型特征无法直接数字化表示,因此需要借助原特征的名称,组合产生新的特征,并采用0/1的二值方式进行量化。
一些文本数据表现得更原始,几乎没有使用特殊的数据结构进行存储,只是一系列字符串。处理这些特征常用的文本特征表示方法为词袋法(Bag of Words):不考虑词语出现的顺序,只是将训练文本中的每个出现过的词汇单词视作一列特征。称这些不重复的词汇集合为词表(Vocabulary),每条训练文本都可以在高纬度的词表上映射出一个特征向量。而特征数值的常见计算方式有两种,分别是CountVectorizer和TfidfVectortizer。对于每一条训练文本,CountVectorizer只考虑每种词汇(Term)在该训练文本中出现的频率(Term Frequency)。而TfidfVectortizer除了考量某一词汇在当前文本中出现的频率之外,同时关注包含这个词汇的文本条数的倒数(Inverse Document Frequency)。相比之下,训练文本的数量越多,TfidfVectortizer这种特征量化方式更有优势。因为计算词频的目的在于找出所在文本的含义更有贡献的重要词汇。如果一个词汇几乎在每篇文本中出现,说明这是一个常用词汇,反而不会帮助模型对文本的分类;在训练文本量较多的时候,利用TfidfVectorizer压制这些常用词汇的对分类决策的干扰,往往可以起到提升模型性能的作用。

通常称这些在每条文本中都出现的常用词汇为停用词(Stop Words),如英文中的 the,a等。这些停用词在文本特征抽取中经常以黑名单的方式过滤掉,并且用来提高模型的性能表现。


下面重新对“20类新闻文本分类”问题进行分析处理,重点在于列举上述两种文本特征量化模型的使用方法,并比较性能差异。
Python源码:
#coding=utf-8from sklearn.datasets import fetch_20newsgroups#-------------from sklearn.cross_validation import train_test_split#---------------------------from sklearn.feature_extraction.text import CountVectorizer#-------------from sklearn.naive_bayes import MultinomialNB#-------------from sklearn.metrics import classification_report#---------------------------from sklearn.feature_extraction.text import TfidfVectorizer#-------------download data, subset='all' means download all datanews=fetch_20newsgroups(subset='all')#-------------split data#75% training set,25% testing setX_train,X_test,y_train,y_test=train_test_split(news.data,news.target,test_size=0.25,random_state=33)#-----------------------transfer data to vector  (default config won't clear english stop words)count_vec=CountVectorizer()X_count_train=count_vec.fit_transform(X_train)vectorizer_test = CountVectorizer(vocabulary=count_vec.vocabulary_)X_count_test = vectorizer_test.transform(X_test)#-------------training#initialize NB model with default configmnb_count=MultinomialNB()mnb_count.fit(X_count_train,y_train)#-------------performanceprint '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)print classification_report(y_test,y_count_predict,target_names=news.target_names)#-----------------------transfer data to vector  (default config won't clear english stop words)tfidf_vec=TfidfVectorizer()X_tfidf_train=tfidf_vec.fit_transform(X_train)X_tfidf_test=tfidf_vec.transform(X_test)#-------------trainingmnb_tfidf=MultinomialNB()mnb_tfidf.fit(X_tfidf_train,y_train)#-------------performanceprint 'The accuracy of classifying 20newsgroups 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)

Result:






在使用TfidfVectorizer而不去掉停用词的条件下,对训练和测试文本进行特征量化,并利用默认配置的朴素贝叶斯分类器,在测试文本上可以得到比CountVectorizer更加高的预测准确率。P,R和F1指标都得到提升,表明:训练文本量较多时,yongTfidfVectorizer压制这些常用词汇对分类决策的干扰,可以起到提升模型性能的作用

下面验证:停用词在文本特征抽取中经常以黑名单的方式过滤掉,并且用来提高模型的性能表现。
Python源码:
#coding=utf-8from sklearn.datasets import fetch_20newsgroups#-------------from sklearn.cross_validation import train_test_split#---------------------------from sklearn.feature_extraction.text import CountVectorizer#-------------from sklearn.naive_bayes import MultinomialNB#-------------from sklearn.metrics import classification_report#---------------------------from sklearn.feature_extraction.text import TfidfVectorizer#-------------from sklearn.metrics import classification_report#-------------download data, subset='all' means download all datanews=fetch_20newsgroups(subset='all')#-------------split data#75% training set,25% testing setX_train,X_test,y_train,y_test=train_test_split(news.data,news.target,test_size=0.25,random_state=33)#-----------------------transfer data to vector  (default config won't clear english stop words)#initialize with filtering stop wordscount_filter_vec,tfidf_filter_vec=CountVectorizer(analyzer='word',stop_words='english'),TfidfVectorizer(analyzer='word',stop_words='english')X_count_filter_train=count_filter_vec.fit_transform(X_train)#X_count_filter_test=count_filter_vec.fit_transform(X_test)  dimension mismatchcountVectorizer_test = CountVectorizer(vocabulary=count_filter_vec.vocabulary_)X_count_filter_test = countVectorizer_test.transform(X_test)X_tfidf_filter_train=tfidf_filter_vec.fit_transform(X_train)#X_tfidf_filter_test=tfidf_filter_vec.fit_transform(X_test)tfidfVectorizer_test = CountVectorizer(vocabulary=tfidf_filter_vec.vocabulary_)X_tfidf_filter_test = tfidfVectorizer_test.transform(X_test)mnb_count_filter=MultinomialNB()mnb_count_filter.fit(X_count_filter_train,y_train)print 'The accuracy of classifying 20newsgroups using Naive bayes(CountVectorizer with filtering stopwords):',mnb_count_filter.score(X_count_filter_test,y_test)y_count_filter_predict=mnb_count_filter.predict(X_count_filter_test)mnb_tfidf_filter=MultinomialNB()mnb_tfidf_filter.fit(X_tfidf_filter_train,y_train)print 'The accuracy of classifying 20newsgroups using Naive bayes(TfidfVectorizer with filtering stopwords):',mnb_tfidf_filter.score(X_count_filter_test,y_test)y_tfidf_filter_predict=mnb_count_filter.predict(X_tfidf_filter_test)print classification_report(y_test,y_count_filter_predict,target_names=news.target_names)print classification_report(y_test,y_tfidf_filter_predict,target_names=news.target_names)


 Result:




输出证明 TfidfVectorizer的特征抽取和量化方法更加具备优势,对比发现:对停用词进行过滤的文本特征抽取方法,平均比不过滤停用词的模型综合性能高出3%~4%





原创粉丝点击