鳶尾花K-means聚類算法_python數據分析與機器學習


  1. 采用的算法。
    K-means即均值聚類,是一種容易上手的聚類機器學習算法。
  2. 鳶尾花概述
    鳶尾花(iris)是一種常見溫帶植物。鳶尾屬(拉丁學名:Iris L.),單子葉植物綱,百合目,鳶尾科多年生草本植物,有塊莖或匍匐狀根莖;葉劍形,嵌疊狀;花美麗,狀花序或圓錐花序;花被花瓣狀,有一長或短的管,外彎,花柱分枝擴大,花瓣狀而有顏色,外展而覆蓋着雄蕊;子房下位,胚珠多數,果為蒴果。本屬模式種:德國鳶尾(Iris germanica L. )原產歐洲,中國各地常見栽培。鳶尾屬約300種,分布於北溫帶,少數入葯,鳶尾根莖為誘吐劑或緩下劑,具消炎作用。鳶尾花大而美麗,葉片青翠碧綠,觀賞價值很高。很多種類供庭園觀賞用,在園林中可用作布置花壇,栽植於水濕畦地、池邊湖畔,或布置成鳶尾專類花園,亦可作切花及地被植物,是一種重要的庭園植物。

     

     

  3. 問題的轉化:
    由於鳶尾種類龐雜,正確辨識鳶尾種類就具有重要的實踐意義。而辨識過程往往是一種經驗積累,無外乎對其外形進行觀察和比較。因此,鳶尾花分類看似是一個實踐問題,實際上可以轉化為一個數據驅動的機器學習算法理論問題。
  4. 數據
    該數據集聚類時只輸入前4個變量,聚類結果可以與物種(變量Species)進行比較,該變量包含了3個類別,分別為Setosa、Versicolour和Virginica,每類50個樣本。
  5. 載入python庫
    1 import pandas as pd 2 import numpy as np 3 from matplotlib import pyplot as plt 4 from matplotlib.colors import ListedColormap 5 from sklearn.datasets import load_iris, make_moons, make_circles, make_blobs 6 from sklearn.metrics import silhouette_score, homogeneity_completeness_v_measure 7 from sklearn.cluster import KMeans, DBSCAN, AgglomerativeClustering

     

  6. sklearn.datasets的作用演示
    sklearn.datasets的函數make_moons()用於生成兩個交織的半圓環(moons),
    make_circles()用於生成一個大圓環套小圓環(circles
    make_blobs()用於生成兩團點(blobs)
    1 moons = make_moons(500, noise=0.05, random_state=0)
    2 circles = make_circles(500, noise=0.05, factor=0.5, random_state=1)
    3 blobs = make_blobs(500, centers=2, cluster_std = 0.1, center_box = (-1,1), random_state=8)
    4 synthetic_data = {"moons" : moons, "circles" : circles, "blobs" : blobs}

    運行代碼后,利用matplotlib(from matplotlib import pyplot as plt)繪制圖形

    1 plt.figure(figsize = (18,5))
    2 i = 0
    3 for name, (X, y) in synthetic_data.items():
    4     plt.subplot(131 + i)
    5     plt.scatter(X[:, 0], X[:, 1], c=y, cmap=ListedColormap(['#FF0000', '#0000FF']))
    6     plt.title(name)
    7     i += 1
    8 
    9 plt.show()

                       圖1 交織的半圓                                     圖2 同心圓                                     圖3 兩團數據點

  7. 聚類的目的,是把形如以上形狀的數據點進行分類。
    聚類即clustering,將數據集中的樣本划分為若干個子集,每個子集稱為一個簇(cluster)。k均值算法需要指定簇的數量,可擴展性較強,能夠適應大數據集。

  8. 解釋K-means算法

    k均值算法將N個樣本的數據集X划分為K個不相交的簇C,每個簇由簇內樣本的均值μj作為代表,稱為簇的中心。k均值算法最小化慣性即簇內平方和

     

    慣性能夠衡量簇的內部是否緊密,然而也有一些缺點,之后章節會通過一些例子具體解讀,包括:

    假定簇是凸的且各向同性的;
    並不是歸一化的指標,即范圍不是0到1之間,我們只知道該指標越小越好,0為最佳。
    k均值算法分為3個步驟:
    第1步,選擇初始的簇中心,可以隨機選擇數據集中的樣本;
    第2步,將每個樣本分配到最近的簇中心所在的簇;
    第3步,計算新的簇中心。
    重復迭代第2和3步,直到簇中心在不同的迭代之間變化不大。

  9. 載入鳶尾花數據集
    sklearn.datasets自帶鳶尾花數據集,可以用load_iris()載入
    iris數據集分為兩部分,data部分為四個測量數據,target部分為分類數據用於訓練模型參數
    1 iris = load_iris() ##讀入數據集
    2 iris_X = iris.data  ##測量數據保存為自變量
    3 iris_y = iris.target ##target數據保存為因變量
  10. 構造K-means模型
    1 clf = KMeans(n_clusters=3,n_init=3,random_state=123)

    k-means聚類模型的屬性參數:
    參數n_clusters:聚類得到簇的數量
    參數n_init:隨機選擇初始中心的組數,最終選擇慣性最小的模型
    參數random_state:生成隨機中心的點的數量
    代碼中,指定簇的數量為3,初始中心的組數為3,生成隨機中心點數量為123個,並訓練

    1 clf.fit(iris_X)
    output:
    KMeans(algorithm='auto', copy_x=True, init='k-means++', max_iter=300, n_clusters=3, n_init=3, n_jobs=None, precompute_distances='auto', random_state=123, tol=0.0001, verbose=0)


    cluster_centers_labels_inertia_得到簇的中心、每個樣本的簇序號和慣性

    1 clf.cluster_centers_  ##簇的中心
    output:
    array([[5.006 , 3.428 , 1.462 , 0.246 ],
           [5.88360656, 2.74098361, 4.38852459, 1.43442623],
           [6.85384615, 3.07692308, 5.71538462, 2.05384615]])
    1 clf.labels_ ##每個樣本的簇序號
    output:
    array([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, 1, 2, 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, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
           1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 2, 2, 2, 1, 2, 2, 2,
           2, 2, 2, 1, 1, 2, 2, 2, 2, 1, 2, 1, 2, 1, 2, 2, 1, 1, 2, 2, 2, 2,
           2, 1, 2, 2, 2, 2, 1, 2, 2, 2, 1, 2, 2, 2, 1, 2, 2, 1])
    1 clf.inertia_ ##簇的慣性
    output:
    78.8556658259773

     

  11. 可視化前兩個變量的聚類結果:花萼長度Sepal.Length,花萼寬度Sepal.Width

    1 plt.figure(figsize = (8,6))
    2 plt.scatter(iris_X[:, 0], iris_X[:, 1], c=clf.labels_, cmap=ListedColormap(['darkorange', 'c', 'darkblue']))
    3 plt.scatter(clf.cluster_centers_[:,0], clf.cluster_centers_[:,1], c=np.array([0,1,2]), 
    4             marker = 'x', s=300, cmap=ListedColormap(['darkorange', 'c', 'darkblue']))
    5 plt.show()

     

    可以看出,左上方的凸面分成了1個簇,右下方的凸面分成了2個簇。

    得到真實類別序號與簇的序號的交叉表。

    1 pd.crosstab(iris_y,clf.labels_)

     

     

    可以看出,類別序號0代表的setosa完全對應1個簇,而類別序號1代表的versicolor和類別序號2代表的virginica基本也分成了2個簇。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM