文本情感倾向分析——机器学习模型

本文介绍了情感分析的挑战,如文本特征提取、词与词的关系以及多维情绪识别,并探讨了情感词典和高维向量模型(如Word2Vec)在解决这些问题上的作用。此外,还展示了TF-IDF和Word2Vec在文本表示上的优缺点,并通过多种机器学习模型(如SVM、NB、ANN、LR)进行了情感分类实验,最后分析了不同模型的测试结果和优化方案,强调了情感词典在提高判断准确率上的重要性。
摘要由CSDN通过智能技术生成

一、文本情感倾向分析

1. 内容

通过算法去判断一段文本、评论的情感倾向,从而快速地了解文本原作者的主观情绪。情感分析的结果可以用于舆情监控、信息预测,或用于判断产品的口碑,进而帮助生产者改进产品。

2. 难点
  1. 文本特征较难提取,文字讨论的主体可能是人、商品、事件。
  2. 文本较难规范化。
  3. 词与词之间有联系,关联关系纳入模型中不容易。
  4. 不带情感色彩的停用词会影响文本情感打分。
  5. 中文复杂,一个词在不同语境下可能表达完全不一样的情感含义,“冬天能穿多少穿多少,夏天能穿多少穿多少。”
  6. 不同语义差别巨大,比如“路上小心点”。
  7. 否定词的存在“我其实不是很喜欢你”。
  8. 多维情绪识别。
3. 方法
3.1 情感词典
  1. 质量良好的中文情感词典非常少。
  2. 不带情感的停用词会影响情感打分。
  3. 中文博大精深,词性的多变影响准确性。
  4. 无法结合上下文分析情感。

在这里插入图片描述

3.2 高维向量模型
  1. 解决了多维语义问题。
  2. 可利用强大的机器学习,深度学习学习模型。

在这里插入图片描述

二、向量表示

1. TF-IDF向量表示
1.1 定义

TF-IDF:Term Frequency - Inverse Document Frequency,即“词频-逆文本频率”。它由两部分组成,TF和IDF。TF-IDF是一种加权技术,采用一种统计方法,根据字词在文本中出现的次数和在整个语料中出现的文档频率来计算一个字词在整个语料中的重要程度。

优点:能过滤掉一些常见的却无关紧要的词语,同时保留整个文本的重要词语,简单快速,容易理解。
缺点:
(1)没有考虑特征词的位置因素对文本的区分度,词条出现在文档的不同位置时,对区分度的贡献大小是不一样的。
(2)按照传统TF-IDF,往往一些生僻词的IDF(反文档频率)会比较高、因此这些生僻词常会被误认为是文档关键词。
(3)传统TF-IDF中的IDF部分只考虑了特征词与它出现的文本数之间的关系,而忽略了特征项在一个类别中不同的类别间的分布情况。
(4)对于文档中出现次数较少的重要人名、地名信息提取效果不佳。

IDF:InversDocument Frequency,表示计算倒文本频率。文本频率是指某个关键词在整个语料所有文章中出现的次数。倒文本频率是文本频率的倒数,主要用于降低所有文档中一些常见却对文档影响不大的词语的作用。IDF反应了一个词在所有文本中出现的频率,如果一个词在很多的文本中出现,那么它的IDF值应该低,而反过来如果一个词在比较少的文本中出现,那么它的IDF值应该高。比如100篇文章里的某一篇文章大量的出现了“机器学习”,说明“机器学习”是关键词,应该给它较高的权重,而比如100篇文章里100篇都大量出现了“的”,”你“,“我”,说明这是不重要的词。

1.2 TF-IDF的实现

使用sklearn库来计算tfidf值

import pandas as pd
from sklearn.feature_extraction.text import TfidfVectorizer

words = ['它由两部分组成,TF和IDF。TF-IDF是一种加权技术,采用一种统计方法,根据字词在文本中出现的次数和在整个语料中出现的文档频率来计算一个字词在整个语料中的重要程度......']

tfidf_vec = TfidfVectorizer(stop_words={'english'})
"""
相关参数
token_pattern:使用正则表达式进行分词。
max_df/min_df:用于过滤出现太多的无意义词语。
stop_words:list类型,直接过滤指定的停用词。
vocabulary:dict类型,值使用特定的词汇,制定对应关系。
"""
tfidf_maxtrix = tfidf_vec.fit_transform(valid_words)

# 输出generator
print(tfidf_matix)

# 得到语料库所有不重复的词
print(tfidf_vec.get_feature_names())

# 得到每个单词对应的id值
print(tfidf_vec.vocabulary_)

# 得到每个句子对应的向量
print(tfidf_matrix.toarray())

使用jieba实现TF-IDF算法

