我的学习笔记:机器学习(02)词典文本情感分析补充

Python 同时被 3 个专栏收录
3 篇文章 0 订阅
1 篇文章 0 订阅
1 篇文章 0 订阅

我的学习笔记:机器学习(02)文本情感分析补充

菜鸟学习中,大神请指教!

上次在学习词典文本情感分析的过程中,尚有很多不足,经过这段时间的学习,有了一点自己的理解,故写此博客加以记录。若有错误或不足,欢迎批评指正。

基于情感词典的方法主要是通过情感词典对文本进行情感分析。

文档:

  1. 导入各个模块和包
  • 安装结巴:pip install jieba -i https://pypi.douban.com/simple/
from collections import defaultdict
import os
import re
import jieba
import codecs
import ast
  • 在Python中如果访问字典中不存在的键,会引发Key异常,defaultdict的作用就在于当字典中不存在给定的键,则返回参数中提供的默认值;反之,则返回字典中保存的值。
  1. 结巴分词和去除停用词
  • 停用词文件:
def seg_word(sentence):
    #使用jieba对文档分词
    seg_list = jieba.cut(sentence)
    seg_result = []
    for w in seg_list:
        seg_result.append(w)
    # 读取停用词文件
    stopwords = set()
    fr = codecs.open('data/stopwords.txt', 'r', 'gbk')
    for word in fr:
        stopwords.add(word.strip())
    fr.close()
    # 去除停用词
    return list(filter(lambda x: x not in stopwords, seg_result))
  • 测试分词结果:
seg_word('一直喝这个茶业,性价比不是很高,不是很满意')

我们对“一直喝这个茶业,性价比不是很高,不是很满意” 这就话进行分词,得到的分词结果为“喝”,“茶业”,“性价比”,“很”,“高”,“很”,“满意”。
3. 读取情感词典文件,对分词进行分类:

  • 情感词典
def classify_words(word_dict):
    """词语分类,找出情感词、否定词、程度副词"""
    # 读取情感字典文件
    sen_file = open('data/BosonNLP_sentiment_score.txt', 'r+', encoding='utf-8')
    # 获取字典文件内容
    sen_list = sen_file.readlines()
    # 创建情感字典
    sen_dict = defaultdict()
    # 读取字典文件每一行内容,将其转换为字典对象,key为情感词,value为对应的分值
    for s in sen_list:
         if len(s.split(' ')) == 2:
                sen_dict[s.split(' ')[0]] = s.split(' ')[1]
        
  • 否定词
# 读取否定词文件
    not_word_file = open('data/notDic.txt', 'r+', encoding='gbk')
    # 由于否定词只有词,没有分值,使用list即可
    not_word_list = not_word_file.readlines()
 
  • 程度副词
 # 读取程度副词文件
    degree_file = open('data/degree.txt', 'r+', encoding='gbk')
    degree_list = degree_file.readlines()
    degree_dic = defaultdict()
    # 程度副词与情感词处理方式一样,转为程度副词字典对象,key为程度副词,value为对应的程度值
    for d in degree_list:
        if len(d.split(' ')) == 2:
            degree_dic[d.split(',')[0]] = d.split(',')[1]
 
  • 分类
# 分类结果,词语的index作为key,词语的分值作为value,否定词分值设为-1
    sen_word = dict()
    not_word = dict()
    degree_word = dict()
 
    # 分类
    for word in word_dict.keys():
        if word in sen_dict.keys() and word not in not_word_list and word not in degree_dic.keys():
            # 找出分词结果中在情感字典中的词
            sen_word[word_dict[word]] = sen_dict[word]
        elif word in not_word_list and word not in degree_dic.keys():
            # 分词结果中在否定词列表中的词
            not_word[word_dict[word]] = -1
        elif word in degree_dic.keys():
            # 分词结果中在程度副词中的词
            degree_word[word_dict[word]] = degree_dic[word]
    sen_file.close()
    degree_file.close()
    not_word_file.close()
    # 将分类结果返回
    return sen_word, not_word, degree_word
 
  1. 将分词后的列表转为词典
def list_to_dict(word_list):
    """将分词后的列表转为字典,key为单词,value为单词在列表中的索引,索引相当于词语在文档中出现的位置"""
    data = {}
    for x in range(0, len(word_list)):
        data[word_list[x]] = x
    return data
 
