最近在研究情感分析,感谢CSDN上很多博主的文章,让我受益匪浅。因此在跑出准确率高达88%的分类结果后,写下自己的代码和总结,希望对大家有所帮助~

目录

  • 一、文本数据预处理
    • 1、读取json并转化为列表
    • 2、文本清洗与处理
      • 1)去除网页链接
      • 2)判断字符串是否全是英文
      • 3)分词、识别英文单词、去除标点符号
      • 4)词性标注、词形还原、停用词过滤
    • 3、处理数据集B完整代码及主函数
    • 4、处理数据集A的完整代码与主函数
  • 二、训练算法模型
    • 1、文本特征表示
    • 2、训练算法模型
      • 1)随机划分数据集和训练集
      • 2)导入算法模型
      • 3)训练算法模型
      • 4)预测测试集中的文本情感
      • 5)评估分类效果
    • 3、保存及调用训练好的算法模型
      • 1)保存训练好的模型
      • 2)调用之前保存的模型
    • 4、词袋模型和贝叶斯模型串联的完整代码
    • 5、TF-IDF和支持向量机串联预测的完整代码

一、文本数据预处理

情感分析主要涉及两个数据集,一个是人工标注好的数据集,即包含了情感标签和文本的数据集A,另一个是用于情感分析的原始数据集,即只包含文本的数据集B。数据集A用于训练和测试,数据集B用于得到想要的情感分析结果。

本文数据集A为斯坦福大学的Sentiment140数据集,包含了160万条标注情感极性的推文。数据集B为我从TwitterAPI上爬取的两个月推文。

预处理主要是处理数据集B中的原始数据和数据集A中的文本,目的是将包含网页链接、标点符号及无意义单词的杂乱数据转化为干净的由有意义单词组成的字符串,并使用pandas dataframe存储。

1、读取json并转化为列表

初始爬取到的推文为json格式,因此需要读取json文件,并将其中的每条推文存储到列表中,目标格式为 [‘今天天气真好’,‘This is my bag’]

import jsondef get_tweets(filepath):tweets = []file = open(filepath, 'r')for line in file.readlines():#由于json为多层嵌套,所以分行读取dic = json.loads(line) #将json转化为字典text = str(dic.get('text', '!')) #如果字典中'text'键为空,则返回'!',不处理会返回Nonetweets.append(text)return tweets

2、文本清洗与处理

1)去除网页链接

使用正则表达式去除http,https网页链接

import redef remove_urls(vTEXT):vTEXT = re.sub(r'(https|http)?:\/\/(\w|\.|\/|\?|\=|\&|\%)*\b', '', vTEXT, flags=re.MULTILINE)return (vTEXT)

2)判断字符串是否全是英文

使用ASCII字符串的取值范围判断是否是英文字符串

def judge_english(text):return all(ord(c) < 128 for c in text) #包括英文文本、英文标点符号

3)分词、识别英文单词、去除标点符号

  • 这里使用nltk的TweetTokenizer进行英文分词,strip_handles参数表示删除句柄,即@Justin这种格式的短语,如果没有删除句柄的需求可以使用nltk的tokenize,将字符串分词为列表

  • 使用enchant检查字符串是否是英文单词,这是比nltk更全面的英文词典库,但是enchant将 They’re 这种缩略词也判定为英文单词,因此使用 isalpha() 函数加一层过滤,筛选掉含有标点符号的字符串,只保留纯英文字符串

import enchant
from nltk.tokenize import TweetTokenizerdef get_word(text):USdict = enchant.Dict("en_US") #英语词典text = text.replace('.', ' ') #将句号替换为空格tknzr = TweetTokenizer(strip_handles=True, reduce_len=True) #删除句柄rawwords = tknzr.tokenize(text) #分词words = [word.lower() for word in rawwords if USdict.check(word) and word.isalpha() and len(word) > 2]  #判断是否是长度大于2的英文单词并转化为小写字母return words

