应用scikit-learn做文本分类

http://blog.csdn.net/abcjennifer/article/details/23615947

文本挖掘的paper没找到统一的benchmark,只好自己跑程序,走过路过的前辈如果知道20newsgroups或者其它好用的公共数据集的分类(最好要所有类分类结果,全部或取部分特征无所谓)麻烦留言告知下现在的benchmark,万谢!

嗯,说正文。20newsgroups官网上给出了3个数据集,这里我们用最原始的20news-19997.tar.gz

分为以下几个过程:

  • 加载数据集
  • 提feature
  • 分类
    • Naive Bayes
    • KNN
    • SVM
  • 聚类

说明: scipy官网上有参考,但是看着有点乱,而且有bug。本文中我们分块来看。

Environment:Python 2.7 + Scipy (scikit-learn)

1.加载数据集

20news-19997.tar.gz下载数据集,解压到scikit_learn_data文件夹下,加载数据,详见code注释。

[python] view plaincopy

  1. #first extract the 20 news_group dataset to /scikit_learn_data
  2. from sklearn.datasets import fetch_20newsgroups
  3. #all categories
  4. #newsgroup_train = fetch_20newsgroups(subset=‘train‘)
  5. #part categories
  6. categories = [‘comp.graphics‘,
  7. ‘comp.os.ms-windows.misc‘,
  8. ‘comp.sys.ibm.pc.hardware‘,
  9. ‘comp.sys.mac.hardware‘,
  10. ‘comp.windows.x‘];
  11. newsgroup_train = fetch_20newsgroups(subset = ‘train‘,categories = categories);

可以检验是否load好了:

[python] view plaincopy

  1. #print category names
  2. from pprint import pprint
  3. pprint(list(newsgroup_train.target_names))

结果:

[‘comp.graphics‘,
 ‘comp.os.ms-windows.misc‘,
 ‘comp.sys.ibm.pc.hardware‘,
 ‘comp.sys.mac.hardware‘,
 ‘comp.windows.x‘]

2. 提feature:

刚才load进来的newsgroup_train就是一篇篇document,我们要从中提取feature,即词频啊神马的,用fit_transform

Method 1. HashingVectorizer,规定feature个数

[python] view plaincopy

  1. #newsgroup_train.data is the original documents, but we need to extract the
  2. #feature vectors inorder to model the text data
  3. from sklearn.feature_extraction.text import HashingVectorizer
  4. vectorizer = HashingVectorizer(stop_words = ‘english‘,non_negative = True,
  5. n_features = 10000)
  6. fea_train = vectorizer.fit_transform(newsgroup_train.data)
  7. fea_test = vectorizer.fit_transform(newsgroups_test.data);
  8. #return feature vector ‘fea_train‘ [n_samples,n_features]
  9. print ‘Size of fea_train:‘ + repr(fea_train.shape)
  10. print ‘Size of fea_train:‘ + repr(fea_test.shape)
  11. #11314 documents, 130107 vectors for all categories
  12. print ‘The average feature sparsity is {0:.3f}%‘.format(
  13. fea_train.nnz/float(fea_train.shape[0]*fea_train.shape[1])*100);

结果:

Size of fea_train:(2936, 10000)
Size of fea_train:(1955, 10000)
The average feature sparsity is 1.002%

因为我们只取了10000个词,即10000维feature,稀疏度还不算低。而实际上用TfidfVectorizer统计可得到上万维的feature,我统计的全部样本是13w多维,就是一个相当稀疏的矩阵了。

**************************************************************************************************************************

上面代码注释说TF-IDF在train和test上提取的feature维度不同,那么怎么让它们相同呢?有两种方法:

Method 2. CountVectorizer+TfidfTransformer

让两个CountVectorizer共享vocabulary:

