基于LR的新闻⽂本分类
  本项⽬是基于jieba、TfidfVectorizer、LogisticRegression的搜狐新闻⽂本分类,jieba中⽂叫做结巴,是⼀款中⽂分词⼯
具,TfidfVectorizer中⽂叫做词袋向量化模型,是⽤来⽂章内容向量化的⼯具,LogisticRegression中⽂叫做逻辑回归模型,是⼀种基础、常⽤的分类⽅法。
  开发环境:jupyter notebook
1.数据准备
  训练集共有24000条样本,12个分类,每个分类2000条样本。
  测试集共有12000条样本,12个分类,每个分类1000条样本。
  在jupyter notebook中新建tfidfVectorizerTest⽂件
  加载训练集到变量train_df中,并打印训练集前5⾏,代码如下。
  read_csv⽅法中有3个参数,第1个参数是加载⽂本⽂件的路径,第2个关键字参数sep是分隔符,第3个
关键字参数header是⽂本⽂件的第1⾏是否为字段名。
1import pandas as pd
2
3 train_df = pd.read_csv('', sep='\t', header=None)
4 train_df.head()
  运⾏结果如下图所⽰:
  查看训练集每个分类的名字以及样本数量,代码如下:
1for name, group in upby(0):
2print(name,len(group))
  运⾏结果如下图所⽰:
  加载测试集并查看每个分类的名字以及样本数量,代码如下:
1 test_df = pd.read_csv('', sep='\t', header=None)
2for name, group in upby(0):
3print(name, len(group))
  运⾏结果如下图所⽰:
  载⼊停顿词赋值给变量stopWord_list,代码如下:
1 with open('', encoding='utf8') as file:
2    stopWord_list = [k.strip() for k adlines()]
2.分词
  需要安装jieba库,cmd中安装命令:pip install jieba
  对训练集的24000条样本循环遍历,使⽤jieba库的cut⽅法获得分词列表赋值给变量cutWords。  判断分词是否为停顿词,如果不为停顿词,则添加进变量cutWords中。
  代码如下:
import jieba
import time
lumns = ['分类', '⽂章']
stopword_list = [k.strip() for k in open('', encoding='utf8').readlines() if k.strip() != '']
cutWords_list = []
i = 0
startTime = time.time()
for article in train_df['⽂章']:
cutWords = [k for k in jieba.cut(article) if k not in stopword_list]
i += 1
if i % 1000 == 0:
print('前%d篇⽂章分词共花费%.2f秒' %(i, time.time()-startTime))
cutWords_list.append(cutWords)
  运⾏结果如下:
  从上⾯的运⾏结果可以看出,对24000篇⽂章进⾏分词共使⽤1332.62秒。
  将分词结果保存为本地⽂件,代码如下:
1 with open('', 'w') as file:
2for cutWords in cutWords_list:
3        file.write(''.join(cutWords) + '\n')
  载⼊分词⽂件的代码如下:
1 with open('') as file:
2    cutWords_list = [k.split() for k adlines()]
3.TfidfVectorizer模型
1from sklearn. import TfidfVectorizer
2
3 tfidf = TfidfVectorizer(cutWords_list, stop_words=stopWord_list, min_df=40, max_df=0.3)
4.特征⼯程
  第1⾏代码查看向量化的维数,即特征的维数;
  第2⾏代码调⽤TfidfVectorizer对象的fit_transform⽅法获得特征矩阵赋值给X;  第3⾏代码查看特征矩阵的形状。
1 X = tfidf.fit_transform(train_df[1])
2print('词表⼤⼩:', len(tfidf.vocabulary_))
3print(X.shape)
  运⾏结果如下:
5.模型训练
5.1 标签编码
  调⽤sklearn.preprocessing库的LabelEncoder⽅法对⽂章分类做标签编码。
  最后⼀⾏代码查看预测⽬标的形状。
1from sklearn.preprocessing import LabelEncoder
2import pandas as pd
3
4 train_df = pd.read_csv('', sep='\t', header=None)
5 labelEncoder = LabelEncoder()
6 y = labelEncoder.fit_transform(train_df[0])
7 y.shape
import pickle5.2 逻辑回归模型
  调⽤sklearn.linear_model库的LogisticRegression⽅法实例化模型对象。
  调⽤del_selection库的train_test_split⽅法划分训练集和测试集。
