Неправильный расчет важности функций дерева решений в R - PullRequest
0 голосов
/ 05 апреля 2019

Я обучил дерево решений как на python, так и на R, но я думаю, что способ вычисления важности функции в R может быть неправильным.Ниже приведен пример кода, который вы можете использовать для воспроизведения проблемы.Допустим, я прогнозирую доход населения 1000 на основе пола и страны.

x = data.frame(gender=sample(c("M","F"),n,T), country=sample(c("A","I"),n,T))
x$income = ifelse(x$gender=="M", rnorm(n, 100, 10), rnorm(n, 80, 10))
x$income = x$income + ifelse(x$country=="A", rnorm(n, 100, 10), rnorm(n, 80, 10))
write.csv(x, "data.csv")

Затем давайте поместим дерево решений в R с максимальной глубиной 1.

fit = rpart(income~., data = x, control=rpart.control(maxdepth=1))
caret::varImp(fit)
fit

Я получаю следующее значение функции
страна 0.2507630 и
пол 0.2424981
Для дерева, разделенного только в стране

1) root 1000 407373.4 180.5759  
2) country=I 481 147999.6 170.0772 *  
3) country=A 519 157219.6 190.3060 *  

При повторной попытке с максимальной глубиной 2 я получаю значение особенности как
страна 0,2507630 и
пол 0,8874599

Для дерева, разделенного сначала в стране, как прежде, а затем в поле

1) root 1000 407373.40 180.5759    
  2) country=I 481 147999.60 170.0772    
     4) gender=F 232  40082.49 159.2805 *  
     5) gender=M 249  55676.09 180.1367 *  
  3) country=A 519 157219.60 190.3060    
     6) gender=F 248  57546.77 180.4749 *  
     7) gender=M 271  53767.73 199.3028 *  

Однако, если я запускаю подобный код в python

from io import StringIO
from sklearn.tree import DecisionTreeRegressor
from sklearn.tree.export import export_graphviz
from IPython.display import Image 
from sklearn import tree
import pydot
import pandas as pd

data = pd.read_csv("data.csv")

dtree=DecisionTreeRegressor(max_depth= 1)
X = data[["gender", "country" ]]
X["gender"] = X["gender"] == 'M'
X["country"] = X["country"] == 'A'
y = data[['income']]
dtree.fit(X,y)

# Export as dot file
export_graphviz(dtree, out_file='tree.dot', 
                feature_names = X.columns,filled=True, rounded=True,
                special_characters=True)

(graph,) = pydot.graph_from_dot_file('tree.dot')
graph.write_png('tree.png')
# Display in jupyter notebook
from IPython.display import Image
Image(filename = 'tree.png')

для максимальной глубины 1, я получаю функциюВажность как

gender  0, and  
country 1 

и для максимальной глубины два

gender  0.49, and  
country 0.51  

Теперь у меня есть следующие два вопроса
1) В R, когда я выбираю максимальную глубину = 1 и произошло разделениетолько в столбце страны, тогда почему он все еще дает значение важности для пола.Хотя пол даже не является частью окончательной модели.Например, в python это дает пол как значение var.
2) Во-вторых, почему в R значение характеристики столбца пола стало больше, чем значения столбца страны?Поскольку столбец стран был более важным, так как первоначальный раскол произошел по стране, а не по полу.Как и значения, которые мы получили для python.
Один из моих коллег отметил, что в R важность функций каждого столбца вычисляется при каждом разделении.Например, значение важности для некоторого признака пола и страны будет рассчитано при первом разделении.Затем снова это происходит во втором расколе.Но так как у нас уже был раскол, основанный на стране, не будет никакого получения информации, основанной на стране, но было бы там для пола.И в итоге все эти значения суммируются.Следовательно, мы получаем большее значение для тех, которые использовались на более поздней стадии для разделения.

...