做了下初步实验,因为现在还是有点蒙,所以决定先写初稿理理思路。
实验数据来源于各大平台五台山景区游记评论
中文情感词汇本体库是大连理工大学信息检索研究室在林鸿飞教授的指导下经过全体教研室成员的努力整理和标注的一个中文本体资源。该资源从不同角度描述一个中文词汇或者短语,包括词语词性种类、情感类别、情感强度及极性等信息。
中文情感词汇本体的情感分类体系是在国外比较有影响的Ekman的6大类情感分类体系的基础上构建的。在Ekman的基础上,词汇本体加入情感类别“好”对褒义情感进行了更细致的划分。最终词汇本体中的情感共分为7大类21小类。
构造该资源的宗旨是在情感计算领域,为中文文本情感分析和倾向性分析提供一个便捷可靠的辅助手段。中文情感词汇本体可以用于解决多类别情感分类的问题,同时也可以用于解决一般的倾向性分析的问题。
情感词汇本体中,一般的格式为。
词语 | 词性种类 | 词义数 | 词义序号 | 情感分类 | 强度 | 极性 |
---|---|---|---|---|---|---|
无所畏惧 | idiom | 1 | 1 | PH | 7 | 1 |
手头紧 | idiom | 1 | 1 | NE | 7 | 0 |
周到 | adj | 1 | 1 | PH | 5 | 1 |
言过其实 | idiom | 1 | 1 | NN | 5 | 2 |
情感分类按照论文《情感词汇本体的构造》所述,情感分为7大类21小类。
情感强度分为1,3,5,7,9五档,9表示强度最大,1为强度最小。
|
|
|
|
---|---|---|---|
1 | 乐 | 快乐(PA) | 喜悦、欢喜、笑眯眯、欢天喜地 |
2 | 安心(PE) | 踏实、宽心、定心丸、问心无愧 | |
3 | 好 | 尊敬(PD) | 恭敬、敬爱、毕恭毕敬、肃然起敬 |
4 | 赞扬(PH) | 英俊、优秀、通情达理、实事求是 | |
5 | 相信(PG) | 信任、信赖、可靠、毋庸置疑 | |
6 | 喜爱(PB) | 倾慕、宝贝、一见钟情、爱不释手 | |
7 | 祝愿(PK) | 渴望、保佑、福寿绵长、万寿无疆 | |
8 | 怒 | 愤怒(NA) | 气愤、恼火、大发雷霆、七窍生烟 |
9 | 哀 | 悲伤(NB) | 忧伤、悲苦、心如刀割、悲痛欲绝 |
10 | 失望(NJ) | 憾事、绝望、灰心丧气、心灰意冷 | |
11 | 疚(NH) | 内疚、忏悔、过意不去、问心有愧 | |
12 | 思(PF) | 思念、相思、牵肠挂肚、朝思暮想 | |
13 | 惧 | 慌(NI) | 慌张、心慌、不知所措、手忙脚乱 |
14 | 恐惧(NC) | 胆怯、害怕、担惊受怕、胆颤心惊 | |
15 | 羞(NG) | 害羞、害臊、面红耳赤、无地自容 | |
16 | 恶 | 烦闷(NE) | 憋闷、烦躁、心烦意乱、自寻烦恼 |
17 | 憎恶(ND) | 反感、可耻、恨之入骨、深恶痛绝 | |
18 | 贬责(NN) | 呆板、虚荣、杂乱无章、心狠手辣 | |
19 | 妒忌(NK) | 眼红、吃醋、醋坛子、嫉贤妒能 | |
20 | 怀疑(NL) | 多心、生疑、将信将疑、疑神疑鬼 | |
21 | 惊 | 惊奇(PC) | 奇怪、奇迹、大吃一惊、瞠目结舌 |
每个词在每一类情感下都对应了一个极性。其中,0代表中性,1代表褒义,2代表贬义,3代表兼有褒贬两性。
注:褒贬标注时,通过词本身和情感共同确定,所以有些情感在一些词中可能极性1,而其他的词中有可能极性为0。
import pandas as pd
weibo_df = pd.read_excel('F:\\BaiduNetdiskDownload\\论文\\###论文数据\\pythonProject2\\Ensio\\论文\\词典文件保存路径\\携程旅行游记攻略6837.xlsx')
weibo_df.head(100)
# 读取
import pandas as pd
df = pd.read_excel('F:\BaiduNetdiskDownload\论文\###论文数据\词典汇总\三个情感词典汇总\其他词典和分类\情感词汇本体\情感词汇本体.xlsx')
df.head(10)
df = df[['词语', '词性种类', '词义数', '词义序号', '情感分类', '强度', '极性']]
df.head()
Happy = []
Good = []
Surprise = []
Anger = []
Sad = []
Fear = []
Disgust = []
for idx, row in df.iterrows():
if row['情感分类'] in ['PA', 'PE']:
Happy.append(row['词语'])
if row['情感分类'] in ['PD', 'PH', 'PG', 'PB', 'PK']:
Good.append(row['词语'])
if row['情感分类'] in ['PC']:
Surprise.append(row['词语'])
if row['情感分类'] in ['NA']:
Anger.append(row['词语'])
if row['情感分类'] in ['NB', 'NJ', 'NH', 'PF']:
Sad.append(row['词语'])
if row['情感分类'] in ['NI', 'NC', 'NG']:
Fear.append(row['词语'])
if row['情感分类'] in ['NE', 'ND', 'NN', 'NK', 'NL']:
Disgust.append(row['词语'])
Positive = Happy + Good +Surprise
Negative = Anger + Sad + Fear + Disgust
print('情绪词语列表整理完成')
print(Positive)
print(Negative)
from string import digits
import jieba # 分词
import re # 过滤特殊字符
import numpy as np # 辅助处理
import pandas as pd # 处理
import emoji # 过滤表情
import jieba.analyse # 分级级别权重
import imageio # 图片
import jieba.posseg as pseg # 词性标注
from wordcloud import WordCloud # 词云
import os
import matplotlib.pyplot as plt # 画布
import difflib # 相似度判断
path = 'F:\\BaiduNetdiskDownload\\论文\\###论文数据\\pythonProject2\\Ensio\\论文\\词典文件保存路径\\result\\juzi_1.txt'
# 台湾大学积极词典
pos_dict_path = 'F:\\BaiduNetdiskDownload\\论文\\###论文数据\\pythonProject2\\Ensio\\论文\\词典文件保存路径\\ntusd-positive.txt'
# 台湾大学消极词典
neg_dict_path = 'F:\\BaiduNetdiskDownload\\论文\\###论文数据\\pythonProject2\\Ensio\\论文\\词典文件保存路径\\ntusd-negative.txt'
# 台湾大学停用词
no_dict_path = 'F:\\BaiduNetdiskDownload\\论文\\###论文数据\\pythonProject2\\Ensio\\论文\\词典文件保存路径\\not.txt'
# 常用中文停用词
cn_stopwords = 'F:\\BaiduNetdiskDownload\\论文\\###论文数据\\pythonProject2\\Ensio\\论文\\词典文件保存路径\\cn_stopwords.txt'
# 宋体字体
simsun_path = 'F:\\BaiduNetdiskDownload\\论文\\###论文数据\\pythonProject2\\Ensio\\论文\\词典文件保存路径\\simsun.ttc'
# 词云背景图片
bg_path = 'F:\\BaiduNetdiskDownload\\论文\\###论文数据\\pythonProject2\\Ensio\\论文\\词典文件保存路径\\五台山字.jpg'
# 评论元数据
excel_path = 'F:\\BaiduNetdiskDownload\\论文\\###论文数据\\pythonProject2\\Ensio\\论文\\词典文件保存路径\\携程旅行游记攻略6837.xlsx'
# 情感分析结果输出 初始文件为空
Sentiment_analysis_ioPath = 'F:\\BaiduNetdiskDownload\\论文\\###论文数据\\pythonProject2\\Ensio\\论文\\词典文件保存路径\\result\\携程旅行游记攻略6837-情感分析结果.txt'
# 评论格式化写出 初始文件为空
comment_ioPath = 'F:\\BaiduNetdiskDownload\\论文\\###论文数据\\pythonProject2\\Ensio\\论文\\词典文件保存路径\\result\\携程旅行游记攻略-纯文本6837.txt'
# 句子级写出
juzi_path = 'F:\\BaiduNetdiskDownload\\论文\\###论文数据\\pythonProject2\\Ensio\\论文\\词典文件保存路径\\result\\juzi_1_1.txt'
# 词云保存路径 初始文件为空
wordcloud_ioPath = 'F:\\BaiduNetdiskDownload\\论文\\###论文数据\\pythonProject2\\Ensio\\论文\\词典文件保存路径\\result\\五台山词云.png'
# 五台山关键字词典 初始不为空
wts_dict_path = 'F:\\BaiduNetdiskDownload\\论文\\###论文数据\\pythonProject2\\Ensio\\论文\\词典文件保存路径\\五台山关机键词典.txt'
weibo_text = weibo_comment[0]
weibo_text = "".join(weibo_text.split())
weibo_text = re.sub(u"([^\u4e00-\u9fa5\u0030-\u0039\u0041-\u005a\u0061-\u007a])", "",weibo_text)
print(weibo_text)
def filter_emoji(test_str):
result = emoji.demojize(test_str)
return emoji.emojize(result)
def pretreatment():
# 加载excel
excel = pd.read_excel(excel_path) #encoding = utf-8
# punt_list = ',.!?;~。!?;~… '.encode('utf8').decode('utf8')
# 暂时留取时间,不做处理
data = excel[['Title', 'Notes']]
# 生成单维DataFrame 并删除重复行
datafreame = pd.DataFrame(data).dropna(how='any').drop_duplicates(subset='Notes')
# 去除空值 NaN
dataToTwo = datafreame.dropna(axis=0)
# 存放comment列----》字符串列表
dataToTwoStr = []
for i in dataToTwo['Notes']:
dataToTwoStr.append(filter_emoji(str(i))) # 表情处理
#print(dataToTwoStr)
return dataToTwoStr
pretreatment()
import jieba
import time
def emotion_caculate(text):
positive = 0
negative = 0
anger = 0
disgust = 0
fear = 0
sad = 0
surprise = 0
good = 0
happy = 0
wordlist = jieba.lcut(text)
wordset = set(wordlist)
wordfreq = []
for word in wordset:
freq = wordlist.count(word)
if word in Positive:
positive+=freq
if word in Negative:
negative+=freq
if word in Anger:
anger+=freq
if word in Disgust:
disgust+=freq
if word in Fear:
fear+=freq
if word in Sad:
sad+=freq
if word in Surprise:
surprise+=freq
if word in Good:
good+=freq
if word in Happy:
happy+=freq
emotion_info = {
'length':len(wordlist),
'positive': positive,
'negative': negative,
'anger': anger,
'disgust': disgust,
'fear':fear,
'good':good,
'sadness':sad,
'surprise':surprise,
'happy':happy,
}
indexs = ['length', 'positive', 'negative', 'anger', 'disgust','fear','sadness','surprise', 'good', 'happy']
return pd.Series(emotion_info, index=indexs)
weibo_comment = weibo_df['Notes']
emotion_caculate(text='景区人太多了吧,物价还死贵死贵的,买瓶水要5块,随处可见的垃圾,让人心情不好!!')
# 相似度计算
def get_equal_rate_1(str1, str2):
return difflib.SequenceMatcher(None, str1, str2).quick_ratio()
# 对比关键字词典
def comment_base_split(wts_lst, comment_base):
index = []
for i in wts_lst:
if i in comment_base:
sall_index = [r.span() for r in re.finditer(i, comment_base)]
index.append(sall_index)
index_commnet = list(index)
t = []
# print(index_commnet)
for i in index_commnet:
for j in i:
tutle = list(j)
if tutle[0] < 10:
tutle[0] = 0
else:
tutle[0] = tutle[0] - 30
if tutle[1] < 10:
tutle[1] = 20
else:
tutle[1] = tutle[1] + 30
t.append(tutle)
for s in range(len(index_commnet)):
index_commnet[s] = t
# print(index_commnet)
comment_base_split_dict = []
for i in index_commnet:
for j in i:
comment_base_split_dict.append(comment_base[j[0]:j[1]])
for i in comment_base_split_dict:
for j in comment_base_split_dict:
if get_equal_rate_1(i, j) > 0.85: # 相似度大于0.85 删除
comment_base_split_dict.remove(j)
break
return comment_base_split_dict
# 加载关键字词典
def wts_dict():
wts_lst = []
with open(wts_dict_path, encoding='utf-8') as f:
for line in f:
line = line.replace("\n", "").replace("\r", "")
wts_lst.append(line)
return wts_lst
# 加载词典
def dict_load(path):
print("文件加载!")
dt = []
with open(path, encoding='utf-8-sig') as f:
for line in f:
if line.strip() != '': # 去除空格
dt.append(line.strip())
return (dt)
def first_Load():
neg_dict = [] # 消极情感词典
pos_dict = [] # 积极情感词典
no_dict = [] # 否定词词典
pos_dict = dict_load(pos_dict_path)
# print(pos_dict)
neg_dict = dict_load(neg_dict_path)
# print(neg_dict)
no_dict = dict_load(no_dict_path)
# print(no_dict)
return pos_dict, neg_dict, no_dict
# dicts = {,{,[]}}
def batchProcessing():
with open(juzi_path, 'a', encoding='utf-8') as f:
# 加载五台山关键字词典
wts_lst = wts_dict()
# 三个情感分析词典加载
pos_dict, neg_dict, no_dict = first_Load()
# 获取评论 字符串列表
inputs = pretreatment()
lsts = []
lst = []
#print(inputs)
for i in inputs:
comment_base = i.replace("\n", "")
lst.append(comment_base_split(wts_lst, comment_base))
break
for i in lst:
for j in i:
base = re.sub(u"([^\u4e00-\u9fa5\u0030-\u0039\u0041-\u005a\u0061-\u007a])", "", j)
remove_digits = str.maketrans('', '', digits)
res =base.translate(remove_digits)
emo = emotion_caculate(text=res)
lsts.append(emo)
f.write(res + '\n')
print("句子级写入完成!")
return lsts
#batchProcessing()
lsts = batchProcessing()
# s = lsts[0]
# length 31
# positive 2 正向
# negative 0 负向
# anger 0 愤怒
# disgust 0 厌恶
# fear 0 恐惧
# sadness 0 悲伤
# surprise 0 惊喜
# good 2 好
# happy 0 快乐
# dtype: int64
pos_scores = []
neg_scores = []
for i in lsts:
pos_scores.append(int(i[1]))
neg_scores.append(int(i[2]))
final_scores = sum(pos_scores) - sum(neg_scores)
# 情感分
print(final_scores)
lsts
第1天2014-09-05前记:山西游的想法来自于父亲,他说几乎游遍了祖国的大好河山,现在全中国的省份只有山西、西藏和宁夏没有去过。我琢磨着想和爸爸一起旅游,所以便说我们带你去山西吧,老爸随即说了他特别想去的几个景点,我上网查山西地图,可以啊,这几个景点几乎纵贯山西,从南到北。。。好吧,反正说都说了,就走吧!写这篇游记的初衷:之前去过不少地方旅游,从来没有写过游记,但是这次去山西,感触太深了。每次
做攻略都会上网参照网友的旅游信息,自己也得益不少,这次去了山西以后,发现有不少信息,主要是交通方面的,都已经不是最新的了,所以想把自己认为是最新的消息提供出来,方便之后想去山西(仅限我去过的地方哈:))的朋友们。 第一天都是在路上度过的,因为第一站去晋城皇城相府,而上海没有直接到晋城的火车,所以我选择了离晋城相对较近而且长途车班次较多的郑州作为中转站。上海到郑州的动车大概7个半小时左右,长途汽车站就在火车站对面,郑州到晋城的长途车差不多一个小时一班,最晚到6点。我们下午2点半到达郑州,买到了3点半前往晋城的车票,车程说是3个半小时,不过从汽车站开到高速入口这一路堵的不行,足足多出了40分钟,最后快8点才到达晋城客运东站。需要注意的是,现在晋城的长途汽车已经全部从客运东站始发和到达,之前的省运和市运已退出历史舞台,据说是为了缓解市内交通。客运东站地点比较偏,离我们住的地方也就4,5公里路,正常的出租费用在11元左右,
不过出租车司机都不愿意去,毕竟在汽车站候客的出租车总想拉个远差,问了一个黑车,说20能走,这样的价钱我还是能接受的。之后在各地的火车站和汽车站都碰到了出租车不愿去酒店的情形,稍后再说。晋城的酒店定在锦江之星金广快捷七星广场店,因为我有锦江之星的会员卡,而且我觉得锦江之星在全国各地的分店设施都差不多,属于满规范化的连锁快捷酒店,价钱折后也在150之内,所以这次旅行地只要有锦江之星的,我都会预订。上海郑州晋城,第2天2014-09-06晋城 美好的一天从美好的早餐开始,这是在山西的第一顿早饭,山西的豆腐很出
名,这看上去太赞了。吃完早饭,出发去此行的第一个景点——皇城相府。晋城晋城 晋城到皇城相府的车子每天从早上6点半开始,几乎一个小时一班,最后一般是晚上6点半。车费15,车程一个半小时。因为去完皇城相府,我们还是要回到晋城客运东站再坐车前往临汾,所以一早我们就带了行李,直接把行李寄放在了汽车站,4元一件。皇城相府 皇城相府是康熙的老师、《康熙字典》总阅官、清代名相陈廷敬的府邸。明清时期生活在这里的陈氏家族科甲鼎盛,有多达38人走上仕途,而且大多政绩显赫,可谓是翰林世家。导游说,皇城相府后来是让老百姓居住的,直到1998年才被国家收回作为旅游景点开发。说到导游,我之前去买票的时候忘了找在售票处旁边的导
游,结果进了景区,被告之有实习导游,50一次(导游是80),不过实习导游和正式导游还是有差距的,我蹭听了好多别人家的导游。皇城相府皇城相府皇城相府皇城相府皇城相府 彩旗飘扬的地方是阶梯,长长的阶梯一共53格(应该没有记错),陈廷敬当官53载,巧合!皇城相府 从皇城相府回晋城的车,在景区门口是没有站的,不过可以有几种方式回去,一种就是在景区门口等开往皇城相府的车,然后车会把你带到北留镇上,皇城相府是属于北留镇的,再从北留镇上坐车回晋城;还有一种就是在景区门口叫面的,3元一人,也是把你拉到北
留镇上的汽车点。两种方式花费一样,唯一不同的是,可能第一种方式需要等很长时间才会有车来,而第二种应该是招手即有的。我比较幸运,出了景点就有一部到站的汽车,所以我们就上了。回到晋城客运东站,直接买票去临汾,好巧的是买到了5分钟后的汽车,时间算的太好了。 从晋城开往临汾大概需要4个小时左右,途径一个休息站休息的时候,看到一张山西全省的旅游景点地图。我给老爸指了指要去的那些景点,老爸说,离的那么远啊,你太伟大了,哈哈。 临汾没有锦江之星,所以预订了离汽车站不远的尧都区政府商务酒店,三人套房,两个房间,还不错,比周围的那些酒店看上去好,反正凑活一夜,明天一早就上路了。,第3天2014-09-07 前往壶口瀑布的交通不是很方便,我在淘宝上觅得壶口小李,成人190一位,包含来去车费和门票及保险,享受免票政策的人群120一位。全程高速,车上备有WIFI,有免费的接送站服务,他们还会提前一天和当天早上电话确认,性价比满高的,最最主
要是方便。其实这就是包车,不过人家信誉做出来了,就比较可靠。听说从今年9月开始,自己的车不能开进景区了,从售票处到景点还有4公里的路,所以必须坐景点提供的所谓环保车,20一人,好吧。黄河壶口瀑布风景名胜区 壶口瀑布的雄伟只有自己去了才能感受到,我们在那里足足呆了2个多小时,只是呆呆地看。我们运气好好,包车的司机说这几天水特别大,只要靠近围栏将近10米左右,就感觉像下雨一般,密密的,这直接导致了我们全身湿透,而且干了以后到处留下了泥印。 水中冒烟的奇景描述的就是这种画面吧。黄河壶口瀑布风景名胜区黄河壶口瀑布风景名胜区黄河壶口瀑布风景名胜区黄河壶口瀑布风景名胜区黄河壶口瀑布风景名胜区 每头毛驴头上都贴着它们的名字。黄河壶口瀑布风景名胜区 这位叫壶口老什么来着,还看到过壶口花花,壶口小花什么的。黄河壶口瀑布风景名胜区 壶口瀑布一游非常顺利,前一天晚上到我们出发一直都在下大雨,车子上了高速,开到一半,雨停了。路上几乎都没有车,超爽。车程2个小时,再加上景区呆2个多小时,我们是早上8点出发的,下午3点不到已经回到了市区。我买了下午4点临汾到平遥的火车,本想去看看能够改签到早一班的伐,不过没有座位了,只好等咯。平遥古城的住宿是![在这里插入图片描述](https://img-blog.csdnimg.cn/20210328164609613.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzMwODAzNTIz,size_16,color_FFFFFF,t_70#pic_center)
定在锦江之星平遥古城店,离火车站不远,靠近西大门,住宿正好是周日和周一两天,还抢到了锦江之星的百元房,实在是划算。
积极倾向值:56
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210328164539650.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzMwODAzNTIz,size_16,color_FFFFFF,t_70)
消极倾向值:64
情感倾向:积极
------------------
def toWordCloud():
# 停用词
fr = open(cn_stopwords, 'r', encoding='utf-8')
stop_word_list = fr.readlines()
new_stop_word_list = []
for stop_word in stop_word_list:
stop_word = stop_word.replace('\ufeef', '').strip()
new_stop_word_list.append(stop_word)
with open(path, 'r', encoding='utf-8') as f:
words = f.read()
word_dict = {}
word_list = ''
words_arr = words.split('\n')
words_jiebas = []
for i in words_arr:
words_jiebas.append(jieba.lcut(i))
for words_jieba in words_jiebas:
for word in words_jieba:
if (len(word) > 1 and not word in new_stop_word_list):
word_list = word_list + ' ' + word
if (word_dict.get(word)):
word_dict[word] = word_dict[word] + 1
else:
word_dict[word] = 1
##print(word_list)
# print(word_dict)
# 按次数进行排序
sort_words = sorted(word_dict.items(), key=lambda x: x[1], reverse=True)
print(sort_words[0:101]) # 输出前0-100的词
#color_mask = imageio.imread(bg_path)
wc = WordCloud(
background_color="white", # 背景颜色
max_words=1000, # 显示最大词数
font_path=simsun_path, # 使用字体
min_font_size=20,
max_font_size=500,
random_state=42, # 随机数
collocations=False, # 避免重复单词
width=1600,
height=1200,
margin=10,
#mask=color_mask) # 图幅宽度
)
#wc.recolor([random_state, color_func, colormap])
wc.generate(word_list)
wc.to_file(wordcloud_ioPath)
plt.figure(dpi=100)
# 以图片的形式显示词云
plt.imshow(wc,interpolation='catrom',vmax=1000)
# 关闭图像坐标系
plt.axis("off")
plt.show()