前言:
上一节介绍了基于情感词典的文本情感分类方法,这一节主要介绍采用机器学习的方法,对已有分类的数据集进行训练并测试,我从网上下载了一些关于外卖评论的情感语料,分成两个txt文件,一个是正向评论的文本文档,一个是负面评论的文本文档,如下图所示,本文基于此进行分类学习。


目录:
1.读取数据
2.分词
3.提取特征向量
4.机器学习之分类

1.读取数据

import numpy as np
import pandas as pd
import jieba
from sklearn.model_selection import train_test_split           #划分训练/测试集
from sklearn.feature_extraction.text import CountVectorizer    #抽取特征
from sklearn.naive_bayes import MultinomialNB
from sklearn.feature_extraction.text import TfidfVectorizer
#读取并清洗数据
#因为几个文档的编码不大一样,所以兼容了三种编码模式,根据经验,这三种是经常会遇到的
def get_txt_data(txt_file):mostwords=[]try:file=open(txt_file,'r',encoding='utf-8')for line in file.readlines():curline=line.strip().split("\t")mostwords.append(curline)except:try:file=open(txt_file,'r',encoding='gb2312')for line in file.readlines():curline=line.strip().split("\t")mostwords.append(curline)except:try:file=open(txt_file,'r',encoding='gbk')for line in file.readlines():curline=line.strip().split("\t")mostwords.append(curline)except:''   return mostwordsneg_doc=get_txt_data(r'D:\nltk_data\waimai_nlp\情感分析语料\waimai_neg.txt')
pos_doc=get_txt_data(r'D:\nltk_data\waimai_nlp\情感分析语料\waimai_pos.txt')

2.分词
分词工具有很多,主流的主要包括以下几种:

  1. 哈工大的LTP HIT-SCIR/ltp
  2. jieba分词工具 yanyiwu/cppjieba
  3. 清华大学THULAC https://github.com/thunlp/THULAC
  4. 斯坦福分词器 https://nlp.stanford.edu/software/segmenter.shtml
  5. Hanlp分词 hankcs/HanLP
  6. 字嵌入+Bi-LSTM+CRF分词器 https://github.com/koth/kcws
  7. ZPar分词器 frcchang/zpar

本篇主要采用了比较主流的jieba分词包,具体内容可以详见:jieba分词完整文档

另外,我将每个评论中一些垃圾词汇去掉了。所谓的垃圾词汇,就是指意义模糊的词,或者一些语气助词,标点符号等等,通常他们对文本起不了分类特征的意义。这些垃圾词汇我们称之为停用词。把所有停用词集合起来构成一张停用词表格,这样,以后我们处理文本时,就可以从这个根据表格,过滤掉文本中的一些垃圾词汇了。我的停用词是从网上下载了几个,合并起来的。大家可以自行下载或者准备自己需要的停用词。

def context_cut(sentence):words_list=[]#获取停用词stop=open(r'D:\nltk_data\NLP\情感分析\停用词库.txt','r+',encoding='utf-8')stopwords=stop.read().split('\n')cut_words=list(jieba.cut(sentence))for word in cut_words:if not(word in stopwords):words_list.append(word)words_str=','.join(words_list)return words_str,words_list #合并两个数据集,并且打上标签,分成测试集和训练集
words=[]
word_list=[]
for i in neg_doc:cut_words_str,cut_words_list=context_cut(i[0])word_list.append((cut_words_str,-1))words.append(cut_words_list)
for j in pos_doc:cut_words_str2,cut_words_list2=context_cut(j[0])word_list.append((cut_words_str2,1))words.append(cut_words_list2)
#word_list=[('菜品,质量,好,味道,好,就是,百度,的,问题,总是,用,运力,原因,来,解释,我,也,不,懂,这,是,什么,原因,晚,了,三个,小时,呵呵,厉害,吧,反正,订,了,就,退,不了,只能,干,等', -1),...,...]
#将word_list中的值和标签分别赋予给x,y
x,y=zip(*word_list)
x_train,x_test,y_train,y_test=train_test_split(x,y,test_size=0.2,random_state=0)