4)词性标注、词形还原、停用词过滤

  • 相较于词干提取,词形还原的结果更具有可读性,词干提取把词的后缀删减掉,比如luckily缩减为lucki,而lucki并不是单词,词形还原则是将ate还原为eat,将luckily还原为lucky,还原结果仍是英文单词。
  • 词形还原依赖于对词性进行准确的标注,不进行标注的话函数默认词性为名词进行还原,还原结果并不好,如wnl.lemmatize(‘ate’)结果仍是‘ate’,标注动词词性后wnl.lemmatize(‘ate’,‘V’)还原为‘eat’
  • 停用词过滤使用nltk的英文停用词词典
from nltk.corpus import stopwords
from nltk.stem import WordNetLemmatizer
from nltk import pos_tag
from nltk.corpus import wordnetstoplist = set(stopwords.words('english'))#停用词词典def get_pos_word(words):# def get_wordnet_pos(tag):if tag.startswith('J'):return wordnet.ADJelif tag.startswith('V'):return wordnet.VERBelif tag.startswith('N'):return wordnet.NOUNelif tag.startswith('R'):return wordnet.ADVelse:return Nonewords = pos_tag(words) #词性标注pos_word = [wnl.lemmatize(tag[0], pos=get_wordnet_pos(tag[1]) or wordnet.NOUN) for tag in words] #词形还原# 停用词过滤cleanwords = [word for word in pos_word if word not in stoplist]return cleanwords

3、处理数据集B完整代码及主函数

使用pandas dataframe存储处理后的文本数据并保存为csv格式文件

import json
import re
import enchant
from nltk.corpus import stopwords
from nltk.stem import WordNetLemmatizer
import pandas as pd
from nltk import pos_tag
from nltk.corpus import wordnet
from nltk.tokenize import TweetTokenizerwnl = WordNetLemmatizer()
USdict = enchant.Dict("en_US")
stoplist = set(stopwords.words('english'))# 获取处理后的英文推特
def get_tweets(filepath):tweets = []file = open(filepath, 'r')# 去除链接def remove_urls(vTEXT):vTEXT = re.sub(r'(https|http)?:\/\/(\w|\.|\/|\?|\=|\&|\%)*\b', '', vTEXT, flags=re.MULTILINE)return (vTEXT)# 筛选英文def judge_english(text):return all(ord(c) < 128 for c in text)# 获取文本for line in file.readlines():dic = json.loads(line)text = str(dic.get('text', '!'))if judge_english(text):tweets.append(remove_urls(text))return tweetsdef get_word(text):text = text.replace('.', ' ')tknzr = TweetTokenizer(strip_handles=True, reduce_len=True)rawwords = tknzr.tokenize(text)words = [word.lower() for word in rawwords if USdict.check(word) and word.isalpha() and len(word) > 2]return words# 词性还原
def get_pos_word(words):def get_wordnet_pos(tag):if tag.startswith('J'):return wordnet.ADJelif tag.startswith('V'):return wordnet.VERBelif tag.startswith('N'):return wordnet.NOUNelif tag.startswith('R'):return wordnet.ADVelse:return Nonewords = pos_tag(words)pos_word = [wnl.lemmatize(tag[0], pos=get_wordnet_pos(tag[1]) or wordnet.NOUN) for tag in words]# 停用词过滤cleanwords = [word for word in pos_word if word not in stoplist]return cleanwordsif __name__ == '__main__':filepath='D:/data/test.json' storename = 'D:/data/test.csv' tweets = get_tweets(filepath)df = pd.DataFrame()df['tweets'] = tweets# 分词df['tweets'] = df['tweets'].apply(get_word)# 词形还原df['tweets'] = df['tweets'].apply(get_pos_word)# 删除tweets中的空列表df = df[~(df['tweets'].str.len() == 0)]# 将列表转换为字符串df['tweets'] = df['tweets'].apply(lambda x: ' '.join(x))# 保存文本df.to_csv(storename, encoding='utf-8')

4、处理数据集A的完整代码与主函数

不同于处理数据集B,数据集A为行列数据整齐的英文文本,但是没有列名,且有几列多余数据,因此主要加入了对csv格式文件的读取和处理,注意本文使用的数据集A编码格式为 ISO-8859-1,大家读取csv文件 读取csv文件 encoding=‘ISO-8859-1’ 报错时改成 encoding=‘utf-8’

