当前位置:   article > 正文

Python训练文本情感分析模型_python情感分析训练模型

python情感分析训练模型

最近闲来无事,看了 王树义老师 的一篇文章 《如何用Python和机器学习训练中文文本情感分类模型》,跟着步骤做了一个demo,此demo是爬取了美团用户的评论,对评论进行情感分析,收获很大,特此做下了笔记。

首先导入库

import pandas as pd
import numpy as np
from pandas import DataFrame, Series
  • 1
  • 2
  • 3

读取评论数据,数据在 这里

data = pd.read_csv("data.csv", encoding='GB18030')
data
  • 1
  • 2

数据如图所示
在这里插入图片描述

根据评分,使用lambda匿名函数,把评分>3的,取值1,当作正向情感,评分<3的,取值0,当作负向情感

def make_label(df):
    df["sentiment"] = df["star"].apply(lambda x: 1 if x > 3 else 0)
  • 1
  • 2

调用方法,并查看结果

make_label(data)
data
  • 1
  • 2

特征、标签分开赋值:

X = data[["comment"]]
y = data.sentiment
  • 1
  • 2

导入 jieba分词库,创建分词函数,将评论拆分,并用空格连接
通过 apply 调用函数,并新增列,填充值:

import jieba
def chinese_word_cut(mytext):
    return " ".join(jieba.cut(mytext))

X["cuted_comment"] = X.comment.apply(chinese_word_cut)
  • 1
  • 2
  • 3
  • 4
  • 5

接下来要将一团的数据,拆分成训练数据集、测试数据集
sklearn.model_selection导入数据拆分函数train_test_split

from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=1)
  • 1
  • 2

查看数据集形状:

X_train.shape
  • 1

可知道,train_test_split在默认模式下,训练数据集、测试数据集比例是3:1。

接下来要处理中文停用词,可使用第三方停用词表,能在 这个GitHub上找到
创建停词函数,将停用词转成列表形式返回:

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")
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

导入 CountVectorizer函数,将中文词语向量化:

from sklearn.feature_extraction.text import CountVectorizer
  • 1

默认参数向量化

vect = CountVectorizer()
term_matrix = DataFrame(vect.fit_transform(X_train.cuted_comment).toarray(), columns=vect.get_feature_names())
  • 1
  • 2

数据集长这样:
在这里插入图片描述

向量化后的数据集

term_matrix.shape
  • 1
(1500, 7305)
  • 1

发现有特别多的数字存在,这些数字并不具有特征性,若是不过滤,会影响后面模型训练的效果

将一部分特征向量过滤,
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(), columns=vect.get_feature_names())
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

向量化后的数据集

term_matrix.shape
  • 1
(1500, 1972)
  • 1

过滤了很多词汇,好棒!

训练集已向量化完成,现在使用此特征矩阵训练模型
导入 朴素贝叶斯函数,建立分类模型

from sklearn.naive_bayes import MultinomialNB
nb = MultinomialNB()
  • 1
  • 2

注意,我们的处理数据流程是:
1、特征向量化
2、贝叶斯分类
如果每修改一次参数,就要重新运行以上函数,会十分头疼

sklearn提供了一个管道pipeline功能,能将顺序工作连接起来

from sklearn.pipeline import make_pipeline
pipe = make_pipeline(vect, nb)
pipe
  • 1
  • 2
  • 3

现在我们就可以把pipe当成一个完整的模型来使用了。

将未特征向量化的数据输入,验证模型的准确率:

from sklearn.model_selection import cross_val_score
cross_val_score(pipe, X_train, y_train, cv=5, scoring='accuracy').mean()
  • 1
  • 2

得分:

0.8333673633410742
  • 1

到此为止,模型已经初步搭建好了。【鼓掌】


但是我们用的都是训练过的数据集来测试的,准确率真的有这么高吗,来,我们进行下一步测试。

先用训练集拟合数据:

pipe.fit(X_train.cuted_comment, y_train)
  • 1

测试集预测结果:

y_pred = pipe.predict(x_test.cuted_comment)
  • 1

结果是, 都是 0,1,0,1…:
在这里插入图片描述

使用 metrics测度工具查看评分

from sklearn import metrics
metrics.accuracy_score(y_test, y_pred)
  • 1
  • 2

评分:

0.866
  • 1

结果显示,我们的模型对未曾见过的数据,预测的精确度达86.6%。

混淆矩阵验证

metrics.confusion_matrix(y_test, y_pred)
  • 1

结果

array([[200,  37],
       [ 30, 233]], dtype=int64)
  • 1
  • 2

混淆矩阵中的数字从上到下,从左到右分别表示:

  • 本来是正向,预测也是正向
  • 本来是正向,预测却是反向
  • 本来是反向,预测确实正向
  • 本来是反向,预测也是反向

可见我们的模型性能还是挺不错的。

下面我们来用 snowNLP 来做对比:

from snownlp import SnowNLP
def get_sentiment(text):
    return SnowNLP(text).sentiments
  • 1
  • 2
  • 3

使用测试集跑一遍:

y_pred_snow = X_test.comment.apply(get_sentiment)
  • 1

结果:
在这里插入图片描述
snowNLP 返回的结果是0-1之间的数,而不是0、1,因此我们需要将数据转换一下,大于0.5为1,小于0.5为0。

y_pred_snow_norm = y_pred_snow.apply(lambda x: 1 if x>0.5 else 0)
  • 1

结果:
在这里插入图片描述
这下好看多啦。
查看snowNLP的评分:

metrics.accuracy_score(y_test, y_pred_snow_norm)
  • 1
0.77
  • 1

en,比我们的模型差点。。

混淆矩阵:

metrics.confusion_matrix(y_test, y_pred_snow_norm)
  • 1
array([[189,  48],
       [ 67, 196]], dtype=int64)
  • 1
  • 2

en,确实比我们的模型差点。。

以上。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/347320
推荐阅读
相关标签
  

闽ICP备14008679号