3.提取特征向量
3.1 ##将内容转为词袋向量(Bag of words)
在正式使用之前,我们首先举个例子来看一下词袋向量是什么样的:

data1= '今天上海的天气真好!我的心情非常高兴!如果去旅游的话我会非常兴奋!和你一起去旅游我会更加幸福!'
data2= '救命,你是个坏人,救命,你不要碰我,救命,你个大坏蛋!'
data3= '美国华裔科学家,祖籍江苏扬州市高邮县,生于上海,斯坦福大学物理系,电子工程系和应用物理系终身教授!'
words_str1,words_list1=context_cut(data1)
words_str2,words_list2=context_cut(data2)
words_str3,words_list3=context_cut(data3)
count = CountVectorizer()#这里可以加上max_features=10的参数,不加就是这三句话的全部词语。
doc = np.array([words_str1,words_str2,words_str3])
bag = count.fit_transform(doc)
print(count.vocabulary_) #查看词袋字典
[out]:{'今天': 3, '上海': 1, '天气': 8, '心情': 13, '非常高兴': 31, '如果': 9, '旅游': 19, '的话': 25, '我会': 14, '非常': 30,'兴奋': 4, '一起': 0, '更加': 20, '幸福': 11, '救命': 16, '坏人': 6, '不要': 2, '大坏蛋': 7, '美国': 29, '华裔': 5, '科学家': 27, '祖籍': 26, '江苏': 21, '扬州市': 15, '高邮县': 32,'生于': 23, '斯坦福大学': 18, '物理系': 22, '电子': 24, '工程系': 10, '应用': 12, '终身': 28, '教授': 17}
#三个句子的所有词的字典,后面的数字为每个词的唯一索引
print(bag.toarray()) #将语句转化为向量列表
#按照上述词袋的索引值从小到大进行排列,['一起','上海','不要',······],根据此顺序列出每句话的词语出现的频次,所以下列输出重得值为词的出现频率
[out]:[[1 1 0 1 1 0 0 0 1 0 1 0 1 2 0 0 0 0 2 1 0 0 0 0 0 0 0 0 1 1 0][0 0 1 0 0 0 1 1 0 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0][0 1 0 0 0 1 0 0 0 1 0 1 0 0 1 0 1 1 0 0 1 2 1 1 1 1 1 1 0 0 1]]

回归正题,下面将上面的分词文本转化成结构化向量:

#注意,countvectorizer只能训练str格式的,因为它里面会有lower之类的函数,不适用于列表等其它格式
count = CountVectorizer(max_features=500) #这里的max_features实根据后面的机器学习模型确定的,原先定为200的时候,机器学习效果较差,后改为500效果较好
bag = count.fit_transform(x_train)

3.2 TF-IDF(词频-逆向文件频率)
TF-IDF的主要思想是:如果某个单词在一篇文章中出现的频率TF高,并且在其他文章中很少出现,则认为此词或者短语具有很好的类别区分能力,适合用来分类。具体原理可以参照TF-IDF算法介绍及实现
具体实现:

from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_extraction.text import TfidfTransformercount = CountVectorizer(max_features=500) #该类会将文本中的词语转换为词频矩阵,矩阵元素a[i][j] 表示j词在i类文本下的词频
tfidf = TfidfTransformer(use_idf = True, norm = 'l2', smooth_idf = True) #该类会统计每个词语的tf-idf权值
tfidf_x_train=tfidf.fit_transform(count.fit_transform(x_train)) #将文本转为词频矩阵并计算tf-idf
np.set_printoptions(precision = 2)
x_train_weight = tfidf_x_train.toarray()print(x_train_weight)
#还有另一种方法是TfidfVectorizer,
#关于TfidfVectorizer和TfidfTransformer的关联可以参照[TfidfVectorizer和TfidfTransformer](https://blog.csdn.net/liuchenbaidu/article/details/105063535?biz_id=102&utm_term=TfidfVectorizer&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduweb~default-1-105063535&spm=1018.2118.3001.4187)
from sklearn.feature_extraction.text import TfidfVectorizer
vec=TfidfVectorizer(analyzer='word', ngram_range=(1,4), max_features=500)
tfidf_x_train=vec.fit_transform(x_tain) #与上面一种TfidfTransformer
tfidf_x_test=vec.fit_transform(x_test)

