内容目录
一、数据集介绍二、解压文件明确需求三、批量读取和合并文本数据集四、中文文本分词五、停止词使用六、编码器处理文本标签七、常规算法模型1、k近邻算法2、决策树3、多层感知器4、伯努力贝叶斯5、高斯贝叶斯6、多项式贝叶斯7、逻辑回归8、支持向量机八、集成算法模型1、随机森林算法2、自适应增强算法3、lightgbm算法4、xgboost算法九、深度学习1、前馈神经网络2、LSTM 神经网络十、算法之间性能比较
一、数据集介绍
文档共有4中类型:女性、体育、文学、校园
训练集放到train文件夹里,测试集放到test文件夹里。
停用词放到stop文件夹里。
训练集:3305 [女性,体育,文学,校园]
测试集 200 [女性,体育,文学,校园]
import os
import shutil
import zipfile
import jieba
import time
import warnings
import xgboost
import lightgbm
import numpy as np
import pandas as pd
from keras import models
from keras import layers
from keras.utils.np_utils import to_categorical
from keras.preprocessing.text import Tokenizer
from sklearn import svm
from sklearn import metrics
from sklearn.neural_network import MLPClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.neighbors import KNeighborsClassifier
from sklearn.naive_bayes import BernoulliNB
from sklearn.naive_bayes import GaussianNB
from sklearn.naive_bayes import MultinomialNB
from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier
from sklearn.ensemble import AdaBoostClassifier
from sklearn.preprocessing import LabelEncoder
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_extraction.text import TfidfVectorizer
warnings.filterwarnings('ignore')
二、解压文件明确需求
《获取数据》—《数据分析和处理》—《特征工程与选择》—《算法模型》—《性能评估/参数调优》
目标需求1:批量读取文档文件.txt
目标需求2:文本向量化使用词袋法或者TFIDF
目标需求3:比较各个算法的性能优劣,包括模型消耗用时、模型准确率
三、批量读取和合并文本数据集
path = 'D:\\A\\AI-master\\py-data\\text_classification-master\\text classification'
def read_text(path, text_list):
'''
path: 必选参数,文件夹路径
text_list: 必选参数,文件夹 path 下的所有 .txt 文件名列表
return: 返回值
features 文本(特征)数据,以列表形式返回;
labels 分类标签,以列表形式返回
'''
features, labels = [], []
for text in text_list:
if text.split('.')[-1] == 'txt':
try:
with open(path + text, encoding='gbk') as fp:
features.append(fp.read()) # 特征
labels.append(path.split('\\')[-2]) # 标签
except Exception as erro:
print('\n>>>发现错误, 正在输出错误信息...\n', erro)
return features, labels
def merge_text(train_or_test, label_name):
'''
train_or_test: 必选参数,train 训练数据集 or test 测试数据集
label_name: 必选参数,分类标签的名字
return: 返回值
merge_features 合并好的所有特征数据,以列表形式返回;
merge_labels 合并好的所有分类标签数据,以列表形式返回
'''
print('\n>>>文本读取和合并程序已经启动, 请稍候...')
merge_features, merge_labels = [], [] # 函数全局变量
for name in label_name:
path = 'D:\\A\\AI-master\\py-data\\text_classification-master\\text classification\\' + train_or_test + '\\' + name + '\\'
text_list = os.listdir(path)
features, labels = read_text(path=path, text_list=text_list) # 调用函数
merge_features += features # 特征
merge_labels += labels # 标签
# 可以自定义添加一些想要知道的信息
print('\n>>>你正在处理的数据类型是...\n', train_or_test)
print('\n>>>[', train_or_test, ']数据具体情况如下...')
print('样本数量\t', len(merge_features), '\t类别名称\t', set(merge_labels))
print('\n>>>文本读取和合并工作已经处理完毕...\n')
return merge_features, merge_labels
#获取训练集
train_or_test = 'train'
label_name = ['女性', '体育', '校园', '文学']
X_train, y_train = merge_text(train_or_test, label_name)
# 获取测试集
train_or_test = 'test'
label_name = ['女性', '体育', '校园', '文学']
X_test, y_test = merge_text(train_or_test, label_name)
print('X_train, y_train',len(X_train), len(y_train))
print('X_test, y_test',len(X_test), len(y_test))
X_train, y_train 3305 3305
X_test, y_test 200 200
四、中文文本分词
# 训练集
X_train_word = [jieba.cut(words) for words in X_train]
X_train_cut = [' '.join(word) for word in X_train_word]
X_train_cut[:5]
['明天 三里屯 见 瑞丽 服饰 美容 :2011 瑞丽 造型 大赏 派对 瑞丽 专属 模特 黄美熙 康猴 猴 康乐 帕丽扎 提 也 会 参加 哦 瑞丽 专属 模特 转发 ( 53 ) 评论 ( 5 ) 12 月 8 日 17 : 10 来自 新浪 微博',
'转发 微博 水草 温 :北京 早安 中国 宝迪沃 减肥 训练营 2012 年 寒假 班 开始 报名 早安 中国 吧 : 51 ( 分享 自 百度 贴 吧 ) 您 还 在 为 肥胖 为难 吗 冬季 减肥 训练 帮助 您 快速 减掉 多余 脂肪 咨询 顾问 温 老师 1071108677 原文 转发 原文 评论',
'多谢 支持 , 鱼子 精华 中 含有 太平洋 深海 凝胶 能 给 秀发 源源 滋养 , 鱼子 精华 发膜 含有 羟基 积雪草 苷 , 三重 神经酰胺 能 补充 秀发 流失 的 胶质 , 可以 有 焕然 新生 的 感觉 。鲍艺芳 :我 在 倍 丽莎 美发 沙龙 做 的 奢华 鱼子酱 护理 超级 好用 以后 就 用 它 了 我 的 最 爱 巴黎 卡诗 原文 转发 原文 评论',
'注射 除皱 针 时会 疼 吗 ?其他 产品 注射 会 产生 难以忍受 的 疼痛 , 除皱 针中 含有 微量 的 利多卡因 以 减轻 注射 过程 中 的 疼痛 , 注射 过程 只有 非常 轻微 的 疼痛感 。另外 , 除皱 针 的 胶原蛋白 具有 帮助 凝血 作用 , 极少 产生 淤血 现象 。一般 注射 后 就 可以 出门 。其他 产品 容易 产生 淤斑 , 而且 时间 较长 。让 人 难以 接受 。',
'注射 除皱 针 时会 疼 吗 ?其他 产品 注射 会 产生 难以忍受 的 疼痛 , 除皱 针中 含有 微量 的 利多卡因 以 减轻 注射 过程 中 的 疼痛 , 注射 过程 只有 非常 轻微 的 疼痛感 。另外 , 除皱 针 的 胶原蛋白 具有 帮助 凝血 作用 , 极少 产生 淤血 现象 。一般 注射 后 就 可以 出门 。其他 产品 容易 产生 淤斑 , 而且 时间 较长 。让 人 难以 接受 。']
# 训练集
# 测试集
X_test_word = [jieba.cut(words) for words in X_test]
X_test_cut = [' '.join(word) for word in X_test_word]
X_test_cut[:5]
['【 L 丰胸 — — 安全 的 丰胸 手术 】 华美 L 美胸 非常 安全 , 5 大 理由 :① 丰胸 手术 在世界上 已有 超过 100 年 的 历史 ; ② 假体 硅胶 有 40 多年 的 安全 使用 史 ; ③ 每年 都 有 超过 600 万 女性 接受 丰胸 手术 ; ④ 不 损伤 乳腺 组织 , 不 影响 哺乳 ; ⑤ 华美 美莱 率先 发布 中国 首部 《 整形 美容 安全 消费 白皮书 》 , 维护 社会 大众 整形 美容 消费 利益 。\t \t \t \t $ LOTOzf $',
'【 穿 高跟鞋 不磨 脚 小 方法 】 1 . 用 热 毛巾 在 磨 脚 的 部位 捂 几分钟 , 再拿块 干 的 软 毛巾 垫 着 , 用 锤子 把 鞋子 磨脚 的 地方 敲 平整 就 可以 啦 ;2 . 把 报纸 捏 成团 沾点 水 , 不要 太湿 , 但 要 整团 都 沾 到 水 , 再 拿 张干 的 报纸 裹住 湿 的 报纸 , 塞 在 挤 脚 部位 , 用 塑料袋 密封 一夜 ;3 . 穿鞋 之前 , 拿 香皂 ( 蜡烛 亦可 ) 在 磨脚 位置 薄薄的 涂上一层 。\t \t \t \t $ LOTOzf $',
'要 在 有限 的 空间 里 实现 最大 的 价值 , 布 上网 线 、 音频线 、 高清 线 、 投影 线 、 电源线 、 闭 路线 等 一切 能够 想到 的 线 ;在 32 ㎡ 里 放 一套 沙发 和 预留 5 - 6 个人 的 办公 环境 ;5 ㎡ 里 做 一个 小 卧室 ;在 6 ㎡ 里装 一个 袖珍 厨房 和 一个 厕所 ;还要 在 2 米 * 5 米 的 阳台 上 做 一个 小 花园 ;除 阳台 外套 内 只有 43 ㎡ 的 房子 要 怎么 做 才能 合理 利用 ?$ LOTOzf $',
'【 女人 命好 的 几点 特征 】 1 . 圆脸 ( 对 人际关系 及 财运 都 有加 分 ) ;2 . 下巴 丰满 ( 可能 会 拥有 两栋 以上 的 房产 ) ;3 . 臀大 ( 代表 有 财运 ) ;4 . 腿 不能 细 ( 腿 长脚 瘦 , 奔走 不停 , 辛苦 之相 也 ) ;5 . 小腹 有 脂肪 ( 状是 一种 福寿之 相 ) 。$ LOTOzf $',
'中央 经济 工作 会议 12 月 12 日至 14 日 在 北京 举行 , 很 引人瞩目 的 一个 新 的 提法 是 , 要 提高 中等 收入者 比重 , 但是 股市 却 把 “ 中等 收入者 ” 一批 又 一批 地 变成 了 “ 低收入 人群 ” !$ LOTOzf $']
五、停止词使用
1 停止词是为了过滤掉已经确认对训练模型没有实际价值的分词
2 停止词作用:提高模型的精确度和稳定性
# 加载停止词语料
stoplist = [word.strip() for word in open(
'D:\\A\\AI-master\\py-data\\text_classification-master\\
text classification\\stop\\stopword.txt', encoding='utf-8').readlines()]
stoplist[:10]
['\ufeff,', '?', '、', '。', '“', '”', '《', '》', '!', ',']
六、编码器处理文本标签
le = LabelEncoder()
y_train_le = le.fit_transform(y_train)
y_test_le = le.fit_transform(y_test)
y_train_le, y_test_le
(array([1, 1, 1, ..., 2, 2, 2], dtype=int64),
array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2], dtype=int64))
文本数据转换成数据值数据矩阵
count = CountVectorizer(stop_words=stoplist)
'''注意:
这里要先 count.fit() 训练所有训练和测试集,保证特征数一致,
这样在算法建模时才不会报错
'''
count.fit(list(X_train_cut) + list(X_test_cut))
X_train_count = count.transform(X_train_cut)
X_test_count = count.transform(X_test_cut)
X_train_count = X_train_count.toarray()
X_test_count = X_test_count.toarray()
print(X_train_count.shape, X_test_count.shape)
X_train_count, X_test_count
(3305, 23732) (200, 23732)
(array([[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
...,
[1, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0]], dtype=int64), array([[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
...,
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0],
[0, 0, 0, ..., 0, 0, 0]], dtype=int64))
七、常规算法模型
封装一个函数,提高复用率,使用时只需调用函数即可。
# 用于存储所有算法的名字,准确率和所消耗的时间
estimator_list, score_list, time_list = [], [], []
def get_text_classification(estimator, X, y, X_test, y_test):
'''
estimator: 分类器,必选参数
X: 特征训练数据,必选参数
y: 标签训练数据,必选参数
X_test: 特征测试数据,必选参数
y_tes: 标签测试数据,必选参数
return: 返回值
y_pred_model: 预测值
classifier: 分类器名字
score: 准确率
t: 消耗的时间
matrix: 混淆矩阵
report: 分类评价函数
'''
start = time.time()
print('\n>>>算法正在启动,请稍候...')
model = estimator
print('\n>>>算法正在进行训练,请稍候...')
model.fit(X, y)
print(model)
print('\n>>>算法正在进行预测,请稍候...')
y_pred_model = model.predict(X_test)
print(y_pred_model)
print('\n>>>算法正在进行性能评估,请稍候...')
score = metrics.accuracy_score(y_test, y_pred_model)
matrix = metrics.confusion_matrix(y_test, y_pred_model)
report = metrics.classification_report(y_test, y_pred_model)
print('>>>准确率\n', score)
print('\n>>>混淆矩阵\n', matrix)
print('\n>>>召回率\n', report)
print('>>>算法程序已经结束...')
end = time.time()
t = end - start
print('\n>>>算法消耗时间为:', t, '秒\n')
classifier = str(model).split('(')[0]
return y_pred_model, classifier, score, round(t, 2), matrix, report
1、k近邻算法
knc = KNeighborsClassifier()
result = get_text_classification(knc, X_train_count, y_train_le, X_test_count, y_test_le)
estimator_list.append(result[1]), score_list.append(result[2]), time_list.append(result[3])
算法正在启动,请稍候...算法正在进行训练,请稍候...KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski', metric_params=None, n_jobs=None, n_neighbors=5, p=2, weights='uniform')算法正在进行预测,请稍候...[1 0 0 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 1 1 1 0 1 0 1 2 0 1 0 0 1 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 2 2 2 0 0 0 0 2 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 2 2 2 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 2 0 0 0 0 0 0 2 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 2 2 0 0 2 0 3 0 2 2 2 2 2 2 0 2 0 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 0 2 2 0 0 0 0 0 2 2 2 2]算法正在进行性能评估,请稍候...准确率 0.665混淆矩阵 [[99 0 16 0] [26 10 2 0] [ 8 0 23 0] [ 6 0 9 1]]召回率 precision recall f1-score support 0 0.71 0.86 0.78 115 1 1.00 0.26 0.42 38 2 0.46 0.74 0.57 31 3 1.00 0.06 0.12 16 accuracy 0.67 200 macro avg 0.79 0.48 0.47 200weighted avg 0.75 0.67 0.62 200算法程序已经结束...算法消耗时间为: 28.78205680847168 秒
(None, None, None)
2、决策树
dtc = DecisionTreeClassifier()
result = get_text_classification(dtc, X_train_count, y_train_le, X_test_count, y_test_le)
estimator_list.append(result[1]), score_list.append(result[2]), time_list.append(result[3])
算法正在进行训练,请稍候...
DecisionTreeClassifier(class_weight=None, criterion='gini', max_depth=None,
max_features=None, max_leaf_nodes=None,
min_impurity_decrease=0.0, min_impurity_split=None,
min_samples_leaf=1, min_samples_split=2,
min_weight_fraction_leaf=0.0, presort=False,
random_state=None, splitter='best')
算法正在进行预测,请稍候...
[1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 3 1 2 1 1 0
1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 2 2 0 0 0 1 0 2 0 0 2 0
1 0 0 0 0 1 0 1 1 1 0 0 0 0 0 0 3 3 0 0 1 1 0 0 0 0 0 0 0 0 1 0 0 0 0 2 0
1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 1 1 1 1 0 1 1 1 1
1 0 0 0 0 1 3 1 3 2 3 3 3 3 3 0 3 2 2 2 3 2 1 2 1 2 2 2 2 2 1 2 2 2 2 2 3
3 2 2 0 1 2 3 3 0 2 1 0 2 2 2]
算法正在进行性能评估,请稍候...
准确率
0.735
混淆矩阵
[[84 24 5 2]
[ 1 35 1 1]
[ 3 5 19 4]
[ 1 2 4 9]]
召回率
precision recall f1-score support
0 0.94 0.73 0.82 115
1 0.53 0.92 0.67 38
2 0.66 0.61 0.63 31
3 0.56 0.56 0.56 16
accuracy 0.73 200
macro avg 0.67 0.71 0.67 200
weighted avg 0.79 0.73 0.74 200
算法程序已经结束...
算法消耗时间为: 20.55004119873047 秒
Out[35]: (None, None, None)
3、多层感知器
mlpc = MLPClassifier()
result = get_text_classification(mlpc, X_train_count, y_train_le, X_test_count, y_test_le)
estimator_list.append(result[1]), score_list.append(result[2]), time_list.append(result[3])
算法正在启动,请稍候...算法正在进行训练,请稍候...MLPClassifier(activation='relu', alpha=0.0001, batch_size='auto', beta_1=0.9, beta_2=0.999, early_stopping=False, epsilon=1e-08, hidden_layer_sizes=(100,), learning_rate='constant', learning_rate_init=0.001, max_iter=200, momentum=0.9, n_iter_no_change=10, nesterovs_momentum=True, power_t=0.5, random_state=None, shuffle=True, solver='adam', tol=0.0001, validation_fraction=0.1, verbose=False, warm_start=False)算法正在进行预测,请稍候...[1 1 2 1 3 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 0 0 0 0 0 2 2 0 0 0 1 0 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 1 0 0 0 0 0 1 0 0 0 0 0 0 3 2 3