为什么 R 也能做文本挖掘
一提到 R,大家先想到的是画直方图、跑回归。但 R 生态里其实有一整套做文本的包:抓网页用 rvest,管语料用 tm,做词云用 wordcloud。它们和 R 的数据框、ggplot2 无缝衔接,让你从"抓到一段话"到"看出大家在聊什么"可以一路顺下来。
文本挖掘的核心思路:把一堆句子拆成一个词一个词,数每个词出现多少次,再看哪些词最扎堆。机器看不懂"心情好"这三个字,但它知道"好"这个字在全部语料里出现了 800 次——频率就是信息。
文本挖掘的本质:把非结构化的文字,变成一张"词—频次"的结构化表,然后用统计和可视化去读它。
- rvest抓取网页、按 CSS 选择器抽你要的段落。
- 语料清洗去标点、去停用词、小写化,让"好"和"好。"算同一个词。
- 词频表每个词出现了多少次,是后面所有分析的底。
- wordcloud把高频词画成图,字越大出现越多。
第一步:抓网页文本
用 rvest 包:先把整页 HTML 抓下来,再用 CSS 选择器把你真正要的段落挑出来。这和浏览器里"按元素审查"是同一个思路。
library(rvest)
url <- "https://example.com/post"
page <- read_html(url)
# 抽正文段落:假设正文在 <div class="content"> 里
text <- page %>%
html_elements("div.content p") %>%
html_text2()
head(text, 3) # 看看抓到了什么
%>% 是管道符(magrittr 包),把左边的结果直接喂给右边的函数,读起来像"先抓、再抽标签、再取文字"。CSS 选择器写错了就会抓到空,多试几次、对着网页元素审查工具看就好。
第二步:清洗语料
抓来的原文是脏的:有标点、有空格、有大小写混杂、有一堆"的、了、是"这种没有信息量的停用词。直接数词频会被这些噪声淹没。清洗通常做这几步:
library(tm)
# 把一组文本变成语料库
corpus <- VCorpus(VectorSource(text))
corpus <- corpus %>%
tm_map(tolower) %>% # 全部小写
tm_map(removePunctuation) %>% # 去标点
tm_map(removeNumbers) %>% # 去数字
tm_map(removeWords, stopwords("chinese")) # 去停用词
清洗完的语料才是"干净的词袋子"。对中文来说,停用词表("的、了、和、是")很关键,tm 包里自带中文停用词表,也可以自己加行业里的高频虚词。
第三步:分词与词频
中文不像英文天生有空格分词,所以要专门的分词工具。常用 jiebaR 或 tidytext。分词之后,每个句子变成一个词的向量,再统计每个词出现多少次,得到一张词频表。
library(jiebaR)
mix <- worker()
words <- segment(text, mix)
# words 现在是一个个词,比如 "这次"、"活动"、"很"、"好"
freq <- sort(table(words), decreasing = TRUE)
head(freq, 10) # 出现最多的 10 个词
这张词频表就是后面所有分析的底:哪些词出现最多、哪些词和哪些词经常一起出现、不同文档之间用词差异有多大——全靠它。
第四步:画词云看整体
词云是最直观的展示:词出现得越多,字在图上就越大。一眼就能看到这段语料的"主题词"扎堆在哪些词上。
library(wordcloud)
wordcloud(
words = names(freq),
freq = as.numeric(freq),
max.words = 50,
random.order = FALSE, # 高频词放中间
colors = brewer.pal(8, "Dark2")
)
看到词云里"屏幕""卡顿"特别大,你就知道这段评论里大家最关心的是流畅度;看到"续航""充电"突出,关注点就转到了电池。文字是定性的,词频让它变成可比较的。
克制与礼貌:别给服务器添乱
抓网页是把双刃剑。技术上你能抓,不代表应该猛抓。几条底线:
- 看一眼目标网站的
robots.txt,明确禁止的路径别碰。 - 每次请求之间停个一两秒,别一口气几十次请求把对方服务器打满。
- 只抓公开、可公开使用的内容;涉及登录后才能看的、个人隐私的,一律不碰。
- 抓到的数据做分析可以,直接原文转载别人的文章要注意版权。
这既是法律底线,也是长期合作——对方服务器别被你抓崩了,下次你才还能继续用。
实战:从一组评论里看关注点
串起来:抓一组公开评论段落,清洗分词后画词云,再算一下高频词的分布。这是文本挖掘最小可用的工作流。
library(rvest); library(tm); library(jiebaR); library(wordcloud)
# 1. 抓评论段落
text <- read_html(url) %>% html_elements("div.comment") %>% html_text2()
# 2. 清洗
corpus <- VCorpus(VectorSource(text))
corpus <- tm_map(corpus, removePunctuation)
corpus <- tm_map(corpus, removeWords, stopwords("chinese"))
# 3. 分词统计
mix <- worker()
words <- segment(sapply(corpus, as.character), mix)
freq <- sort(table(words), decreasing = TRUE)
# 4. 画词云
wordcloud(names(freq), as.numeric(freq), max.words = 40)
从词云里你会一眼看出:评论讨论最多的是哪几个主题?是价格、还是做工、还是客服?把这一套包装成一个函数,每次换个 URL 就能跑一遍新评论——这就是 R 在文本场景里的杠杆。
文本挖掘检查清单
把 R 文本挖掘记成一条链:抓网页 → 清洗语料 → 分词 → 词频 → 词云。跑之前对照自查:
- 抓回来的文本是不是你真正要的那段,CSS 选择器对没对准?
- 停用词表是不是够干净,"的、了"这种虚词有没有被算进高频?
- 词频表里有没有异常词(比如一段被截断的 HTML 标签混进来)?
- 抓取节奏有没有克制,别给对方服务器添乱?
- 结论是基于词频图读出来的,而不是凭印象?
文本挖掘不是"猜大家在想什么",而是把每个人随手写的一段段话,聚成一份"大家最常说的"清单——让定性的评论变成可比较的数字。
下一篇我们换个味道:VB.NET 做桌面程序 + 接数据库,看看这门老牌语言在小工具、内部系统里怎么落地。