Kmeans應用


1、思路

應用Kmeans聚類時,需要首先確定k值,如果k是未知的,需要先確定簇的數量。其方法可以使用拐點法、輪廓系數法(k>=2)、間隔統計量法。若k是已知的,可以直接調用sklearn子模塊cluster中Kmeans方法,對數據進行切割。

另外如若數據集不規則,存在量綱上的差異,也需要對其進行標准化處理。

2、數據的標准化處理

(minmax_scale為sklearn子模塊processing 中 的函數),第一種方法為壓縮變量為mean=0,std=1的無量綱數據,第二種方式會壓縮變量為[0,1]之間無量綱數據 。

3、案例

1)對iris聚類(已知簇類的情況)

情況1,已知k值,k=3

調用KMeans模塊

import pandas as pd 
import numpy as np
import matplotlib.pyplot as plt
from  sklearn.cluster  import KMeans
from pylab import *
mpl.rcParams['font.sans-serif'] = ['SimHei']

iris = pd.read_csv(r'iris.csv')

# 設置聚為3類,n_clusters =3
X = iris.drop(labels = 'Species',axis = 1)
kmeans = KMeans(n_clusters =3 )
kmeans.fit(X)

X['cluster'] = kmeans.labels_
X.cluster.value_counts()

# 繪制花瓣長度與寬度的散點圖
import seaborn as sns

centers = kmeans.cluster_centers_
print(centers)
sns.lmplot(x = 'Petal_Length', 
           y=  'Petal_Width',
           hue = 'cluster',
           markers = ['^','s','o'],
           data = X,
           fit_reg= False,
           scatter_kws = {'alpha':0.8},
           legend_out = False          
          )
plt.scatter(centers[:,2], centers[:,3], marker = '*',color = 'black', s =130)  # 繪制簇中心點
plt.xlabel('花瓣長度')
plt.ylabel('花瓣寬度')
plt.show()

iris['Species_map'] = iris.Species.map({'virginica':0,'setosa':1,"versicolor":2})  # 3種類型進行映射到0,1,2
sns.lmplot(x = 'Petal_Length', 
           y=  'Petal_Width',
           hue = 'Species_map',
           markers = ['^','s','o'],
           data = iris,
           fit_reg= False,
           scatter_kws = {'alpha':0.8},
           legend_out = False  )
plt.xlabel('花瓣長度')
plt.ylabel('花瓣寬度')
plt.show()

生成圖形如下:

 

 

 

 

對簇中心做雷達圖

import pygal

radar_chart = pygal.Radar(fill = True)
radar_chart.x_labels = ['花萼長度','花萼寬度', '花瓣長度','花瓣寬度']

# 雷達圖區域繪制
radar_chart.add('C1',centers[0])
radar_chart.add('C2',centers[1])
radar_chart.add('C3',centers[2])
radar_chart.render_to_file('radar_chart.svg')

  生成如下圖形,C1類型的花,花萼長和花瓣長都是最大的。C2類型的花,對應的3個指標值都比較小,C3類型的花,3個指標的平均值,恰好落在C1和C2之間。

 

 

 

2)NBA球員數據集聚類(未知k值)

數據集

 

 

選定得分、命中率,三分命中率,罰球命中率四個維度進行分析,觀察數據情況,需進行標准化。

  • 先對得分和命中率作散點圖,進行觀察
sns.lmplot(x = '得分', 
           y = '命中率',
          data = players,
           fit_reg = False,
           scatter_kws = {'alpha': 0.8,'color': 'steelblue'}
          )

plt.show()

  

 

肉眼無法進行觀察數據集適合分為幾個簇。分別采用 以上確定k值的3種方法進行測試。

拐點法:

from sklearn import preprocessing

X = preprocessing.minmax_scale(players[['得分','罰球命中率','命中率','三分命中率']])   # 數據集的標准化
X = pd.DataFrame(X, columns=['得分','罰球命中率','命中率','三分命中率'])
k_SSE(X,15)

  

 

 

 結果看出,k值在3、4斜率變化比較明顯,在5以后斜率保持一定的水平。所以k取3,4,5均有可能。在比較其他方法。

輪廓系數法及Gap statistic法可視化效果如下:

 

 

 

結合上圖,輪廓系數在大於0的情況下,最大值對應的k值為2,統計量法首次出現正值的k值為3,綜合考慮以上三種方法取k值為3,即將數據集分為3個簇最理想。

  • 對得分和命中率進行聚類
kmeans = KMeans(n_clusters = 3)
kmeans.fit(X)
players['cluster'] = kmeans.labels_
centers = []

for i in players.cluster.unique():
    centers.append(players.ix[players.cluster == i, ['得分','罰球命中率','命中率','三分命中率']].mean())
    
centers = np.array(centers)

sns.lmplot(x = '得分', 
           y = '命中率',
           hue = 'cluster',
           data = players,
           markers = ['^','s','o'],
           fit_reg = False,
           scatter_kws = {'alpha': 0.8},
           legend = False
)
plt.scatter(centers[:,0],centers[:,2],c = 'k',marker = '*',s =180)
plt.xlabel('得分')
plt.ylabel('命中率')
plt.show()

# 雷達圖繪制
centers_std = kmeans.cluster_centers_
radar_chart = pygal.Radar(fill = True) # 設置填充型雷達圖
radar_chart.x_labels = ['得分','罰球命中率','命中率','三分命中率']
radar_chart.add('C1', centers_std[0])
radar_chart.add('C2', centers_std[1])
radar_chart.add('C3', centers_std[2])

radar_chart.render_to_file('radar_charts.svg')

 結果如下圖:

 

 

 由聚類結果可以發現,三角形區域代表的球員屬於低得分低命中率類型,命中率普遍低於50%,方形區域代表低得分高命中率的球員,圓形區域球員與三角形區域球員具有類似的命中率,單圓形區域球員具有高得分。且該區域存在部分球員具有高得分且高命中率。通過對比雷達圖,C1、C2類球員平均得分差不多,但C2具有更高的命中率。平均罰球命中率和三分球命中率上來看,C1球員也要明顯高於C2.


免責聲明!

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



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