-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathAPP评论数据分析初步探索.R
More file actions
233 lines (168 loc) · 6.07 KB
/
Copy pathAPP评论数据分析初步探索.R
File metadata and controls
233 lines (168 loc) · 6.07 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
#######################################################
#
# 论文研究
#
#######################################################
#### 第一步:加载数据并查看结构
library(dplyr)
# 加载数据
reviews <- read.csv("//Users//wulixin//Desktop//user_reviews.csv", header = TRUE, stringsAsFactors = FALSE)
library(tmcn)
library(tm)
data(STOPWORDS)
# 转换为小写
reviews$Review <- tolower(reviews$Review)
# 移除标点、数字
reviews$Review <- gsub("[[:punct:]]", "", reviews$Review)
reviews$Review <- gsub("[0-9]", "", reviews$Review)
# 查看前几行
head(reviews)
library(DataExplorer)
plot_bar(reviews,title='图1 ')
##版本更新次数
plot_bar(reviews,by='AppName')
# 查看各 App 的评论数量
table(reviews$AppName)
#### 第二步:预处理评论文本
library(jiebaR) # 中文分词
library(tm) # 文本清洗
library(stringr) # 字符串处理
# 去除停用词(需准备中文停用词文件)
## 哈工大停用词表,中文停用词表,四川大学机器智能实验室停用词表,百度停用词表
#stopwords <- readLines("//Users//wulixin//Desktop//百度cleaned_stopwords.txt",encoding = "UTF-8")
library(stringi)
# 读取停用词并清理
stopwords <- readLines("//Users//wulixin//Desktop//百度停用词表.txt", encoding = "UTF-8")
stopwords <- unique(trimws(stopwords))
stopwords <- stopwords[stopwords != ""]
# 写入标准停用词文件备用
writeLines(stopwords, "//Users//wulixin//Desktop//百度cleaned_stopwords.txt")
# 示例评论数据(你自己的 user_reviews.csv 中的 Review 列)
reviews <- read.csv("//Users//wulixin//Desktop//user_reviews.csv", stringsAsFactors = FALSE)
comments <- reviews$Review
# 分词函数(jiebaR)
segger <- worker()
tokens <- lapply(comments, function(x) {
unlist(segger[x])
})
# 构建语料库
corpus <- Corpus(VectorSource(tokens))
# 文本清洗
corpus <- tm_map(corpus, content_transformer(tolower)) # 小写转换(可选)
corpus <- tm_map(corpus, removePunctuation) # 去标点
corpus <- tm_map(corpus, removeNumbers) # 去数字
# 使用 stringi 删除停用词(更安全)
corpus <- tm_map(corpus, content_transformer(function(x, words) {
for (word in words) {
x <- stri_replace_all_fixed(x, word, "", vectorize_all = FALSE)
}
return(x)
}), words = stopwords)
# 构建 DTM
dtm <- DocumentTermMatrix(corpus)
# 查看前几个词频
freq <- colSums(as.matrix(dtm))
head(sort(freq, decreasing = TRUE), 50)
# 检查是否有空文档(行和列都非零)
row_sums <- rowSums(as.matrix(dtm))
col_sums <- colSums(as.matrix(dtm))
# 去掉全零的行(即空文档)
dtm_clean <- dtm[row_sums > 0, ]
# 查看清理前后的矩阵维度
cat("原始 DTM 维度:", dim(dtm), "\n")
cat("清理后 DTM 维度:", dim(dtm_clean), "\n")
#########第四步:LDA 主题建模(识别主要关注点)
library(topicmodels)
# 设置主题数
lda_model <- LDA(dtm_clean, k = 5)
# 获取每个主题的关键词
terms <- terms(lda_model, 10)
# 输出主题关键词
for (i in 1:5) {
cat("Topic", i, ":", paste(terms[[i]], collapse = ", "), "\n")
}
#########第五步:可视化展示
##词云图高频关键词
library(wordcloud)
wordcloud(words = colSums(as.matrix(dtm)),
freq = rowSums(as.matrix(dtm)),
max.words = 100,
random.order = FALSE)
# 情感分析(示例)
library(readxl)
library(stringr)
# 读取情感分类表
sentiment_data <- read_excel("情感词汇本体.xlsx", sheet = "情感分类")
# 提取情感标签(如 PA, PE, NA, NB 等)
sentiment_data$emotion_tag <- str_extract(sentiment_data$情感类, "\\([A-Z]+\\)") %>%
str_remove_all("[()]")
# 将“例词”列转换为词向量列表
emotion_words <- lapply(sentiment_data$例词, function(x) {
unlist(str_split(x, "、"))
})
# 构建成命名列表(key = emotion_tag, value = 词列表)
emotion_dict <- setNames(emotion_words, sentiment_data$emotion_tag)
#定义情感评分函数
get_emotion_scores <- function(tokens, emotion_dict) {
scores <- sapply(names(emotion_dict), function(tag) {
sum(tokens %in% emotion_dict[[tag]])
})
return(scores)
}
##################################
# token list 介绍
##############################
library(jiebaR)
library(dplyr)
# 初始化分词引擎
segger <- worker()
# 分词函数
tokenize <- function(text) {
unlist(lapply(text, function(x) segger[x]))
}
# 获取 tokens_list
tokens_list <- tokenize(reviews$Review)
# 清洗评论(去除空评论)
tokens_list <- lapply(tokens_list, function(tokens) {
tokens[tokens != ""]
})
# 找出非空评论的索引
non_empty_indices <- which(sapply(tokens_list, length) > 0)
# 过滤出非空评论的 AppName
filtered_AppName <- reviews$AppName[non_empty_indices]
# 获取情感得分(假设你已定义 get_emotion_scores 函数)
emotion_scores <- lapply(tokens_list[non_empty_indices], get_emotion_scores, emotion_dict = emotion_dict)
# 转换为矩阵
emotion_matrix <- do.call(rbind, emotion_scores)
# 构建最终的情感 DataFrame
emotion_df <- data.frame(
AppName = filtered_AppName,
emotion_matrix,
row.names = NULL
)
# 查看结果
head(emotion_df)
## 按APP统计情感平均值
library(dplyr)
app_summary <- emotion_df %>%
group_by(AppName) %>%
summarise(across(everything(), mean, na.rm = TRUE))
print(app_summary)
###2. 雷达图对比不同 App 的情感分布
library(fmsb)
# 选择几个关键情感标签进行对比
selected_tags <- c("PA", "NA", "PB", "NB", "PC")
radarchart(app_summary[selected_tags],
vlabels = selected_tags,
title = "不同 App 用户情感雷达图",
pty.axes = "v")
### 各类情感总得分柱子
total_scores <- colSums(emotion_matrix)
barplot(total_scores, las = 2, col = rainbow(length(total_scores)), main = "整体情感分布")
### 不同APP情感对比
library(fmsb)
# 示例:选取 5 种情感进行对比
selected_tags <- c("PA", "NA", "PB", "NB", "PC")
app_summary <- aggregate(. ~ AppName, data = emotion_df[selected_tags], mean)
radarchart(app_summary, vlabels = selected_tags, pty.axes = "v",
title = "不同 App 用户情感雷达图")