Я пытаюсь понять, как рассчитать листовые значения в классификаторе LightGBM. Я построил простую модель с n_estimator = 1 и max_depth = 1, это означает, что она имеет только одно дерево решений и одну точку разделения. Я сравнил результаты, полученные по модели, и результаты, которые я вычислил сам, используя Python. В результате между ними есть небольшая разница: -0.000457 в листе 0 и -0.001548 в листе 1. Это из-за разницы, что LightGBM написан на C ++, и я использовал Python для расчета? Или что-то не так с моими шагами расчета?
ссылки:
Что такое leaf_values из Python LightGBM?
[ Вопрос] Как определяется выход листа для LambdaMART?
import pandas as pd
import lightgbm as lgb
from sklearn import datasets
## load data
data = datasets.load_breast_cancer()
df = pd.DataFrame(data.data, columns=data.feature_names)
df['label'] = data.target
## build a simple model
params = {'max_depth':1, 'n_estimators': 1, 'learning_rate':0.1}
model = lgb.LGBMClassifier(**params)
model.fit(df.drop('label', axis=1), df['label'])
## calculate scores by the model
df_pred = df[['label']].copy()
df_pred['score_raw'] = model.predict_proba(df.drop('label', axis=1), raw_score=True)
df_pred['score_proba'] = model.predict_proba(df.drop('label', axis=1))[:, 1]
df_pred['leaf'] = model.predict_proba(df.drop('label', axis=1), pred_leaf=True)
## calculate scores by myself
start_value = len(df[df['label']==1])/len(df)
df_pred['gradient'] = start_value - df_pred['label']
df_pred['hessian'] = 1
def calc_score_proba_(leaf):
sum_gradients = df_pred[df_pred['leaf']==leaf]['gradient'].sum()
sum_hessiants = df_pred[df_pred['leaf']==leaf]['hessian'].sum()
delta = -sum_gradients / sum_hessiants * model.learning_rate
df_pred.loc[df_pred['leaf']==leaf, 'score_proba_'] = start_value + delta
calc_score_proba_(0)
calc_score_proba_(1)
## calculate the gap between the scores
df_pred['score_proba_gap'] = df_pred['score_proba'] - df_pred['score_proba_']
df_pred
label score_raw score_prob leaf gradient hessian score_prob_ score_prob_gap
0 0 0.275629 0.568474 1 0.627417 1 0.570022 -0.001548
1 0 0.275629 0.568474 1 0.627417 1 0.570022 -0.001548
2 0 0.275629 0.568474 1 0.627417 1 0.570022 -0.001548
3 0 0.641339 0.655056 0 0.627417 1 0.655513 -0.000457
4 0 0.275629 0.568474 1 0.627417 1 0.570022 -0.001548
... ... ... ... ... ... ... ... ...
564 0 0.275629 0.568474 1 0.627417 1 0.570022 -0.001548
565 0 0.275629 0.568474 1 0.627417 1 0.570022 -0.001548
566 0 0.275629 0.568474 1 0.627417 1 0.570022 -0.001548
567 0 0.275629 0.568474 1 0.627417 1 0.570022 -0.001548
568 1 0.641339 0.655056 0 -0.372583 1 0.655513 -0.000457
569 rows × 8 columns
lgb.create_tree_digraph(model)