Python训练⽂本情感分析模型
最近闲来⽆事,看了 的⼀篇⽂章 ,跟着步骤做了⼀个demo,此demo是爬取了美团⽤户的评论,对评论进⾏情感分析,收获很⼤,特此做下了笔记。
⾸先导⼊库
import pandas as pd
import numpy as np
from pandas import DataFrame, Series
读取评论数据,数据在
data = pd.read_csv("data.csv", encoding='GB18030')
data
数据如图所⽰
根据评分,使⽤lambda匿名函数,把评分>3的,取值1,当作正向情感,评分<3的,取值0,当作负向情感
def make_label(df):
df["sentiment"]= df["star"].apply(lambda x:1if x >3else0)
调⽤⽅法,并查看结果
make_label(data)
data
特征、标签分开赋值:
X = data[["comment"]]
y = data.sentiment
导⼊ jieba分词库,创建分词函数,将评论拆分,并⽤空格连接
通过 apply 调⽤函数,并新增列,填充值:
import jieba
def chinese_word_cut(mytext):
return" ".join(jieba.cut(mytext))
X["cuted_comment"]= Xment.apply(chinese_word_cut)
接下来要将⼀团的数据,拆分成训练数据集、测试数据集
从del_selection导⼊数据拆分函数train_test_split
del_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=1)
查看数据集形状:
X_train.shape
可知道,train_test_split在默认模式下,训练数据集、测试数据集⽐例是3:1。
接下来要处理中⽂停⽤词,可使⽤第三⽅停⽤词表,能在
创建停词函数,将停⽤词转成列表形式返回:
def get_custom_stopword(stop_word_file):
with open(stop_word_file)as f:
stop_word = f.read()
stop_word_list = stop_word.split("/n")
custom_stopword =[i for i in stop_word_list]
return custom_stopword
stopwords = get_custom_stopword("哈⼯⼤停⽤词表.txt")
导⼊ CountVectorizer函数,将中⽂词语向量化:
from sklearn. import CountVectorizer
默认参数向量化
vect = CountVectorizer()
term_matrix = DataFrame(vect.fit_transform(X_train.cuted_comment).toarray(), _feature_names())数据集长这样:
向量化后的数据集
term_matrix.shape
(1500,7305)
发现有特别多的数字存在,这些数字并不具有特征性,若是不过滤,会影响后⾯模型训练的效果
将⼀部分特征向量过滤,
给CountVectorizer添加参数,并重新对数据集向量化:
max_df =0.8# 在超过这⼀⽐例的⽂档中出现的关键词(过于平凡),去除掉。
min_df =3# 在低于这⼀数量的⽂档中出现的关键词(过于独特),去除掉。
vect = CountVectorizer(max_df = max_df,
min_df = min_df,
token_pattern=u'(?u)\\b[^\\d\\W]\\w+\\b',
stop_words=frozenset(stopwords))
term_matrix = DataFrame(vect.fit_transform(X_train.cuted_comment).toarray(), _feature_names())向量化后的数据集
term_matrix.shape
(1500,1972)
过滤了很多词汇,好棒!
训练集已向量化完成,现在使⽤此特征矩阵训练模型
导⼊ 朴素贝叶斯函数,建⽴分类模型
from sklearn.naive_bayes import MultinomialNB
nb = MultinomialNB()
注意,我们的处理数据流程是:
1、特征向量化
2、贝叶斯分类
如果每修改⼀次参数,就要重新运⾏以上函数,会⼗分头疼
sklearn提供了⼀个管道pipeline功能,能将顺序⼯作连接起来
from sklearn.pipeline import make_pipeline
pipe = make_pipeline(vect, nb)
pipe
现在我们就可以把pipe当成⼀个完整的模型来使⽤了。
将未特征向量化的数据输⼊,验证模型的准确率:
del_selection import cross_val_score
cross_val_score(pipe, X_train, y_train, cv=5, scoring='accuracy').mean()
得分:
python中文文档
0.8333673633410742
到此为⽌,模型已经初步搭建好了。【⿎掌】
但是我们⽤的都是训练过的数据集来测试的,准确率真的有这么⾼吗,来,我们进⾏下⼀步测试。先⽤训练集拟合数据:
pipe.fit(X_train.cuted_comment, y_train)
测试集预测结果:
y_pred = pipe.predict(x_test.cuted_comment)
结果是, 都是 0,1,0,1…:
使⽤ metrics测度⼯具查看评分
from sklearn import metrics
metrics.accuracy_score(y_test, y_pred)
评分:
0.866
结果显⽰,我们的模型对未曾见过的数据,预测的精确度达86.6%。
混淆矩阵验证
结果
array([[200,37],
[30,233]], dtype=int64)
混淆矩阵中的数字从上到下,从左到右分别表⽰:
本来是正向,预测也是正向
本来是正向,预测却是反向
本来是反向,预测确实正向
本来是反向,预测也是反向
可见我们的模型性能还是挺不错的。
下⾯我们来⽤ snowNLP 来做对⽐:
from snownlp import SnowNLP
def get_sentiment(text):
return SnowNLP(text).sentiments
使⽤测试集跑⼀遍:
y_pred_snow = X_testment.apply(get_sentiment)
结果:
snowNLP 返回的结果是0-1之间的数,⽽不是0、1,因此我们需要将数据转换⼀下,⼤于0.5为1,⼩于0.5为0。y_pred_snow_norm = y_pred_snow.apply(lambda x:1if x>0.5else0)
结果:
这下好看多啦。
查看snowNLP的评分:
metrics.accuracy_score(y_test, y_pred_snow_norm)
0.77
en,⽐我们的模型差点。。
混淆矩阵:
array([[189,48],
[67,196]], dtype=int64)
en,确实⽐我们的模型差点。。
以上。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论