当前位置:   article > 正文

Python—基于情感词典的情感分析_from collections import defaultdict import os impo

from collections import defaultdict import os import re import jieba import
*代码在前人的基础上做了一些更正。借鉴的代码已经找不到了,如之前的作者看到可以联系本人增加参照链接。*
  • 1

基于情感词典的分析重点在于给句子打分,在这里情感词典显得尤为重要。在垂直领域中,一般需要根据情景建立特有的情感词典。

本文使用的情感词典:情感词典

from collections import defaultdict
import os
import re
import jieba
import codecs
import pandas as  pd


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('senti_dict/stopwords.txt', 'r', 'utf-8')
    for word in fr:
        stopwords.add(word.strip())
    fr.close()
    # 去除停用词
    return list(filter(lambda x: x not in stopwords, seg_result))


def classify_words(word_dict):
    """词语分类,找出情感词、否定词、程度副词"""
    # 读取情感字典文件
    sen_file = open('senti_dict/情感词.txt', 'r+', encoding='utf-8')
    # 获取字典文件内容
    sen_list = sen_file.readlines()
    # 创建情感字典
    sen_dict = defaultdict()
    # 读取字典文件每一行内容,将其转换为字典对象,key为情感词,value为对应的分值
    i = 0
    for s in sen_list:
        slist = s.strip('\n').split('\t')
        # 每一行内容根据空格分割,索引0是情感词,索引01是情感分值
        sen_dict[slist[0]] = slist[1]

    # 读取否定词文件
    not_word_file = open('senti_dict/否定词1.txt', 'r+', encoding='utf-8')
    # 由于否定词只有词,没有分值,使用list即可
    not_word_list = not_word_file.readlines()

    # 读取程度副词文件
    degree_file = open('senti_dict/degree1.txt', 'r+', encoding='utf-8')
    degree_list = degree_file.readlines()
    degree_dic = defaultdict()
    # 程度副词与情感词处理方式一样,转为程度副词字典对象,key为程度副词,value为对应的程度值
    for d in degree_list:
        degree_dic[d.split('\t')[0]] = d.rstrip('\n').split('\t')[1]

    # 分类结果,词语的index作为key,词语的分值作为value,否定词分值设为-1
    sen_word = dict()
    not_word = dict()
    degree_word = dict()

    # 分类
    print(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


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


def socre_sentiment(sen_word, not_word, degree_word, seg_result):
    """计算得分"""
    # 权重初始化为1
    W = get_init_weight(sen_word, not_word, degree_word)
    # W = 1
    score = 0
    # 情感词下标初始化
    sentiment_index = -1
    # 情感词的位置下标集合
    sentiment_index_list = list(sen_word.keys())
    sentiment_index_list.sort()
    print('sentiment_index_list',sentiment_index_list)
    # 遍历分词结果(遍历分词结果是为了定位两个情感词之间的程度副词和否定词)
    for i in range(0, len(seg_result)):
        # 如果是情感词(根据下标是否在情感词分类结果中判断)
        if i in sen_word.keys():
            # 权重*情感词得分
            score += W * float(sen_word[i])
            print("score....", sen_word[i], W, score)
            # 情感词下标加1,获取下一个情感词的位置
            sentiment_index += 1
            if sentiment_index < len(sentiment_index_list) - 1:
                # 判断当前的情感词与下一个情感词之间是否有程度副词或否定词
                # 在判断是否存在程度副词或否定词之前,先将权重初始化1
                W = 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)
    print(seg_list)
    # 2.将分词结果列表转为dic,然后找出情感词、否定词、程度副词
    sen_word, not_word, degree_word = classify_words(list_to_dict(seg_list))
    print(sen_word)
    print(not_word)
    print(degree_word)
    # 3.计算得分
    score = socre_sentiment(sen_word, not_word, degree_word, seg_list)
    return score


# 测试
# print(setiment_score("2008年节能减排工作安排 制定鼓励发展节能省地环保型建筑和绿色建筑以及促进太阳能与建筑一体化应用的经济政策。"))

if __name__ == "__main__":
    file_data = "data/data.xlsx"
    df = pd.read_excel(file_data)
    data=df.loc[:,['内容']].values

    for i in range(len(data.tolist())):
        content = "".join(data.tolist()[i])
        print(setiment_score(content))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/496363
推荐阅读
相关标签
  

闽ICP备14008679号