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

使用R语言tm包处理德语文本情感分类时遇编码错误求助

解决德语文本情感分类中的UTF-8编码错误问题

问题背景

你在处理德语文本情感分类时,preprocess函数抛出了utf8towcs相关的无效输入错误——错误文本里的🌺是乱码的表情符号,说明你的数据里存在非UTF-8兼容字符,导致tm包处理文本时失败。原代码在英文文本上正常运行,但德语数据中的特殊字符(emoji、非标准编码的德语变音符号)破坏了编码处理流程。

错误根源

tm包的文本处理函数依赖标准UTF-8编码,而你的数据里混入了emoji、乱码的德语特殊字符(比如变音符号),这些字符无法被utf8towcs解析,直接触发了编码错误。

解决方案步骤

  1. 清理非标准字符:创建语料库前,先过滤掉emoji、非打印字符等干扰项;
  2. 修复德语字符:确保ä、ö、ü、ß这类德语变音符号被正确识别,避免乱码;
  3. 修正特征选择逻辑:原代码的卡方检验选了最无关的特征,这是逻辑错误,需要调整为选择与类别最相关的特征。

修改后的完整代码

# 加载所需库
library(tm)
library(readxl)
library(data.table)
library(plyr)
library(dplyr)
library(zoo)
library(ggplot2)
library(ranger)
library(e1071)
library(rJava)
library(RWeka)

# 设置Java环境(根据你的实际路径调整)
Sys.setenv(JAVA_HOME='D://Program Files/Java/jre1.8.0_112') # 适配32位版本

# 加载数据集
df <- data.table(read_excel("data/German2datasets.xlsx", skip = 1))

# 辅助函数:清理编码问题和特殊字符
clean_utf8 <- function(text) {
  # 移除emoji和非打印字符
  text <- gsub("[^[:print:]]", "", text)
  # 修复德语变音符号的乱码形式
  text <- gsub("ä", "ä", text)
  text <- gsub("ö", "ö", text)
  text <- gsub("ü", "ü", text)
  text <- gsub("ß", "ß", text)
  # 强制设置为UTF-8编码
  Encoding(text) <- "UTF-8"
  return(text)
}

# 改进的文本预处理函数
preprocess <- function(text_column) {
  # 先处理编码问题
  text_column <- sapply(text_column, clean_utf8)
  # 创建语料库
  corpus <- Corpus(VectorSource(text_column))
  # 转换为小写
  corpus <- tm_map(corpus, content_transformer(tolower))
  # 移除标点(保留词内连字符,适配德语复合词)
  corpus <- tm_map(corpus, content_transformer(function(x) removePunctuation(x, preserve_intra_word_dashes = TRUE)))
  # 移除数字
  corpus <- tm_map(corpus, content_transformer(removeNumbers))
  # 移除德语停用词
  corpus <- tm_map(corpus, removeWords, stopwords("german"))
  # 德语词干提取
  corpus <- tm_map(corpus, stemDocument, language = "german")
  # 去除多余空格
  corpus <- tm_map(corpus, stripWhitespace)
  # 返回处理后的语料库
  return(corpus)
}

# 预处理文本列
corpus <- preprocess(df$TEXT)

# Bi-Trigram分词器函数
bitrigramtokeniser <- function(x) {
  RWeka::NGramTokenizer(x, RWeka::Weka_control(min = 2, max = 3))
}

# 创建文档-词项矩阵(包含Bi/Tri-gram)
dtm <- DocumentTermMatrix(corpus, control=list(
  wordLengths=c(2, Inf), 
  tokenize = bitrigramtokeniser, 
  weighting = function(x) weightTfIdf(x, normalize = FALSE), 
  bounds=list(global=c(floor(length(corpus)*0.01), floor(length(corpus)*.8)))
))

# 拆分训练集/测试集(设置随机种子保证可复现)
set.seed(123)
n <- nrow(df)
shuffled_idx <- sample(n)
df_shuffled <- df[shuffled_idx,]
dtm_shuffled <- dtm[shuffled_idx,]

train_size <- round(0.7 * n)
train_dtm <- dtm_shuffled[1:train_size,]
test_dtm <- dtm_shuffled[(train_size + 1):n,]
train_data <- df_shuffled[1:train_size,]
test_data <- df_shuffled[(train_size + 1):n,]

# 卡方检验特征选择函数(修正逻辑错误)
chisqTwo <- function(dtm, labels, n_out=2000){
  mat <- as.matrix(dtm)
  # 适配二元分类场景
  label_levels <- unique(labels)
  cat1 <- colSums(mat[labels == label_levels[1],])
  cat2 <- colSums(mat[labels == label_levels[2],])
  total_cat1 <- sum(mat[labels == label_levels[1],])
  total_cat2 <- sum(mat[labels == label_levels[2],])
  n_cat1 <- total_cat1 - cat1
  n_cat2 <- total_cat2 - cat2
  
  num <- (cat1*n_cat2 - cat2*n_cat1)^2
  den <- (cat1 + cat2)*(cat1 + n_cat1)*(cat2 + n_cat2)*(n_cat1 + n_cat2)
  chisq <- num/den
  # 选择卡方值最大的n_out个特征(原代码取最小是错误的)
  chi_order <- chisq[order(-chisq)][1:n_out]
  mat <- mat[, colnames(mat) %in% names(chi_order)]
  return(mat)
}

# 特征选择
train_mat <- chisqTwo(train_dtm, train_data$Sentiment)
test_mat <- testmat(colnames(train_mat), as.matrix(test_dtm))

# 转换为数据框,适配caret模型训练
train_mat_df <- as.data.frame(train_mat)
colnames(train_mat_df) <- make.names(colnames(train_mat_df))
train_mat_df$Sentiment <- as.factor(train_data$Sentiment)

test_mat_df <- as.data.frame(test_mat)
colnames(test_mat_df) <- make.names(colnames(test_mat_df))
test_mat_df$Sentiment <- as.factor(test_data$Sentiment)

# 后续可使用caret训练模型,示例:
# library(caret)
# train_control <- trainControl(method="cv", number=5)
# model <- train(Sentiment ~ ., data=train_mat_df, method="rf", trControl=train_control)
# predictions <- predict(model, test_mat_df)

关键改进说明

  • 新增clean_utf8函数专门处理编码问题,彻底清除emoji和乱码字符;
  • 修正了chisqTwo函数的逻辑错误——原代码选取了卡方值最小的特征,这完全违背了特征选择的初衷,现在改为选取与类别最相关的高卡方值特征;
  • 对德语预处理做了适配:保留词内连字符、指定德语词干提取语言;
  • 设置随机种子,保证数据拆分和模型训练的可复现性。

内容的提问来源于stack exchange,提问作者Shivam

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:58:15