失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > Bilibili数据分析 B站爬虫|Bilibili 弹幕信息情感分析 Snow NLP 情感词典

Bilibili数据分析 B站爬虫|Bilibili 弹幕信息情感分析 Snow NLP 情感词典

时间:2022-09-07 03:56:36

相关推荐

Bilibili数据分析 B站爬虫|Bilibili 弹幕信息情感分析 Snow NLP 情感词典

需求分析

该代码旨在分析B站视频弹幕数据,包括情绪分类、情感分析和按秒计算弹幕数量。分析结果将作为一个CSV文件保存。

功能介绍

读取弹幕文件和词库文件。对弹幕内容进行清洗和分词。对弹幕进行情绪分类和情感分析。按秒计算每个弹幕的情绪数量和情感得分。将分析结果保存为CSV文件。

重点代码介绍

定义了document_to_list()函数,用于将文档内容读取为列表。

定义了clean_text()函数,用于对弹幕内容进行清洗。

定义了count()函数,用于计算每个弹幕的情绪数量。

定义了sentiment_score()函数,用于计算每个弹幕的情感得分。

定义了Analyze()函数,用于分析弹幕数据并将结果保存为CSV文件。

清理文本

def clean_text(text):# 使用正则表达式删除特殊字符text = re.sub(r"[^\w\s]", "", text)emoji_pattern = pile("["u"\U0001F600-\U0001F64F" # emoticonsu"\U0001F300-\U0001F5FF" # symbols & pictographsu"\U0001F680-\U0001F6FF" # transport & map symbolsu"\U0001F1E0-\U0001F1FF" # flags (iOS)u"\U00002702-\U000027B0""]+", flags=re.UNICODE)text = emoji_pattern.sub(r'', text)return text.strip()

这个函数用于清理文本,去除特殊字符和表情符号,使得分析过程更加准确。

计算情绪

def count(cut_list):emo_cnt = {"anger": 0, "disgust": 0, "fear": 0, "joy": 0, "sadness": 0}danmuku_emotion = []for word in cut_list:if word in anger:emo_cnt["anger"] += 1if word in disgust:emo_cnt["disgust"] += 1if word in fear:emo_cnt["fear"] += 1if word in joy:emo_cnt["joy"] += 1if word in sadness:emo_cnt["sadness"] += 1emo_max = max(emo_cnt.values())if emo_max == 0:danmuku_emotion.append("none")else:for key, value in emo_cnt.items():if value == emo_max:danmuku_emotion.append(key)if len(danmuku_emotion) == 1:danmuku_emotion = danmuku_emotion[0]else:danmuku_emotion = "complex"return emo_cnt

这个函数用于计算情绪向量。对于给定的分词列表,它将检查每个词是否属于预定义的情绪类别,并更新情绪计数。

SNowNLP情感分析

def sentiment_score(text):if not text or text.isspace():return 0 # 返回默认值,例如0# 使用snownlp进行情感分析s = SnowNLP(text)# 返回情感分析得分return s.sentiments

这个函数使用SNowNLP库进行情感分析,根据给定的文本返回情感得分。

分析函数

这是主要的分析函数,它负责读取弹幕文件,进行清理和分词,然后计算情绪和情感得分,最后将结果保存到CSV文件。

循环处理所有视频

for cid in tqdm(cid_list):...Analyze(cid)

这部分代码负责遍历视频列表,调用分析函数处理每个视频的弹幕。在处理过程中,它会检查文件是否存在以及是否已完成分析,确保不重复处理。

注意事项

请确保已安装所需的库(例如:pandas、jieba、re、snownlp、matplotlib等)。

请确保文件路径正确,并且所需的情绪词汇表、停用词表和弹幕文件存在。

代码中的路径可能需要根据您的实际情况进行调整。

本程序的运行时间可能较长,因为它需要处理大量的弹幕数据。可以考虑使用多线程或多进程优化代码,提高运行速度。

Snownlp可能无法完全准确地分析情感,您可以尝试使用其他情感分析库,以获得更准确的结果。

完整代码

下面是本文介绍的完整代码:

# 导入必要的库import pandas as pdimport jiebaimport refrom snownlp import SnowNLPimport matplotlib as mplimport matplotlib.pyplot as pltimport osfrom tqdm import tqdmdef document_to_list(path):# 读取文档,按行划分,返回列表print("正在将%s转换为文本列表, 请稍等..." % path)doc_list = []with open(path, 'r', encoding='utf-8') as doc_f:for line in doc_f.readlines():line = line.strip('\n')doc_list.append(line)return doc_list# 对弹幕内容进行分词和清理def clean_text(text):# 使用正则表达式删除特殊字符text = re.sub(r"[^\w\s]", "", text)emoji_pattern = pile("["u"\U0001F600-\U0001F64F" # emoticonsu"\U0001F300-\U0001F5FF" # symbols & pictographsu"\U0001F680-\U0001F6FF" # transport & map symbolsu"\U0001F1E0-\U0001F1FF" # flags (iOS)u"\U00002702-\U000027B0""]+", flags=re.UNICODE)text = emoji_pattern.sub(r'', text)return text.strip()def count(cut_list):# 闭包函数B,构建情绪向量 emo_cnt, 判断微博情绪(存在无情绪 None 和复杂情绪 [..., ...]情况)''':param cut_list::return emo_cnt: 情绪向量wb_emo: 判断的本条微博情绪'''emo_cnt = {"anger": 0, "disgust": 0, "fear": 0, "joy": 0, "sadness": 0}danmuku_emotion = []for word in cut_list:if word in anger:emo_cnt["anger"] += 1if word in disgust:emo_cnt["disgust"] += 1if word in fear:emo_cnt["fear"] += 1if word in joy:emo_cnt["joy"] += 1if word in sadness:emo_cnt["sadness"] += 1emo_max = max(emo_cnt.values())if emo_max == 0:danmuku_emotion.append("none")else:for key, value in emo_cnt.items():if value == emo_max:danmuku_emotion.append(key)if len(danmuku_emotion) == 1:danmuku_emotion = danmuku_emotion[0]else:danmuku_emotion = "complex"return emo_cnt# SNowNLP情感分析def sentiment_score(text):if not text or text.isspace():return 0 # 返回默认值,例如0# 使用snownlp进行情感分析s = SnowNLP(text)# 返回情感分析得分return s.sentimentsglobal anger_path, disgust_path, fear_path, joy_path, sadness_pathanger_path = "0_Res/anger.txt"disgust_path = "0_Res/disgust.txt"fear_path = "0_Res/fear.txt"joy_path = "0_Res/joy.txt"sadness_path = "0_Res/sadness.txt"anger = document_to_list(anger_path)disgust = document_to_list(disgust_path)fear = document_to_list(fear_path)joy = document_to_list(joy_path)sadness = document_to_list(sadness_path)global stopwordsstopwords = document_to_list("0_Res/stopwords_list.txt")document_list = document_to_list("0_Res/weibo.txt")def Analyze(cid):DANMUKU_PATH = f'/Volumes/SSD/Data/Danmuku/{cid}.csv'SAVE_PATH = f'/Volumes/SSD/Data/AnaDanmuku/{cid}.csv'print(cid)df = pd.read_csv(DANMUKU_PATH, encoding='utf-8', error_bad_lines=False)# 删除重复数据df = df.drop_duplicates()df['content'] = df['content'].astype(str)df['content_clean'] = df['content'].apply(clean_text)df['emo_cnt'] = df['content_clean'].apply(count)df['anger'] = df['emo_cnt'].apply(lambda x:x['anger'])df['disgust'] = df['emo_cnt'].apply(lambda x:x['disgust'])df['fear'] = df['emo_cnt'].apply(lambda x:x['fear'])df['joy'] = df['emo_cnt'].apply(lambda x:x['joy'])df['sadness'] = df['emo_cnt'].apply(lambda x:x['sadness'])df['sentiment'] = df['content_clean'].apply(sentiment_score) # 将progress列的数据类型转换为浮点数 df['progress'] = pd.to_numeric(df['progress'], errors='coerce') # 去除progress为空的行 df = df.dropna(subset=['progress']) # 将毫秒转换为秒并向下取整 df['progress'] = df['progress'].astype(int) df['second'] = df['progress'] // 1000 # 按照progress_seconds分组并计算每秒的angry、joy、disgust、fear和sadness值总和 sum_per_second = df.groupby('second')[['anger', 'joy', 'disgust', 'fear', 'sadness']].sum().reset_index() # 将结果赋值给一个新的数据框 result_df = pd.DataFrame(sum_per_second) # 按照progress_seconds分组并计算每秒的sentiment列的平均值 sentiment_mean_per_second = df.groupby('second')['sentiment'].mean().reset_index() # 按照second分组并计算每秒的弹幕总数 danmuku_count_per_second = df.groupby('second')['content'].count().reset_index() # 将计算得到的sentiment平均值和弹幕总数添加到result_df数据框中 result_df = result_df.merge(sentiment_mean_per_second, on='second') result_df = result_df.merge(danmuku_count_per_second, on='second') # 计算sentiment_count_product列的值,该值为每组的弹幕总数与sentiment平均值的乘积 result_df['sentiment_count_product'] = result_df['sentiment'] * result_df['content'] # 保存结果到CSV文件 result_df.to_csv(SAVE_PATH) return # 读取csv中的bvid、cid video_list = pd.read_csv('/Volumes/SSD/Data/getVideoinfo/getVideoinfo_byhot.csv') cid_list = video_list['cid'].values.tolist() for cid in tqdm(cid_list): DANMUKU_PATH = f'/Volumes/SSD/Data/Danmuku/{cid}.csv' SAVE_PATH = f'/Volumes/SSD/Data/AnaDanmuku/{cid}.csv' # 读取弹幕文件 if not os.path.exists(DANMUKU_PATH): print(f"Skipping bvid {cid} due to missing file(s).") continue if os.path.exists(SAVE_PATH): print(f"Skipping bvid {cid} due to finish.") continue Analyze(cid)

如果觉得《Bilibili数据分析 B站爬虫|Bilibili 弹幕信息情感分析 Snow NLP 情感词典》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。