def get_init_weight(sen_word, not_word, degree_word):
    # 权重初始化为1
    W = 1
    # 将情感字典的key转为list
    sen_word_index_list = list(sen_word.keys())
    if len(sen_word_index_list) == 0:
        return W
    # 获取第一个情感词的下标,遍历从0到此位置之间的所有词,找出程度词和否定词
    for i in range(0, sen_word_index_list[0]):
        if i in not_word.keys():
            W *= -1
        elif i in degree_word.keys():
            # 更新权重,如果有程度副词,分值乘以程度副词的程度分值
            W *= float(degree_word[i])
    return W
 
  1. 计算得分
def socre_sentiment(sen_word, not_word, degree_word, seg_result):
    """计算得分"""
    # 权重初始化为1
    W = 1
    score = 0
    # 情感词下标初始化
    sentiment_index = -1
    # 情感词的位置下标集合
    sentiment_index_list = list(sen_word.keys())
    # 遍历分词结果(遍历分词结果是为了定位两个情感词之间的程度副词和否定词)
    for i in range(0, len(seg_result)):
        # 如果是情感词(根据下标是否在情感词分类结果中判断)
        if i in sen_word.keys():
            # 权重*情感词得分
            score += W * float(sen_word[i])
            # 情感词下标加1,获取下一个情感词的位置
            sentiment_index += 1
            if sentiment_index < len(sentiment_index_list) - 1:
                # 判断当前的情感词与下一个情感词之间是否有程度副词或否定词
                for j in range(sentiment_index_list[sentiment_index], sentiment_index_list[sentiment_index + 1]):
                    # 更新权重,如果有否定词,取反
                    if j in not_word.keys():
                        W *= -1
                    elif j in degree_word.keys():
                        # 更新权重,如果有程度副词,分值乘以程度副词的程度分值
                        W *= float(degree_word[j])
        # 定位到下一个情感词
        if sentiment_index < len(sentiment_index_list) - 1:
            i = sentiment_index_list[sentiment_index + 1]
    return score
 
#调度各个函数
# 计算得分
def setiment_score(sententce):
    # 1.对文档分词
    seg_list = seg_word(sententce)
    # 2.将分词结果列表转为dic,然后找出情感词、否定词、程度副词
    sen_word, not_word, degree_word = classify_words(list_to_dict(seg_list))
    # 3.计算得分
    score = socre_sentiment(sen_word, not_word, degree_word, seg_list)
    return score
 
  1. 文档分析
  • 导入分析文档
tea_test = []
with open("tea_test_sentiment.txt","r",encoding="utf-8") as f:
    tea_test = [line.strip() for line in f.readlines()]
    
tea_test_labels = []
tea_test_sentence = []
  • 查看文档信息
tea_test
for i in range(len(tea_test)):
    dic = ast.literal_eval(tea_test[i])
    tea_test_labels.append(dic['label'])
    tea_test_sentence.append(dic['text'])
tea_test_labels
tea_test_sentence
  1. 计算文档得分
tea_test_score = []
for sentence in tea_test_sentence:
    score =setiment_score(sentence)
    tea_test_score.append(score)
tea_test_score
tea_test = []
for i in range(len(tea_test_score)):
    if tea_test_score[i] >=0:
        tea_test.append(1)
    else:
        tea_test.append(0)
from sklearn.metrics import accuracy_score,f1_score,roc_auc_score,recall_score,precision_score

recall = recall_score(tea_test_labels,tea_test)
print('recal是:',recall)
f1_score = f1_score(tea_test_labels,tea_test)
print('f1 score是:',f1_score)
roc_auc_score1 = roc_auc_score(tea_test_labels,tea_test)
print('auc是:',roc_auc_score1)
  1. 画图
#画auc图形
from sklearn import metrics
import matplotlib.pyplot as plt
from sklearn.metrics import roc_curve,auc
fpr,tpr,thresholds =metrics.roc_curve(tea_test_labels,tea_test)
                                                     #fpr,tpr,roc曲线上的一个点
                                                     #thresholds,求解fpr,tpr时使用的阈值

                                                     #roc曲线roc_curve
roc_auc = auc(fpr,tpr)                               #auc为ROC曲线
                                                     #开始画ROC曲线
plt.plot(fpr,tpr,'b',label='AUC = %0.2f'% roc_auc)
plt.legend(loc=' Lower right')
plt.plot([0,1], [0,1],'r--')
plt.xlim([-0.1,1.1])
plt.ylim([-0.1,1.1])
plt.xlabel( 'Fa1se Positive Rate')

学习记录,尚在学习中,欢迎批评指正!

  • 0
    点赞
  • 1
    评论
  • 1
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 游动-白 设计师:白松林 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值