1from sklearn.linear_model import LogisticRegression
del_selection import train_test_split
3
4 train_X, test_X, train_y, test_y = train_test_split(X, y, test_size=0.2)
5 logistic_model = LogisticRegression(multi_class='multinomial', solver='lbfgs')
6 logistic_model.fit(train_X, train_y)
7 logistic_model.score(test_X, test_y)
  运⾏结果如下:
5.3 保存模型
  保存模型需要先安装pickle库,安装命令:pip install pickle
  调⽤pickle库的dump⽅法保存模型,需要2个参数。
  第1个参数是保存的对象,可以为任意数据类型,因为有3个模型需要保存,所以下⾯代码第1个参数是字典。  第2个参数是保存的⽂件对象,数据类型为_io.BufferedWriter
1import pickle
2
3 with open('del', 'wb') as file:
4    save = {
5'labelEncoder' : labelEncoder,
6'tfidfVectorizer' : tfidf,
7'logistic_model' : logistic_model
8    }
9    pickle.dump(save, file)
5.4 交叉验证
  在进⾏此步的时候,不需要运⾏此步之前的所有步骤,即可以重新运⾏jupyter notebook。
  调⽤pickle库的load⽅法加载保存的模型对象,代码如下:
1import pickle
2
3 with open('del', 'rb') as file:
4    tfidf_model = pickle.load(file)
5    tfidfVectorizer = tfidf_model['tfidfVectorizer']
6    labelEncoder = tfidf_model['labelEncoder']
7    logistic_model = tfidf_model['logistic_model']
  调⽤pandas的read_csv⽅法加载训练集数据。
  调⽤TfidfVectorizer对象的transform⽅法获得特征矩阵。
  调⽤LabelEncoder对象的transform⽅法获得预测⽬标值。
  代码如下:
1import pandas as pd
2
3 train_df = pd.read_csv('', sep='\t', header=None)
4 X = ansform(train_df[1])
5 y = ansform(train_df[0])
  调⽤sklearn.linear_model库的LogisticRegression⽅法实例化逻辑回归模型对象。
  调⽤del_selection库的ShuffleSplit⽅法实例化交叉验证对象。
  调⽤del_selection库的cross_val_score⽅法获得交叉验证每⼀次的得分。  最后打印每⼀次的得分以及平均分,代码如下:
1from sklearn.linear_model import LogisticRegression
del_selection import ShuffleSplit
del_selection import cross_val_score
4
5 logistic_model = LogisticRegression(multi_class='multinomial', solver='lbfgs')
6 cv_split = ShuffleSplit(n_splits=5, test_size=0.3)
7 score_ndarray = cross_val_score(logistic_model, X, y, cv=cv_split)
8print(score_ndarray)
9print(an())
  结果如下:
6.模型评估
  绘制混淆矩阵,代码如下:
del_selection import train_test_split
2from sklearn.linear_model import LogisticRegressionCV
ics import confusion_matrix
4import pandas as pd
5
6 train_X, test_X, train_y, test_y = train_test_split(X, y, test_size=0.2)
7 logistic_model = LogisticRegressionCV(multi_class='multinomial', solver='lbfgs')
8 logistic_model.fit(train_X, train_y)
9 predict_y = logistic_model.predict(test_X)
10 pd.DataFrame(confusion_matrix(test_y, predict_y),
11              columns=labelEncoder.classes_,
12              index=labelEncoder.classes_)
  结果如下图所⽰:
  绘制precision、recall、f1-score、support报告表,代码如下:
1import numpy as np
ics import precision_recall_fscore_support
3
4def eval_model(y_true, y_pred, labels):
5# 计算每个分类的Precision, Recall, f1, support
6    p, r, f1, s = precision_recall_fscore_support(y_true, y_pred)
7# 计算总体的平均Precision, Recall, f1, support
8    tot_p = np.average(p, weights=s)
9    tot_r = np.average(r, weights=s)
10    tot_f1 = np.average(f1, weights=s)
11    tot_s = np.sum(s)
12    res1 = pd.DataFrame({
13        u'Label': labels,

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。