算法簡介
K-means算法是很典型的基於距離的聚類算法,採用距離作爲相似性的評價指標,即認爲兩個對象的距離越近,其相似度就越大。該算法認爲簇是由距離靠近的對象組成的,因此把得到緊湊且獨立的簇作爲最終目標。
算法過程如下:
1)從N個文檔隨機選取K個文檔作爲質心;
2)對剩餘的每個文檔測量其到每個質心的距離,並把它歸到最近的質心的類;
3)重新計算已經得到的各個類的質心;
4)迭代2~3步直至新的質心與原質心相等或小於指定閾值,算法結束。
算法優缺點:
優點:
- 對處理大數據集,該算法保持可伸縮性和高效性
- 算法快速、簡單,易於理解;
缺點:
- 在 K-means 算法中 K 是事先給定的,這個 K 值的選定是非常難以估計的,具體應用中只能靠經驗選取;
- 對噪聲和孤立點數據敏感,導致均值偏離嚴重;
- 當數據量非常大時,算法的時間開銷是非常大的;
- 初始聚類中心的選擇對聚類結果有較大的影響,一旦初始值選擇的不好,可能無法得到有效的聚類結果。
代碼實現
第一步:讀取文件,簡單查看數據
import pandas as pd
import numpy as np
from pandas import DataFrame,Series
from sklearn.cluster import KMeans
from sklearn.cluster import Birch
#讀取文件
datafile = u'E:\\pythondata\\julei.xlsx'#文件所在位置,u爲防止路徑中有中文名稱,此處沒有,可以省略
outfile = u'E:\\pythondata\\julei_out.xlsx'#設置輸出文件的位置
data = pd.read_excel(datafile)#datafile是excel文件,所以用read_excel,如果是csv文件則用read_csv
d = DataFrame(data)
d.head()
assists height time age points 0 0.0888 201 36.02 28 0.5885 1 0.1399 198 39.32 30 0.8291 2 0.0747 198 38.80 26 0.4974 3 0.0983 191 40.71 30 0.5772 4 0.1276 196 38.40 28 0.5703
列名:助攻,身高,比賽時間,年齡,得分,根據這幾項進行聚類。
第二步:聚類
#聚類
mod = KMeans(n_clusters=3, n_jobs = 4, max_iter = 500)#聚成3類數據,併發數爲4,最大循環次數爲500
mod.fit_predict(d)#y_pred表示聚類的結果
#聚成3類數據,統計每個聚類下的數據量,並且求出他們的中心
r1 = pd.Series(mod.labels_).value_counts()
r2 = pd.DataFrame(mod.cluster_centers_)
r = pd.concat([r2, r1], axis = 1)
r.columns = list(d.columns) + [u'類別數目']
print(r)
#給每一條數據標註上被分爲哪一類
r = pd.concat([d, pd.Series(mod.labels_, index = d.index)], axis = 1)
r.columns = list(d.columns) + [u'聚類類別']
print(r.head())
r.to_excel(outfile)#如果需要保存到本地,就寫上這一列
第三步:可視化,簡單的標註上分爲哪一類怎麼能滿足?當然要看看可視化效果,畢竟注意一目瞭然的判斷聚類的效果
#可視化過程
from sklearn.manifold import TSNE
ts = TSNE()
ts.fit_transform(r)
ts = pd.DataFrame(ts.embedding_, index = r.index)
import matplotlib.pyplot as plt
a = ts[r[u'聚類類別'] == 0]
plt.plot(a[0], a[1], 'r.')
a = ts[r[u'聚類類別'] == 1]
plt.plot(a[0], a[1], 'go')
a = ts[r[u'聚類類別'] == 2]
plt.plot(a[0], a[1], 'b*')
plt.show()
因爲K-means 算法過於大衆化,而且代碼其實比較簡單的,所以備註比較少,如果需要備註或者有任何疑問,歡迎留言。