1.用ML实现外卖评论的分类

步骤

  • 语料加载、
  • 分词、
  • 去停用词、
  • 抽取词向量特征、
  • 分别进行算法建模和模型训练、
  • 评估、计算AUC值、
  • 模型对比

1.进行语料加载。 在此之前,引入python依赖的包,并将全部语料和停用词dict读入内存中。

setp 1:引入依赖库:random随机数库、jieba分词库、pandas库
import random
import jieba
import pandas as pd
setp 2: 加载停用词字典 停用词词典为 stopwords.txt 文件,可以根据场景自己在该文本里面添加要去除的词(比如冠词、人称、数字等特定词)
stopwords = pd.read_csv('~/Desktop/stopWords_3.txt',index_col=False,quoting=3,sep='\t',names=['stopword'],encoding='utf-8')
stopwords = stopwords['stopword'].values
step 3:加载语料,语料是4个已经分好类的 csv 文件,直接用 pandas 加载即可,加载之后可以首先删除 nan 行,并提取要分词的 content 列转换为 list 列表
waimai_df = pd.read_csv('~/Downloads/ChineseNlpCorpus-master/datasets/waimai_10k/waimai_10k.csv', encoding='utf-8', sep=',')#删除语料的nan行
waimai_df.dropna(inplace=True)
#转换成列表形式
waimai = waimai_df.review.values.tolist()
label_id = waimai_df.label.values.tolist()

2. 分词和去停用词

step 1:定义分词、去停用词的函数,函数包含2个参数:content_lines 参数为语料列表;sentences 参数为预先定义的 list,用来存储分词并打标签后的结果;
def preprocess_text(content_lines, sentences):for line in content_lines:try:segs=jieba.lcut(line)segs = [v for v in segs if not str(v).isdigit()]#去数字segs = list(filter(lambda x:x.strip(), segs))   #去左右空格segs = list(filter(lambda x:len(x)>1, segs)) #长度为1的字符segs = list(filter(lambda x:x not in stopwords, segs)) #去掉停用词sentences.append(" ".join(segs))except Exception:continue
step 2:调用函数、生成训练数据
sentences = []
preprocess_text(waimai,sentences)sentences = list(zip(sentences,label_id))
# print(sentences)
Building prefix dict from the default dictionary ...
Loading model from cache /tmp/jieba.cache
Loading model cost 0.726 seconds.
Prefix dict has been built succesfully.
step 3:将得到的数据集打散,生成更可靠的训练集分布,避免同类数据分布不均匀:
random.shuffle(sentences)
#在控制台输出前10条数据,观察一下
for sentence in sentences[:10]:print(sentence[0], sentence[1])
一般 服务 差到 至极 饭量 要死 0
好吃 卫生 满意 1
味道 送餐 太慢 饭菜 全凉 0
送餐 米饭 三盒 两盒 两盒 0
两份 筷子 0
太坑 图片 很大 可怜 肥肉 肘子 0
好吃 准时 1
猪肉 堡里 酱流 满意 猪肉 1
送来 没人接 电话 0
太贵 八个 饺子 大小 包子 几口 1

3. 抽取词向量特征。

step 1:抽取特征,我们定义文本抽取词袋模型特征
from sklearn.feature_extraction.text import CountVectorizer
vec = CountVectorizer(analyzer='word', # tokenise by character ngramsmax_features=None,  # keep the most common 1000 ngramsvocabulary=None
)
step 2:把语料数据切分,用 sk-learn 对数据切分,分成训练集和测试集
from sklearn.model_selection import train_test_splitx, y = zip(*sentences)
x_train, x_test, y_train, y_test = train_test_split(x, y)
step 3:把训练数据转换为词袋模型
vec.fit(x_train)
CountVectorizer(analyzer='word', binary=False, decode_error='strict',dtype=<class 'numpy.int64'>, encoding='utf-8', input='content',lowercase=True, max_df=1.0, max_features=None, min_df=1,ngram_range=(1, 1), preprocessor=None, stop_words=None,strip_accents=None, token_pattern='(?u)\\b\\w\\w+\\b',tokenizer=None, vocabulary=None)

4.分别进行算法建模和模型训练。

setp 1:定义SVM模型,然后对训练集进行模型训练,直接使用 sklearn 中的 svm.SVC
from sklearn.svm import SVC
# svm = SVC(kernel='rbf',C=1000,gamma=0.001)
svm = SVC(kernel='linear') #0.8401735068401736
# svm = SVC(kernel='poly',gamma=1000)
svm.fit(vec.transform(x_train), y_train)
SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0,decision_function_shape='ovr', degree=3, gamma='auto_deprecated',kernel='linear', max_iter=-1, probability=False, random_state=None,shrinking=True, tol=0.001, verbose=False)

5. 评估、计算 AUC 值。

setp 1:上面步骤1-4完成了从语料到模型的训练,训练之后,我们要用测试集来计算 AUC 值:
 print(svm.score(vec.transform(x_test), y_test))
0.8468468468468469
step 2:进行测试集的预测:
pre = svm.predict(vec.transform(x_test))

6. 模型对比。

整个模型从语料到训练评估 步骤1-5就完成了,接下来看看,改变特征向量模型和训练模型对结果有什么变化。
6-1 改变特征向量模型

下面可以把特征做得更强一点,尝试加入抽取 2-gram 和 3-gram 的统计特征,把词库的量放大一点。

from sklearn.feature_extraction.text import CountVectorizer
vec = CountVectorizer(analyzer='word', # tokenise by character ngramsngram_range=(1,4),  # use ngrams of size 1 and 2max_features=20000,  # keep the most common 1000 ngrams
)
vec.fit(x_train)from sklearn.svm import SVC
# svm = SVC(kernel='rbf',C=1000,gamma=0.001)
svm = SVC(kernel='linear') #0.8401735068401736
# svm = SVC(kernel='poly',gamma=1000)
svm.fit(vec.transform(x_train), y_train)
print(svm.score(vec.transform(x_test), y_test))
0.8375041708375042
6-2 改变训练模型
1 使用朴素贝叶斯训练 直接使用 sklearn 中的 MultinomialNB
from sklearn.model_selection import train_test_splitx, y = zip(*sentences)
x_train, x_test, y_train, y_test = train_test_split(x, y)vec.fit(x_train)from sklearn.naive_bayes import MultinomialNB
classifier = MultinomialNB()
classifier.fit(vec.transform(x_train), y_train)
print(classifier.score(vec.transform(x_test), y_test))
0.8495161828495161
2 使用XGBoost训练
import xgboost as xgb
from sklearn.model_selection import StratifiedKFold
import numpy as np
# xgb矩阵赋值  xgb_train = xgb.DMatrix(vec.transform(x_train), label=y_train)
xgb_test = xgb.DMatrix(vec.transform(x_test))params={'booster':'gbtree','objective': 'binary:logistic','eval_metric': 'auc','max_depth':4,'lambda':10,'subsample':0.75,'colsample_bytree':0.75,'min_child_weight':2,'eta': 0.025,'seed':0,'nthread':8,'silent':1}watchlist = [(xgb_train,'train')]
bst=xgb.train(params,xgb_train,num_boost_round=5,evals=watchlist)
#输出概率
ypred=bst.predict(xgb_test)# 设置阈值, 输出一些评价指标,选择概率大于0.5的为1,其他为0类
y_pred = (ypred >= 0.5)*1from sklearn import metrics
print ('AUC: %.4f' % metrics.roc_auc_score(y_test,ypred))
print ('ACC: %.4f' % metrics.accuracy_score(y_test,y_pred))
print ('Recall: %.4f' % metrics.recall_score(y_test,y_pred))
print ('F1-score: %.4f' %metrics.f1_score(y_test,y_pred))
print ('Precesion: %.4f' %metrics.precision_score(y_test,y_pred))
print(metrics.confusion_matrix(y_test,y_pred))
[0]  train-auc:0.682634
[1] train-auc:0.701378
[2] train-auc:0.70118
[3] train-auc:0.701877
[4] train-auc:0.702868
AUC: 0.7019
ACC: 0.7501
Recall: 0.4863
F1-score: 0.5622
Precesion: 0.6662
[[1767  241][ 508  481]]

2. 何为AUC值和ROC曲线?

参考百度百科及以下这篇博文:
https://baijiahao.baidu.com/s?id=1597939133517926460&wfr=spider&for=pc

AUC(Area Under Curve被定义为ROC曲线下的面积。
我们往往使用AUC值作为模型的评价标准是因为很多时候ROC曲线并不能清晰的说明哪个分类器的效果更好,而作为一个数值,对应AUC更大的分类器效果更好。

其中,ROC曲线全称为受试者工作特征曲线 (receiver operating characteristic curve),它是根据一系列不同的二分类方式(分界值或决定阈),以真阳性率(敏感性)为纵坐标,假阳性率(1-特异性)为横坐标绘制的曲线。

具体到机器学习的理论中,ROC曲线该怎么理解呢?首先,需要指出的是,ROC分析的是二元分类模型,也就是输出结果只有两种类别的模型,比如:(阳性/阴性)(有病/没病)(垃圾邮件/非垃圾邮件)。在二分类问题中,数据的标签通常用(0/1)来表示,在模型训练完成后进行测试时,会对测试集的每个样本计算一个介于0~1之间的概率,表征模型认为该样本为阳性的概率,我们可以选定一个阈值,将模型计算出的概率进行二值化,比如选定阈值=0.5,那么当模型输出的值大于等于0.5时,我们就认为模型将该样本预测为阳性,也就是标签为1,反之亦然。选定的阈值不同,模型预测的结果也会相应地改变。二元分类模型的单个样本预测有四种结果:

  • 真阳性(TP):判断为阳性,实际也是阳性。
  • 伪阳性(FP):判断为阴性,实际却是阳性。
  • 真阴性(TN):判断为阴性,实际也是阴性。
  • 伪阴性(FN):判断为阴性,实际却是阳性。

这四种结果可以画成2 × 2的混淆矩阵:

有了混淆矩阵,就可以定义ROC曲线了。ROC曲线将假阳性率(FPR)定义为 X 轴,真阳性率(TPR)定义为 Y 轴。其中:
TPR:在所有实际为阳性的样本中,被正确地判断为阳性的样本比率。
FPR:在所有实际为阴性的样本中,被错误地判断为阳性的样本比率。
TPR = TP / (TP + FN)
FPR = FP / (FP + TN)
给定一个二分类模型和它的阈值,就可以根据所有测试集样本点的真实值和预测值计算出一个 (X=FPR, Y=TPR) 坐标点,这也就是绘制单个点的方法。那整条ROC曲线又该怎么画呢?具体方法如下:
在我们训练完一个二分类模型后,可以使用该模型对测试集中的全部样本点计算一个对应的概率值,每个值都介于0~1之间。假设测试集有100个样本点,我们可以对这100个样本的预测值从高到低排序,然后依次取每个值作为阈值,一旦阈值确定我们就可以绘制ROC曲线上的一个点,按照这种方法依次将100个点绘制出来,再将各个点依次连接起来,就得到了我们想要的ROC曲线!

然后再回到最初的问题,
AUC就是衡量学习器优劣的一种性能指标,可通过对ROC曲线下各部分的面积求和而得。当我们绘制出ROC曲线之后,AUC的值自然也就计算好啦。

为什么需要用AUC值表征模型的好坏?
在进行学习器的比较时,若一个学习器的ROC曲线被另一个学习器的曲线完全“包住”,则可断言后者的性能优于前者;若两个学习器的ROC曲线发生交叉,则难以一般性的断言两者孰优孰劣。此时如果一定要进行比较,则比较合理的判断依据是比较ROC曲线下的面积,即AUC(Area Under ROC Curve)。

从AUC 判断分类器(预测模型)优劣的标准:

AUC = 1,是完美分类器。
AUC = [0.85, 0.95], 效果很好
AUC = [0.7, 0.85], 效果一般
AUC = [0.5, 0.7],效果较低,但用于预测股票已经很不错了
AUC = 0.5,跟随机猜测一样(例:丢铜板),模型没有预测价值。
AUC < 0.5,比随机猜测还差;但只要总是反预测而行,就优于随机猜测。

【NLP】用ML实现中文短文本分类(二分类)相关推荐

  1. ML之LoR:利用LoR二分类之非线性决策算法案例应用之划分正负样本

    ML之LoR:利用LoR二分类之非线性决策算法案例应用之划分正负样本 目录 输出结果 实现代码 输出结果 1.对数据集进行特征映射 2.正则化 → 正则化 → 过度正则化 实现代码 import nu ...

  2. ML之LoR:LoR之二分类之线性决策算法实现根据两课成绩分数~预测期末通过率(合格还是不合格)

    ML之LoR:LoR之二分类之线性决策算法实现根据两课成绩分数~预测期末通过率(合格还是不合格) 目录 输出结果 代码设计 输出结果 LoR之二分类算法实现预测期末考试成绩合格还是不合格 LoR回归函 ...

  3. 第06课:动手实战基于 ML 的中文短文本分类

    文本分类,属于有监督学习中的一部分,在很多场景下都有应用,下面通过小数据的实例,一步步完成中文短文本的分类实现,整个过程尽量做到少理论重实战. 开发环境,我们选择: Windows 系统 Python ...

  4. Deep Learing 记录:电影评论分类——二分类问题

    文章目录 一.数据集介绍与可视化展示 1.数据集介绍 2.数据展示--评论解码 二.数据处理与说明 1.train_data处理(列表处理) 2.train_labels处理(标签向量化) 三.网络构 ...

  5. 第07课:动手实战基于 ML 的中文短文本聚类

    关于文本聚类,我曾在 Chat<NLP 中文文本聚类之无监督学习>中介绍过,文本聚类是将一个个文档由原有的自然语言文字信息转化成数学信息,以高维空间点的形式展现出来,通过计算哪些点距离比较 ...

  6. 分类家族:二分类、多分类、多标签分类、多输出分类

    分类家族:二分类.多分类.多标签分类.多输出分类 目录 分类家族:二分类.多分类.多标签分类.多输出分类 二分类

  7. LESSON 10.110.210.3 SSE与二分类交叉熵损失函数二分类交叉熵损失函数的pytorch实现多分类交叉熵损失函数

    在之前的课程中,我们已经完成了从0建立深层神经网络,并完成正向传播的全过程.本节课开始,我们将以分类深层神经网络为例,为大家展示神经网络的学习和训练过程.在介绍PyTorch的基本工具AutoGrad ...

  8. 机器学习中的数学原理——二分类问题

    今天是2022年的最后一天,提前祝大家新年快乐!这个专栏主要是用来分享一下我在机器学习中的学习笔记及一些感悟,也希望对你的学习有帮助哦!感兴趣的小伙伴欢迎私信或者评论区留言!这一篇就更新一下<白 ...

  9. NLP 中文短文本分类项目实践(下)

    本场 Chat 和<NLP 中文短文本分类项目实践(上)>可以看做姊妹篇,在上一篇的基础上,本篇主要讲一下文本分类在集成学习和深度学习方面的应用,由于内容比较多,笔者不可能面面俱到.下面我 ...

最新文章

  1. Java 虚拟机总结给面试的你(中)
  2. php百度地图添加标记,JavaScript API - 自定义标注 | 百度地图API SDK
  3. linux查看文件隐藏字符,Linux使用cat命令显示隐藏字符的方法
  4. Mac安装双系统-win10
  5. Java io字符流读入英文_Java IO 系列教程(四)-字符输入流(2)
  6. Halcon算子学习:surface_normals_object_model_3d
  7. Node.js文件操作二
  8. eclipse 最全快捷键(网络收集)
  9. linux蜂鸣器控制实验,【Linux公开课】蜂鸣器使用、LCD背光控制、触摸屏校准、GPIO操作...
  10. Mybatis——持久层框架
  11. android定义键盘示例(斗地主或跑得快的记牌器)
  12. kettle同步数据 (SAP hana到 Mysql)
  13. Programming-寻找发贴水王(C)
  14. Padded优化LinkedTransferQue并发性能是错误方向
  15. rebase操作步骤
  16. Android实现直播的博文和流程(全过程,超详细/附源码)
  17. signal(SIGCHLD, SIG_IGN)
  18. 【Linux】用最形象的例子学习进程,从入门到深入
  19. 远程连接云服务器中的mysql数据库_云服务器远程连接mysql数据库
  20. mysql数据库一些常用操作

热门文章

  1. Mapbox、GeoServer离线部署矢量地图
  2. 智慧城市数字孪生系统深度融合大数据、云计算等技术应用
  3. mac 下 GBK 显示乱码
  4. 明解C语言入门篇_第6章_函数
  5. 微信公众号添加聊天机器人
  6. Git 如何带你回到过去
  7. 分布式系统全链路压测方法
  8. python使用pyecharts展示中国各城市天气数据
  9. 卸载已有navicat for mysql,安装破解版。
  10. ant root环境配置_ANT介绍及安装及配置