websocketpp区分文件和文本_机器学习之文本分类项目

此项目针对20 Newgroups 的数据集进行分析研究,这是网上非常流行的对文本进行分类和聚类的数据集。

一、数据集特点分析

数据集中的数据分为两部分,一部分是用来训练算法模型的数据,一部分是用来评估算法的新数据。网站上还提供了3个数据集,这里采用 20news-bydate 这个数据进行项目研究。这个数据集是按照日期进行排序的,并去掉了部分重复数据和header,共包含18846个文档。

二、导入数据

导入项目所需的类库并使用scikit-learnloadfiles导入文档数据,文档是按照不同的分类分目录来保存的,文件目录名称即所属类别,文件目录结构如下图所示。

c6deb7bf5fda13d377386098121b5fd6.png

2.1  导入类库

导入在项目中将要使用的类库和方法。代码如下:

#导入类库from sklearn.datasets import load_filesfrom sklearn.feature_extraction.text import CountVectorizerfrom sklearn.feature_extraction.text import TfidfVectorizerfrom sklearn.linear_model import LogisticRegressionfrom sklearn.naive_bayes import MultinomialNBfrom sklearn.neighbors import KNeighborsClassifierfrom sklearn.svm import SVCfrom sklearn.tree import DecisionTreeClassifierfrom sklearn.metrics import classification_reportfrom sklearn.metrics import accuracy_scorefrom sklearn.model_selection import cross_val_scorefrom sklearn.model_selection import KFoldfrom sklearn.model_selection import GridSearchCVfrom sklearn.ensemble import AdaBoostClassifierfrom sklearn.ensemble import RandomForestClassifierfrom matplotlib import pyplot as plt

所有类库的导入确保无误方可进行下一步操作,若有错误提示,先纠错或检查编程环境配置以及类库安装是否有问题。

2.2  导入数据集

首先下载文本数据集,下载完成后,再保存在项目的统计目录中。数据集下载链接地址如下:http://www.qwone.com/~jason/20Newsgroups/ 

c05676162a2a1b7a20d302d20283e229.png

导入文档数据,代码如下:

#导入数据categories =['alt.atheism',             'rec.sport.hockey'             'comp.graphics',             'sci.crypt',             'comp.os.ms-windows.misc',             'sci.electronics',             'comp.sys.ibm.pc.hardware',             'sci.med',             'comp.sys.mac.hardware',             'sci.space',             'comp.windows.x',             'soc.religion.christian',             'misc.forsale',             'talk.politics.guns',             'rec.autos',             'talk.politics.mideast',             'rec.motorcycles',             'talk.politics.misc',             'rec.sport.baseball',             'talk.religion.misc']#导入训练数据train_path = '20news-bydate-train'dataset_train = load_files(container_path=train_path,categories=categories)#导入评估数据集test_path = '20news-bydate-test'dataset_test = load_files(container_path=test_path,categories=categories)

利用机器学习对文本进行分类,与对数值特征进行分类最大的区别是,对文本进行分类时要先提取文本特征,相对于之前的项目来说,提取到的文本特征属性的个数是巨大的,会有超过万个的特征属性,甚至会超过10万个。

三、文本特征提取

文本数据属于非结构化的数据,一般要转换成结构化的数据才能够通过机器学习算法进行文本分类。常见的做法是将文本转换成“文档-词项矩阵”,矩阵中的元素可以使用词频TF-IDF值等。

TF-IDF值是一种用于信息检索与数据挖掘的常用加权技术。TF的意思是词频(Term Frequency),IDF的意思是逆向文件频率(Inverse Document Frequency)。TF-IDF的主要思想是:如果一个词或者短语在一篇文章中出现的频率高,并且在其他文章中很少出现,则认为此词或短语具有很好的类别区分能力,适用于分类。TF-IDF实际上是TF*IDF。IDF的主要思想是:如果包含词条t的文档越少,也就是n越小,IDF越大,则说明词条t具有很好的类别区分能力。如果某一类文档C中包含词条t的文档数为m,而其他类包含t的文档总数为k,显然所有包含t的文档数n=m+k,当m大的时候,n也大,按照IDF公式得到的IDF的值小,这说明该词条能够很好地代表这个类的文本特征,这样的词条应该被赋予较高的权重,并将其作为该类文本的特征词,以区别于其他类文档。这就是IDF的不足之处,在一份给定的文件里,TF指的是某一个给定的词语在该文件中出现的频率,这是对词数(Term Count)的归一化,以防止它偏向长的文件。IDF是一个词语普遍重要性的度量,某一个特定词语的IDF,可以由总文件数目除以包含该词语的文件的数目,再将得到的商取对数得到。

