原創(chuàng): JasonYe 北辰文閣 今天 本節(jié)將要介紹一種被廣泛使用的直接聚類算法k-means,。在給定的數(shù)據(jù)集中,將里面的對(duì)象劃分到多個(gè)聚簇中,,使得同一聚簇內(nèi)的對(duì)象互相比較相似,而不同聚簇間的對(duì)象彼此差別較大,。換而言之,就是將相似接近的對(duì)象分到同一聚簇,,將不相似的對(duì)象分到不同聚簇,。因此聚類歸屬于無監(jiān)督學(xué)習(xí)算法,我們并不知道數(shù)據(jù)對(duì)象的標(biāo)記,,只知道它的特征如何,。 K-means算法的輸入是維向量空間的數(shù)據(jù)點(diǎn),我們將這些點(diǎn)標(biāo)記為S,Si指中第個(gè)數(shù)據(jù)點(diǎn),每個(gè)Si屬于且僅屬于K個(gè)聚簇中的某一個(gè),。K是指定K-means算法聚類個(gè)數(shù)的輸入?yún)?shù),,一般由用戶指定,。在實(shí)際問題上,,用戶往往難以給出合適最佳的K值,,這時(shí)候可以先隨機(jī)指定一個(gè)值,,根據(jù)后面聚類情況再調(diào)整(當(dāng)然有更好的處理方法),。選定K值后,,我們會(huì)用適當(dāng)?shù)姆椒ㄟx取適當(dāng)?shù)腒個(gè)初始質(zhì)心,即聚簇的中心點(diǎn),,質(zhì)心的選取也是一個(gè)關(guān)鍵步驟,,常見的選定方法是隨機(jī)初始化,一般的K-means算法也是這么設(shè)定,。 選定K值和K個(gè)質(zhì)心點(diǎn)后,,我們將會(huì)遍歷S,將每個(gè)點(diǎn)歸屬到離其最近的各個(gè)聚簇中心點(diǎn)上,,一般采用歐式距離來衡量距離遠(yuǎn)近,,當(dāng)然也可以用余弦距離,還有其他距離,,可以參考我之前寫過的一篇專門講述距離的文章《我和你的距離有多遠(yuǎn)》,,因此K-means算法的關(guān)鍵是在于最小化如下的目標(biāo)代價(jià)函數(shù)來將各個(gè)點(diǎn)聚到各自的聚簇上(其中M指數(shù)據(jù)點(diǎn)的總個(gè)數(shù),Cj指第j個(gè)聚簇的中心點(diǎn)): #設(shè)置環(huán)境包import matplotlib.pyplot as plt #可視化展示用from sklearn import datasets #datasets加載數(shù)據(jù)from sklearn.cluster import KMeans #kmeans的處理包import sklearn.metrics as sm #sm:矩陣處理import pandas as pdimport numpy as np#可視化初始化,,如果沒有可視化需求可以忽略%matplotlib inline iris = datasets.load_iris()#查看數(shù)據(jù)的維度# print(iris.data)# print(iris.target)print(iris.feature_names) print(iris.target_names)# 將數(shù)據(jù)存儲(chǔ)為Pandas Dataframe 設(shè)置變量名x = pd.DataFrame(iris.data) x.columns = ['Sepal_Length','Sepal_Width','Petal_Length','Petal_Width'] y = pd.DataFrame(iris.target) y.columns = ['Targets']# 設(shè)置plot的區(qū)域plt.figure(figsize=(14,7))# 創(chuàng)造畫板colormap = np.array(['red', 'lime', 'black'])# 展示花萼長(zhǎng)寬下的具體分類plt.subplot(1, 2, 1) plt.scatter(x.Sepal_Length, x.Sepal_Width, c=colormap[y.Targets], s=40) plt.title('Sepal')# 展示花瓣長(zhǎng)寬下的具體分類plt.subplot(1, 2, 2) plt.scatter(x.Petal_Length, x.Petal_Width, c=colormap[y.Targets], s=40) plt.title('Petal') ['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)'] ['setosa' 'versicolor' 'virginica'] model = KMeans(n_clusters=3)# 設(shè)定K=3的聚類模型model.fit(x)#開始運(yùn)行,,參數(shù)設(shè)置默認(rèn)值,運(yùn)行后會(huì)顯示,,也可以更改對(duì)應(yīng)參數(shù)運(yùn)行模型 KMeans(algorithm='auto', copy_x=True, init='k-means++', max_iter=300, n_clusters=3, n_init=10, n_jobs=1, precompute_distances='auto', random_state=None, tol=0.0001, verbose=0) #模型結(jié)果model.labels_ array([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, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 2, 0, 2, 0, 2, 0, 0, 2, 2, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 2], dtype=int32) #展示結(jié)果# 設(shè)置plot的區(qū)域plt.figure(figsize=(14,7))# 創(chuàng)造畫板colormap = np.array(['red', 'lime', 'black','blue'])#展示原有分類結(jié)果:花瓣plt.subplot(1, 2, 1) plt.scatter(x.Petal_Length, x.Petal_Width, c=colormap[y.Targets], s=40) plt.title('Real Classification')#展示模型分類結(jié)果:花瓣plt.subplot(1, 2, 2) plt.scatter(x.Petal_Length, x.Petal_Width, c=colormap[model.labels_], s=40) plt.title('K Mean Classification') # 非監(jiān)督聚類結(jié)果是不確定的,,所以需要調(diào)整轉(zhuǎn)換predY = np.choose(model.labels_, [2, 0, 1]).astype(np.int64)print (model.labels_)print (predY) [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 0 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 0 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 0 2 0 0 0 0 2 0 0 0 0 0 0 2 2 0 0 0 0 2 0 2 0 2 0 0 2 2 0 0 0 0 0 2 0 0 0 0 2 0 0 0 2 0 0 0 2 0 0 2] [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 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] #展示調(diào)整后的結(jié)果plt.figure(figsize=(14,7))# 創(chuàng)造畫板colormap = np.array(['red', 'lime', 'black'])#展示原有分類結(jié)果:花瓣plt.subplot(1, 2, 1) plt.scatter(x.Petal_Length, x.Petal_Width, c=colormap[y.Targets], s=40) plt.title('Real Classification')#展示模型分類結(jié)果:花瓣plt.subplot(1, 2, 2) plt.scatter(x.Petal_Length, x.Petal_Width, c=colormap[predY], s=40) plt.title('K Mean Classification') #準(zhǔn)確率輸出sm.accuracy_score(y, predY) 0.89333333333333331 #混淆矩陣輸出sm.confusion_matrix(y, predY) array([[50, 0, 0], [ 0, 48, 2], [ 0, 14, 36]]) import matplotlib.pyplot as plt plt.figure(figsize=(14,7))# 創(chuàng)造畫板#展示原有分類結(jié)果:花瓣plt.subplot(1, 2, 1) plt.scatter(1, 2, s=40) plt.title('Real Classification') 小結(jié) k-means也有它的優(yōu)缺點(diǎn),感興趣的同學(xué)可以思考一下總結(jié)出來,。我這里說出兩種比k-means好一點(diǎn)的算法,,一個(gè)是k-modes,一個(gè)是s-means.. 寫在最后
|
|