[python] view plaincopy

  1. #----------------------------------------------------
  2. #method 1:CountVectorizer+TfidfTransformer
  3. print ‘*************************\nCountVectorizer+TfidfTransformer\n*************************‘
  4. from sklearn.feature_extraction.text import CountVectorizer,TfidfTransformer
  5. count_v1= CountVectorizer(stop_words = ‘english‘, max_df = 0.5);
  6. counts_train = count_v1.fit_transform(newsgroup_train.data);
  7. print "the shape of train is "+repr(counts_train.shape)
  8. count_v2 = CountVectorizer(vocabulary=count_v1.vocabulary_);
  9. counts_test = count_v2.fit_transform(newsgroups_test.data);
  10. print "the shape of test is "+repr(counts_test.shape)
  11. tfidftransformer = TfidfTransformer();
  12. tfidf_train = tfidftransformer.fit(counts_train).transform(counts_train);
  13. tfidf_test = tfidftransformer.fit(counts_test).transform(counts_test);

结果:

*************************

CountVectorizer+TfidfTransformer
*************************
the shape of train is (2936, 66433)
the shape of test is (1955, 66433)

Method 3. TfidfVectorizer

让两个TfidfVectorizer共享vocabulary:

[python] view plaincopy

  1. #method 2:TfidfVectorizer
  2. print ‘*************************\nTfidfVectorizer\n*************************‘
  3. from sklearn.feature_extraction.text import TfidfVectorizer
  4. tv = TfidfVectorizer(sublinear_tf = True,
  5. max_df = 0.5,
  6. stop_words = ‘english‘);
  7. tfidf_train_2 = tv.fit_transform(newsgroup_train.data);
  8. tv2 = TfidfVectorizer(vocabulary = tv.vocabulary_);
  9. tfidf_test_2 = tv2.fit_transform(newsgroups_test.data);
  10. print "the shape of train is "+repr(tfidf_train_2.shape)
  11. print "the shape of test is "+repr(tfidf_test_2.shape)
  12. analyze = tv.build_analyzer()
  13. tv.get_feature_names()#statistical features/terms

结果:

*************************
TfidfVectorizer
*************************
the shape of train is (2936, 66433)
the shape of test is (1955, 66433)

此外,还有sklearn里封装好的抓feature函数,fetch_20newsgroups_vectorized

Method 4. fetch_20newsgroups_vectorized

但是这种方法不能挑出几个类的feature,只能全部20个类的feature全部弄出来:

[python] view plaincopy

  1. print ‘*************************\nfetch_20newsgroups_vectorized\n*************************‘
  2. from sklearn.datasets import fetch_20newsgroups_vectorized
  3. tfidf_train_3 = fetch_20newsgroups_vectorized(subset = ‘train‘);
  4. tfidf_test_3 = fetch_20newsgroups_vectorized(subset = ‘test‘);
  5. print "the shape of train is "+repr(tfidf_train_3.data.shape)
  6. print "the shape of test is "+repr(tfidf_test_3.data.shape)

结果:

*************************
fetch_20newsgroups_vectorized
*************************
the shape of train is (11314, 130107)
the shape of test is (7532, 130107)

3. 分类

3.1 Multinomial Naive Bayes Classifier

见代码&comment,不解释

[python] view plaincopy

  1. ######################################################
  2. #Multinomial Naive Bayes Classifier
  3. print ‘*************************\nNaive Bayes\n*************************‘
  4. from sklearn.naive_bayes import MultinomialNB
  5. from sklearn import metrics
  6. newsgroups_test = fetch_20newsgroups(subset = ‘test‘,
  7. categories = categories);
  8. fea_test = vectorizer.fit_transform(newsgroups_test.data);
  9. #create the Multinomial Naive Bayesian Classifier
  10. clf = MultinomialNB(alpha = 0.01)
  11. clf.fit(fea_train,newsgroup_train.target);
  12. pred = clf.predict(fea_test);
  13. calculate_result(newsgroups_test.target,pred);
  14. #notice here we can see that f1_score is not equal to 2*precision*recall/(precision+recall)
  15. #because the m_precision and m_recall we get is averaged, however, metrics.f1_score() calculates
  16. #weithed average, i.e., takes into the number of each class into consideration.

注意我最后的3行注释,为什么f1≠2*(准确率*召回率)/(准确率+召回率)

其中,函数calculate_result计算f1:

[python] view plaincopy

  1. def calculate_result(actual,pred):
  2. m_precision = metrics.precision_score(actual,pred);
  3. m_recall = metrics.recall_score(actual,pred);
  4. print ‘predict info:‘
  5. print ‘precision:{0:.3f}‘.format(m_precision)
  6. print ‘recall:{0:0.3f}‘.format(m_recall);
  7. print ‘f1-score:{0:.3f}‘.format(metrics.f1_score(actual,pred));

3.2 KNN:

[python] view plaincopy

  1. ######################################################
  2. #KNN Classifier
  3. from sklearn.neighbors import KNeighborsClassifier
  4. print ‘*************************\nKNN\n*************************‘
  5. knnclf = KNeighborsClassifier()#default with k=5
  6. knnclf.fit(fea_train,newsgroup_train.target)
  7. pred = knnclf.predict(fea_test);
  8. calculate_result(newsgroups_test.target,pred);

3.3 SVM:

[cpp] view plaincopy

  1. ######################################################
  2. #SVM Classifier
  3. from sklearn.svm import SVC
  4. print ‘*************************\nSVM\n*************************‘
  5. svclf = SVC(kernel = ‘linear‘)#default with ‘rbf‘
  6. svclf.fit(fea_train,newsgroup_train.target)
  7. pred = svclf.predict(fea_test);
  8. calculate_result(newsgroups_test.target,pred);

结果:

*************************

Naive Bayes
*************************
predict info:
precision:0.764
recall:0.759
f1-score:0.760
*************************
KNN
*************************
predict info:
precision:0.642
recall:0.635
f1-score:0.636
*************************
SVM
*************************
predict info:
precision:0.777
recall:0.774
f1-score:0.774

4. 聚类

[cpp] view plaincopy

  1. ######################################################
  2. #KMeans Cluster
  3. from sklearn.cluster import KMeans
  4. print ‘*************************\nKMeans\n*************************‘
  5. pred = KMeans(n_clusters=5)
  6. pred.fit(fea_test)
  7. calculate_result(newsgroups_test.target,pred.labels_);

结果:

*************************
KMeans
*************************
predict info:
precision:0.264
recall:0.226
f1-score:0.213

本文全部代码下载:在此

貌似准确率好低……那我们用全部特征吧……结果如下:

*************************
Naive Bayes
*************************
predict info:
precision:0.771
recall:0.770
f1-score:0.769
*************************
KNN
*************************
predict info:
precision:0.652
recall:0.645
f1-score:0.645
*************************
SVM
*************************
predict info:
precision:0.819
recall:0.816
f1-score:0.816
*************************
KMeans
*************************
predict info:
precision:0.289
recall:0.313
f1-score:0.266

关于Python更多的学习资料将继续更新,敬请关注本博客和新浪微博Rachel Zhang

时间: 2024-08-24 21:26:22

应用scikit-learn做文本分类的相关文章

《机器学习系统设计》之应用scikit-learn做文本分类(下)

前言: 本系列是在作者学习<机器学习系统设计>([美] WilliRichert)过程中的思考与实践,全书通过Python从数据处理,到特征工程,再到模型选择,把机器学习解决问题的过程一一呈现.书中设计的源代码和数据集已上传到我的资源:http://download.csdn.net/detail/solomon1558/8971649 第3章通过词袋模型+K均值聚类实现相关文本的匹配.本文主要讲解K-均值聚类相关知识以及在20newsgroup数据集上使用K-均值聚类进行测试.     相关

《机器学习系统设计》之应用scikit-learn做文本分类(上)

前言: 本系列是在作者学习<机器学习系统设计>([美] WilliRichert)过程中的思考与实践,全书通过Python从数据处理,到特征工程,再到模型选择,把机器学习解决问题的过程一一呈现.书中设计的源代码和数据集已上传到我的资源:http://download.csdn.net/detail/solomon1558/8971649 第3章通过词袋模型+K均值聚类实现相关文本的匹配.本文主要讲解文本预处理部分内容,涉及切分文本.数据清洗.计算TF-IDF值等内容. 1. 统计词语 使用一个