在scikit-learn中提供了词频和TF-IDF来进行文本特征提取的实现,分别是CountVectorizer和TfidTransformer。下面对训练数据集分别进行词频和TF-IDF的计算。代码如下:

#数据准备与理解#计算词频count_vect = CountVectorizer(stop_words='english',decode_error='ignore')X_train_counts=count_vect.fit_transform(dataset_train.data)#查看数据维度print(X_train_counts.shape)

answer:

4acdc8b428a9317b95d0348041857b31.png

词频计算结果如上。

接下来计算一下TF-IDF,代码如下:

#计算TF-IDFtf_transformer = TfidfVectorizer(stop_words='english',decode_error='ignore')X_train_counts_tf = tf_transformer.fit_transform(dataset_train.data)#查看数据维度print(X_train_counts_tf.shape)

TF-IDF的计算结果如下:

1c898ec70d087066304b762bce31ebb7.png

这里通过两种方法进行了文本特征的提取,并且查看了数据维度,得到的数据维度还是非常巨大的。在后续的项目中,将使用TF-IDF进行分类模型的训练。因为,TF-IDF的数据维度巨大,并且自用提取的特征数据,进一步对数据进行分析的意义不大,因此只简单地查看数据维度的信息。接下来将进行算法评估。

四、评估算法

在这里将采用10折交叉验证来评估算法模型的准确度。10折交叉验证是随机地将数据分成10份:9份用来训练模型,1份用来评估算法。代码如下:

#设置评估算法的基准num_folds=10seed=7scoring='accuracy'

接下来将会利用提取到的文本特征TF-IDF来对算法进行审查,审查的算法如下。

·逻辑回归(LR)。

·分类与回归树(CART)。

·支持向量机(SVM)。

·朴素贝叶斯分类器(MNB)。

·K近邻算法(KNN)。

这个算法列表中包含了线性算法(LR)和非线性算法(CART、SVM、MNB和KNN)。代码如下:

# 评估算法# 生成算法模型models ={}models['LR'] = LogisticRegression()models['SVM'] = SVC()models['CART'] = DecisionTreeClassifier()models['MNB'] =MultinomialNB()models['KNN'] = KNeighborsClassifier()#比较算法results = []for key in models:   kfold = KFold(n_splits=num_folds, random_state=seed)   cv_results = cross_val_score(models[key], X_train_counts_tf, dataset_train.target, cv=kfold, scoring=scoring)   results.append(cv_results)   print('%s: %f (%f)' % (key, cv_results.mean(), cv_results.std()))

执行结果显示,逻辑回归(LR)具有最好的准确度,朴素贝叶斯分类器(MNB)和K近邻(KNN)也值得进一步的研究。执行结果如下:

5399bc717e7008ef2ea55b862db8eec2.png

这只是K折交叉验证给出的平均统计结果,通常还要看算法每次得出的结果的分布状况。在这里使用箱线图来显示数据的分布状况。代码如下:

#评估算法--箱线图fig=pyplot.figure()fig.suptitle('Algorithm Comparison')ax=fig.add_subplot(111)pyplot.boxplot(results)ax.set_xticklabels(models.keys())pyplot.show()

answer:

afb4c055873746e6bb16d9987834c29f.png

执行结果显示,朴素贝叶斯分类器的数据离散程度比较好,逻辑回归的偏度较大。算法结果的离散程度能够反应算法对数据的适用情况,所以对逻辑回归和朴素贝叶斯分类器进行进一步研究,实行算法调参。

五、算法调参

通过上面的分析发现,逻辑回归(LR)和朴素贝叶斯分类器(MNB)算法值得进一步进行优化。下面对这两个算法的参数进行调参,进一步提高算法的准确度。

5.1  逻辑回归调参

在逻辑回归中的超参数是C。C是目标的约束函数,C值越小则正则化强度越大。对C进行调参,每次给C设定一定数量的值,如果临界值是最优参数,重复这个步骤,直到找到最优值。代码如下:

#算法调参#调参LRparam_grid ={}param_grid['C']=[0.1,5,13,15]model=LogisticRegression()kfold=KFold(n_splits=num_folds,random_state=seed)grid=GridSearchCV(estimator=model,param_grid=param_grid,scoring=scoring,cv=kfold)grid_result=grid.fit(X_train_counts_tf,y=dataset_train.target)print('最优:%s使用%s' %(grid_result.best_score_,grid_result.best_params_))

answer:

1d0f3f5fcc3a809474060a0075335510.png

可以看到C的最优参数是15(15是通过多次调整param_grid参数得到的)。

5.2  朴素贝叶斯分类器调参

通过对逻辑回归调参,准确度提升到大概0.92,提升还是比较大的。朴素贝叶斯分类器有一个alpha参数,该参数是一个平滑参数,默认值为1.0。我们也可以对这个参数进行调参,以提高算法的准确度。代码如下:

