IPhone16评论自然语言处理
最近看到了一个自然语言处理的项目,发现自己也没怎么写过这方面的文章,所以上周写了一篇,上周忘记发了,这周才发。
这是两个数据集的概况
最近看到了一个IPhone评论数据的自然语言处理的项目,就想到了在GitHub上的一个开源的处理中文文本的模型HanLP,这是他的地址https://github.com/hankcs/HanLP
大家可以去学习一下,Jieba是基于传统的词典匹配和HMM,而HanLP2.x版本是基于深度学习,对于分词的处理可能更加精确
一.准备工作
!pip install snownlp -i https://pypi.tuna.tsinghua.edu.cn/simple/
!pip install wordcloud -i https://pypi.tuna.tsinghua.edu.cn/simple/
!pip install hanlp[full] -i https://pypi.tuna.tsinghua.edu.cn/simple/
先下载需要用到的分词,情感分析,词云图的第三方库
import hanlp
import pandas as pd
import numpy as np
from snownlp import SnowNLP
from wordcloud import WordCloud
导入包
df1 = pd.read_excel("D:/每周挑战/B站视频-何同学_241020_1729431535.xlsx")
df2 = pd.read_excel("D:/每周挑战/B站视频-影视飓风_241020_1729431473.xlsx")
pd.set_option("display.max_columns",1000)
pd.set_option("display.max_rows",1000)
读取数据,并解除行和列的限制
df1.info()
///
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 6310 entries, 0 to 6309
Data columns (total 14 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 oid 6310 non-null int64
1 rpid 6310 non-null int64
2 rrpid 1290 non-null float64
3 评论层级 6310 non-null object
4 用户昵称 6310 non-null object
5 评论内容 6310 non-null object
6 评论时间 6310 non-null object
7 被回复用户 1290 non-null object
8 性别 6310 non-null object
9 用户当前等级 6310 non-null int64
10 点赞数 6310 non-null int64
11 回复数 6310 non-null int64
12 视频标题 6310 non-null object
13 视频链接 6310 non-null object
dtypes: float64(1), int64(5), object(8)
memory usage: 690.3+ KB
///
df2.info()
///
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 9128 entries, 0 to 9127
Data columns (total 14 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 oid 9128 non-null int64
1 rpid 9128 non-null int64
2 rrpid 4321 non-null float64
3 评论层级 9128 non-null object
4 用户昵称 9128 non-null object
5 评论内容 9128 non-null object
6 评论时间 9128 non-null object
7 被回复用户 4321 non-null object
8 性别 9128 non-null object
9 用户当前等级 9128 non-null int64
10 点赞数 9128 non-null int64
11 回复数 9128 non-null int64
12 视频标题 9128 non-null object
13 视频链接 9128 non-null object
dtypes: float64(1), int64(5), object(8)
memory usage: 998.5+ KB
///
从这里看出,数据集里缺失数据还是有的,rrpid是被回复用户的唯一标识,因为我们主要是做文本分析的,id对我们来说没用,因此,我们就不管了
data1 = df1[['用户昵称', '评论内容', '评论时间', '性别', '用户当前等级', '点赞数', '回复数']]
data2 = df2[['用户昵称', '评论内容', '评论时间', '性别', '用户当前等级', '点赞数', '回复数']]
提取出我们用到的数据
二.数据可视化
import matplotlib.pyplot as plt
plt.rcParams['font.family'] = 'sans-serif'
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.figure(figsize=(12,10))
# 点赞数箱线图
plt.subplot(2, 1, 1)
plt.boxplot(data1['点赞数'])
plt.title('何同学 - 点赞数箱线图')
plt.ylabel('点赞数')
plt.grid(True)
# 回复数箱线图
plt.subplot(2, 1, 2)
plt.boxplot(data1['回复数'])
plt.title('何同学 - 回复数箱线图')
plt.ylabel('回复数')
plt.grid(True)
plt.tight_layout()
plt.show()
plt.figure(figsize=(12,10))
# 点赞数箱线图
plt.subplot(2, 1, 1)
plt.boxplot(data2['点赞数'])
plt.title('影视飓风 - 点赞数箱线图')
plt.ylabel('点赞数')
plt.grid(True)
# 回复数箱线图
plt.subplot(2, 1, 2)
plt.boxplot(data2['回复数'])
plt.title('影视飓风 - 回复数箱线图')
plt.ylabel('回复数')
plt.grid(True)
plt.tight_layout()
ply.show()
print("何同学视频点赞数最高的10条评论:")
data1.nlargest(10, '点赞数')[['用户昵称','用户当前等级', '评论内容', '点赞数', '回复数']]
print("影视飓风视频点赞数最高的10条评论:")
data2.nlargest(10, '点赞数')[['用户昵称','用户当前等级', '评论内容', '点赞数', '回复数']]
plt.figure(figsize=(12, 6))
plt.subplot(1, 2, 1)
plt.scatter(data1['用户当前等级'], data1['点赞数'], color='blue', alpha=0.5)
plt.title('何同学 - 用户等级与点赞数的关系')
plt.xlabel('用户当前等级')
plt.ylabel('点赞数')
plt.subplot(1, 2, 2)
plt.scatter(data1['用户当前等级'], data1['回复数'], color='green', alpha=0.5)
plt.title('何同学 - 用户等级与回复数的关系')
plt.xlabel('用户当前等级')
plt.ylabel('回复数')
plt.tight_layout()
plt.show()
plt.figure(figsize=(12, 6))
plt.subplot(1, 2, 1)
plt.scatter(data2['用户当前等级'], data2['点赞数'], color='blue', alpha=0.5)
plt.title('影视飓风 - 用户等级与点赞数的关系')
plt.xlabel('用户当前等级')
plt.ylabel('点赞数')
plt.subplot(1, 2, 2)
plt.scatter(data2['用户当前等级'], data2['回复数'], color='green', alpha=0.5)
plt.title('影视飓风 - 用户等级与回复数的关系')
plt.xlabel('用户当前等级')
plt.ylabel('回复数')
plt.tight_layout()
plt.show()
import re
def clean_text(text):
"""
文本预处理:只删除表情符号和emoji,保留所有文字内容
"""
if not isinstance(text, str):
return ''
# 1. 去除[xxx]格式的表情
cleaned_text = re.sub(r'\[.*?\]', '', text)
# 2. 去除emoji表情
cleaned_text = re.sub(r'[\U00010000-\U0010ffff]', '', cleaned_text)
# 3. 去除多余空格
cleaned_text = ' '.join(cleaned_text.split())
return cleaned_text.strip()
data1['清洗评论'] = data1['评论内容'].apply(clean_text)
data2['清洗评论'] = data2['评论内容'].apply(clean_text)
# 加载分词模型
tokenizer = hanlp.load(hanlp.pretrained.tok.COARSE_ELECTRA_SMALL_ZH)
# 加载停用词表
with open('E:/ChromeDownloads/baidu_stopwords.txt', 'r', encoding='utf-8') as f:
stopwords = set(line.strip() for line in f)
# def participle(texts):
# # 批量分词并过滤停用词
# word_lists = tokenizer(texts)
# result = [[word for word in words if word not in stopwords] for words in word_lists]
# return result
product_words = {'苹果', '手机', 'iphone', '华为', '三星', '何同学', '影视飓风', '回复'}
all_stopwords = stopwords.union(product_words)
def participle(text):
# 对每条评论分词并过滤停用词
words = tokenizer(text)
filtered_words = [word for word in words if word not in all_stopwords]
return ''.join(filtered_words)
data1['分词结果'] = data1['清洗评论'].apply(participle)
data2['分词结果'] = data2['清洗评论'].apply(participle)
对评论内容进行处理后在进行分词
def get_sentiment(text):
"""
情感分析函数,包含错误处理
"""
try:
# 如果文本为空或者只包含空格
if not text or text.isspace():
return 0.5 # 返回中性分数
return SnowNLP(text).sentiments
except:
return 0.5 # 出错时返回中性分数
data1['情感分数'] = data1['清洗评论'].apply(get_sentiment)
data2['情感分数'] = data2['清洗评论'].apply(get_sentiment)
对评论内容进行情感分析
plt.figure(figsize=(12, 6))
plt.subplot(1, 2, 1)
plt.hist(data1['情感分数'], bins=50, color='blue', alpha=0.6)
plt.title('何同学 - 评论情感分布')
plt.xlabel('情感分数(0=消极,1=积极)')
plt.ylabel('评论数量')
plt.grid(True, alpha=0.3)
# 影视飓风评论情感分布
plt.subplot(1, 2, 2)
plt.hist(data2['情感分数'], bins=50, color='green', alpha=0.6)
plt.title('影视飓风 - 评论情感分布')
plt.xlabel('情感分数(0=消极,1=积极)')
plt.ylabel('评论数量')
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
def generate_wordcloud(data, title, word_cloud_type):
# 根据情感分数过滤数据并将分词结果拼接成字符串
if word_cloud_type == '积极':
text = ' '.join([' '.join(words) for words in data[data['情感分数'] > 0.8]['分词结果']])
else:
text = ' '.join([' '.join(words) for words in data[data['情感分数'] < 0.2]['分词结果']])
plt.figure(figsize=(15, 10))
wordcloud = WordCloud(
font_path='E:/ChromeDownloads/SIMHEI.ttf',
width=800,
height=400,
background_color='white',
max_words=100,
).generate(text)
plt.imshow(wordcloud, interpolation='bilinear')
plt.title(title)
plt.axis('off')
绘制词云图
generate_wordcloud(data1, '何同学 - 积极评论词云', '积极')
generate_wordcloud(data1, '何同学 - 消极评论词云', '消极')
generate_wordcloud(data2, '影视飓风 - 积极评论词云', '积极')
generate_wordcloud(data2, '影视飓风 - 消极评论词云', '消极')
原文地址:https://blog.csdn.net/qq_60688380/article/details/143485028
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!