欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

中文情感分析

程序员文章站 2024-03-07 16:59:21
...

情感分析在NLP领域中是应用很广泛的技术,一般用深度学习来解决这一类的问题。其实我的理解就是情感分析就是一个分类问题。这里我爬取了京东小米9的用户评论,正面和负面的评价各1000条,爬虫和整体的代码我放在了 GitHub 。然后我把预训练的词向量文件放在了 百度网盘,提取码:rxci。
我们一起来看看数据长得啥样,首先是小米9正面的评价:
中文情感分析
然后是小米9负面的评价:
中文情感分析
从这些数据印证了一句话,幸福的人都是相似的,不幸的人各有各的不幸。可以看到正类的评价里面基本上都是说小米9外观好看性能好,很容易就找到正类的特征词了。但是我们来看负类的小米9评价,基本上每一条负面评价吐槽的点都不一样,有对客服不满意的,有对小米活动失望的,有对没有优惠不满意的。有的正常看来似乎没有什么不满意,但是还是打了低分。这样的数据我感觉其实对结果是有一定影响的,我们如果想得到效果更好的模型,我们其实可以对数据进行筛选。好了,为了方便,我就直接用这个数据进行训练了。
首先我们逐行读取数据集,分别读取话术和标签。然后读入已经训练好的词向量 sgns.zhihu.bigram,这个训练好的词向量是一个长度为300维的。如下图所示,比如深圳这个词的300维词向量:
中文情感分析
然后同时可以计算两个词的相似度:
中文情感分析
同时也可以找出某一个词的最相似的 n 个词:
中文情感分析
从上面的图可以看出,这个词向量训练的是不错的,和烤肉相似的都是一些吃的。然后我们可以用训练集构建词典,代码如下所示:

train_tokens = []
for text in train_texts_orig:
    # 去掉标点
    text = re.sub("[\s+\.\!\/_,$%^*(+\"\']+|[+——!,。?、aaa@qq.com#¥%……&*()]+", "",text)
    # 结巴分词
    cut = jieba.cut(text)
    # 结巴分词的输出结果为一个生成器
    # 把生成器转换为list
    cut_list = [ i for i in cut ]
    for i, word in enumerate(cut_list):
        try:
            # 将词转换为索引index
            cut_list[i] = cn_model.vocab[word].index
        except KeyError:
            # 如果词不在字典中,则输出0
            cut_list[i] = 0
    train_tokens.append(cut_list)

这里我们定义一下输入token的长度:
中文情感分析
我们长度定98就可以覆盖了95%以上的话术长度了。然后不足98的我们在前面补0:
中文情感分析
然后我们处理好训练集之后,我们可以开始定义网络了,这里我们用双向LSTM加一个输出层,网络结构非常简单,代码如下所示:

model = Sequential()
model.add(Embedding(num_words,
                   embedding_dim,
                   weights=[embedding_matrix],
                   input_length = max_tokens,
                   trainable = False))
model.add(Bidirectional(LSTM(units=64, return_sequences=True)))
model.add(LSTM(units=16, return_sequences=False))
model.add(Dense(1, activation='sigmoid'))
# 我们使用adam以0.001的learning rate进行优化
optimizer = Adam(lr=1e-3)

代码结果如下所示:
中文情感分析
然后我们就可以进行模型训练了,训练完成之后,我们需要一个预测的函数:

def predict_sentiment(text):
    print(text)
    # 去标点
    text = re.sub("[\s+\.\!\/_,$%^*(+\"\']+|[+——!,。?、aaa@qq.com#¥%……&*()]+", "",text)
    # 分词
    cut = jieba.cut(text)
    cut_list = [ i for i in cut ]
    # tokenize
    for i, word in enumerate(cut_list):
        try:
            cut_list[i] = cn_model.vocab[word].index
            if cut_list[i] >= 30000:
                cut_list[i] = 0
        except KeyError:
            cut_list[i] = 0
    # padding
    tokens_pad = pad_sequences([cut_list], maxlen=max_tokens,
                           padding='pre', truncating='pre')
    # 预测
    result = model.predict(x=tokens_pad)
    coef = result[0][0]
    if coef >= 0.5:
        print('是一例正面评价','output=%.2f'%coef)
    else:
        print('是一例负面评价','output=%.2f'%coef)

这也是讲输入的话术去掉符号之后分词,然后向量化之后进行预测,我们可以看看预测的结果:
中文情感分析
中文情感分析
总的来说分类效果还是不错的。这就是用双向LSTM进行情感分析的整个流程,希望可以帮助大家理解整个的中文情感分析流程和原理,谢谢。

相关标签: 情感分析