2016-05-17 2 views
3

Я хочу сгенерировать код (Python на данный момент, но в конечном счете C) из подготовленного градиентного повышающего классификатора (из sklearn). Насколько я понимаю, модель берет начальный предиктор, а затем добавляет прогнозы из последовательно обученных деревьев регрессии (с учетом коэффициента обучения). Выбранный класс - это класс с самым высоким выходным значением.Сгенерируйте код для GradientBoostingClassifier для sklearn

Это код, который я до сих пор:

def recursep_gbm(left, right, threshold, features, node, depth, value, out_name, scale): 
    # Functions for spacing 
    tabs = lambda n: (' ' * n * 4)[:-1] 
    def print_depth(): 
     if depth: print tabs(depth), 
    def print_depth_b(): 
     if depth: 
      print tabs(depth), 
      if (depth-1): print tabs(depth-1), 

    if (threshold[node] != -2): 
     print_depth() 
     print "if " + features[node] + " <= " + str(threshold[node]) + ":" 
     if left[node] != -1: 
      recursep_gbm(left, right, threshold, features, left[node], depth+1, value, out_name, scale) 
     print_depth() 
     print "else:" 
     if right[node] != -1: 
      recursep_gbm(left, right, threshold, features, right[node], depth+1, value, out_name, scale) 
    else: 
     # This is an end node, add results 
     print_depth() 
     print out_name + " += " + str(scale) + " * " + str(value[node][0, 0]) 

def print_GBM_python(gbm_model, feature_names, X_data, l_rate): 
    print "PYTHON CODE" 

    # Get trees 
    trees = gbm_model.estimators_ 

    # F0 
    f0_probs = np.mean(clf.predict_log_proba(X_data), axis=0) 
    probs = ", ".join([str(prob) for prob in f0_probs]) 
    print "# Initial probabilities (F0)" 
    print "scores = np.array([%s])" % probs 
    print 

    print "# Update scores for each estimator" 
    for j, tree_group in enumerate(trees): 
     for k, tree in enumerate(tree_group): 
      left  = tree.tree_.children_left 
      right  = tree.tree_.children_right 
      threshold = tree.tree_.threshold 
      features = [feature_names[i] for i in tree.tree_.feature] 
      value = tree.tree_.value 

      recursep_gbm(left, right, threshold, features, 0, 0, value, "scores[%i]" % k, l_rate) 
     print 

    print "# Get class with max score" 
    print "return np.argmax(scores)" 

Я изменил генерирующую дерево кода из this question.

Это пример того, что он генерирует (с 3-х классов, 2 оценок, 1 максимальная глубина и 0,1 скорости обучения):

# Initial probabilities (F0) 
scores = np.array([-0.964890, -1.238279, -1.170222]) 

# Update scores for each estimator 
if X1 <= 57.5: 
    scores[0] += 0.1 * 1.60943587225 
else: 
    scores[0] += 0.1 * -0.908433703247 
if X2 <= 0.000394500006223: 
    scores[1] += 0.1 * -0.900203054177 
else: 
    scores[1] += 0.1 * 0.221484425933 
if X2 <= 0.0340005010366: 
    scores[2] += 0.1 * -0.848148803219 
else: 
    scores[2] += 0.1 * 1.98100820717 

if X1 <= 57.5: 
    scores[0] += 0.1 * 1.38506104792 
else: 
    scores[0] += 0.1 * -0.855930587354 
if X1 <= 43.5: 
    scores[1] += 0.1 * -0.810729087535 
else: 
    scores[1] += 0.1 * 0.237980820334 
if X2 <= 0.027434501797: 
    scores[2] += 0.1 * -0.815242297324 
else: 
    scores[2] += 0.1 * 1.69970863021 

# Get class with max score 
return np.argmax(scores) 

Я использовал вероятность журнала как F0, основанный на this.

Для одной оценки это дает мне те же прогнозы, что и метод predict на обученной модели. Однако, когда я добавляю больше оценок, предсказания начинают отклоняться. Должен ли я включать длину шага (описано here)? Кроме того, мой F0 правильный? Должен ли я воспринимать среднее значение? И нужно ли преобразовывать логарифмические вероятности в нечто другое? Любая помощь очень ценится!

+0

Вы читали о модели [persistence] (http://scikit-learn.org/stable/modules/model_persistence.html)? Визуализация модели повышения градиента более сложна, чем интерпретация отдельных деревьев решений. Особенность важности - это общая методика, когда [интерпретация] (http://scikit-learn.org/stable/modules/ensemble.html#interpretation) и визуализация модели. –

+0

Конечная цель состоит в том, чтобы модель работала на C, следовательно, желая генерировать код. Насколько я могу судить, постоянство модели только позволяет сохранить модель для запуска снова в Python? –

ответ

1

Под капотом градиента Ускоряющий классификатор представляет собой сумму деревьев регрессии.

Вы можете получить деревья решений с слабым учащимся из обученного классификатора, прочитав атрибут estimators_. Из documentation это фактически ndarray of DecisionTreeRegressor.

Наконец, чтобы полностью воспроизвести функцию прогнозирования, вам также необходимо получить доступ к весам, как описано в этом документе answer.

В качестве альтернативы вы можете экспортировать представление дерева решений (вместо его псевдокода) GraphViz. Найти визуальный пример ниже от scikit-learn.org: enter image description here

В качестве последней, предельной ноте/предложение, вы можете попробовать также xgboost: помимо других функций, она имеет встроенную «модель свалка» функциональность (чтобы показать все деревья решений под обученной моделью и сохранить их в текстовом файле).

+0

Спасибо за ответ! Функция, которую я предоставил, предназначалась для принятия «оценок» в качестве ввода (я отредактировал его, чтобы он скорее взял модель для ясности). Этот ответ, кажется, предполагает, что вес деревьев запекается в самих деревьях? Единственным дополнительным весом является скорость обучения, которую я уже добавил. –

+0

Я также хотел бы проверить, соответствуют ли графическое представление каждого дерева и его сгенерированного кода: есть ли какие-либо «вложенные, если» отсутствуют? –

+0

В ответе, который вы скопировали, есть круглые скобки для управления «вложенными». Я сомневаюсь, что вы можете их опустить, хотя ваша максимальная глубина равна 1 ... –

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