import enchant
from nltk.corpus import stopwords
from nltk.stem import WordNetLemmatizer
from nltk import pos_tag
from nltk.corpus import wordnet
from nltk.tokenize import TweetTokenizer
import pandas as pd
import rewnl = WordNetLemmatizer()
USdict = enchant.Dict("en_US")
stoplist = set(stopwords.words('english'))def remove_urls(vTEXT):vTEXT = re.sub(r'(https|http)?:\/\/(\w|\.|\/|\?|\=|\&|\%)*\b', '', vTEXT, flags=re.MULTILINE)return (vTEXT)def get_word(text):text = text.replace('.', ' ')tknzr = TweetTokenizer(strip_handles=True, reduce_len=True)rawwords = tknzr.tokenize(text)words = [word.lower() for word in rawwords if USdict.check(word) and not str.isdigit(word) and len(word) > 2]return wordsdef get_pos_word(words):def get_wordnet_pos(tag):if tag.startswith('J'):return wordnet.ADJelif tag.startswith('V'):return wordnet.VERBelif tag.startswith('N'):return wordnet.NOUNelif tag.startswith('R'):return wordnet.ADVelse:return Nonewords = pos_tag(words)pos_word = [wnl.lemmatize(tag[0], pos=get_wordnet_pos(tag[1]) or wordnet.NOUN) for tag in words]# 停用词过滤cleanwords = [word for word in pos_word if word not in stoplist]return cleanwordsif __name__ == '__main__':file = pd.read_csv('D:/data/Train.csv', encoding='ISO-8859-1',header=None, names=['label', 'id', 'day', 'query', 'user', 'tweets']) #pandas dataframe自定义列表名file = file.drop(file.columns[1:5], axis=1) #删除多余列#去除链接df['tweets'] = df['tweets'].apply(remove_urls)# 分词df['tweets'] = df['tweets'].apply(get_word)# 文本处理结果df['tweets'] = df['tweets'].apply(get_pos_word)# 删除tweets中的空列表df = df[~(df['tweets'].str.len() == 0)]# 转换字符串df['tweets'] = df['tweets'].apply(lambda x: ' '.join(x))# 打乱顺序df = df.sample(frac=1.0).reset_index(drop=True)#保存文本df.to_csv("D:\data\Test5000.csv", encoding='utf-8',index=None)

二、训练算法模型

本文主要使用sklearn中封装的模型进行训练

1、文本特征表示

分别使用词袋模型和TF-IDF进行文本特征表示,max_features参数是指选取的特征数最大值,大家根据各自的数据情况和需要制定最大值

from sklearn.feature_extraction.text import CountVectorizer
from sklearn.feature_extraction.text import TfidfVectorizer#词袋模型
bow_vectorizer = CountVectorizer(max_df=0.80, min_df=2, max_features=5000)# TF-IDF feature
tfidf_vectorizer = TfidfVectorizer(max_df=0.80, min_df=2, max_features=5000)

2、训练算法模型

1)随机划分数据集和训练集

将数据集A中人工标注的标签和文本分别作为因变量y和自变量x,并使用sklearn中的train_test_split进行随机划分,test_size参数为测试集比例,一般选择0.2,即80%训练集,20%测试集

from sklearn.model_selection import train_test_splitdf = pd.read_csv("D:\data\Train.csv", encoding='utf-8')
x=df['tweets'] #自变量
y=df['label']  #因变量x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=1) #划分测试集和训练集

2)导入算法模型

本文选取五种算法模型:K近邻、逻辑回归、随机森林、支持向量机、朴素贝叶斯进行模型训练

