当前位置:   article > 正文

用TFIDF词袋模型进行新闻分类_词袋模型 虚假新闻分类

词袋模型 虚假新闻分类

词袋  不关注词的先后顺序---词袋模型(bow--一元模型)  bag of  words 
二元模型
n-gram

  1. # 创建输出目录 保存训练好的模型
  2. import os#对文件和目录进行操作
  3. output_dir = u'output'
  4. if not os.path.exists(output_dir):
  5. os.mkdir(output_dir)

加载数据

  1. import numpy as np#一个数据分析处理数据的常见的库,它提供的数据结构比 Python 自身的更高效
  2. import pandas as pd

1.Pandas 是基于 NumPy 的一个开源 Python 库,它被广泛用于快速分析数据,以及数据清洗和准备等工作。它的名字来源是由“ Panel data”(面板数据,一个计量经济学名词)两个单词拼成的。简单地说,你可以把 Pandas 看作是 Python 版的 Excel。
2. Pandas能很好地处理来自各种不同来源的数据,比如 Excel 表格、CSV 文件、SQL 数据库,甚至还能处理存储在网页上的数据。
3. Pandas基于Numpy,常常与Numpy、matplotlib一起使用。
4. Pandas库的两个主要数据结构:
Series:一维
DataFrame:多维

python list 列表保存的是对象的指针,比如 [0,1,2] 需要保存 3 个指针和 3 个整数的对象,这样就很浪费内存了。

Numpy 是储存在一个连续的内存块中,节约了计算资源。

  1. # 查看训练数据
  2. train_data = pd.read_csv('sohu_train.txt', sep='\t', header=None, dtype=np.str_, encoding='utf8',error_bad_lines=False, delimiter="\t", names=[u'频道', u'文章'])
  3. train_data.head()

  1. # 载入停用词
  2. stopwords = set()
  3. with open('stopwords.txt', 'r',encoding='utf8') as infile:
  4. for line in infile:
  5. line = line.rstrip('\n')
  6. if line:
  7. stopwords.add(line.lower())

计算每个文章的tfidf特征

  1. import jieba
  2. from sklearn.feature_extraction.text import TfidfVectorizer

min_df去掉df值小的词  这样的词一般是非常专业的名词或者是生僻词  是噪音
max_df 去掉df值很大的词  这样词是常用词 去掉不要

  1. tfidf = TfidfVectorizer(tokenizer=jieba.lcut, stop_words=stopwords, min_df=50, max_df=0.3)#使用TfidfVectorizer实例化
  2. x = tfidf.fit_transform(train_data[u'文章'])

