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
相关产品推荐
相关产品推荐