4.模型训练
4.1 回归模型

from sklearn.linear_model import LinearRegressionlin_reg=LinearRegression()lin_reg.fit(vec.transform(x_train),y_train)from sklearn.metrics import mean_squared_errory_test_hat=lin_reg.predict(vec.transform(x_test))
y_train_hat=lin_reg.predict(vec.transform(x_train))
lin_mse1=mean_squared_error(y_test,y_test_hat)
lin_mse2=mean_squared_error(y_train,y_train_hat)
lin_rmse1=np.sqrt(lin_mse1)
lin_rmse2=np.sqrt(lin_mse2)
print ('测试集:',lin_rmse1)
print ('训练集:',lin_rmse2)
#使用tf-idf特征向量,使用线性回归分类,mean_squared_error均方误差为0.71440708
'''测试集: 0.7144070856551623
训练集: 0.6777972230714499'''

4.2 决策树模型

##----------2.决策树-----##
#模型效果不好的时候(拟合不足),考虑换个更强大的模型,决策树
from sklearn.tree import DecisionTreeRegressor
tree_reg=DecisionTreeRegressor()tree_reg.fit(vec.transform(x_train),y_train)y_test_hat=tree_reg.predict(vec.transform(x_test))
y_train_hat=tree_reg.predict(vec.transform(x_train))
tree_mse1=mean_squared_error(y_test,y_test_hat)
tree_mse2=mean_squared_error(y_train,y_train_hat)
tree_rmse1=np.sqrt(tree_mse1)
tree_rmse2=np.sqrt(tree_mse2)
print ('测试集',tree_rmse1)
print ('训练集',tree_rmse2)
#使用tf-idf特征向量,使用决策树,
#如果tree_rmse接近0,可能模型师完美的,更可能的是数据严重过度拟合了
#在有信心启动模型之前,都不要触碰测试集,所以,建议拿训练集中的一部分用户训练,另一部分用于模型的验证
'''测试集 0.7432269884814903
训练集 0.31452945551691786'''

4.3 贝叶斯分类器–MultinomialNB

'''
使用CountVectorizer进行特征提取,使用MultinomialNB分类训练,max_features=200时,结果为0.4728125
max_features=500时,结果为0.5665625
'''
classfier = MultinomialNB()
classfier.fit(count.fit_transform(x_train),y_train)
print(classfier.score(count.fit_transform(x_test),y_test))#改用tf-idf进行特征提取,max_features=500时,结果为0.834375
classfier = MultinomialNB()
classfier.fit(vec.transform(x_train),y_train)
print('训练集:',classfier.score(vec.transform(x_test),y_test))
print('测试集:',classfier.score(vec.transform(x_train),y_train))
'''训练集: 0.8275
测试集: 0.83953125'''

4.4 SVM模型

##----------4.使用SVM模型进行训练----##
from sklearn import svm
#使用TF-IDF提取特征,使用SVM训练,结果为0.83125
from sklearn.metrics import accuracy_score
from sklearn.metrics import recall_score
from sklearn.metrics import f1_score
from sklearn.metrics import roc_auc_scoreclassfier = svm.SVC(kernel='linear')
classfier.fit(vec.transform(x_train),y_train)
#print(classfier.score(vec.transform(x_test),y_test))print ('训练集:',classfier.score(vec.transform(x_train), y_train))  # 精度
print ('测试集:',classfier.score(vec.transform(x_test), y_test))
'''训练集: 0.85234375
测试集: 0.83125'''
y_train_hat=classfier.predict(vec.transform(x_train))
print ('训练集准确率:',accuracy_score(y_train_hat,y_train))
print ('训练集召回率:',recall_score(y_train_hat,y_train))
print ('F1:',f1_score(y_train_hat,y_train))
print ('ROC值:',roc_auc_score(y_train_hat,y_train))
'''训练集准确率: 0.85234375
训练集召回率: 0.8585552543453995
F1: 0.8506873123716229
ROC值: 0.852466476919981'''# 分类报告:precision/recall/fi-score/均值/分类个数
from sklearn.metrics import classification_report
target_names = ['-1','1']
print(classification_report(y_train_hat,y_train, target_names=target_names))

