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

R语言predict()函数基于J48模型预测结果异常求助

R中C4.5模型预测结果异常问题排查

问题现象

使用RWeka的J48(C4.5决策树)模型训练高尔夫打球决策数据时,训练集中所有Nublado(阴天)场景对应的Jugar(是否打球)结果均为Si(是),但输入Panorama=Nublado, Temperatura=Medio, Humedad=Normal, Viento=Normal时,predict()函数返回错误结果No(否),预期结果应为Si。

相关代码

library(RWeka)
library(caret)
library(datasets)

table_golf = read.table("C:/Users/Mario S-Herrero/Desktop/golf.txt.txt",
                        header = T,
                        sep = ",",
)
data_golf <- as.data.frame(table_golf)

data_golf$Panorama=as.factor(data_golf$Panorama)
data_golf$Temperatura=as.factor(data_golf$Temperatura)
data_golf$Humedad=as.factor(data_golf$Humedad)
data_golf$Viento=as.factor(data_golf$Viento)
data_golf$Jugar=as.factor(data_golf$Jugar)

modelC45 <- J48(`Jugar` ~ ., data = data_golf)
modelC45
plot(modelC45)

# 创建输入数据并预测
nuevopartido = read.table("C:/Users/Mario S-Herrero/Desktop/input.txt",
                        header = T,
                        sep = ",",
)
input <- as.data.frame(nuevopartido)
input$Panorama=as.factor(input$Panorama)
input$Temperatura=as.factor(input$Temperatura)
input$Humedad=as.factor(input$Humedad)
input$Viento=as.factor(input$Viento)

prediccion <- predict(modelC45,input)
plot(prediccion)

训练数据(golf.txt)

Panorama,Temperatura,Humedad,Viento,Jugar
Soleado,Calor,Alta,Ligero,No
Soleado,Calor,Alta,Fuerte,No
Nublado,Calor,Alta,Ligero,Si
Lluvia,Medio,Alta,Ligero,Si
Lluvia,Frio,Normal,Ligero,Si
Lluvia,Frio,Normal,Fuerte,No
Nublado,Frio,Normal,Fuerte,Si
Soleado,Medio,Alta,Ligero,No
Soleado,Medio,Normal,Ligero,Si
Lluvia,Medio,Normal,Ligero,Si
Soleado,Medio,Normal,Fuerte,Si
Nublado,Medio,Alta,Fuerte,Si
Nublado,Calor,Normal,Ligero,Si
Lluvia,Medio,Alta,Fuerte,No

输入数据(input.txt)

Panorama,Temperatura,Humedad,Viento
Nublado,Medio,Normal,Normal

问题原因

核心问题出在输入数据的Viento字段包含训练数据中不存在的因子水平:

  • 训练数据里Viento的取值只有Ligero(微风)和Fuerte(大风)两个水平;
  • 输入数据的Viento是Normal,这个水平从未在训练集中出现过。

当J48模型遇到训练时未见过的因子水平时,无法按照决策树的分支逻辑进行判断,会默认将样本归类到某个类别(此处错误归为No),导致预测结果不符合预期。

解决方案

方案1:修正输入数据(最直接)

如果是输入错误,将input.txt中的Viento值改为训练数据中存在的Ligero或Fuerte,比如:

Panorama,Temperatura,Humedad,Viento
Nublado,Medio,Normal,Ligero

此时重新运行预测,会得到预期的Si结果。

方案2:提前定义所有可能的因子水平(适用于业务存在新水平的场景)

如果业务中确实存在Normal这个风速水平,需要在转换因子时明确指定所有可能的水平,确保训练和输入数据的因子水平一致:

# 训练数据转换因子时指定全量水平
data_golf$Viento <- factor(data_golf$Viento, levels = c("Ligero", "Fuerte", "Normal"))
# 输入数据同步使用相同的水平定义
input$Viento <- factor(input$Viento, levels = c("Ligero", "Fuerte", "Normal"))

注:由于训练数据中没有Normal的样本,模型仍无法对该水平的样本做出准确预测,但可以避免因未知水平导致的异常归类。若要准确预测,需补充包含Viento=Normal的训练样本后重新训练模型。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 11:17:22