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

R中是否有等效于sklearn.OneHotEncoder的工具?解决测试集编码报错

在R中实现类似Python sklearn OneHotEncoder的独热编码功能

先看Python端的实现示例,再对应给出R的解决方案,包括报错处理、替代工具和drop='first'的实现。

Python sklearn OneHotEncoder 示例

from sklearn.preprocessing import OneHotEncoder
import pandas as pd

# 构造训练集和测试集
train_df = pd.DataFrame({
    'category': ['A', 'B', 'C', 'D', 'A', 'B'],
    'value': [10, 20, 30, 40, 50, 60]
})
test_df = pd.DataFrame({
    'category': ['A', 'A', 'A'],
    'value': [70, 80, 90]
})

# 初始化编码器,设置drop='first'去掉第一个水平
ohe = OneHotEncoder(sparse_output=False, drop='first')
# 仅在训练集上拟合
ohe.fit(train_df[['category']])

# 转换训练集和测试集
train_ohe = ohe.transform(train_df[['category']])
test_ohe = ohe.transform(test_df[['category']])

# 合并结果
train_result = pd.concat([train_df, pd.DataFrame(train_ohe, columns=ohe.get_feature_names_out())], axis=1)
test_result = pd.concat([test_df, pd.DataFrame(test_ohe, columns=ohe.get_feature_names_out())], axis=1)

R 中的解决方案

1. 修复 caret::dummyVars 测试集水平缺失的报错

dummyVars默认会校验测试集的特征水平是否与训练集完全匹配,遇到测试集水平更少的情况会抛出错误。解决方法是添加levelsOnly = TRUE参数,强制转换时沿用训练集的特征水平,缺失的水平自动填充0:

library(caret)

# 构造训练集和测试集
train_df <- data.frame(
  category = c('A', 'B', 'C', 'D', 'A', 'B'),
  value = c(10, 20, 30, 40, 50, 60)
)
test_df <- data.frame(
  category = c('A', 'A', 'A'),
  value = c(70, 80, 90)
)

# 创建dummyVars对象,指定levelsOnly=TRUE
dummy_obj <- dummyVars(~ category, data = train_df, levelsOnly = TRUE)

# 转换训练集和测试集
train_dummy <- predict(dummy_obj, newdata = train_df)
test_dummy <- predict(dummy_obj, newdata = test_df)

# 合并结果
train_result <- cbind(train_df, train_dummy)
test_result <- cbind(test_df, test_dummy)

2. 更推荐的替代工具

如果觉得caret的dummyVars不够灵活,可以试试这两个工具:

a. recipes 包(贴合sklearn的拟合-转换工作流)

recipes支持完整的“定义配方-拟合-转换”流程,处理测试集水平缺失更顺滑,也能轻松实现drop='first':

library(recipes)
library(tibble)

# 构造数据
train_df <- tibble(
  category = c('A', 'B', 'C', 'D', 'A', 'B'),
  value = c(10, 20, 30, 40, 50, 60)
)
test_df <- tibble(
  category = c('A', 'A', 'A'),
  value = c(70, 80, 90)
)

# 定义配方,对category做独热编码并去掉第一个水平
rec <- recipe(value ~ category, data = train_df) %>%
  step_dummy(category, drop = "first")

# 在训练集上拟合配方
rec_fit <- prep(rec, training = train_df)

# 转换训练集和测试集
train_ohe <- bake(rec_fit, new_data = train_df)
test_ohe <- bake(rec_fit, new_data = test_df)

b. fastDummies 包(轻量快速)

fastDummies的dummy_cols函数可以一键生成独热编码,通过指定因子水平来对齐训练集和测试集:

library(fastDummies)

# 训练集生成编码,同时去掉第一个水平
train_dummy <- dummy_cols(train_df, select_columns = 'category', remove_first_dummy = TRUE)
# 提取训练集的category水平
train_levels <- unique(train_df$category)

# 测试集先把category转为因子,指定水平为训练集的水平
test_df$category <- factor(test_df$category, levels = train_levels)
# 生成测试集编码
test_dummy <- dummy_cols(test_df, select_columns = 'category', remove_first_dummy = TRUE)

3. 实现类似Python的drop='first'功能

不同工具的对应参数:

  • caret::dummyVars:设置fullRank = TRUE,生成满秩编码(自动去掉第一个水平):
    dummy_obj <- dummyVars(~ category, data = train_df, levelsOnly = TRUE, fullRank = TRUE)
    
  • recipes::step_dummy:设置drop = "first"(或默认one_hot = FALSE)
  • fastDummies::dummy_cols:设置remove_first_dummy = TRUE

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 17:33:10