刘建平老师博客:
https://www.cnblogs.com/pinard/p/6136914.html
以下代码是在刘老师的代码进注解,由于对于sklearn包不熟悉,所以新手可以参考
code
import numpy as np
import matplotlib.pyplot as plt
from sklearn.ensemble import AdaBoostClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.datasets import make_gaussian_quantiles
#生成随机数据
#设置cov协方差,n_samples,n_features(正态分布的维数),n_classes:数组分的组数,random_state
X1,y1=make_gaussian_quantiles(cov=2.0,n_samples=500,n_features=2,n_classes=2,random_state=1)
X2,y2=make_gaussian_quantiles(mean=(3,3),cov=1.5,n_samples=400,n_features=2,n_classes=2,random_state=1)
#数据合并使用Numpy的方法concatenate(参数是个array)
X=np.concatenate((X1,X2))
y=np.concatenate((y1,-y2+1))
#展示数据
plt.scatter(X[:,0],X[:,1],marker="o",c=y)
plt.show()
#此时 图片的数据比较混杂,我们使用基于决策树的Adaboost做分类
#我们选择200个弱分类器(n_estimators),learning_rate(每个弱学习器的权重缩减系数)--》实际使用需要交叉验证,
# AdaBoostClassifier(base_estimator,n_estimators,algorithm,learning_rate,random_state)
#(观察学习率和弱分类器的数目)
bdt=AdaBoostClassifier(DecisionTreeClassifier(max_depth=2,min_samples_split=20,min_samples_leaf=5),
algorithm="SAMME",
n_estimators=200,learning_rate=0.8
)
bdt1 = AdaBoostClassifier(DecisionTreeClassifier(max_depth=2, min_samples_split=20, min_samples_leaf=5),
algorithm="SAMME",
n_estimators=300, learning_rate=0.8)
bdt2= AdaBoostClassifier(DecisionTreeClassifier(max_depth=2, min_samples_split=20, min_samples_leaf=5),
algorithm="SAMME",
n_estimators=300, learning_rate=0.5)
bdt3 = AdaBoostClassifier(DecisionTreeClassifier(max_depth=2, min_samples_split=20, min_samples_leaf=5),
algorithm="SAMME",
n_estimators=600, learning_rate=0.7)
#构建一个boost classifier
bdt.fit(X,y)
bdt1.fit(X,y)
bdt2.fit(X,y)
bdt3.fit(X,y)
#找到数据的x的最大值和y的最大值
x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
# print("最小值最大值",x_min,x_max,y_min,y_max)
# 最小值最大值 -5.318675003090752 8.067474174107211 -4.947064970881012 8.848278359647372
#np.meshgrid() 从坐标向量返回坐标矩阵。
# 坐标矩阵——横坐标矩阵 X中的每个元素,与纵坐标矩阵 Y中对应位置元素,共同构成一个点的完整坐标
a=np.arange(x_min, x_max, 0.02)
b=np.arange(y_min, y_max, 0.02)
# print("a,b的长度",len(a),len(b)) 670 690
xx, yy = np.meshgrid(a,b)
# 虽然a,b在一维上不同,但是经过meshgrid后shape一样(可以一一对应)
# xx.ravel():将多维数组转换为一维数组
#np.c[data1,data2] :详见test.py中(一维数组与多维数组的结果不同)
# 一位数组通过np.c_[]的操作得到一对对的数据
Z = bdt.predict(np.c_[xx.ravel(), yy.ravel()])
Z1 = bdt1.predict(np.c_[xx.ravel(), yy.ravel()])
Z2 = bdt2.predict(np.c_[xx.ravel(), yy.ravel()])
Z3 = bdt3.predict(np.c_[xx.ravel(), yy.ravel()])
# print("Z原来形状:",Z.shape)
# Z原来形状: (462300,)
Z = Z.reshape(xx.shape) #为例与(x,y)一一对应
Z1 = Z1.reshape(xx.shape)
Z2 = Z2.reshape(xx.shape)
Z3 = Z3.reshape(xx.shape)
# print("Z之后的形状:",Z.shape)
# Z之后的形状: (690, 670)
# plt.contourf是来绘制等高线的,但在这个函数中输入的参数是x,y对应的网格数据以及此网格对应的高度值,因此我们调用np.meshgrid(x,y)把x,y值转换成网格数据:
cs = plt.contourf(xx, yy, Z, cmap=plt.cm.Paired)
plt.scatter(X[:, 0], X[:, 1], marker='o', c=y)
plt.show()
cs1 = plt.contourf(xx, yy, Z1, cmap=plt.cm.Paired)
plt.scatter(X[:, 0], X[:, 1], marker='o', c=y)
plt.show()
cs2 = plt.contourf(xx, yy, Z2, cmap=plt.cm.Paired)
plt.scatter(X[:, 0], X[:, 1], marker='o', c=y)
plt.show()
cs3 = plt.contourf(xx, yy, Z3, cmap=plt.cm.Paired)
# cs = plt.contourf(xx, yy, Z, cmap=plt.cm.hot) #只是样式不同而已
plt.scatter(X[:, 0], X[:, 1], marker='o', c=y)
plt.show()
#调用AdaBoostClassifier的score计算得分
print("Score:",bdt.score(X,y))
print("Score:",bdt1.score(X,y))
print("Score:",bdt2.score(X,y))
print("Score:",bdt3.score(X,y))
# Score: 0.9133333333333333 200,0.8
# Score: 0.9622222222222222 弱分离器个数从200增加到300
# Score: 0.8944444444444445 learning_rate)从上面的0.8减少到0.5
# Score: 0.9611111111111111 当弱分类器个数为700(增加),步长为0.7(比0.8小点)时候
# #-----------------------下面为注释补充------------------------
# #---------------------------------------------------
# #---------------------------------------------------
#
# #看来分数不低
# # 分数高并不一定好,因为可能过拟合。
# #第二种::-》将最大弱分离器个数从200增加到300。再来看看拟合分数
# bdt = AdaBoostClassifier(DecisionTreeClassifier(max_depth=2, min_samples_split=20, min_samples_leaf=5),
# algorithm="SAMME",
# n_estimators=300, learning_rate=0.8)
# bdt.fit(X, y)
# print("Score:", bdt.score(X,y))
#
# 这印证了我们前面讲的,弱分离器个数越多,则拟合程度越好,当然也越容易过拟合。
#
# #第三种:-》现在我们降低步长,将步长(learning_rate)从上面的0.8减少到0.5,再来看看拟合分数。
# bdt = AdaBoostClassifier(DecisionTreeClassifier(max_depth=2, min_samples_split=20, min_samples_leaf=5),
# algorithm="SAMME",
# n_estimators=300, learning_rate=0.5)
# bdt.fit(X, y)
# print("Score:", bdt.score(X,y))
#
# # 可见在同样的弱分类器的个数情况下,如果减少步长,拟合效果会下降。
#
#
# #第四种:
# # 最后我们看看当弱分类器个数为700(增加),步长为0.7(比0.8小点)时候的情况:
#
# bdt = AdaBoostClassifier(DecisionTreeClassifier(max_depth=2, min_samples_split=20, min_samples_leaf=5),
# algorithm="SAMME",
# n_estimators=600, learning_rate=0.7)
# bdt.fit(X, y)
# print("Score:", bdt.score(X,y))
#
# #
# # 此时的拟合分数和我们最初的300弱分类器,0.8步长的拟合程度相当。
# # 也就是说,在我们这个例子中,如果步长从0.8降到0.7,
# # 则弱分类器个数要从300增加到700才能达到类似的拟合效果。
# #所以学习率参数很强
以上就是对于AdaBoost方法的心得体会
详细概念可以参考:刘建平老师博客 或者 李航老师的书(统计学习方法)(公式很全)
Adaboost类库的使用&spm=1001.2101.3001.5002&articleId=122568867&d=1&t=3&u=5f30230c18894e60891a0897e1caa98b)
335

被折叠的 条评论
为什么被折叠?



