You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用R的gutenbergr与cv.glmnet做文本分析出现意外结果

大家好,
我正在尝试使用R语言的gutenbergr库复现文本分析练习,并通过glmnet库运行机器学习模型。

目前代码可正常运行,但输出结果不符合预期。以下是可完整复现的精简代码:

第一部分 运行正常的代码
##### 加载所需依赖库 #####
library(tidyverse)
library(tidytext)
library(udpipe)
library(gutenbergr)
library(rsample)
library(glmnet)
library(yardstick)

##### 1. 从Gutenberg项目下载目标书籍 #####
twist_tale <- gutenberg_metadata %>%
  filter(
    title %in% c("A Tale of Two Cities", "Oliver Twist"),
    has_text,
    language == "en") %>%
  pull(gutenberg_id) %>%
  gutenberg_download(meta_fields = "title")

##### 2. 去除空白行 #####
twist_tale <- twist_tale %>%
  filter(text != "")

View(twist_tale)

##### 3. 创建标签变量 #####
twist_tale <- twist_tale %>%
  mutate(
    es_two_cities = case_when(
      title == "A Tale of Two Cities" ~ 1L,
      title == "Oliver Twist" ~ 0L
    ),
    line_id = row_number()
  )%>%
  view()

##### 3.1 统计不同书籍的行数 #####
twist_tale %>%
  count(title)

##### 4. 数据集预处理与建模准备 #####
dl <- udpipe_download_model(language = "english")
english_model <- udpipe_load_model(dl$file_model)

text <- twist_tale %>%
  select(doc_id = line_id, text)

twist_tale_preprocesado <- udpipe(text, english_model, parallel.cores = 4L)

##### 4b 拆分训练集与测试集 #####
set.seed(1234L)
twist_tale_split <- initial_split(twist_tale)
twist_tale_training <- training(twist_tale_split)
twist_tale_testing <- testing(twist_tale_split)

##### 4a 文本标准化与稀疏矩阵构建 #####
sparse_train_data <- twist_tale_preprocesado %>%
  mutate(lemma = str_to_lower(lemma)) %>%
  anti_join(stop_words, by = c("lemma" = "word")) %>%
  filter(upos %in% c("PUNCT", "SYM", "X", "NUM")) %>%
  mutate(doc_id = as.integer(doc_id)) %>%
  anti_join(twist_tale_testing, by = c("doc_id" = "line_id")) %>%
  count(doc_id, lemma) %>%
  cast_sparse(doc_id, lemma, n)

截至此处所有步骤运行正常。问题出在运行cv.glmnet()模型环节:该步骤没有返回任何错误或警告信息,但输出结果为行向量,预期应当返回矩阵或tibble格式的结果。

存在问题的代码
##### 5a 提取模型标签变量 #####
y <- twist_tale_training %>%
  filter(line_id %in% rownames(sparse_train_data)) %>%
  pull(es_two_cities)

##### 6a 拟合正则化逻辑回归模型 #####
model <- cv.glmnet(sparse_train_data, y, family = "binomial", 
                   keep = T, trace.it=1)           # 问题实际出在这里

coeficientes <- model$glmnet.fit %>%
  tidy() %>%
  filter(lambda == model$lambda.1se)

coeficientes %>%
  group_by(estimate > 0) %>%
  slice_max(estimate, n = 5) %>%
  ungroup()

coeficientes %>%
  group_by(estimate > 0) %>%
  slice_max(estimate, n = 5) %>%
  ungroup() %>%
  ggplot() +
  geom_col(aes(x = fct_reorder(term, estimate), y = estimate, fill = estimate > 0)) + 
  coord_flip()

问题修复说明

核心错误原因

稀疏矩阵构建阶段的词性过滤逻辑写反了:当前代码只保留了标点、符号、未知词、数词四类无实际语义的特征,模型无法从这些特征中学习到区分两本书的规律,最终所有特征的系数都被正则化压缩为0,仅保留截距项,所以返回的系数结果只有一行。

修复方法

将稀疏矩阵构建环节的过滤代码修改为反向过滤:

# 原错误代码
filter(upos %in% c("PUNCT", "SYM", "X", "NUM"))
# 替换为以下代码,过滤掉无意义词性,保留实义词汇
filter(!upos %in% c("PUNCT", "SYM", "X", "NUM"))

修改后重新运行即可得到包含多个特征系数的tibble结果,后续可视化代码也可正常输出。

内容的提问来源于stack exchange,提问作者Sergio A. Gottret Rios

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 13:27:01