from sklearn.linear_model import LogisticRegression
from sklearn.naive_bayes import MultinomialNB
from sklearn.linear_model import SGDClassifier
from sklearn.neighbors import KNeighborsClassifier
from sklearn.ensemble import RandomForestClassifier# KNN Classifier K近邻算法
Knn = KNeighborsClassifier()# Logistic Regression Classifier 逻辑回归
Lr = LogisticRegression()# Random Forest Classifier 随机森林
Rf = RandomForestClassifier()# SVM Classifier 支持向量机
Svm = SGDClassifier()# Naive Bayes 朴素贝叶斯
Nb = MultinomialNB()

3)训练算法模型

为了防止出错和精简代码,本文使用pipe管道封装文本特征表示和算法模型两个步骤,后续直接使用pipe拟合即可,这里以串联词袋模型和朴素贝叶斯为例,也可以串联词袋模型和随机森林等等,根据需要串联即可。

from sklearn.pipeline import make_pipelinepipe = make_pipeline(bow_vectorizer, Nb) #词袋模型串联朴素贝叶斯算法
pipe.fit(x_train, y_train)

4)预测测试集中的文本情感

y_pred = pipe.predict(x_test) #进行预测
df['pred']=y_pred #将预测结果保存到dataframe中

5)评估分类效果

常用的分类算法评估指标包括:准确率(Accuracy)、精准度(Precision)、召回率(Recall)和F1值(F1-score),使用sklearn自带的metrics即可得到包含上面几个指标的分类效果评估报告。

from sklearn import metrics
print(metrics.classification_report(y_test, y_pred))

3、保存及调用训练好的算法模型

1)保存训练好的模型

为了防止以后每次进行数据时都要进行拟合,直接使用sklearn自带的joblib即可保存训练好的模型。

from sklearn.externals import joblib
joblib.dump(pipe, 'D:/data/Bayes.pkl')

2)调用之前保存的模型

Bayes=joblib.load('D:/data/Bayes.pkl') #加载模型
y_pred = Bayes.predict(x_test) #预测结果和pipe一致
df['pred02']=y_pred #将预测结果保存到dataframe中

4、词袋模型和贝叶斯模型串联的完整代码

import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.naive_bayes import MultinomialNB
from sklearn.pipeline import make_pipeline
from sklearn.externals import joblibdf = pd.read_csv("D:\data\Train.csv", encoding='utf-8')
df = df.sample(frac=1.0).reset_index(drop=True)x=df['tweets'] #自变量
y=df['label']  #因变量x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=1) #划分测试集和训练集# 词袋模型
bow_vectorizer = CountVectorizer(max_df=0.80, min_df=2)#贝叶斯模型
Nb = MultinomialNB()
pipe = make_pipeline(bow_vectorizer, Nb)
pipe.fit(x_train, y_train)y_pred = pipe.predict(x_test) #预测df['pred']=y_pred #保存预测结果到dataframe中print(metrics.classification_report(y_test, y_pred)) #评估joblib.dump(pipe, 'D:/data/Bayes.pkl') #保存模型

5、TF-IDF和支持向量机串联预测的完整代码