#调参MNBparam_grid={}param_grid['alpha']=[0.001,0.01,0.1,1.5]model=MultinomialNB()kfold=KFold(n_splits=num_folds,random_state=seed)grid=GridSearchCV(estimator=model,param_grid=param_grid,scoring=scoring,cv=kfold)grid_result=grid.fit(X_train_counts_tf,y=dataset_train.target)print('最优:%s使用%s' %(grid_result.best_score_,grid_result.best_params_))

answer:

95dc23483c28f64bc472366a4d7ec947.png

同样,通过多次调整param_grid,得到朴素贝叶斯分类器的alpha参数的最优值是0.01。

通过调参发现,逻辑回归在C=15时具有最好的准确度。接下来审查集成算法。

六、集成算法

除调参之外,提高模型准确度的方法是使用集成算法。下面对以下两种集成算法进行比较,来看看能否进一步提高模型的准确度。

       ·随机森林(RF)。

       ·AdaBoost(AB)。

       集成算法的评估代码如下:

#集成算法ensembles={}ensembles['RF']=RandomForestClassifier()ensembles['AB']=AdaBoostClassifier()#比较集成算法results=[]for key in ensembles:    kfold = KFold(n_splits=num_folds, random_state=seed)    cv_results = cross_val_score(ensembles[key],X_train_counts_tf,dataset_train.target,cv=kfold,scoring=scoring)    results.append(cv_results)    print('%s :%f (%f)' % (key,cv_results.mean(),cv_results.std()))

answer:

7bda365988a776effec6211aad73824e.png

接下来通过箱线图看一下算法结果的离散情况。代码如下:

#集成算法--箱线图fig=pyplot.figure()fig.suptitle('Algorithm Comparison')ax=fig.add_subplot(111)pyplot.boxplot(results)ax.set_xticklabels(ensembles.keys())pyplot.show()

answer:

687d5ba081090801800b5efe78959fcc.png

从箱线图可以看到随机森林(RF)的分布比较均匀,对数据的适用性比较高,更值得进一步优化研究。

七、集成算法调参

通过对集成算法的分析,发现随机森林算法具有较高的准确度和非常稳定的数据分布,非常值得进一步的研究。下面通过调参对随机森林算法进行优化。

随机森林有一个很重要的参数n_estimators,这是一个很好的可以用来调整的参数。对于集成参数来说,n_estimators会带来更准确的结果,当然这也有一定的限度。下面对n_estimators 进行调参优化,争取找到最优解。代码如下:

#调参RFparam_grid={}param_grid['n_estimators']=[10,100,150,200]model=RandomForestClassifier()kfold=KFold(n_splits=num_folds,random_state=seed)grid=GridSearchCV(estimator=model,param_grid=param_grid,scoring=scoring,cv=kfold)grid_result=grid.fit(X_train_counts_tf,y=dataset_train.target)print('最优:%s使用%s' %(grid_result.best_score_,grid_result.best_params_))

answer:

1676f5d854b357fdea7ccd7821e39157.png

八、确定最终模型

由前面对算法的评估发现,逻辑回归(LR)算法具有最佳的准确度。所以将会采用逻辑回归(LR)算法,通过训练数据生成算法模型。接下来会利用评估数据集对生成的模型进行验证,以确认模型的准确度。需要注意的是,为了保持数据特征的一致性,对新数据进行文本特征提取时应进行特征扩充,下面使用之前生成的tf_transformer的transform方法来处理评估数据集。代码如下:

#生成模型model=LogisticRegression(C=15)model.fit(X_train_counts_tf,dataset_train.target)X_test_counts=tf_transformer.transform(dataset_test.data)predictions=model.predict(X_test_counts)print(accuracy_score(dataset_test.target,predictions))print(classification_report(dataset_test.target,predictions))

answer:

4a670d8ad830a1d661fcca46ec15acf6.png

从执行结果可以看到,准确度大概达到了85.22%,差不多符合预期。

九、总结

本项目实例从问题定义开始,直到最后的模型生成为止,完成了一个文本分类项目,这类问题可以应用在垃圾邮件自动分类、新闻分类等方面。

在文本分类中很重要的一点是文本特征提取,在进行文本特征提取时可以进一步优化,以提高模型的准确度。

另外,对中文的文本分类,需要先进行分词,然后利用 sklearn.datasets.base.Bunch 将分词之后的文件加载到scikit-learn中,在运用机器学习处理问题时,需要灵活处理已经掌握的知识,寻找问题的解决方案。

eda553a0a634c16c922552f519467842.png

想法丨发现丨科技丨人文

让阅读成为习惯,让灵魂拥有温度

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值