文本分类实例

Python机器学习项目的模板

1.定义问题
a)导入类库
b)导入数据集

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
#导入数据
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.guns','rec.autos',
'talk.politics.mideast','rec.motorcycles','talk.politics.misc','rec.sport.baseball',
'talk.religion.misc'
]
#导入训练数据
train_path = '/home/hadoop/DataSet/20news-bydate/20news-bydate-train'
dataset_train = load_files(container_path=train_path,categories=categories)
#导入评估数据
test_path = '/home/hadoop/DataSet/20news-bydate/20news-bydate-test'
dataset_test = load_files(container_path=test_path,categories=categories)

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

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

TF-IDF值是一种用于信息检索或数据挖掘的常用加权技术。TF的意思是词频,IDF的意思是逆向文件频率。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的类别区分能力不强。TF指的是某一个给定词的词语在该文件中出现的频率,这是对词数的归一化,以防止它偏向长的文件。IDF是一个词语普遍重要性的度量,某一个特定词语的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_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进行分类模型的训练。因为TF-IDF的数据维度巨大,并且自用提取的特征数据,进一步对数据进行分析的意义不大,因此只简单地查看数据维度的信息。

3.评估算法

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

线性算法:LR(逻辑回归)
非线性算法:CART,SVM,朴素贝叶斯,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()))
#箱线图比较算法
fig = plt.figure()
fig.suptitle('Algorithm Comparison')
ax = fig.add_subplot(111)
plt.boxplot(results)
ax.set_xticklabels(models.keys())
plt.show()

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

逻辑回归调参
在逻辑回归中的超参数是C。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_))

朴素贝叶斯分类器调参
朴素贝叶斯分类器有一个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_))

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

#集成算法
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()))

集成算法调参
对随机森林算法进行优化,随机森林有一个重要的参数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_))

确定最终模型

#生成模型
model = LogisticRegression(C=13)
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))
  • 2
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值