Насколько я понимаю, вы хотите иметь возможность привязывать каждую точку к набору правил, которые классифицируют эту точку. Добиться этого можно, преобразовав дерево J48
в дерево party
и используя инструменты из пакета partykit
.
Поскольку вы не установили начальное число для генератора случайных чисел,
мы не можем получить точно такой же тест / разделение тренировок, как у вас.
Я установлю семя, чтобы сделать мой пример воспроизводимым, но даже
хотя я использую ваш код, мое дерево будет немного отличаться от вашего.
Воспроизводимый пример (в основном ваш код)
library(RWeka)
library("mlbench")
data("PimaIndiansDiabetes")
## Split in training and test (2/3 - 1/3)
set.seed(1234)
idtrain <- c(sample(1:768,512))
PimaTrain <-PimaIndiansDiabetes[idtrain,]
Pimatest <-PimaIndiansDiabetes[-idtrain,]
m1 <- RWeka::J48(as.factor(as.character(PimaTrain$diabetes)) ~ .,
data = PimaTrain[,-c(9)],
control = RWeka::Weka_control(M = 10, C= 0.25))
m1
J48 pruned tree
------------------
glucose <= 122
| mass <= 26.8: neg (85.0/1.0)
| mass > 26.8
| | pregnant <= 4: neg (137.0/19.0)
| | pregnant > 4
| | | glucose <= 106: neg (44.0/10.0)
| | | glucose > 106: pos (24.0/6.0)
glucose > 122
| glucose <= 157
| | age <= 31
| | | age <= 24: neg (30.0/5.0)
| | | age > 24
| | | | pressure <= 72: pos (16.0/5.0)
| | | | pressure > 72: neg (22.0/5.0)
| | age > 31: pos (78.0/27.0)
| glucose > 157: pos (76.0/13.0)
Number of Leaves : 9
Size of the tree : 17
У моего дерева было 9 листьев вместо ваших 7. Это связано с
экземпляры, выбранные для учебного набора. Теперь мы готовы получить правила.
library(partykit)
Pm1 = as.party(m1)
Pm1
Fitted party:
[1] root
| [2] glucose <= 122
| | [3] mass <= 26.8: neg (n = 85, err = 1.2%)
| | [4] mass > 26.8
| | | [5] pregnant <= 4: neg (n = 137, err = 13.9%)
| | | [6] pregnant > 4
| | | | [7] glucose <= 106: neg (n = 44, err = 22.7%)
| | | | [8] glucose > 106: pos (n = 24, err = 25.0%)
| [9] glucose > 122
| | [10] glucose <= 157
| | | [11] age <= 31
| | | | [12] age <= 24: neg (n = 30, err = 16.7%)
| | | | [13] age > 24
| | | | | [14] pressure <= 72: pos (n = 16, err = 31.2%)
| | | | | [15] pressure > 72: neg (n = 22, err = 22.7%)
| | | [16] age > 31: pos (n = 78, err = 34.6%)
| | [17] glucose > 157: pos (n = 76, err = 17.1%)
Number of inner nodes: 8
Number of terminal nodes: 9
Это то же дерево, что и раньше, но имеет то преимущество, что узлы помечены. Мы также можем выписать правила для каждого листа.
Pm1_rules = partykit:::.list.rules.party(Pm1)
Pm1_rules
3
"glucose <= 122 & mass <= 26.8"
5
"glucose <= 122 & mass > 26.8 & pregnant <= 4"
7
"glucose <= 122 & mass > 26.8 & pregnant > 4 & glucose <= 106"
8
"glucose <= 122 & mass > 26.8 & pregnant > 4 & glucose > 106"
12
"glucose > 122 & glucose <= 157 & age <= 31 & age <= 24"
14
"glucose > 122 & glucose <= 157 & age <= 31 & age > 24 & pressure <= 72"
15
"glucose > 122 & glucose <= 157 & age <= 31 & age > 24 & pressure > 72"
16
"glucose > 122 & glucose <= 157 & age > 31"
17
"glucose > 122 & glucose > 157"
Решения записаны в виде правил. Имена наборов правил являются
номера листовых узлов. Чтобы получить правила, используемые для контрольной точки, вам просто нужно знать, на каком конечном узле он заканчивается. Но метод predict
для объекта вечеринки даст вам это.
TestPred = predict(Pm1, newdata=Pimatest, type="node")
TestPred
3 4 5 6 9 12 17 20 22 27 28 29 31 32 33 35 36 38 41 43
17 5 16 3 17 17 5 5 7 16 3 16 8 17 3 8 3 7 17 3
46 48 50 56 57 60 62 64 65 66 68 70 72 75 76 79 84 95 96 97
17 5 3 3 17 5 16 12 8 7 5 15 14 5 3 14 3 12 16 5
...
Я обрезал вывод, потому что он был слишком длинным. Теперь, например,
мы видим, что первая контрольная точка перешла на узел 17. Нам просто нужно использовать это для индексации в наборах правил. Но нужна небольшая осторожность. 17 возвращается predict
является числом. Имя набора правил является строкой, поэтому нам нужно использовать as.character
для его преобразования.
Pm1_rules[as.character(TestPred[1])]
17
"glucose > 122 & glucose > 157"
Мы подтверждаем:
Pimatest[1,]
pregnant glucose pressure triceps insulin mass pedigree age diabetes
3 8 183 64 0 0 23.3 0.672 32 pos
Так что да, glucose > 122
И glucose > 157
Вы можете получить правила для других контрольных точек таким же образом.