天天看点

快速入门Python机器学习(27)11聚类

10.5 堆垛分类(Stacking Classifier)

10.5.1 理论

stacking严格来说并不是一种算法,而是精美而又复杂的,对模型集成的一种策略。

  1. 首先我们会得到两组数据:训练集和测试集。将训练集分成5份:train1,train2,train3,train4,train5。
  2. 选定基模型。这里假定我们选择了xgboost, lightgbm 和 randomforest 这三种作为基模型。比如xgboost模型部分:依次用train1,train2,train3,train4,train5作为验证集,其余4份作为训练集,进行5折交叉验证进行模型训练;再在测试集上进行预测。这样会得到在训练集上由xgboost模型训练出来的5份predictions,和在测试集上的1份预测值B1。将这五份纵向重叠合并起来得到A1。lightgbm和randomforest模型部分同理。
  3. 三个基模型训练完毕后,将三个模型在训练集上的预测值作为分别作为3个"特征"A1,A2,A3,使用LR模型进行训练,建立LR模型。
  4. 使用训练好的LR模型,在三个基模型之前在测试集上的预测值所构建的三个"特征"的值(B1,B2,B3)上,进行预测,得出最终的预测类别或概率。

做stacking,首先需要安装mlxtend库。安装方法:进入Anaconda Prompt,输入命令 pip install mlxtend 即可。

快速入门Python机器学习(27)11聚类

10.5.2堆垛分类(Stacking Classifier)

堆垛分类学习曲线

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)           

复制

输出

鸢尾花数据  StackingClassifier:
100.00%
鸢尾花数据  StackingClassifier:
100.00%
红酒数据  StackingClassifier:
100.00%
红酒数据  StackingClassifier:
80.00%
乳腺癌数据  StackingClassifier:
100.00%
乳腺癌数据  StackingClassifier:
93.71%           

复制

快速入门Python机器学习(27)11聚类

堆垛分类多重验证

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)           

复制

输出

鸢尾花数据五重交叉验证:
准确度: 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介绍

快速入门Python机器学习(27)11聚类

分类:事先的类别是已知的,属于有监督学习;

聚类:事先的类别是未知的,属于无监督学习;聚类根据数据的共同性,自由结合,所谓鱼找鱼、虾找虾。由于聚类事现不知道最后应该属于哪个类,所以就不存在目标值,也就不存在得分了。

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类参数、属性和方法

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算法散点图分析

#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()           

复制

快速入门Python机器学习(27)11聚类
mglearn.plots.plot_kmeans_boundaries()
plt.show()           

复制

快速入门Python机器学习(27)11聚类

mglearn库,该库集成了sklearn和数据的许多操作方法,很便捷,获取对应数据。

1.3.4 K均值聚类鸢尾花

Util.py

#画聚类散点图
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+"训练簇标签标签图")           

复制

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")           

复制

输出

鸢尾花原始数据集分配簇标签为:
[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]           

复制

快速入门Python机器学习(27)11聚类

1.3.5 K均值聚类红酒

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")           

复制

输出

红酒原始数据集分配簇标签为:
[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]           

复制

快速入门Python机器学习(27)11聚类

1.3.6 K均值聚类乳腺癌

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")           

复制

输出

乳腺癌原始数据集分配簇标签为:
[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]           

复制

快速入门Python机器学习(27)11聚类

1.3.7 K均值聚类两个月亮

#两个月亮
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")           

复制

输出

处理后的数据形态: (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]           

复制

快速入门Python机器学习(27)11聚类

1.3.8 K均值聚类的缺点

  • 依赖随机种子
  • 对簇形状的假设约束比较强
  • 要求指定寻找簇的个数