import jieba.analyse
text='关键词是能够表达文档中心内容的词语,常用于计算机系统标引论文内容特征、信息检索、系统汇集以供读者检阅。关键词提取是文本挖掘领域的一个分支,是文本检索、文档比较、摘要生成、文档分类和聚类等文本挖掘研究的基础性工作'

keywords=jieba.analyse.extract_tags(text, topK=5, withWeight=False, allowPOS=())
print(keywords)

在这里插入图片描述

2. Word2Vec 向量表示
2.1 定义

Word2Vec:把每一个单词表示成一个向量,向量在空间中越近则词的含义越近。这些模型一般是基于某种文本中与单词共现相关的统计量来构造。一旦向量表示算出,就可以像使用TF-IDF向量一样使用这些模型。一个比较通用的例子是使用单词的向量表示基于单词的含义计算两个单词的相似度。

2.2 词向量

下图为man、boy、water三个单词用50维向量的热度图表示,可以看到,man和boy有一些相似的地方,在向量空间中相隔比较近。而water与之没有相似之处。简单地说,这个模型可以根据上下文的语境来推断出每个词的词向量,如果两个词在上下文的语境中可以被互相替换,那么这两个词的距离就非常近。

在这里插入图片描述

2.3 Word2Vec的实现
from gensim.models.word2vec import Word2Vec
w2v = Word2Vec(x_train,min_count=5,size=n_dim)
w2v.build_vocab(x_train)
w2v.train(x_train_examples=w2v.corpus_count,epochs=10)

三、各种机器学习分类模型

分别使用了SGD、SVM、NB、ANN、LR等九种模型进行分类,并比较各种模型的测试结果。

1. TF-IDF & SGD
1.1 代码演示
from typing import List
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.linear_model import SGDClassifier
from sklearn.svm import SVC
import pickle
import jieba
import os
import re
import string

file_path1 = '../dataset/train/neg.txt'
file_path2 = '../dataset/train/pos.txt'


# 训练分词
def train_fenci():
    list_words = []

    test_text = open(file_path1, 'r', encoding='utf-8').readlines()
    for line in test_text:
        # 清洗数据
        text = ''.join(line.split())
        # 实现目标文本中对正则表达式中的模式字符串进行替换
        text = re.sub("[\s+\.\!\/_,$%^*(+\"\']+|[+——!,。?、~@#¥%……&*()~-]+", "", text)
        # 利用jieba包自动对处理后的文本进行分词
        test_list = jieba.cut(text, cut_all=False)
        # 得到所有分解后的词
        list_words.append(' '.join(test_list))

    test_text = open(file_path2, 'r', encoding='utf-8').readlines()
    for line in test_text:
        # 清洗数据
        text = ''.join(line.split())
        # 实现目标文本中对正则表达式中的模式字符串进行替换
        text = re.sub("[\s+\.\!\/_,$%^*(+\"\']+|[+——!,。?、~@#¥%……&*()~-]+", "", text)
        # 利用jieba包自动对处理后的文本进行分词
        test_list = jieba.cut(text, cut_all=False)
        # 得到所有分解后的词
        list_words.append(' '.join(test_list))
    return list_words


# 测试分词
def test_fenci():
    FindPath1 = '../dataset/test/pos.txt_utf8'
    neg_words = []

    lines = open(FindPath1, 'r', encoding='utf-8').readlines()
    for line in lines:
        temp = ''.join(line.split())
        # 实现目标文本中对正则表达式中的模式字符串进行替换
        temp = re.sub("[\s+\.\!\/_,$%^*(+\"\']+|[+——!,。?、~@#¥%……&*()~-]+", "", temp)
        # 利用jieba包自动对处理后的文本进行分词
        temp_list = jieba.cut(temp, cut_all=False)
        # 得到所有分解后的词
        neg_words.append(' '.join(temp_list))
    return neg_words


if __name__ == '__main__':
    tfidf_vect = TfidfVectorizer(analyzer='word', stop_words=['我', '你', '是', '的', '在', '这里'])
    train_tfidf = tfidf_vect.fit_transform(train_fenci())
    test_tfidf = tfidf_vect.transform(test_fenci())
    # words = tfidf_vect.get_feature_names()
    # print(words)
    # print(train_tfidf)
    # print(len(words))
    # print(train_tfidf)
    # print(tfidf_vect.vocabulary_)

    lr = SGDClassifier(loss='log', penalty='l1')
    lr.fit(train_tfidf, ['neg'] * len(open(file_path1, 'r', encoding='utf-8').readlines()) +
           ['pos'] * len(open(file_path2, 'r', encoding='utf-8').readlines()))
    y_pred = lr.predict(test_tfidf)
    print(y_pred)
    # 统计结果和准确率
    sum_counter = 0
    pos_counter = 0
    neg_counter = 0
    for i in y_pred:
        sum_counter += 1
        if i == 'pos':
            pos_counter += 1
        else:
            neg_counter += 1
    print("总测试语句数:", sum_counter)
    print("积极语句数:", pos_counter)
    print("消极语句数:", neg_counter)

    # model = SVC(kernel='rbf',verbose=True)
    # model.fit(train_tfidf,['neg']*3000+['pos']*3000)
    # model.predict(test_tfidf)

