R包e1071中无关列引发SVM计算崩溃问题问询
SVM调参因无关列含NA崩溃的问题解决
问题背景
公式true~aaaa+bbbb+cccc已明确指定仅使用三个特征列,但保留含NA的junk列时,e1071::tune调用SVM会崩溃;删除junk列则代码正常运行,返回结果如下:
Parameter tuning of ‘e1071::svm’: - sampling method: 5-fold cross validation - best parameters: gamma cost 0.5 4 - best performance: 0.17
原始代码
options( error = function() { traceback( 2 ) options( error = NULL ) stop( "exiting after script error" ) }) data <- data.frame( true = as.factor( c( "a", "b", "b", "a", "a", "b", "a", "b", "b", "b", "a", "a", "b", "a", "a", "b", "b", "b", "a", "a", "a", "a" ) ), aaaa = c( 2, 1, 0, 0, 3, 0, 0, 1, 0, 0, 5, 1, 2, 0, 7, 2, 1, 0, 1, 2, 3, 4 ), bbbb = c( 4, 0, 0, 0, 4, 1, 4, 1, 0, 0, 6, 1, 1, 4, 0, 2, 0, 2, 1, 2, 3, 4 ), cccc = c( 3, 2, 0, 0, 3, 1, 4, 1, 2, 0, 0, 7, 1, 3, 5, 2, 2, 1, 1, 2, 3, 4 ), junk = c(NA, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ) ) data$junk <- NULL # 移除该行则代码崩溃 print( str( data ) ) e1071::tune( e1071::svm, true~aaaa+bbbb+cccc, data = data, type = 'C-classification', scale = TRUE, ranges = list( gamma = 2^(-1:1), cost = 2^(2:4) ), tunecontrol = e1071::tune.control( sampling = 'cross', cross = 5 ) )
版本信息
$ Rscript --version Rscript (R) version 4.3.2 (2023-10-31) $ R installed.packages() e1071 "4.3.2"
问题原因
核心问题是junk列中的缺失值(NA)。尽管公式未引用该列,但e1071::tune在执行交叉验证时,会对整个数据框进行抽样划分,抽样后的子数据集会包含junk列的NA值,而SVM算法无法处理含缺失值的数据,最终导致崩溃。
解决方法
无需删除无关列,只需处理缺失值即可,两种可行方案:
方案1:移除含NA的行
在调用tune前执行:
data <- na.omit(data)
方案2:在tune中指定忽略NA
直接在tune函数中添加na.action = na.omit参数,仅在调参过程中跳过含NA的行,不修改原始数据:
e1071::tune( e1071::svm, true~aaaa+bbbb+cccc, data = data, type = 'C-classification', scale = TRUE, ranges = list( gamma = 2^(-1:1), cost = 2^(2:4) ), tunecontrol = e1071::tune.control( sampling = 'cross', cross = 5 ), na.action = na.omit # 新增参数忽略缺失值 )
内容的提问来源于stack exchange,提问作者Pieter Hartel
相关产品推荐
相关产品推荐

