1.词典法
众所周知,文本中蕴含着丰富的情绪信息。这些信息对于理解公众情绪、市场趋势乃至政治态势都有着不可估量的价值。文本情感分析,即通过自动化工具分析文本中的情感倾向,是自然语言处理(NLP)领域中的一项重要技术,它帮助机器理解人类语言中的主观信息。
词典法作为文本情感标注的一种基本方法,其核心思想是利用预先定义的情感词典来评估文本中词语的情感色彩。这种方法的优势在于操作简单、直观,不需要复杂的模型训练过程。情感词典通常包含大量带有情感极性的词汇,如“快乐”、“悲伤”等,每个词汇都被赋予一个正负情感值。在分析文本时,系统通过匹配这些词汇并根据其情感值和权重计算整个文本的情感倾向。
2.词典法的分类:无权重vs权重
词典法在实际应用中,根据对情感极性的量化程度,通常分为以下两类:
- • 原理:仅将词汇简单分类为“正向(+1)”、“负向(-1)”或“中性(0)”。
- • 计算:文本的总情感倾向由正负词汇的数量对比决定(例如:正向词多于负向词,则判定为正向)。
- • 特点:极其简单,适用于快速粗略的判断,但无法区分“喜欢”与“狂爱”之间程度的差异。
- • 原理:为每个情感词赋予一个具体的权重得分(如:在 -5 到 5 之间取值)。
- • 计算:不仅考虑词汇本身的得分,还会结合程度副词(如“非常”、“稍微”)和否定词(如“不”、“没有”)进行加权修正。
- • 特点:能够更精细地刻画情感强度,是目前词典法的主流应用方式。
3.词典法情感标注的代码思路
1.文本预处理
import osimport reimport jiebadef get_cut(text: str, stopwords: set) -> list[str]: """ 对给定的文本进行清洗、中文分词并去除停用词,仅保留长度大于1的名词。 参数: text (str): 需要进行处理的原始文本。 stopwords (set[str]): 停用词集合。 返回: list[str]: 处理后的分词结果列表。 """ # 清洗文本:去除换行符和特定的十六进制编码字符 cleaned_text = re.sub(r'\n|_x[0-9A-Fa-f]{4}_', '', text.lower()) # 分词并去除停用词 words = [word for word in jieba.cut(cleaned_text) if word not in stopwords] return wordsdef load_stopwords(dir_path: str = '../stopwords') -> set[str]: """ 从指定目录载入停用词文件。 参数: dir_path (str): 停用词文件所在目录的路径。 返回: set[str]: 停用词的集合。 """ stopwords = set() for file in os.listdir(dir_path): if file.startswith("."): continue with open(os.path.join(dir_path, file), 'r', encoding='utf-8') as f: stopwords.update(word.strip() for word in f.readlines()) # 添加自定义停用词 # stopwords.update([]) return stopwordsdef load_lexicon(filepath): """加载情感词典并添加到 jieba 分词词库中""" jieba.load_userdict(filepath) with open(filepath, 'r', encoding='utf-8') as file: return set(line.strip() for line in file if line.strip())def load_degree_words(filepath): """加载程度副词及其对应的权重""" degree_words = {} with open(filepath, 'r', encoding='utf-8') as file: for line in file: if line.strip(): # 假设文件格式为:词语,权重 word, weight = line.strip().split(',') jieba.add_word(word) degree_words[word] = float(weight) return degree_words
2.不带权重词典法
# 计算情绪得分def calculate_sentiment(cut_words): score = 0 for i, word in enumerate(cut_words): if word in (pos_lexicon | neg_lexicon): # 基础得分 temp_score = 1 if word in pos_lexicon else -1 # 寻找前面的否定词和程度副词 negation_count = 0 degree_factor = 1 # 向前遍历找否定词和程度副词 j = i - 1 j_min = i - 5 while j >= j_min and (cut_words[j] in negation_words or cut_words[j] in deg_lexicon): if cut_words[j] in negation_words: negation_count += 1 if cut_words[j] in deg_lexicon: degree_factor *= deg_lexicon[cut_words[j]] j -= 1 # 应用否定词 if negation_count % 2 == 1: temp_score *= -1 # 应用程度副词 temp_score *= degree_factor # 累计得分 score += temp_score return score
3.带权重词典法
import pandas as pd# 加载情感得分词典def load_sentiment_score(filepath): sentiment_scores = {} with open(filepath, 'r', encoding='utf-8') as file: for line in file: if line.strip(): parts = line.strip().split() word = parts[0] score = float(parts[1]) jieba.add_word(word) sentiment_scores[word] = score return sentiment_scoresdef calculate_sentiment(cut_words): score = 0 for i, word in enumerate(cut_words): if word in sentiment_dict: # 获取基础情感得分 temp_score = sentiment_dict[word] # 寻找前面的否定词和程度副词 negation_count = 0 degree_factor = 1 # 向前遍历找否定词和程度副词 j = i - 1 while j >= 0 and (cut_words[j] in negation_words or cut_words[j] in deg_lexicon): if cut_words[j] in negation_words: negation_count += 1 if cut_words[j] in deg_lexicon: degree_factor *= deg_lexicon[cut_words[j]] j -= 1 # 应用否定词 if negation_count % 2 == 1: temp_score *= -1 # 应用程度副词 temp_score *= degree_factor # 累计得分 score += temp_score return score
4.结果展示
不带权重词典法
带权重词典法