基于情感词典的文本情感极性分析相关代码

相关文档

示例代码

# -*- coding:utf8 -*-

from collections import defaultdict
import os
import re
import jieba
import codecs
import sys
import chardet
import matplotlib.pyplot as plt



# php install jieba





#使用jieba 函数  对 sentence 文本进行分词

def sent2word(sentence):


#调用jieba进行分词
    segList = jieba.cut(sentence)

#分词后的结果存为segResult 为list类型
    segResult = []
    for w in segList:
        segResult.append(w)

#调用 readLines 读取停用词
    stopwords = readLines('stop_words.txt')

#如果是停用词 就不保存到newSent
    newSent = []
    for word in segResult:
        if word+'\n' in stopwords:
            continue
        else:
            newSent.append(word)
#返回newSent
    return newSent


#直接对 sentence 进行分词  不使用停用词 并返回(主要是根据word需要这个操作)
def returnsegResult(sentence):

    segResult = []
    segList = jieba.cut(sentence)

    for w in segList:
        segResult.append(w)
    return segResult


#获取 filepath 目录下的所有文件目录并返回
def eachFile(filepath):
    pathDir =  os.listdir(filepath)
    child=[]
    for allDir in pathDir:
        child.append(os.path.join('%s/%s' % (filepath, allDir)))
    return child

#读取 filename路径 的每一行数据 并返回 转换为GBK
def readLines(filename):
    fopen = open(filename, 'r')
    data=[]
    for x in fopen.readlines():
        if x.strip() != '':
                data.append(unicode(x.strip(),"GBK"))

    fopen.close()
    return data



#读取 filename路径 的每一行数据 并返回
def readLines2(filename):
    fopen = open(filename, 'r')
    data=[]
    for x in fopen.readlines():
        if x.strip() != '':
                data.append(x.strip())

    fopen.close()
    return data

#主要为情感定位  见程序文件相关代码 这里是为了速度 提取了部分代码 本来应该在classifyWords 里边  貌似对速度影响不大
def words():
    #情感词
    senList = readLines2('BosonNLP_sentiment_score.txt')
    senDict = defaultdict()
    for s in senList:
        senDict[s.split(' ')[0]] = s.split(' ')[1]
    #否定词
    notList = readLines2('notDict.txt')
    #程度副词
    degreeList = readLines2('degreeDict.txt')
    degreeDict = defaultdict()
    for d in degreeList:
        degreeDict[d.split(' ')[0]] = d.split(' ')[1]

    return senDict,notList,degreeDict




# 见文本文档  根据情感定位  获得句子相关得分
def classifyWords(wordDict,senDict,notList,degreeDict):

    senWord = defaultdict()
    notWord = defaultdict()
    degreeWord = defaultdict()
    for word in wordDict.keys():
        if word in senDict.keys() and word not in notList and word not in degreeDict.keys():
            senWord[wordDict[word]] = senDict[word]
        elif word in notList and word not in degreeDict.keys():
            notWord[wordDict[word]] = -1
        elif word in degreeDict.keys():
            degreeWord[wordDict[word]] = degreeDict[word]
    return senWord, notWord, degreeWord


#计算句子得分  见程序文档
def scoreSent(senWord, notWord, degreeWord, segResult):
    W = 1
    score = 0
    # 存所有情感词的位置的列表
    senLoc = senWord.keys()
    notLoc = notWord.keys()
    degreeLoc = degreeWord.keys()
    senloc = -1
    # notloc = -1
    # degreeloc = -1
    # 遍历句中所有单词segResult,i为单词绝对位置
    for i in range(0, len(segResult)):
        # 如果该词为情感词
        if i in senLoc:
            # loc为情感词位置列表的序号
            senloc += 1
            # 直接添加该情感词分数
            score += W * float(senWord[i])
            # print "score = %f" % score
            if senloc < len(senLoc) - 1:
                # 判断该情感词与下一情感词之间是否有否定词或程度副词
                # j为绝对位置
                for j in range(senLoc[senloc], senLoc[senloc + 1]):
                    # 如果有否定词
                    if j in notLoc:
                        W *= -1
                    # 如果有程度副词
                    elif j in degreeLoc:
                        W *= float(degreeWord[j])
        # i定位至下一个情感词
        if senloc < len(senLoc) - 1:
            i = senLoc[senloc + 1]
    return score


#列表 转 字典
def listToDist(wordlist):
    data={}
    for x in range(0, len(wordlist)):
        data[wordlist[x]]=x
    return data

#绘图相关  自行百度下
def runplt():
    plt.figure()
    plt.title('test')
    plt.xlabel('x')
    plt.ylabel('y')
    #这里定义了  图的长度 比如 2000条数据 就要 写 0,2000  
    plt.axis([0,1000,-10,10])
    plt.grid(True)
    return plt




#主题从这里开始 上边全是方法


#获取 test/neg 下所有文件 路径
filepwd=eachFile("test/neg")



#
scre_var=[]


#获取 本地的情感词 否定词 程度副词
words_vaule=words()

#循环 读取 filepwd  (也就是test/neg目录下所有文件全部跑一下)
for x in filepwd:
    #读目录下文件的内容
    data=readLines(x)
    #对data内容进行分词
    datafen=sent2word(data[0])
    #列表转字典
    datafen_dist=listToDist(datafen)
    #通过classifyWords函数 获取句子的 情感词 否定词 程度副词 相关分值
    data_1=classifyWords(datafen_dist,words_vaule[0],words_vaule[1],words_vaule[2])
    # 通过scoreSent 计算 最后句子得分
    data_2=scoreSent(data_1[0],data_1[1],data_1[2],returnsegResult(data[0]))
    # 将得分保存在score_var 以列表的形式
    score_var.append(data_2)
    #打印句子得分
    print data_2

#对所有句子得分进行倒序排列
score_var.sort(reverse=True)

#计算一个index 值 存 1~ 所有句子长度 以便于绘图
index=[]
for x in range(0,len(score_var)):
    index.append(x+1)

#初始化绘图
plt=runplt();
#带入参数
plt.plot(index,score_var,'r.')
#显示绘图
plt.show();