import numpy as np
from sklearn.ensemble import GradientBoostingClassifier
from sklearn import tree
import matplotlib.pyplot as plt
xi = np.arange(1,11)
yi = np.array([0,0,0,1,1]*2)
gbdt = GradientBoostingClassifier(n_estimators=3,max_depth=1)
gbdt.fit(xi.reshape(-1,1),yi)
gbdt.estimators_.shape #3是3棵树,1是二分类问题(3分类问题是3 4分类问题是4)
plt.figure(figsize=(9,6))
_ = tree.plot_tree(gbdt[0,0],filled = True)
np.var(yi)
0.24
F0 = np.log(4/6)
-0.40546510810816444
#残差,概率,负梯度
yi_1 = yi - 1/(1+np.exp(-F0))
yi_1
array([-0.4, -0.4, -0.4, 0.6, 0.6, -0.4, -0.4, -0.4, 0.6, 0.6])
#计算每个裂分点mse
mse1 = []
for i in range (1,11):
if i == 10:
mse1.append(np.var(yi_1))
else:
mse1.append((np.var(yi_1[:i])*i+np.var(yi_1[i:])*(10-i))/10)
mse1
[0.22222222222222224,
0.2,
0.17142857142857143,
0.225,
0.23999999999999994,
0.23333333333333334,
0.20952380952380958,
0.15,
0.2,
0.24]
np.var(yi_1[:8])
np.var(yi_1[8:])
0.1875
0.0
np.round(yi_1[:8].sum()/(((yi[:8]-yi_1[:8])*(1-yi[:8]+yi_1[:8])).sum()),3)
np.round(yi_1[8:].sum()/(((yi[8:]-yi_1[8:])*(1-yi[8:]+yi_1[8:])).sum()),3)
结果:
-0.625
2.5
#第一棵树数据预测的值
y_1 = [-0.625]*8 +[2.5]*2
y_1 = np.asarray(y_1)
y_1
gbdt[0,0].predict(xi.reshape(-1,1))
结果:
array([-0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625,
2.5 , 2.5 ])
array([-0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625, -0.625,
2.5 , 2.5 ])
I=1,xi属于集合内 I=0,xi不属于集合内
#learning_rate = 0.1
F1 = F0 + y_1*0.1
F1.round(4)
结果:
array([-0.468 , -0.468 , -0.468 , -0.468 , -0.468 , -0.468 , -0.468 ,
-0.468 , -0.1555, -0.1555])
yi_2 = yi - 1/(1+np.exp(-F1))
yi_2.round(4)
结果:
array([-0.3851, -0.3851, -0.3851, 0.6149, 0.6149, -0.3851, -0.3851,
-0.3851, 0.5388, 0.5388])
plt.figure(figsize=(16,8))
tree.plot_tree(gbdt[1,0],filled = True)
#计算每个裂分点mse
mse1 = []
for i in range (1,11):
if i == 10:
mse1.append(np.var(yi_2))
else:
mse1.append((np.var(yi_2[:i])*i+np.var(yi_2[i:])*(10-i))/10)
mse1
mse1 = np.asarray(mse1)
mse1
结果:
array([0.20620922, 0.18564623, 0.1592081 , 0.21054968, 0.22242788,
0.2186899 , 0.19976152, 0.15 , 0.19036645, 0.22265961])
np.round(yi_2[:8].sum()/(((yi[:8]-yi_2[:8])*(1-yi[:8]+yi_2[:8])).sum()),3)
np.round(yi_2[8:].sum()/(((yi[8:]-yi_2[8:])*(1-yi[8:]+yi_2[8:])).sum()),3)
结果:
-0.571
2.168
np.var(yi_2[:8])
np.var(yi_2[8:])
0.1875
0.0