keywords: 文本挖掘,文本分析,情感分析,R 语言,自然语言处理
随着互联网的飞速发展,人们每天都会产生大量的文本数据,如新闻报道、博客文章、社交媒体评论等。这些非结构化的文本数据蕴含着丰富的信息,通过文本挖掘技术,我们可以从海量文本数据中发现有价值的知识和见解。
本章将介绍如何使用 R 语言进行文本挖掘和分析。我们将学习文本数据的获取与处理、文本分析与可视化、文本分类与聚类等内容,并通过一个实际案例来演示如何进行情感分析。
10.1 文本数据的获取与处理
在进行文本挖掘之前,我们需要先获取文本数据,并对其进行预处理。
10.1.1 获取文本数据
可以通过多种途径获取文本数据,例如:
- 网页抓取:使用 rvest 等 R 包从网页中抓取文本内容
- 读取本地文件:使用 readLines、read.table 等函数读取 txt、csv 等本地文件
- 连接数据库:使用 RMySQL、RSQLite 等包连接数据库获取文本字段
- 调用 API 接口:很多平台如 Twitter 都提供了 API 接口,方便获取文本数据
下面是一个使用 rvest 包从网页中抓取新闻标题的示例:
library(rvest)
url <- "http://news.sina.com.cn/china/"
web <- read_html(url)
titles <- web %>%
html_nodes("a") %>%
html_text()
head(titles)
10.1.2 文本预处理
获取到原始文本数据后,需要进行一系列预处理,将非结构化的文本转换为结构化、规范化的形式,为后续分析奠定基础。主要的预处理步骤包括:
- 分词:将句子切分成单词。中文可使用 jiebaR 包,英文可使用 stringr 包等
- 去除停用词:删除如”的”、”是”等对分析无意义的高频虚词
- 词干提取:将”学习”、”学习者”还原为同一词干”学”。英文 stemDocument 函数
- 转小写:将所有字母转为小写,忽略大小写差异
以下是一个利用 jiebaR 包和停用词表对中文文本进行预处理的例子:
library(jiebaR)
library(dplyr)
# 准备文本和停用词
text <- c("今天天气真好,我们一起去公园玩吧!","不行啊,我今天有很多作业要做。")
stopwords <- c("啊","吧","的")
# 分词
words <- worker() %>%
segment(text,type = "tag")
# 去除停用词,转换为语料格式
corpus <- words[-which(words %in% stopwords)] %>%
table() %>%
as.data.frame()
10.1.3 词云图生成
词云图是一种直观展示文本中高频词的可视化方式。在 R 中可以用 wordcloud2 等包来轻松生成美观的词云图。
library(wordcloud2)
wordcloud2(corpus,
size = 0.5,
minSize = 1,
gridSize = 1,
fontFamily = 'Segoe UI',
color = 'random-light',
backgroundColor = "white",
minRotation = -pi/4,
maxRotation = pi/4,
rotateRatio = 0.8)
通过词云图,我们可以直观看出文本数据中出现频率较高的词,快速把握文本的主题和关键信息。
10.2 文本分析与可视化
对文本数据进行适当的量化分析和可视化展示,能帮助我们更好地理解和挖掘文本信息。
10.2.1 词频分析
词频反映了一个词在文本中出现的频率,是最基本的文本统计方式。
首先,我们需要构建语料库,将多个文本文档组织为语料的格式。tm 包提供了强大的语料处理功能。
library(tm)
text <- c("Text mining is fun.", "R is a great tool for text mining.")
corpus <- Corpus(VectorSource(text))
# 语料预处理
corpus <- tm_map(corpus, tolower)
corpus <- tm_map(corpus, removePunctuation)
corpus <- tm_map(corpus, removeWords, stopwords("english"))
# 构建词频矩阵
dtm <- DocumentTermMatrix(corpus)
freq <- colSums(as.matrix(dtm))
freq_df <- data.frame(word=names(freq), freq=freq)
然后使用 ggplot2 等包对词频进行可视化:
library(ggplot2)
ggplot(freq_df, aes(x=word, y=freq)) +
geom_bar(stat="identity", fill="skyblue") +
coord_flip() +
theme_minimal()
10.2.2 共现分析
共现分析用于揭示文本中词语之间的关联关系,寻找在文本中经常一起出现的词。
我们可以用 widyr 包计算词语共现频率,并用 igraph 包进行可视化。
library(widyr)
library(igraph)
# 提取词对
word_pairs <- corpus %>%
unnest_tokens(paired_words, text, token = "ngrams", n = 2)
# 统计词对共现频率
pair_freq <- word_pairs %>%
count(paired_words, sort = TRUE)
# 筛选高频词对
top_pairs <- pair_freq %>%
filter(n >= 2) %>%
separate(paired_words, c("word1", "word2"), sep = " ")
# 可视化共现网络
graph <- graph_from_data_frame(top_pairs)
plot(graph, vertex.size=5, vertex.label.cex=0.7, edge.curved=0.2)
通过共现网络图,我们可以看出哪些词经常在一起出现,它们在语义上可能有一定的关联。
10.2.3 文本聚类
文本聚类可以发现文本数据内在的分组结构,将相似的文本自动归类到一起。
常见的文本聚类方法有基于 VSM 的 k-means 聚类,以及主题模型如 LDA。下面演示 k-means 聚类的过程。
library(topicmodels)
# 构建TF-IDF矩阵
dtm_tfidf <- DocumentTermMatrix(corpus, control = list(weighting = weightTfIdf))
# 转换为数值矩阵
m <- as.matrix(dtm_tfidf)
# 进行k-means聚类
cl <- kmeans(m, 2)
# 聚类结果可视化
plot(m, col = cl$cluster)
points(cl$centers, col = 1:2, pch = 8, cex=2)
利用聚类,我们可以自动将大规模文本语料划分为不同的主题类别,便于后续针对性分析。
10.3 文本分类与情感分析
文本分类和情感分析是文本挖掘的两大常见任务,前者侧重判别文本的类别,后者侧重判别文本的情感倾向。
10.3.1 文本分类
文本分类就是根据文本内容将其划分到预定义的类别中,如将邮件分为垃圾邮件和正常邮件。
我们以新闻分类为例。首先准备好训练数据:
library(quanteda)
library(caret)
news <- data.frame(
text = c("福布斯:姚明当选名人堂是因为他改变了篮球","美军内部报告揭露驻日美军的腐败和黑幕","今年前4月中国进出口总值7.67万亿","寻找另一个自己:你在另一个平行宇宙过着什么样的生活?"),
type = c("sports","military", "finance","science")
)
# 语料预处理
news_corpus <- corpus(news$text)
news_dfm <- dfm(news_corpus, stem = TRUE, remove = stopwords("chinese"))
然后进行分类器训练和预测:
# 转换为文档-词频矩阵
news_df <- convert(news_dfm, to = "data.frame")
colnames(news_df) <- make.names(colnames(news_df))
# 添加目标分类列
news_df$type <- news$type
# 划分训练集和测试集
set.seed(123)
trainIndex <- createDataPartition(news_df$type, p = 0.8, list = FALSE)
train <- news_df[trainIndex,]
test <- news_df[-trainIndex,]
# 训练分类器
model <- train(type ~ ., data = train, method = "rf")
# 在测试集上预测
pred <- predict(model, newdata = test)
confusionMatrix(pred, test$type)
我们使用了随机森林(rf)作为分类算法,训练出的模型在测试集上可以准确预测新闻类别。通过不断优化特征和模型,可以构建高精度的文本分类器。
10.3.2 情感分析
情感分析就是判断一段文本所包含的情感倾向,是积极、消极还是中性的。
以下是利用 SnowNLP 包对酒店评论进行情感判断的示例:
library(SnowNLP)
review1 <- "酒店环境不错,房间很干净,服务人员态度很好。"
review2 <- "房间隔音效果差,晚上吵的根本睡不着。"
s1 <- SnowNLP(review1)
s1[1]
paste("情感倾向:", s1$sentiment)
s2 <- SnowNLP(review2)
s2[1]
paste("情感倾向:", s2$sentiment)
[1] "酒店环境不错,房间很干净,服务人员态度很好。"
[1] "情感倾向: 0.991765925639926"
[1] "房间隔音效果差,晚上吵的根本睡不着。"
[1] "情感倾向: 0.133741866897081"
可以看到,SnowNLP 包可以较准确地判断出第一条评论为积极情感,第二条为消极情感。我们可以批量应用情感分析,监测网络舆情动向。
10.4 实践案例:豆瓣电影评论情感分析
下面我们通过一个实际案例—豆瓣电影评论情感分析,来综合运用本章学到的知识。
分析思路如下:
- 抓取豆瓣电影《肖申克的救赎》的短评内容
- 对评论内容进行分词、去停用词等预处理
- 提取关键词,生成词云
- 使用 SnowNLP 判断每条评论的情感倾向
- 统计并可视化整体情感分布
10.4.1 抓取豆瓣影评数据
library(rvest)
library(stringr)
# 抓取前10页评论
all_comments <- c()
for (i in 1:10) {
url <- str_c("https://movie.douban.com/subject/1292052/comments?start=", (i-1)*20, "&limit=20&status=P")
web <- read_html(url)
comments <- web %>%
html_nodes("span.short") %>%
html_text()
all_comments <- c(all_comments, comments)
Sys.sleep(rnorm(1,1,0.2))
}
# 保存为本地文件
write.table(all_comments, "comments.csv", sep="\t", row.names=FALSE, fileEncoding="UTF-8")
10.4.2 文本预处理
library(jiebaR)
# 读取评论数据
comments <- read.csv("comments.csv", header=FALSE, sep="\t", stringsAsFactors=FALSE, fileEncoding="UTF-8")
# 定义停用词
stopwords <- c("就是","可以","所以","但是","还是","只是","真的")
# 分词和去停用词
comments$words <- sapply(comments$V1, function(x) {
words <- worker() %>%
segment(x, type = "tag")
paste(words[-which(words %in% stopwords)], collapse=" ")
})
10.4.3 提取关键词,并绘制词云图
library(wordcloud2)
# 统计高频词
word_freq <- comments$words %>%
strsplit(" ") %>%
unlist() %>%
table()好的,我将继续为你输出第10章剩余的内容:
```r
# 选取频率最高的50个词绘制词云
wordcloud2(head(sort(word_freq, decreasing=TRUE), 50),
size = 0.5,
minSize = 1,
gridSize = 1,
fontFamily = 'Segoe UI',
color = 'random-light',
backgroundColor = "white",
minRotation = -pi/4,
maxRotation = pi/4,
rotateRatio = 0.8)
从词云图可以看出,”希望”、”自由”、”信念”等是《肖申克的救赎》影评中的高频词,反映了影片所传递的主题。
10.4.4 情感倾向分析
接下来,我们使用 SnowNLP 对每条评论进行情感判断,并统计整体的情感分布:
library(SnowNLP)
# 定义情感分析函数
sentiment_score <- function(text) {
s <- SnowNLP(text)
return(s$sentiment)
}
# 计算每条评论的情感得分
comments$sentiment <- sapply(comments$V1, sentiment_score)
# 查看情感得分分布
hist(comments$sentiment, main="情感分布图", xlab="情感得分")
从情感分布图可以看出,绝大部分影评的情感得分都在 0.5 以上,整体情感非常正面,说明《肖申克的救赎》这部电影得到了大多数观众的认可和好评。
通过这个实践案例,我们运用爬虫抓取了豆瓣电影的评论数据,并对其进行了分词、关键词提取、情感分析等文本挖掘任务,从大量非结构化的文本数据中挖掘出了有价值的信息和见解。
本章小结
本章我们系统学习了如何使用 R 语言进行文本挖掘与分析。具体内容包括:
- 文本数据的获取与处理,如抓取网页文本、读取本地文件、分词去停用词等
- 文本分析与可视化,如词频统计、共现分析、文本聚类等
- 文本分类与情感分析的基本原理和实现
- 一个实践案例,运用所学知识对豆瓣电影评论进行情感分析
文本挖掘是一个涉及语言学、统计学、计算机科学等多个领域的交叉学科。通过 R 语言及其丰富的包,我们可以较为轻松地上手文本挖掘。但要真正掌握文本挖掘,还需要扎实的自然语言处理和机器学习基础。
希望通过本章的学习,大家能够对文本挖掘的理论与实践有一个初步认识。在后续的学习和工作中,也要多多运用文本挖掘的思想,从文本大数据中发现有价值的商业智能和洞见。
【本章节完毕】