·输出结果

  1. Building prefix dict from the default dictionary ...
  2. Loading model from cache C:\Users\10248\AppData\Local\Temp\jieba.cache
  3. Loading model cost 0.550 seconds.
  4. Prefix dict has been built successfully.
  5. E:\ANACODAN\lib\site-packages\sklearn\feature_extraction\text.py:388: UserWarning: Your stop_words may be inconsistent with your preprocessing. Tokenizing the stop words generated tokens ['&', ',', '.', ';', 'e', 'g', 'nbsp', '—', '\u3000', '傥', '兼', '前', '唷', '啪', '啷', '喔', '始', '漫', '然', '特', '竟', '若果', '莫', '见', '设', '说', '达', '非'] not in stop_words.
  6. warnings.warn('Your stop_words may be inconsistent with '
print(u'词表大小: {}'.format(len(tfidf.vocabulary_)))
词表大小: 14516

训练分类器

编码目标变量  因为咱们的标签是字符串  sklearn只接受数值

  1. from sklearn.preprocessing import LabelEncoder#LabelEncoder:将类别数据数字化
  2. y_encoder = LabelEncoder()
  3. y = y_encoder.fit_transform(train_data[u'频道'])#将类别转换成0,1,2,3,4,5,6,7,8,9...
  4. y[:10]

·输出结果

array([3, 3, 3, 3, 3, 3, 3, 3, 3, 3])

编码X变量
x = tfidf.transform(train_data[u'文章'])

  1. # 划分训练测试数据
  2. from sklearn.model_selection import train_test_split#分割数据集
  3. # 根据y分层抽样,测试数据占20%
  4. #因为现在数据量很大 此时采用对下标进行分割
  5. train_idx, test_idx = train_test_split(range(len(y)), test_size=0.2, stratify=y)
  6. train_x = x[train_idx, :]#训练集
  7. train_y = y[train_idx]
  8. test_x = x[test_idx, :]#测试集
  9. test_y = y[test_idx]

训练逻辑回归模型 我们是12分类  属于多分类

 常用参数说明
         penalty: 正则项类型,l1还是l2
         C: 正则项惩罚系数的倒数,越大则惩罚越小
         fit_intercept: 是否拟合常数项
         max_iter: 最大迭代次数
         multi_class: 以何种方式训练多分类模型
             ovr = 对每个标签训练二分类模型
             multinomial ovo = 直接训练多分类模型,仅当solver={newton-cg, sag, lbfgs}时支持
         solver: 用哪种方法求解,可选有{liblinear, newton-cg, sag, lbfgs}
             小数据liblinear比较好,大数据量sag更快
             多分类问题,liblinear只支持ovr模式,其他支持ovr和multinomial
             liblinear支持l1正则,其他只支持l2正则

  1. from sklearn.linear_model import LogisticRegression#引入逻辑回归
  2. model = LogisticRegression(multi_class='multinomial', solver='lbfgs')#solver='lbfgs':求解方式
  3. model.fit(train_x, train_y)

·输出结果

  1. E:\ANACODAN\lib\site-packages\sklearn\linear_model\_logistic.py:763: ConvergenceWarning: lbfgs failed to converge (status=1):
  2. STOP: TOTAL NO. of ITERATIONS REACHED LIMIT.
  3. Increase the number of iterations (max_iter) or scale the data as shown in:
  4. https://scikit-learn.org/stable/modules/preprocessing.html
  5. Please also refer to the documentation for alternative solver options:
  6. https://scikit-learn.org/stable/modules/linear_model.html#logistic-regression
  7. n_iter_i = _check_optimize_result(
LogisticRegression(multi_class='multinomial')

模型效果评估

  1. from sklearn.metrics import confusion_matrix, precision_recall_fscore_support
  2. # 在测试集上计算模型的表现
  3. test_y_pred = model.predict(test_x)
  4. # 计算混淆矩阵
  5. pd.DataFrame(confusion_matrix(test_y, test_y_pred), columns=y_encoder.classes_, index=y_encoder.classes_)

·输出结果

  1. 体育 健康 女人 娱乐 房地产 教育 文化 新闻 旅游 汽车 科技 财经
  2. 体育 193 1 0 1 0 0 3 2 0 0 0 0
  3. 健康 0 165 9 0 0 4 0 7 3 0 4 8
  4. 女人 1 5 167 4 0 0 13 5 3 0 1 1
  5. 娱乐 0 1 9 164 0 5 17 2 0 0 1 1
  6. 房地产 0 1 4 0 180 0 0 3 0 0 1 11
  7. 教育 0 0 3 2 0 185 2 6 1 0 1 0
  8. 文化 0 3 13 17 0 1 153 8 2 1 2 0
  9. 新闻 1 4 6 5 1 12 4 124 5 2 11 25
  10. 旅游 0 2 8 0 6 1 8 8 163 0 1 3
  11. 汽车 1 1 3 0 0 0 0 4 2 182 1 6
  12. 科技 0 1 0 0 0 2 2 12 5 1 164 13
  13. 财经 1 4 3 0 12 0 4 19 2 4 11 140
  1. # 计算各项评价指标
  2. def eval_model(y_true, y_pred, labels):
  3. # 计算每个分类的Precision, Recall, f1, support
  4. p, r, f1, s = precision_recall_fscore_support(y_true, y_pred)
  5. # 计算总体的平均Precision, Recall, f1, support
  6. tot_p = np.average(p, weights=s)
  7. tot_r = np.average(r, weights=s)
  8. tot_f1 = np.average(f1, weights=s)
  9. tot_s = np.sum(s)
  10. res1 = pd.DataFrame({
  11. u'Label': labels,
  12. u'Precision': p,
  13. u'Recall': r,
  14. u'F1': f1,
  15. u'Support': s
  16. })
  17. res2 = pd.DataFrame({
  18. u'Label': [u'总体'],
  19. u'Precision': [tot_p],
  20. u'Recall': [tot_r],
  21. u'F1': [tot_f1],
  22. u'Support': [tot_s]
  23. })
  24. res2.index = [999]
  25. res = pd.concat([res1, res2])
  26. return res[[u'Label', u'Precision', u'Recall', u'F1', u'Support']]

·输出结果

eval_model(test_y, test_y_pred, y_encoder.classes_)
  1. Label Precision Recall F1 Support
  2. 0 体育 0.979695 0.965 0.972292 200
  3. 1 健康 0.877660 0.825 0.850515 200
  4. 2 女人 0.742222 0.835 0.785882 200
  5. 3 娱乐 0.849741 0.820 0.834606 200
  6. 4 房地产 0.904523 0.900 0.902256 200
  7. 5 教育 0.880952 0.925 0.902439 200
  8. 6 文化 0.742718 0.765 0.753695 200
  9. 7 新闻 0.620000 0.620 0.620000 200
  10. 8 旅游 0.876344 0.815 0.844560 200
  11. 9 汽车 0.957895 0.910 0.933333 200
  12. 10 科技 0.828283 0.820 0.824121 200
  13. 11 财经 0.673077 0.700 0.686275 200
  14. 999 总体 0.827759 0.825 0.825831 2400

 模型保存

  1. # 保存模型到文件 pip install dill
  2. #注意 我们要把tfidf特征提取模型保存 标签转换模型 预测模型
  3. !pip install dill
  4. import dill
  5. import pickle
  6. model_file = os.path.join(output_dir, u'model.pkl')
  7. with open(model_file, 'wb') as outfile:
  8. dill.dump({
  9. 'y_encoder': y_encoder,
  10. 'tfidf': tfidf,
  11. 'lr': model
  12. }, outfile)

·输出结果

Requirement already satisfied: dill in e:\anacodan\lib\site-packages (0.3.4)

测试模型,对新文档预测

  1. # 加载新文档数据
  2. new_data = pd.read_csv('sohu_test.txt', sep='\t', header=None, dtype=np.str_, encoding='utf8',error_bad_lines=False, delimiter="\t", names=[u'频道', u'文章'])
  3. new_data.head()

  1. # 加载模型
  2. import pickle
  3. model_file = os.path.join(output_dir, u'model.pkl')
  4. with open(model_file, 'rb') as infile:
  5. model = pickle.load(infile)
  1. # 对新文档预测(这里只对前10篇预测)
  2. # 1. 转化为词袋表示
  3. new_x = model['tfidf'].transform(new_data[u'文章'][:50])

·输出结果

  1. E:\ANACODAN\lib\site-packages\sklearn\feature_extraction\text.py:388: UserWarning: Your stop_words may be inconsistent with your preprocessing. Tokenizing the stop words generated tokens ['&', ',', '.', ';', 'e', 'g', 'nbsp', '—', '\u3000', '傥', '兼', '前', '唷', '啪', '啷', '喔', '始', '漫', '然', '特', '竟', '若果', '莫', '见', '设', '说', '达', '非'] not in stop_words.
  2. warnings.warn('Your stop_words may be inconsistent with '
  1. # 2. 预测类别
  2. new_y_pred = model['lr'].predict(new_x)
  3. new_y_pred

·输出结果

  1. array([3, 0, 3, 3, 5, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
  2. 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
  3. 3, 3, 3, 3, 3, 3])
  1. # 3. 解释类别
  2. pd.DataFrame({u'预测频道': model['y_encoder'].inverse_transform(new_y_pred), u'实际频道': new_data[u'频道'][:50]})

·输出结果

  1. 预测频道 实际频道
  2. 0 娱乐 娱乐
  3. 1 体育 娱乐
  4. 2 娱乐 娱乐
  5. 3 娱乐 娱乐
  6. 4 教育 娱乐
  7. 5 娱乐 娱乐
  8. 6 娱乐 娱乐
  9. 7 娱乐 娱乐
  10. 8 娱乐 娱乐
  11. 9 娱乐 娱乐
  12. 10 娱乐 娱乐
  13. 11 娱乐 娱乐
  14. 12 娱乐 娱乐
  15. 13 娱乐 娱乐
  16. 14 娱乐 娱乐
  17. 15 娱乐 娱乐
  18. 16 娱乐 娱乐
  19. 17 娱乐 娱乐
  20. 18 娱乐 娱乐
  21. 19 娱乐 娱乐
  22. 20 娱乐 娱乐
  23. 21 娱乐 娱乐
  24. 22 娱乐 娱乐
  25. 23 娱乐 娱乐
  26. 24 娱乐 娱乐
  27. 25 娱乐 娱乐
  28. 26 娱乐 娱乐
  29. 27 娱乐 娱乐
  30. 28 娱乐 娱乐
  31. 29 娱乐 娱乐
  32. 30 娱乐 娱乐
  33. 31 娱乐 娱乐
  34. 32 娱乐 娱乐
  35. 33 娱乐 娱乐
  36. 34 娱乐 娱乐
  37. 35 娱乐 娱乐
  38. 36 娱乐 娱乐
  39. 37 娱乐 娱乐
  40. 38 娱乐 娱乐
  41. 39 娱乐 娱乐
  42. 40 娱乐 娱乐
  43. 41 娱乐 娱乐
  44. 42 娱乐 娱乐
  45. 43 娱乐 娱乐
  46. 44 娱乐 娱乐
  47. 45 娱乐 娱乐
  48. 46 娱乐 娱乐
  49. 47 娱乐 娱乐
  50. 48 娱乐 娱乐
  51. 49 娱乐 娱乐

主函数,调用模型对新闻进行预测

  1. # 加载模型
  2. import pickle
  3. import os
  4. import numpy as np
  5. import pandas as pd
  6. output_dir = u'output'
  7. if not os.path.exists(output_dir):
  8. os.mkdir(output_dir)
  9. model_file = os.path.join(output_dir, u'model.pkl')
  10. with open(model_file, 'rb') as infile:
  11. model = pickle.load(infile)
  12. oo = 1
  13. while oo == 1:
  14. f = open('yuce.txt', 'w', encoding='utf8')
  15. f.write(input())
  16. f.close()
  17. new1_data = pd.read_csv('yuce.txt', sep='\t', header=None, dtype=np.str_, encoding='utf8', names=[u'文章'])
  18. new1_data.head()
  19. # 加载模型
  20. import pickle
  21. model_file = os.path.join(output_dir, u'model.pkl')
  22. with open(model_file, 'rb') as infile:
  23. model = pickle.load(infile)
  24. new1_x = model['tfidf'].transform(new1_data[u'文章'])
  25. # 2. 预测类别
  26. new1_y_pred = model['lr'].predict(new1_x)
  27. pd.DataFrame({u'预测频道': model['y_encoder'].inverse_transform(new1_y_pred)})
  28. print(pd.DataFrame({u'预测频道': model['y_encoder'].inverse_transform(new1_y_pred)}))
  29. with open(r'yuce.txt', 'a+', encoding='utf-8') as test:
  30. test.truncate(0)

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/629582
推荐阅读
相关标签
  

闽ICP备14008679号