如何使用“预训练的词向量”,做文本分类

不多比比了,看代码!!! def train_W2V(w2vCorpus, size=100): w2vModel = Word2Vec(sentences=w2vCorpus, hs=0, negative=5, min_count=5, window=8, iter=1, size=size) w2vModel.save(inPath+'w2vModel.model') return w2vModel def load_W2V(W2V_path, loader_mySelf=1): if l

Tensorflor实现文本分类

Tensorflor实现文本分类 下面我们使用CNN做文本分类 cnn实现文本分类的原理 下图展示了如何使用cnn进行句子分类.输入是一个句子,为了使其可以进行卷积,首先需要将其转化为向量表示,通常使用word2vec实现.d=5表示每个词转化为5维的向量,矩阵的形状是[sentence_length × 5],即[7 ×5].6个filter(卷积核),与图像中使用的卷积核不同的是,nlp使用的卷积核的宽与句子矩阵的宽相同,只是长度不同.这里有(2,3,4)三种size,每种size有两个fi

基于协同训练的半监督文本分类算法

标签: 半监督学习,文本分类 作者:炼己者 --- 本博客所有内容以学习.研究和分享为主,如需转载,请联系本人,标明作者和出处,并且是非商业用途,谢谢! 如果大家觉得格式看着不舒服,也欢迎大家去看我的简书 半监督学习文本分类系列 用半监督算法做文本分类(sklearn) sklearn半监督学习(sklearn) 基于自训练的半监督文本分类算法 一. 摘要 本文主要讲述基于协同训练的半监督算法做文本分类,用三个差异性比较大的分类器对未标注数据进行标注,它们可以进行交叉验证,大大提升了对未标注数据

文本分类:survey

作者:尘心链接:https://zhuanlan.zhihu.com/p/76003775 简述 文本分类在文本处理中是很重要的一个模块,它的应用也非常广泛,比如:垃圾过滤,新闻分类,词性标注等等.它和其他的分类没有本质的区别,核心方法为首先提取分类数据的特征,然后选择最优的匹配,从而分类.但是文本也有自己的特点,根据文本的特点,文本分类的一般流程为:1.预处理:2.文本表示及特征选择:3.构造分类器:4.分类. 通常来讲,文本分类任务是指在给定的分类体系中,将文本指定分到某个或某几个类别中.被

广告行业中那些趣事系列2:BERT实战NLP文本分类任务(附github源码)

摘要:上一篇广告中那些趣事系列1:广告统一兴趣建模流程,我们了解了如何为广告主圈人群以及如何刻画用户的兴趣度.要想给用户打标签,我们需要构建数据源和标签的关联,也就是item-tag.针对数量较少的app数据源我们可以使用人工打标的方式来识别,但是对于news.用户query等数量较多的数据源则需要通过机器学习模型来进行打标.实际项目中我们使用NLP中鼎鼎大名的BERT模型来进行文本分类. 通过本篇学习,小伙伴们可以迅速上手BERT模型用于文本分类任务.对数据挖掘.数据分析和自然语言处理感兴趣的

scikit learn 模块 调参 pipeline+girdsearch 数据举例:文档分类

scikit learn 模块 调参 pipeline+girdsearch 数据举例:文档分类数据集 fetch_20newsgroups #-*- coding: UTF-8 -*- import numpy as np from sklearn.pipeline import Pipeline from sklearn.linear_model import SGDClassifier from sklearn.grid_search import GridSearchCV from sk

R语言做文本挖掘 Part4文本分类

Part4文本分类 Part3文本聚类提到过.与聚类分类的简单差异. 那么,我们需要理清训练集的分类,有明白分类的文本:測试集,能够就用训练集来替代.预測集,就是未分类的文本.是分类方法最后的应用实现. 1.       数据准备 训练集准备是一个非常繁琐的功能,临时没发现什么省力的办法,依据文本内容去手动整理.这里还是使用的某品牌的官微数据,依据微博内容.我将它微博的主要内容分为了:促销资讯(promotion).产品推介(product).公益信息(publicWelfare).生活鸡汤(l