机器学习笔记(4) -- 文本分类实例(20Newgroups数据集)

1. 问题定义

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

2.导入数据

这里使用scikit-learn的loadfiles导入文档数据,文档是按照不同的分类分目录来保存的,文件目录 名称即所属类别。在这里插入图片描述
在导入文档数据之前,要导入项目中所需的类库。

# 导入类库
from sklearn.datasets import load_files

from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_extraction.text import TfidfVectorizer

from sklearn.linear_model import LogisticRegression
from sklearn.naive_bayes import MultinomialNB
from sklearn.neighbors import KNeighborsClassifier
from sklearn.svm import SVC
from sklearn.tree import DecisionTreeClassifier

from sklearn.metrics import classification_report
from sklearn.metrics import accuracy_score

from sklearn.model_selection import cross_val_score
from sklearn.model_selection import KFold
from sklearn.model_selection import GridSearchCV

from sklearn.ensemble import AdaBoostClassifier
from sklearn.ensemble import RandomForestClassifier

from matplotlib import pyplot as plt

import warnings
warnings.filterwarnings('ignore')

利用机器学习对文本进行分类,与对数值特征进行分类最大的区别是,对文本进行分类是要先提取文本特征,提取到的文本特征属性的个数是巨大的,会有超万个的特征属性。

3. 文本特征提取

文本数据属于非结构化的数据,一般要转换成结构化的数据才能够通过机器学习算法进行分类。常见的做法是将文本转换成“文档-词项矩阵”,矩阵中的元素可以使用词频或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的值小,这说明该词条t的类别区分能力不强。但是实际上,如果一个词条在一个类的文档中频繁出现,这说明该词条能够很好地代表这个类的文本特征,这样的词条应该被赋予较高的权重,并将其作为该类文本的特征词,以区别于其他类文档。这就是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)

词频统计结果:
在这里插入图片描述
然后计算TF-IDF:

# 计算TF-IDF
tf_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的计算结果:

在这里插入图片描述
这里通过两种方法进行了文本特征的提取,并且查看了数据维度,得到的数据维度还是非常巨大的。

4. 评估算法

通过简单地查看数据维度,不能确定那个算法对和这个问题比较有效。下面将采用10折交叉验证的方式来比较算法的准确度,一遍找到处理问题最有效的两三种算法,然后进行下一步的处理。

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

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

  • 线性算法:逻辑回归(LR)
  • 非线性算法:分类与回归树(CART)、支持向量机(SVM)、朴素贝叶斯分类器(MNB)和K近邻(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近邻也值得进一步研究。
在这里插入图片描述
接下来看一下算法每次执行结果的分布情况。
在这里插入图片描述

5.算法调参

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

5.1 逻辑回归调参

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

# 调参LR
param_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=X_train_counts_tf,y=dataset_train.target)
print('最优:%s 使用%s'%(grid_result.best_score_,grid_result.best_params_))

可以看到C的最优参数是15。在这里插入图片描述

5.2 朴素贝叶斯分类器调参

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

# 调参 MNB
param_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 = X_train_counts_tf, y = dataset_train.target)
print('最优:%s 使用%s'%(grid_result.best_score_,grid_result.best_params_))

同样,通过多次调整param_grid,得到的朴素贝叶斯分类器的alpha参数的最优值是0.01。
在这里插入图片描述
通过调参发现,逻辑回归在C = 15 是具有最好的准确度。接下来进行审查集成算法。

6. 集成算法

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

随机森林(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()))

评估结果:
在这里插入图片描述

7. 集成算法调参

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

# 调参RF
param_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 =X_train_counts_tf,y = dataset_train.target)
print('最优:%s 使用%s'%(grid_result.best_score_,grid_result.best_params_))

调参之后的最优结果如下:
在这里插入图片描述

8. 确定最终模型

通过对算法的比较和调参发现,逻辑回归算法具有最高的准确度,因此使用逻辑回归算法生成算法模型。接下来会利用评估数据集对生成的模型进行验证,以确认模型的准确度。需要注意的是,为了保持数据特征的一致性,对新数据进行文本特征提取是应进行特征扩充,下面使用之前生成的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))

从结果可以看到,准确度大概达到了85%,与期待的结果比较一致。执行结果:
在这里插入图片描述

参考从书:《机器学习Python实践》 魏贞原

  • 3
    点赞
  • 48
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: LCSTS(Duan等人,2018)是一个中文短文本摘要数据集。该数据集由清华大学自然语言处理与社会人文计算实验室提供。该数据集包括两个部分,其中一个是从微博和新浪新闻中抽取的短文本语料库,另一个是由人类评估员对每个短文本生成的摘要进行的人工注释。 LCSTS数据集共包含2,400,846个短文本,每个短文本的平均长度为26.5个字符。所有的短文本都是以汉字为单位编码的。同时,LCSTS数据集还提供了每个短文本的标题以及两者之间的关联得分。LCSTS数据集为自然语言处理领域的短文本摘要任务提供了有价值的资源,同时也为其他相关研究提供了实验基础和参考数据。 ### 回答2: LCSTS数据集是一个大规模的中文短文本摘要数据集,包含了218万组短文本-摘要对,是目前为止规模最大的中文短文本摘要数据集之一。该数据集可以用于训练自然语言处理模型,如文本摘要自动生成模型等。 该数据集来源于新浪新闻网站,短文本部分是新闻正文段落,摘要部分是该新闻的标题,摘要长度一般为35个中文字符以下。数据集中的每个短文本-摘要对都经过了人工筛选和标注,确保了其质量和准确性。 LCSTS数据集可以用于训练文本摘要模型,其中一个典型的应用场景是将长篇文章转化为简短的摘要,以便读者快速了解文章主旨。该数据集还可以用于训练其他自然语言处理模型,如文本分类、词向量模型等。 总之,LCSTS数据集是一个非常有价值的中文自然语言处理数据集,能够为研究人员提供许多有用的资源,有助于推动中文自然语言处理技术的研究和发展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值