4.5 随机森林(RandomForestRegressor)

from sklearn.ensemble import RandomForestRegressor
from sklearn.model_selection import cross_val_score
from IPython import displayforest_reg=RandomForestRegressor()
forest_reg.fit(vec.transform(x_train),y_train)
print('训练集:',forest_reg.score(vec.transform(x_test),y_test))
print('测试集:',forest_reg.score(vec.transform(x_train),y_train))
'''训练集: 0.5592796842264617
测试集: 0.8471523627994759'''##引入交叉验证,对模型进行调优
x_train_tf=tfidf.fit_transform(count.fit_transform(x_train)).toarray()
forest_scores=cross_val_score(forest_reg,x_train_tf,y_train,scoring='neg_mean_squared_error',cv=10)
forest_rmse_scores=np.sqrt(-forest_scores)
display(forest_rmse_scores)

4.6 逻辑回归

#引入随机搜索,选择最优模型参数
from sklearn.pipeline import Pipeline
from sklearn.linear_model import LogisticRegression
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.model_selection import GridSearchCVtfidf = TfidfVectorizer(strip_accents=None,lowercase=False,preprocessor=None)param_grid = [{'vect__ngram_range': [(1, 1)],'clf__penalty': ['l1', 'l2'],'clf__C': [1.0, 10.0, 100.0]},{'vect__ngram_range': [(1, 1)],'vect__use_idf':[False],'vect__norm':[None],'clf__penalty': ['l1', 'l2'],'clf__C': [1.0, 10.0, 100.0]},]lr_tfidf = Pipeline([('vect', tfidf),('clf', LogisticRegression(random_state=0))])gs_lr_tfidf = GridSearchCV(lr_tfidf, param_grid,scoring='accuracy',cv=5,verbose=1,n_jobs=-1)gs_lr_tfidf.fit(x_train, y_train)
print('Best parameter set: %s ' % gs_lr_tfidf.best_params_)
print('CV Accuracy: %.3f' % gs_lr_tfidf.best_score_)clf = gs_lr_tfidf.best_estimator_
print('Test Accuracy: %.3f' % clf.score(x_test, y_test))
'''
Best parameter set: {'clf__C': 10.0, 'clf__penalty': 'l2', 'vect__ngram_range': (1, 1)}
CV Accuracy: 0.877
Test Accuracy: 0.888'''

总结:
从结果看下来,比较好的模型是逻辑回归,MultinomialNB和SVM三种,本文采用的是tf-idf进行的特征提取,后面计划尝试用word2vec进行看看。以上,为一个NLP的新手学习,有任何不正确的欢迎指正!

