10.5 堆垛分类(Stacking Classifier)
10.5.1 理论
stacking严格来说并不是一种算法,而是精美而又复杂的,对模型集成的一种策略。
- 首先我们会得到两组数据:训练集和测试集。将训练集分成5份:train1,train2,train3,train4,train5。
- 选定基模型。这里假定我们选择了xgboost, lightgbm 和 randomforest 这三种作为基模型。比如xgboost模型部分:依次用train1,train2,train3,train4,train5作为验证集,其余4份作为训练集,进行5折交叉验证进行模型训练;再在测试集上进行预测。这样会得到在训练集上由xgboost模型训练出来的5份predictions,和在测试集上的1份预测值B1。将这五份纵向重叠合并起来得到A1。lightgbm和randomforest模型部分同理。
- 三个基模型训练完毕后,将三个模型在训练集上的预测值作为分别作为3个"特征"A1,A2,A3,使用LR模型进行训练,建立LR模型。
- 使用训练好的LR模型,在三个基模型之前在测试集上的预测值所构建的三个"特征"的值(B1,B2,B3)上,进行预测,得出最终的预测类别或概率。
做stacking,首先需要安装mlxtend库。安装方法:进入Anaconda Prompt,输入命令 pip install mlxtend 即可。
10.5.2堆垛分类(Stacking Classifier)
堆垛分类学习曲线
代码语言:javascript复制def My_StackingClassifier_1(mydata,title):
warnings.filterwarnings("ignore")
myutil = util()
X,y = mydata.data,mydata.target
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=42)
#基分类器1:AdaBoostClassifier
pipe1 = make_pipeline(ColumnSelector(cols=(0, 2)),AdaBoostClassifier())
#基分类器2:RandomForest
pipe2 = make_pipeline(ColumnSelector(cols=(1, 2, 3)),RandomForestClassifier())
sclf = StackingClassifier(classifiers=[pipe1, pipe2], meta_classifier=LogisticRegression())
sclf.fit(X_train, y_train)
mytitle = title " " " StackingClassifier"
myutil.print_scores(sclf,X_train,y_train,X_test,y_test,mytitle)
myutil.plot_learning_curve(StackingClassifier(classifiers=[pipe1, pipe2], meta_classifier=LogisticRegression()),X,y,mytitle)
myutil.show_pic(mytitle)
def call_StackingClassifier_1():
mydatas = [datasets.load_iris(), datasets.load_wine(), datasets.load_breast_cancer()]
titles = ["鸢尾花数据","红酒数据","乳腺癌数据"]
for (mydata,title) in zip(mydatas, titles):
My_StackingClassifier_1(mydata,title)
输出
代码语言:javascript复制鸢尾花数据 StackingClassifier:
100.00%
鸢尾花数据 StackingClassifier:
100.00%
红酒数据 StackingClassifier:
100.00%
红酒数据 StackingClassifier:
80.00%
乳腺癌数据 StackingClassifier:
100.00%
乳腺癌数据 StackingClassifier:
93.71%
堆垛分类多重验证
代码语言:javascript复制def My_StackingClassifier_2(mydata,title):
warnings.filterwarnings("ignore")
myutil = util()
X,y = mydata.data[:, 1:3],mydata.target
basemodel1 = AdaBoostClassifier()
basemodel2 = lgb.LGBMClassifier()
basemodel3 = RandomForestClassifier(random_state=1)
lr = LogisticRegression()
sclf = StackingClassifier(classifiers=[basemodel1, basemodel2, basemodel3], meta_classifier=lr)
print(title '五重交叉验证:n')
for basemodel, label in zip([basemodel1, basemodel2, basemodel3, sclf], ['adaboost', 'lightgbm', 'Random Forest','StackingClassifier']):
scores = model_selection.cross_val_score(basemodel,X, y, cv=5, scoring='accuracy')
print("准确度: %0.2f ( /- %0.2f) [%s]" % (scores.mean(), scores.std(), label))
def call_StackingClassifier_2():
mydatas = [datasets.load_iris(), datasets.load_wine(), datasets.load_breast_cancer()]
titles = ["鸢尾花数据","红酒数据","乳腺癌数据"]
for (mydata,title) in zip(mydatas, titles):
My_StackingClassifier_2(mydata,title)
输出
代码语言:javascript复制鸢尾花数据五重交叉验证:
准确度: 0.86 ( /- 0.10) [adaboost]
准确度: 0.95 ( /- 0.03) [lightgbm]
准确度: 0.94 ( /- 0.04) [Random Forest]
准确度: 0.94 ( /- 0.04) [StackingClassifier]
红酒数据五重交叉验证:
准确度: 0.66 ( /- 0.08) [adaboost]
准确度: 0.58 ( /- 0.06) [lightgbm]
准确度: 0.61 ( /- 0.04) [Random Forest]
准确度: 0.62 ( /- 0.03) [StackingClassifier]
乳腺癌数据五重交叉验证:
准确度: 0.88 ( /- 0.04) [adaboost]
准确度: 0.90 ( /- 0.02) [lightgbm]
准确度: 0.88 ( /- 0.03) [Random Forest]
准确度: 0.89 ( /- 0.02) [StackingClassifier]
11聚类
1.1介绍
分类:事先的类别是已知的,属于有监督学习;
聚类:事先的类别是未知的,属于无监督学习;聚类根据数据的共同性,自由结合,所谓鱼找鱼、虾找虾。由于聚类事现不知道最后应该属于哪个类,所以就不存在目标值,也就不存在得分了。
1.2 三个聚类算法比较
算法 | 特色 |
---|---|
K均值 | 允许用户设定"簇"的数量用簇平均值表示簇 |
凝聚 | 允许用户设定"簇"的数量划分整个层次结构,通过树状图查看 |
DBSCAN | 可以检测没有分配的噪音允许用户设定eps定义接近程度,从而影响"簇"的大小可以生成差别很大的两个"簇" |
1.3 K均值聚类(k-Means)
1.3.1原理
K均值聚类算法(K-Means Clustering Algorithm)是一种迭代求解的聚类分析算法,其步骤是,预将数据分为K组,则随机选取K个对象作为初始的聚类中心,然后计算每个对象与各个种子聚类中心之间的距离,把每个对象分配给距离它最近的聚类中心。聚类中心以及分配给它们的对象就代表一个聚类。每分配一个样本,聚类的聚类中心会根据聚类中现有的对象被重新计算。这个过程将不断重复直到满足某个终止条件。终止条件可以是没有(或最小数目)对象被重新分配给不同的聚类,没有(或最小数目)聚类中心再发生变化,误差平方和局部最小。
K-Means算法基本步骤
- 从数据中选择K个对象作为初始聚类中心;
- 计算每个聚类对象到聚类中心的距离来划分;
- 再次计算每个聚类中心
- 计算标准测度函数,直到到达最大迭代次数,则停止,否则,继续操作。
1.3.2类参数、属性和方法
类
代码语言:javascript复制class sklearn.cluster.KMeans(n_clusters=8, *, init='k-means ', n_init=10, max_iter=300, tol=0.0001, precompute_distances='deprecated', verbose=0, random_state=None, copy_x=True, n_jobs='deprecated', algorithm='auto')
属性
属性 | 类别 | 介绍 |
---|---|---|
cluster_centers_ | ndarray of shape (n_clusters, n_features) | 集群中心的坐标。如果算法在完全收敛之前停止(参见tol和max_iter),这些将与标签不一致。labels_ndarray of shape (n_samples,)每个点的标签 |
inertia_ | float | 样本到最近聚类中心的平方距离之和。 |
n_iter_ | int | 运行的迭代次数。 |
方法
fit(X[, y, sample_weight]) | 计算k-均值聚类。 |
---|---|
fit_predict(X[, y, sample_weight]) | 计算聚类中心并预测每个样本的聚类指数。 |
fit_transform(X[, y, sample_weight]) | 计算聚类,将X变换到聚类距离空间。 |
get_params([deep]) | 获取此估计器的参数。 |
predict(X[, sample_weight]) | 预测X中每个样本所属的最近聚类。 |
score(X[, y, sample_weight]) | 与K-均值目标上的X值相反。 |
set_params(**params) | 设置此估计器的参数。 |
transform(X) | 将X变换到一个聚类距离空间。 |
1.3.3对make_blobs数据进行KMeans算法散点图分析
代码语言:javascript复制#K均值算法,Sklern KMeans算法
from sklearn.datasets import make_blobs
from sklearn.cluster import KMeans
import mglearn #pip3 install mglearn
import matplotlib.pyplot as plt
import numpy as np
def KMeans_for_blobs ():
blobs = make_blobs(random_state=1,centers=1)
X = blobs[0]
y = blobs[1]
#设置簇个数为3
Kmeans = KMeans(n_clusters=3)
Kmeans.fit(X)
print("训练集数据集分配簇标签为:n{}".format(Kmeans.labels_))
print("对训练集数据集预测结果为:",Kmeans.predict(X))
X_blobs = blobs[0]
X_min,X_max = X_blobs[:,0].min()-0.5,X_blobs[:,0].max() 0.5
y_min,y_max = X_blobs[:,1].min()-0.5,X_blobs[:,1].max() 0.5
xx, yy = np.meshgrid(np.arange(X_min, X_max, .02),np.arange(y_min, y_max, .02))
Z = Kmeans.predict(np.c_[xx.ravel(),yy.ravel()])
Z = Z.reshape(xx.shape)
plt.figure(1)
plt.imshow(Z,interpolation='nearest',extent=(xx.min(),xx.max(),yy.min(),yy.max()),cmap=plt.cm.summer,aspect='auto',origin='lower')
plt.plot(X_blobs[:,0],X_blobs[:,1],'r,',markersize=5)
#用蓝色*代表聚类的中心
centroids = Kmeans.cluster_centers_
plt.scatter(centroids[:,0],centroids[:,1],marker='x',s=150,linewidths=3,color='b',zorder=10)
plt.xlim(X_min,X_max)
plt.ylim(y_min,y_max)
plt.xticks(())
plt.yticks(())
plt.show()
代码语言:javascript复制mglearn.plots.plot_kmeans_boundaries()
plt.show()
mglearn库,该库集成了sklearn和数据的许多操作方法,很便捷,获取对应数据。
1.3.4 K均值聚类鸢尾花
Util.py
代码语言:javascript复制#画聚类散点图
def draw_scatter_for_Clustering(self,X,y,result,title,algorithm):
print(title "原始数据集分配簇标签为:n{}".format(y))
print(title " " algorithm " 训练簇标签为:n{}".format(result))
plt.scatter(X[:,0],X[:,1],c=y,cmap=plt.cm.spring,edgecolor='k')
self.show_pic(title "原始数据集分配簇标签图")
plt.scatter(X[:,0],X[:,1],c=result,cmap=plt.cm.spring,edgecolor='k')
self.show_pic(title " " algorithm "训练簇标签标签图")
代码语言:javascript复制def KMeans_for_iris():
myutil = util()
X,y = datasets.load_iris().data,datasets.load_iris().target
Kmeans = KMeans(n_clusters=3)
Kmeans.fit(X)
result = Kmeans.fit_predict(X)
title = "鸢尾花"
myutil.draw_scatter_for_Clustering(X,y,result,title,"KMeans")
输出
代码语言:javascript复制鸢尾花原始数据集分配簇标签为:
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2]
鸢尾花Kmeans训练簇标签为:
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 2 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 1 1 1 1 2 1 1 1 1 1 1 2 2 1 1 1 1 2 1 2 1 2 1 1 2 2 1 1 1 1 1 2 1 1 1 1 2 1 1 1 2 1 1 1 2 1 1 2]
1.3.5 K均值聚类红酒
代码语言:javascript复制def KMeans_for_wine():
myutil = util()
X,y = datasets.load_wine().data,datasets.load_wine().target
Kmeans = KMeans(n_clusters=3)
Kmeans.fit(X)
result = Kmeans.fit_predict(X)
title = "红酒"
myutil.draw_scatter_for_Clustering(X,y,result,title,"KMeans")
输出
代码语言:javascript复制红酒原始数据集分配簇标签为:
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2]
红酒 KMeans 训练簇标签为:
[1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 1 1 2 2 1 1 2 1 1 1 1 1 1 2 2 1 1 2 2 1 1 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 2 0 2 0 0 2 0 0 2 2 2 0 0 1 2 0 0 0 2 0 0 2 2 0 0 0 0 0 2 2 0 0 0 0 0 2 2 0 2 0 2 0 0 0 2 0 0 0 0 2 0 0 2 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 2 0 0 2 2 2 2 0 0 0 2 2 0 0 2 2 0 2 2 0 0 0 0 2 2 2 0 2 2 2 0 2 0 2 2 0 2 2 2 2 0 0 2 2 2 2 2 0]
1.3.6 K均值聚类乳腺癌
代码语言:javascript复制def KMeans_for_breast_cancer():
myutil = util()
X,y = datasets.load_breast_cancer().data,datasets.load_breast_cancer().target
Kmeans = KMeans(n_clusters=2)
Kmeans.fit(X)
result = Kmeans.fit_predict(X)
title = "乳腺癌"
myutil.draw_scatter_for_Clustering(X,y,result,title,"KMeans")
输出
代码语言:javascript复制乳腺癌原始数据集分配簇标签为:
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
…
1 1 1 1 1 1 1 0 0 0 0 0 0 1]
乳腺癌 KMeans 训练簇标签为:
[1 1 1 0 1 0 1 0 0 0 0 1 1 0 0 0 0 1 1 0 0 0 0 1 1 1 0 1 1 1 1 0 1 1 1 1 0
…
0 0 0 0 0 0 0 0 1 1 1 0 1 0]
1.3.7 K均值聚类两个月亮
代码语言:javascript复制#两个月亮
def KMeans_for_two_moon():
myutil = util()
X, y = datasets.make_moons(n_samples=200,noise=0.05, random_state=0)
scaler = StandardScaler()
scaler.fit(X)
X_scaled = scaler.transform(X)
# 打印处理后的数据形态
print("处理后的数据形态:",X_scaled.shape)
# 处理后的数据形态: (200, 2) 200个样本 2类
Kmeans = KMeans(n_clusters=2)
result=Kmeans.fit_predict(X_scaled)
title = "两个月亮"
#绘制簇分配结果
myutil.draw_scatter_for_Clustering(X,y,result,title,"KMeans")
输出
代码语言:javascript复制处理后的数据形态: (200, 2)
两个月亮原始数据集分配簇标签为:
[0 1 1 0 1 1 0 1 0 1 0 1 1 1 0 0 0 1 0 0 1 1 0 1 0 1 1 1 1 0 0 0 1 1 0 1 1
0 0 1 1 0 0 1 1 0 0 0 1 1 0 1 1 0 1 0 0 1 0 0 1 0 1 0 1 0 0 1 0 0 1 0 1 1
1 0 1 0 0 1 1 0 1 1 1 0 0 0 1 1 0 0 1 0 1 1 1 1 0 1 1 1 0 0 0 1 0 0 1 0 0
0 0 0 0 1 0 1 1 0 0 0 1 0 1 0 0 1 1 1 0 0 0 1 1 1 1 0 1 0 1 1 0 0 0 0 1 1
0 1 1 1 0 0 1 0 1 1 0 0 1 1 0 1 1 1 0 1 1 1 0 0 0 0 1 1 1 0 0 0 1 0 1 1 1
0 0 1 0 0 0 0 0 0 1 0 1 1 0 1]
两个月亮 KMeans 训练簇标签为:
[1 0 1 1 0 0 0 0 0 0 1 0 0 0 1 0 1 0 1 1 0 0 1 0 1 0 0 0 0 1 1 1 0 1 1 0 0
0 1 1 0 1 1 1 0 1 0 1 0 0 1 0 0 1 0 1 1 0 1 1 0 1 0 1 0 1 1 0 1 1 0 1 0 1
0 1 1 0 1 0 0 1 0 0 1 1 0 1 0 0 1 0 0 1 0 0 0 0 1 1 0 0 1 0 1 1 1 1 0 1 1
1 1 1 0 0 1 0 0 1 1 1 1 1 1 1 0 0 0 0 0 1 1 0 0 0 0 1 0 0 0 1 1 1 1 0 0 0
1 1 0 0 1 1 0 1 0 0 1 1 0 0 1 0 0 0 1 0 0 0 1 1 1 1 0 0 0 1 1 1 0 1 0 0 0
1 1 0 1 1 1 1 1 0 1 1 0 0 1 0]
1.3.8 K均值聚类的缺点
- 依赖随机种子
- 对簇形状的假设约束比较强
- 要求指定寻找簇的个数