1.2 预测结果分析

在3000条测试语句(1500条积极,1500条消极)中,测试结果如下:在这里插入图片描述

2. TF-IDF && SVM
2.1 代码演示

使用SVM模型:

from sklearn.svm import SVC
lr = SVC(kernel='rbf', verbose=True)
2.2 预测结果分析

在3000条测试语句(1500条积极,1500条消极)中,测试结果如下:

在这里插入图片描述

3. TF-IDF & NB
3.1 代码演示

使用朴素贝叶斯模型:

from sklearn.naive_bayes import MultinomialNB
lr = MultinomialNB()
3.2 预测结果分析

在3000条测试语句(1500条积极,1500条消极)中,测试结果如下:
在这里插入图片描述

4. TF-IDF & ANN
4.1 代码演示

使用人工神经网络模型:

from sklearn.neural_network import MLPClassifier
lr = MLPClassifier(hidden_layer_sizes=1, activation='logistic', solver='lbfgs', random_state=0)
4.2 预测结果分析

在3000条测试语句(1500条积极,1500条消极)中,测试结果如下:

在这里插入图片描述

5. TF-IDF & LR
5.1 代码演示

使用逻辑回归模型:

from sklearn.linear_model import LogisticRegression
lr = LogisticRegression(C=1, penalty='l2')
5.2 预测结果分析

在3000条测试语句(1500条积极,1500条消极)中,测试结果如下:

在这里插入图片描述

6. Word2Vec & SVM
6.1 代码演示
import jieba # 结巴分词
import numpy as np # numpy处理向量
import pandas as pd 

neg = pd.read_excel('data/neg.xls',head = None) # 读取负面词典
pos = pd.read_excel('data/pos.xls',head = None) # 读取正面词典

neg['words'] = neg[0].apply(lambda x: jieba.lcut(x)) # 负面词典分词
pos['words'] = pos[0].apply(lambda x: jieba.lcut(x)) # 正面词典分词

x = np.concatenate((pos['words'],neg['words'])) # 将原句子丢弃掉,并合并正面和负面分词结果
y = np.concatenate((np.ones(len(pos)),np.zeros(len(neg)))) # 向量空间,1表示positive,0表示negative

from gensim.models.word2vec import Word2Vec # 使用Word2Vec包
w2v = Word2Vec(size=300, min_count=10) # 初始化高维向量空间,300个维度,一个词出现的次数小于10则丢弃
w2v.build_vocab(x) # build高维向量空间

w2v.train(x,total_examples=w2v.corpus_count,epochs=w2v.iter) # 训练,获取到每个词的向量
w2v.save(u'w2v_model.model') # 保存训练好的模型

def total_vec(words): # 获取整个句子的向量
  w2v = Word2Vec.load('w2v_model.model')
  vec = np.zeros(300).reshape((1,300))
  for word in words:
    try:
      vec += w2v.wv[word].reshape((1,300))
    except KeyError:
      continue
  return vec

train_vec = np.concatenate([total_vec(words) for words in x]) # 计算每一句的向量,得到用于训练的数据集,用来训练高维向量模型

from sklearn.externals import joblib
from sklearn.model_selection import cross_val_score
from sklearn.svm import SVC

model = SVC(kernel='rbf',verbose=True)
model.fit(train_vec,y) # 训练SVM模型
joblib.dump(model,'svm_model.pkl') # 保存训练好的模型

# 对测试数据进行情感判断
def svm_predict():
  df = pd.read_csv("comments.csv") # 读取测试数据
  
  model = joblib.load('svm_model.pkl') # 读取支持向量机模型
  comment_setiment = []
  sum = 0;
  pos_counter = 0;
  neg_counter = 0;
  for string in df['评论内容']:
    sum += 1;
    # 对评论分词
    words = jieba.lcut(str(string))
    words_vec = total_vec(words)
    result = model.predict(word_vec)
    comment_sentiment.append('积极' if int(result[0]) else '消极')
    
    if sum_counter < 1500:
        if int(result[0]) == 1:
            right += 1
        else:
            wrong += 1
    else:
        if int(result[0]) == 0:
            right += 1
        else:
            wrong += 1
    sum_counter += 1
    
    result = right / sum_counter
    print("判断正确:", right)
    print("判断错误:", wrong)
    print("准确率:", result)

svm_pridict()
6.2 预测准确率

在3000条测试语句(1500条积极,1500条消极)中,测试结果如下:

在这里插入图片描述