基于机器学习的文本情感分类相关推荐

  1. 使用Python和机器学习进行文本情感分类

    使用Python和机器学习进行文本情感分类 1. 效果图 2. 原理 3. 源码 参考 这篇博客将介绍如何使用Python进行机器学习的文本情感分类(Text Emotions Classificat ...

  2. NLP之基于TextCNN的文本情感分类

    TextCNN 文章目录 TextCNN 1.理论 1.1 基础概念 **最大汇聚(池化)层:** ![请添加图片描述](https://img-blog.csdnimg.cn/10e6e1ed6bf ...

  3. 复盘:基于attention的多任务多模态情绪情感识别,基于BERT实现文本情感分类(pytorch实战)

    复盘:基于attention机制的多任务多模态情绪情感识别(pytorch实战),基于BERT实现文本情感分类 提示:系列被面试官问的问题,我自己当时不会,所以下来自己复盘一下,认真学习和总结,以应对 ...

  4. 阅读笔记——基于机器学习的文本情感多分类的学习与研究

    文章目录 1 文章简介 2 文本情感分类概述 3 文本情感多分类项目设计与实现 3.1 数据处理 3.2 特征选取 3.3 线性逻辑回归模型 3.4 朴素贝叶斯模型 4 项目结果与分析 5 总结 1 ...

  5. 基于Bert的文本情感分类

    详细代码已上传到github: click me 摘  要:     情感分类是对带有感情色彩的主观性文本进行分析.推理的过程,即分析说话人的态度,推断其所包含的情感类别.传统机器学习在处理情感分类问 ...

  6. 我的实践:pytorch框架下基于BERT实现文本情感分类

    当前,在BERT等预训练模型的基础上进行微调已经成了NLP任务的一个定式了.为了了解BERT怎么用,在这次实践中,我实现了一个最简单的NLP任务,即文本情感分类. 文章目录 1.基于BERT进行情感分 ...

  7. 【Kesci】【预选赛】2019中国高校计算机大赛——大数据挑战赛(基于FastText的文本情感分类)

    比赛链接:https://www.kesci.com/home/competition/5cb80fd312c371002b12355f 预选赛题--文本情感分类模型 本预选赛要求选手建立文本情感分类 ...

  8. Python基于机器学习的文本情感分析详细步骤[附代码和文字解释]

    最近在研究情感分析,感谢CSDN上很多博主的文章,让我受益匪浅.因此在跑出准确率高达88%的分类结果后,写下自己的代码和总结,希望对大家有所帮助~ 目录 一.文本数据预处理 1.读取json并转化为列 ...

  9. 基于LSTM搭建文本情感分类的深度学习模型:准确率95%

    向AI转型的程序员都关注了这个号

  10. 中文文本情感分类及情感分析资源大全

    摘要:20世纪初以来,文本的情感分析在自然语言处理领域成为了研究的热点,吸引了众多学者越来越多的关注.对于中文文本的情感倾向性研究在这样一大环境下也得到了显著的发展.本文主要是基于机器学习方法的中文文 ...

最新文章

  1. POJ 2828 Buy Tickets | 线段树的喵用
  2. AT2362 [AGC012B] Splatter Painting(思维、dfs染色、剪枝)
  3. 手把手教你Tableau高级数据分析功能(附数据集)
  4. python截取数组的一半_python:28.数组中出现次数超过一半的数字
  5. javaScript事件(二)事件处理程序
  6. 《易学C++(第2版)》——1.4 C++能够做些什么
  7. 100个微信小程序的源码公开分享
  8. TreeTemplate树模板
  9. 4.剑指Offer --- 解决面试题的思路
  10. .Net MVC控制器中进行页面跳转并传递多个参数
  11. Ubuntu、SUSE的发音
  12. 小福利,杨格(Young)不等式验证之用python里面的matplotlib和numpy模块画图
  13. PWM的占空比、分辨率
  14. 获取闲鱼已售商品的价格等信息
  15. 中专毕业后我的七年(励志篇,年轻人必看)
  16. xhci主机规范初探(2) --数据结构预览
  17. 疯狂java讲义(第三版-李刚) 源代码 光盘
  18. 输入数字,输出数字读法
  19. MavenNexus入门
  20. 学习AP历史有哪些建议?

热门文章

  1. OpenCV 4 中文文档(更新mat部分)
  2. C#,数据库,会员积分管理系统
  3. Win10系统下CUDA10.0的安装
  4. ENVI分类格式转TIF
  5. 单机版fifa11显示ea服务器,游戏新消息:EA服务器出问题所有EA游戏在线功能无法正常运行...
  6. 【智能无线小车系列八】在树莓派上使用USB摄像头
  7. Altium Designer 20查找指定元器件
  8. dell台式计算机恢复出厂设置,戴尔电脑如何恢复出厂设置
  9. 百度网盘机器人软件工具自动发货管理文件好友群补发文件资料 (可用于拼多多淘宝闲鱼虚拟店商品自动发货)
  10. 中国省份名称的映射字典