资阳住房和城乡建设厅官方网站,安仁网络推广软件定制开发,洛阳 网站建设公司哪家好,wordpress 文件权限【学术小白的学习之路】基于情感词典的情感分析 1.基础函数1.1 判断情感词的否定词数量1.2 导入情感词典1.3 切分句子1.3.1为什么划分1.3.2 划分代码 1.4 完整代码 2.导入词典3.中文情感分析算法思路4.1情感词获取思路4.2 计算情感分值4.3 得分的归一化处理 4.实证5.总结 本文的… 【学术小白的学习之路】基于情感词典的情感分析 1.基础函数1.1 判断情感词的否定词数量1.2 导入情感词典1.3 切分句子1.3.1为什么划分1.3.2 划分代码 1.4 完整代码 2.导入词典3.中文情感分析算法思路4.1情感词获取思路4.2 计算情感分值4.3 得分的归一化处理 4.实证5.总结 本文的情感分析逻辑大致如下没有进行专门的分词工作进行了分句子工作识别出需要的词计算出情感倾向。 1.基础函数
1.1 判断情感词的否定词数量
在情感分析代码中我们需要写一个函数来主要作用是判断情感词前面是否存在奇数个否定词。这对于情感分析的逻辑非常重要因为否定词的数量会影响最终的情感得分。
def is_odd(self, num):if num % 2 0:return evenelse:return odd具体用途在判断否定影响 在分析情感词时代码会检查该情感词前面出现的否定词数量。如果否定词的数量是奇数则表示这个情感词的情感倾向应该反转。例如“不是好” 表示负面情感因为有一个否定词 “不”。
通过使用 is_odd 函数代码能够更准确地反映文本中的情感。例如在处理类似于 “我不喜欢这个产品” 的句子时函数帮助正确地识别出该句子传达的是负面情感。
1.2 导入情感词典
我们需要写一个函数从指定的文件中加载词典数据并将其存储为一个集合以便后续的情感分析使用。 这个函数在情感分析中起着关键角色负责加载和管理各种情感词典。通过这个函数可以简化代码、提高效率并确保情感分析的准确性和灵活性。因此它是实现情感分析系统不可或缺的组成部分。
def load_dict(self, file): Load dictionarywith open(file, encodingutf-8, errorsignore) as fp:lines fp.readlines()lines [l.strip() for l in lines]print(Load data from file (%s) finished ! % file)dictionary [word.strip() for word in lines]return set(dictionary)作用与重要性就可以实现统一管理词典 1集中加载通过 load_dict 函数所有的情感词典如正面词、负面词、否定词等都可以通过简单的函数调用进行加载避免了重复代码。 2便于维护如果需要更新词典只需修改文件内容即可而不必更改代码逻辑。
1.3 切分句子
1.3.1为什么划分
在情感分析中一个句子可能包含多个分句而这些分句所传达的情感可能截然不同。一个切分函数在这种情况下显得尤其重要需要将复杂句子拆分为独立的子句从而确保对每个分句的情感进行准确分析。
例如
虽然这个产品性能很好但它的价格却很高我觉得不太划算。
分割之后
[‘虽然这个产品性能很好’, ‘但它的价格却很高’, ‘我觉得不太划算’]
情感分析的应用
逐句情感评估 第一句“虽然这个产品性能很好”表达了正面情感。 第二句“但它的价格却很高”引入了负面情感暗示价格是一个问题。 第三句“我觉得不太划算”进一步强调了负面情感。情感冲突识别 通过分句情感分析可以清楚地识别出文本中的情感冲突。第一句的正面情感和后两句的负面情感形成对比表明用户对产品的综合评价并不完全积极。综合情感得分 通过分析每个分句的情感分析系统可以计算出整体情感得分可能得出一个中性或略偏负面的结论。这种方法比简单分析整个句子要准确得多因为它考虑了句子内部的复杂情感变化。
1.3.2 划分代码
我们可以借助正则表达式。使用正则表达式将输入的长文本分割成多个短句能够识别多种标点符号如句号、问号、感叹号等作为分隔符。
同时需要去除空字符串这样确保返回的结果中不包含空字符串返回有效的子句列表。
def sentence_split_regex(self, sentence):Segmentation of sentenceif sentence is not None:sentence re.sub(rndash;|mdash;, -, sentence)sub_sentence re.split(r[。,!?;\s…~]|\.{2,}|hellip;|nbsp|_n|_t, sentence)sub_sentence [s for s in sub_sentence if s ! ]if sub_sentence ! []:return sub_sentenceelse:return [sentence]return []1.4 完整代码
import reclass ToolGeneral():Tool functiondef is_odd(self,num):if num % 2 0:return evenelse:return odd def load_dict(self,file): Load dictionarywith open(file,encodingutf-8,errorsignore) as fp:lines fp.readlines()lines [l.strip() for l in lines]print(Load data from file (%s) finished !%file)dictionary [word.strip() for word in lines]return set(dictionary)def sentence_split_regex(self,sentence):Segmentation of sentenceif sentence is not None:sentence re.sub(rndash;|mdash;, -, sentence)sub_sentence re.split(r[。,!?;\s…~]|\.{2,}|hellip;|nbsp|_n|_t, sentence)sub_sentence [s for s in sub_sentence if s ! ]if sub_sentence ! []:return sub_sentenceelse:return [sentence]return []if __name__ __main__: #tool ToolGeneral() #s 我今天你现在在干嘛。昨天上午还有现在ls tool.sentence_split_regex(s)print(ls) 结果
2.导入词典 环境准备 首先确保你已经导入必要的库并且定义了 ToolGeneral 类。你还需要确保字典文件的路径正确。 Hyperparams 类的定义 接下来我们定义一个名为 Hyperparams 的类其中包含多个静态属性这些属性用于加载不同的情感字典和副词字典。 加载情感字典 在 Hyperparams 类中我们通过调用 load_dict 方法来加载情感字典。这些字典通常用于情感分析分别表示否定词、正面词和负面词。
import ostool ToolGeneral()
pwd os.getcwd()class Hyperparams:Hyper parameters# Load sentiment dictionarydeny_word tool.load_dict(os.path.join(pwd,dict,not.txt))posdict tool.load_dict(os.path.join(pwd,dict,positive.txt))negdict tool.load_dict(os.path.join(pwd,dict, negative.txt))pos_neg_dict posdict|negdict# Load adverb dictionarymostdict tool.load_dict(os.path.join(pwd,dict,most.txt))verydict tool.load_dict(os.path.join(pwd,dict,very.txt))moredict tool.load_dict(os.path.join(pwd,dict,more.txt))ishdict tool.load_dict(os.path.join(pwd,dict,ish.txt))insufficientlydict tool.load_dict(os.path.join(pwd,dict,insufficiently.txt))overdict tool.load_dict(os.path.join(pwd,dict,over.txt))inversedict tool.load_dict(os.path.join(pwd,dict,inverse.txt))导入成功就会现实finish 这些词典包含了否定词 积极情感词和消极情感词 为了保障这个精准度那还需要程度词 以及包含了其他各种可能影响的词
3.中文情感分析算法思路
设计了一个情感分析的类 SentimentAnalysis其主要功能是分析文本的情感倾向返回正面和负面情感的分值。以下是逐步解析其实现思路的详细说明。
代码如下
import os
import sys
import jieba
import numpy as nptool ToolGeneral()
# jieba.load_userdict(os.path.join(os.path.dirname(./dict, dict,jieba_sentiment.txt))
# dict_file os.path.join(os.path.dirname(os.path.abspath()), dict, jieba_sentiment.txt)class SentimentAnalysis():Sentiment Analysis with some dictionarys def sentiment_score_list(self,dataset):seg_sentence tool.sentence_split_regex(dataset)count1,count2 [],[]for sentence in seg_sentence: words jieba.lcut(sentence, cut_allFalse)i 0 a 0 for word in words:poscount 积极词的第一次分值;poscount2 积极反转后的分值;poscount3 积极词的最后分值包括叹号的分值 poscount,negcount,poscount2,negcount2,poscount3,negcount3 0,0,0,0,0,0 # if word in Hyperparams.posdict : if word in [好,真,实在] and words[min(i1,len(words)-1)] in Hyperparams.pos_neg_dict and words[min(i1,len(words)-1)] ! word:continueelse:poscount 1c 0for w in words[a:i]: # 扫描情感词前的程度词if w in Hyperparams.mostdict:poscount * 4elif w in Hyperparams.verydict:poscount * 3 elif w in Hyperparams.moredict:poscount * 2 elif w in Hyperparams.ishdict:poscount * 0.5elif w in Hyperparams.insufficientlydict:poscount * -0.3 elif w in Hyperparams.overdict:poscount * -0.5 elif w in Hyperparams.inversedict: c 1else:poscount * 1if tool.is_odd(c) odd: # 扫描情感词前的否定词数poscount * -1.0poscount2 poscountposcount 0poscount3 poscount poscount2 poscount3poscount2 0else:poscount3 poscount poscount2 poscount3poscount 0a i1elif word in Hyperparams.negdict: # 消极情感的分析与上面一致 if word in [好,真,实在] and words[min(i1,len(words)-1)] in Hyperparams.pos_neg_dict and words[min(i1,len(words)-1)] ! word:continueelse:negcount 1d 0for w in words[a:i]: if w in Hyperparams.mostdict:negcount * 4elif w in Hyperparams.verydict:negcount * 3elif w in Hyperparams.moredict:negcount * 2elif w in Hyperparams.ishdict:negcount * 0.5elif w in Hyperparams.insufficientlydict:negcount * -0.3elif w in Hyperparams.overdict:negcount * -0.5elif w in Hyperparams.inversedict:d 1else:negcount * 1if tool.is_odd(d) odd:negcount * -1.0negcount2 negcountnegcount 0negcount3 negcount negcount2 negcount3negcount2 0else:negcount3 negcount negcount2 negcount3negcount 0a i 1 i 1pos_count poscount3neg_count negcount3count1.append([pos_count,neg_count]) if words[-1] in [!,]:# 扫描感叹号前的情感词发现后权值*2count1 [[j*2 for j in c] for c in count1]for w_im in [但是,但]:if w_im in words : # 扫描但是后面的情感词发现后权值*5ind words.index(w_im)count1_head count1[:ind]count1_tail count1[ind:] count1_tail_new [[j*5 for j in c] for c in count1_tail]count1 []count1.extend(count1_head)count1.extend(count1_tail_new)break if words[-1] in [?,]:# 扫描是否有问好发现后为负面count1 [[0,2]]count2.append(count1)count1[]return count2def sentiment_score(self,s):senti_score_list self.sentiment_score_list(s)if senti_score_list ! []:negatives[]positives[]for review in senti_score_list:score_array np.array(review)AvgPos np.sum(score_array[:,0])AvgNeg np.sum(score_array[:,1]) negatives.append(AvgNeg)positives.append(AvgPos) pos_score np.mean(positives) neg_score np.mean(negatives)if pos_score 0 and neg_score0:pos_score pos_scoreneg_score abs(neg_score)elif pos_score 0 and neg_score0:pos_score pos_scoreneg_score neg_score else:pos_score,neg_score0,0return pos_score,neg_scoredef normalization_score(self,sent):score1,score0 self.sentiment_score(sent)if score1 4 and score0 4:if score1 score0:_score1 1_score0 score0/score1 elif score1 score0:_score0 1_score1 score1/score0 else :if score1 4 :_score1 1elif score1 4 :_score1 score1/4if score0 4 :_score0 1elif score0 4 :_score0 score0/4 return _score1,_score04.1情感词获取思路
情感分值列表计算
def sentiment_score_list(self, dataset):该方法接收一个数据集文本并返回每个句子的情感分值列表。
2句子切分用上面定义的方法进行切分句子 其中seg_sentence tool.sentence_split_regex(dataset)。使用 sentence_split_regex 方法将输入文本分割成独立句子。 count1, count2 [], [] count1 用于存储每个句子的情感分值count2 用于存储所有句子的情感分值。
3 使用下面的算法遍历每个句子
for sentence in seg_sentence:words jieba.lcut(sentence, cut_allFalse)对每个句子进行分词得到词汇列表。
4 情感词分析
for word in words:poscount, negcount, poscount2, negcount2, poscount3, negcount3 0, 0, 0, 0, 0, 0
初始化情感计数器正面和负面情感的计数器以及它们的临时值。5 正面情感词处理
python
if word in Hyperparams.posdict:检查当前词是否在正面词典中。 如果是遍历其之前的词分析程度词的影响并调整 poscount。
5.1 程度词影响
if w in Hyperparams.mostdict:poscount * 4 # 加强根据程度词如 “非常”、“极其” 等调整正面情感的分值。
5.2 否定词处理
if tool.is_odd(c) odd:poscount * -1.0检查是否存在奇数个否定词如果存在反转正面情感的得分。
6 负面情感词处理
elif word in Hyperparams.negdict:与正面情感处理类似检查当前词是否在负面词典中并进行相应分析。
7 特殊情况处理 检查句子末尾的感叹号和问号影响情感得分。
if words[-1] in [!,]:count1 [[j*2 for j in c] for c in count1]
如果句子以感叹号结尾将情感分值加倍。4.2 计算情感分值
sentiment_score 这段代码通过计算输入文本中每个句子的情感得分最终得出整体的正面和负面分值。它有效地整合了多句子的情感分析结果考虑了分值的符号和特殊情况确保了返回的情感得分具有合理性和准确性。这种方法适用于对评论或长文本进行情感倾向的评估。
def sentiment_score(self, s):该方法计算输入文本的整体情感得分。
1 获取情感分值列表
senti_score_list self.sentiment_score_list(s)调用 sentiment_score_list 方法获取每个句子的情感分值。
2 计算平均分值
AvgPos np.sum(score_array[:,0])
AvgNeg np.sum(score_array[:,1])计算所有句子正面和负面情感的平均分值。
4.3 得分的归一化处理
为了对情感分值进行合理的归一化处理以便在不同情感强度的情况下保持分值的可比性和一致性。通过这种方式分析结果可以更清晰地反映出文本的情感倾向同时在高分和低分情况下采取不同的归一化策略以适应不同的情感表达强度。这样的设计使得情感分析结果在实际应用中更具实用性和可解释性
def normalization_score(self, sent):高分情况下的处理
if score1 score0:_score1 1_score0 score0 / score1
elif score1 score0:_score0 1_score1 score1 / score0该方法对情感得分进行归一化处理返回标准化后的正面和负面分值。
根据正面和负面分值的大小关系进行归一化使得分值在一定范围内更加平衡和可比较。
归一化逻辑 如果正面得分大于或等于负面得分设置正面得分 _score1 为 1并将负面得分 _score0 归一化为其相对于正面得分的比例。 反之如果负面得分更高设置负面得分 _score0 为 1并将正面得分 _score1 归一化为其相对于负面得分的比例。
else:if score1 4:_score1 1elif score1 4:_score1 score1 / 4if score0 4:_score0 1elif score0 4:_score0 score0 / 4处理低分情况 如果正面得分大于或等于 4则将其归一化为 1。 如果正面得分小于 4则将其归一化为其与 4 的比例。 对负面得分采用相同的逻辑。 这部分设计意图在于确保即使在情感表达较弱的情况下分值也能在一个合理的范围内进行比较和理解。
4.实证
#计算完一条评论所有分句的情感值[正面分值, 负面分值]用数组list 记录起来。
sa SentimentAnalysis()
text 虽然这个产品性能很好但它的价格却很高我觉得不太划算
print(sa.normalization_score(text))(0.25, 0.08333333333333333) 这样就可以得到正面和负面的情感得分判断出来情感倾向 5.总结
本次代码通过分词、情感词典分析、程度词和否定词处理等步骤构建了一个完整的情感分析流程。它能够从输入的文本中提取情感信息并计算出正面和负面的情感得分最终提供一个归一化的情感评分。通过这种方式情感分析能够有效地捕捉文本中的情感表达支持情感理解和决策。
代码词典获取链接点赞关注失效留言或私信提取码1111