7. Word2Vec & SGD
7.1 代码演示
from sklearn.linear_model import SGDClassifier
model = SGDClassifier(loss='log', penalty='l1')
7.2 预测准确率

在3000条测试语句(1500条积极,1500条消极)中,测试结果如下:

在这里插入图片描述

8. Word2Vec & NB
8.1 代码演示
from sklearn.naive_bayes import BernoulliNB
model = BernoulliNB()
8.2 预测准确率

在3000条测试语句(1500条积极,1500条消极)中,测试结果如下:

在这里插入图片描述

. Word2Vec & ANN
9.1 代码演示
from sklearn.neural_network import MLPClassifier
model = MLPClassifier(hidden_layer_sizes=1, activation='logistic', solver='lbfgs', random_state=0)
9.2 预测准确率

在3000条测试语句(1500条积极,1500条消极)中,测试结果如下:

在这里插入图片描述

10. Word2Vec & LR
10.1 代码演示
from sklearn.linear_model import LogisticRegression
model = LogisticRegression(C=1, penalty='l2')
10.2 预测准确率

在3000条测试语句(1500条积极,1500条消极)中,测试结果如下:

在这里插入图片描述

四、各种机器学习模型评估结果

4.1 某购物网站评论语料

采用20000条(10000条积极,10000条消极)来自某购物网站的评论语句作为训练集,3000条作为测试集,各种模型的测试结果如下:

模型测试(条)判断正确(条)精准率(precision)召回率(recall)F1-score
TF-IDF & SGD300024900.78530.86240.8221
TF-IDF & SVM300027620.87600.96190.9170
TF-IDF & NB300026440.82200.93270.8738
TF-IDF & ANN300027140.88330.92270.9026
TF-IDF & LR300026580.84400.92140.8810
TF-IDF & DT300025580.80730.88780.8457
TF-IDF & RF300026300.82330.92160.8697
TF-IDF & AdaBoost300022760.67470.81090.7365
TF-IDF & GBM300023240.64470.87120.7410
Word2Vec & SGD300022790.89330.70490.7880
Word2Vec & SVM300026110.82330.90880.8639
Word2Vec & NB300020940.70400.69570.6998
Word2Vec & ANN300024390.81460.81200.8133
Word2Vec & LR300024980.79000.86370.8252
Word2Vec & DT300025860.80800.90580.8541
Word2Vec & RF300026080.81530.91410.8619
Word2Vec & AdaBoost300026000.81070.91290.8588
Word2Vec & GBM300026090.81670.91350.8624

五、使用情感词典优化

在机器学习的模块中加入情感词典,对测试样本进行情感词典的判断,得出 样本中每个数据的情感倾向。在机器学习的模型对测试样本进行判断之中加入情 感词典的判断结果,从而辅助机器学习对样本的判断,可以有效提高判断的准确率。

模型测试(条)判断正确(条)精准率(precision)召回率(recall)F1-score
TF-IDF & SGD300027910.96470.90270.9326
TF-IDF & SVM300029270.98000.97160.9758
TF-IDF & NB300028860.97400.95120.9625
TF-IDF & ANN300028990.98600.94870.9670
TF-IDF & LR300028690.97330.94130.9570
Word2Vec & SGD300027200.98730.85020.9136
Word2Vec & SVM300028890.98270.94550.9637
Word2Vec & NB300026870.97800.83970.9036
Word2Vec & ANN300028160.98400.90220.9413
Word2Vec & LR300028390.97870.91920.9480

参考:https://www.bilibili.com/video/BV16t411d7ZY

  • 33
    点赞
  • 432
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
情感分析机器学习的方法有多种。其中一种方法是使用情感词典,将情感词典的判断结果与机器学习模型的判断结果相结合,从而提高判断的准确率。这种方法可以通过在机器学习模型中加入情感词典来对测试样本进行情感词典的判断,然后将情感词典的判断结果与机器学习模型的判断结果相结合。这种方法在实验中得到了较高的精确度、召回率和F1-score。\[2\] 另一种方法是使用逻辑回归模型。逻辑回归模型是一种常用的分类模型,可以用于情感分析。通过使用逻辑回归模型,可以对文本进行情感倾向的预测。在这种方法中,可以使用sklearn库中的LogisticRegression类来创建逻辑回归模型,并通过调整参数来优化模型的性能。\[3\] 总结起来,情感分析机器学习的方法包括使用情感词典和机器学习模型相结合的方法,以及使用逻辑回归模型进行情感分析。这些方法可以帮助我们快速地了解文本情感倾向,并在舆情监控、信息预测和产品口碑改进等方面提供帮助。 #### 引用[.reference_title] - *1* *2* *3* [文本情感倾向分析——机器学习模型](https://blog.csdn.net/m0_46144891/article/details/118710163)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值