import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.linear_model import SGDClassifier
from sklearn.pipeline import make_pipeline
from sklearn.externals import joblibdf = pd.read_csv("D:\data\Train.csv", encoding='utf-8')
df = df.sample(frac=1.0).reset_index(drop=True)x=df['tweets'] #自变量
y=df['label']  #因变量x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=1) #划分测试集和训练集# TF-IDF
tfidf_vectorizer = TfidfVectorizer(max_df=0.80, min_df=2)# SVM Classifier
Svm = SGDClassifier()
pipe = make_pipeline(tfidf_vectorizer, Svm)
pipe.fit(x_train, y_train)y_pred = pipe.predict(x_test) #预测
df['pred']=y_pred #保存预测结果到dataframe中print(metrics.classification_report(y_test, y_pred)) #评估joblib.dump(pipe, 'D:/data/SVM.pkl') #保存模型

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

  1. Python 基于机器学习的微博情感分析与研究

    源码下载地址 中文微博情感分类语料库 "情感分析"是我本科的毕业设计, 也是我入门并爱上NLP的项目hhh, 当时网上相关语料库的质量都太低了, 索性就自己写了个爬虫, 一边标注一 ...

  2. python实现情感分析_使用python+机器学习方法进行情感分析(详细步骤)

    使用python+机器学习方法进行情感分析(详细步骤) 2021-02-07 不是有词典匹配的方法了吗?怎么还搞多个机器学习方法.因为词典方法和机器学习方法各有千秋.机器学习的方法精确度更高,因为词典 ...

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

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

  4. 基于Transformer的文本情感分析编程实践(Encoder编码器-Decoder解码器框架 + Attention注意力机制 + Positional Encoding位置编码)

    日萌社 人工智能AI:Keras PyTorch MXNet TensorFlow PaddlePaddle 深度学习实战(不定时更新) Encoder编码器-Decoder解码器框架 + Atten ...

  5. 基于LSTM分类文本情感分析

    背景介绍 文本情感分析作为NLP的常见任务,具有很高的实际应用价值.本文将采用LSTM模型,训练一个能够识别文本postive, neutral, negative三种情感的分类器. 本文的目的是快速 ...

  6. python实现文本情感分析_用python实现简单的文本情感分析

    很久没在公众号发布新内容,在这段时间内没想到有这么多python爱好者关注了我,港真的,心里很兴奋激动. 今天给大家带来我刚刚实现了的简单多文本情感分析代码,代码环境python3.5 原理 比如这么 ...

  7. 实体词典 情感词典_基于词典的文本情感分析(附代码)

    一.引言 目前中文文本情感分析主要分为三个类型,第一个是由情感词典和句法结构来做的.第二个是根据机器学习来做的(Bayes.SVM等).第三个是用深度学习的方法来做的(例如LSTM.CNN.LSTM+ ...

  8. Python:snownlp中文文本情感分析

    hello,大家好,我是wangzirui32,今天来教大家如何使用snownlp的中文文本情感分析功能,开始学习吧! 1. pip 安装 命令: pip install snownlp -i htt ...

  9. snownlp中文文本情感分析详细教程

    hello,大家好,我是wangzirui32,今天来教大家如何使用snownlp的中文文本情感分析功能,开始学习吧! 1. pip 安装 命令: pip install snownlp -i htt ...

最新文章

  1. 【C++】algorithm具体操作记录
  2. ajax合并表单,ajax。表单
  3. More Effective C++:理解new和delete
  4. 中科院罗平演讲全文:自动撰写金融文档如何实现,用 AI 解
  5. php 下载.csv,php 文件流的形式下载csv
  6. oracle计算表的大小,简要分析估算oracle表的大小
  7. Patrick Wyatt:代码没问题 程序却有bug?
  8. 单线多拨插件安装_Rhino 中的 SU 插件 | Jamparc for Rhino 6
  9. uni-app 实现微信授权登录
  10. Android Studio 无法启动模拟器的一种可能是你装的是Ghost版的系统
  11. Mac下IDEA快捷键操作
  12. spring源码:@Bean注解解析
  13. 在struts中实现验证码
  14. Microsoft Office (Visio)安装与激活
  15. python爬取别人qq空间相册_Python网络爬虫5 - 爬取QQ空间相册
  16. 计算机接口学平时作业,西电《计算机接口与通信技术》平时作业[教学作业]
  17. 学而思的python课怎么样_学而思老师怎么样?上课效果好吗?
  18. Maven基础概念和安装配置教程
  19. HDMI/DVI____串行发送器
  20. python中文件的导入与导出

热门文章

  1. linux后台运行服务
  2. JavaScript【图片轮播】
  3. 【学习笔记】arduino mega2560 和 ESP8266WIFI模块 联合调试 ①
  4. 在数据库中使用关键字作为字段名
  5. 文儿结婚生子再被提起!利、文两家互喷,老利回怼:豆豆妈好!文儿暴怒:阴损至极!小洲专场欠礼之人!利、曼等人名利其中!
  6. python 对数收益率_用python进行风险调整后的收益
  7. NTFS分区结构及图片文档结构
  8. 基于 MSP430 CC1101的WOR的测试
  9. 微信小程序实现下拉刷新功能
  10. 花旗银行java面试_花旗金融—面经(已offer)