2017-02-22 4 views
1

У меня есть следующий код из scikit-сайт: узнатьЯвляется ли алгоритм CART, используемый scikit-learn, детерминированным?

import numpy as np 
from sklearn.datasets import load_iris 
from sklearn.model_selection import cross_val_score 
from sklearn.tree import DecisionTreeClassifier 
iris = load_iris() 
for i in range(10): 
    clf = DecisionTreeClassifier()  
    a = cross_val_score(clf, iris.data, iris.target, cv=10) 
    clf2 = DecisionTreeClassifier()  
    b = cross_val_score(clf2, iris.data, iris.target, cv=10) 
    if not np.array_equal(a,b): 
     print 'diff' 
     print a 
     print b 
     break 

иногда печатает разницу, так что я думаю, его не детерминированной что очень странно.

ответ

0

Деревья принятия решений Детерминированы, они вычисляют листья/вероятности в одном и том же исходном наборе данных. Если бы вы использовали что-то вроде случайного леса, то это не было бы детерминированным, потому что это случайный выбор переменных. Проблема в вашем испытании на равенство. Вы проверяете с помощью

object1 == object2

Python изначально не знает, как сравнить тип DecisionTreeClassifier. Вы спрашиваете, имеют ли те же значения, что и его свойства? Вы хотите знать, является ли размер памяти одинаковым? Являются ли указатели dt и dt2 ссылкой на один и тот же объект? Из того, что вы написали, нет способа узнать. Лучшим тестом было бы обучение моделей и использование метода .predict() для одних и тех же данных. Все ли результаты одинаковы каждый раз? Тогда у вас, вероятно, есть детерминированный классификатор.

Пути «pythonic» - это определить метод __ eq __ в файле класса. Если вы посмотрите here, вы увидите, что в древовидном классе нет ни одного элемента - я не смотрел дальше, но я сомневаюсь, что они определили этот метод. (Проверка того, являются ли две модели классификаторов эквивалентными, не является обычной практикой).

+0

Вы правы, я соответствующим образом изменим пример –

1

Хорошо, я обнаружил, что DecisionTreeClassifier использует случайное семя, если random_state параметр не задан, как было отмечено here:

random_state: Int, RandomState экземпляр или None, необязательно (по умолчанию = None) Если int, random_state - это семя, используемое случайным генератором чисел ; Если экземпляр RandomState, random_state является случайным генератором чисел ; Если None, генератор случайных чисел - это экземпляр RandomState , используемый np.random.

фиксированный код: (Я добавил random_state=0 в DecisionTreeClassifier конструктор)

import numpy as np 
from sklearn.datasets import load_iris 
from sklearn.model_selection import cross_val_score 
from sklearn.tree import DecisionTreeClassifier 
iris = load_iris() 
for i in range(10): 
    clf = DecisionTreeClassifier(random_state=0)  
    a = cross_val_score(clf, iris.data, iris.target, cv=10) 
    clf2 = DecisionTreeClassifier(random_state=0)  
    b = cross_val_score(clf2, iris.data, iris.target, cv=10) 
    if not np.array_equal(a,b): 
     print 'diff' 
     print a 
     print b 
     break 

Это работает, как ожидалось и np.array_equal(a,b)==True всегда.

+1

Джек, я рад, что вы нашли параметр random_state, но насколько я знаю, в методе нет случайности, если 'max_features == None' и 'splitter! = 'random''. Поскольку это по умолчанию, я смущен относительно того, откуда происходит случайность, поскольку CART по умолчанию должен быть детерминированным. Я думаю, что проблема должна быть открыта на страницах gsmub 'sklearn', чтобы решить эту проблему. –

+1

Я открыл этот вопрос здесь: https://github.com/scikit-learn/scikit-learn/issues/8443 –

Смежные вопросы