利用Python實現K-Means聚類並進行圖形化展示
阿新 • • 發佈:2018-12-21
利用K-means進行聚類,顯示聚類結果的各類別的數量,最終進行圖形化展示 。
import pandas as pd import numpy as np import matplotlib.pyplot as plt from scipy import stats import cx_Oracle from sklearn.preprocessing import MinMaxScaler,StandardScaler from sklearn.preprocessing import LabelEncoder,OneHotEncoder from sklearn.cluster import KMeans #匯入K均值聚類演算法 import os file = open('test.xlsx','rb') data = pd.read_excel(file) file.close() data.set_index('CONS_NO',inplace=True) #刪除指標 data.drop('label_訴求行為',axis=1,inplace=True) #填充nan值為0 data.fillna(0, inplace = True) #標準化 for i in data.columns: if i=='TS_FLAG': data = pd.get_dummies(data,columns=[i]) #離散值進行One-Hot編碼 else: data[i]=\ StandardScaler().fit_transform(data[i].values.reshape(-1,1)).reshape(1,-1)[0] #數值標準化 plt.rcParams['font.sans-serif'] = ['SimHei'] #用來正常顯示中文標籤 distance=pd.DataFrame(index=range(1,15),columns=['類內距離','類間距離']) for k in range(3,11): kmodel=KMeans(n_clusters=k) kmodel.fit(data) r1 = pd.Series(kmodel.labels_).value_counts() #統計各個類別的數目 #重命名錶頭 print(r1) distance_in=0 distance_ot=0 for i in range(k): group=kmodel.labels_==i members=data[group] for v in np.mat(members): distance_in += np.linalg.norm(v - kmodel.cluster_centers_[i]) #預設為二範數,即歐式距離 for j in range(k): if i<j: distance_ot +=np.linalg.norm(kmodel.cluster_centers_[i]-kmodel.cluster_centers_[j]) distance.loc[k,'類內距離']=distance_in distance.loc[k,'類間距離']=distance_ot print('完成聚類數為 {} 聚類!'.format(k))
#聚類6類 k = 6 kmodel = KMeans(n_clusters = k, n_jobs = 1) #n_jobs是並行數,一般等於CPU數較好 kmodel.fit(data) #訓練模型 r1 = pd.Series(kmodel.labels_).value_counts() #統計各個類別的數目 r2 = pd.DataFrame(kmodel.cluster_centers_) #找出聚類中心 r = pd.concat([r2, r1], axis = 1) #橫向連線(0是縱向),得到聚類中心對應的類別下的數目 r.columns = list(data.columns) + [u'類別數目'] #重命名錶頭 colr = ['#E15759', '#4E79A7', '#76B7B2', '#F28E2B','blue','#F45E2B','#F67E2B'] plt.figure(figsize = (10, 8)) for i in r.index: if r['類別數目'][i] > 10: plt.plot(r.columns[:-1], r.loc[i, r.columns[:-1]], color = colr[i], label = i, linewidth=2) plt.legend(loc = 0, fontsize=14) plt.axis('tight') plt.xticks(fontsize=12,rotation=30) plt.yticks(fontsize=12) plt.xlabel('標籤名' ,fontsize=20) plt.ylabel('中心點' ,fontsize=20) plt.rcParams['xtick.labelsize'] = 20 plt.rcParams['ytick.labelsize'] = 20 plt.show() data['label_總聚類'] = kmodel.labels_ #得到聚類結果