「Python實現一個算法總是比你理解這個算法更簡單,這也是Python如此流行的原因之一。」
在前面的文章中講過數據離散化和KMeans算法的理論理解。
參見:數據離散化及其KMeans算法實現的理解
這篇文章來看看怎樣用Python實現這個事。
01
—
目標
有下圖所示的一系列數據,總共有900多條,這是《Python數據分析與挖掘實戰》這本書第4章的案例數據。
從圖中可見,測量值非常多,但實際上肝氣鬱結要麼就是有要麼就是沒有,就兩種情況;再細緻一點,我們可能分成好、不太好、差、很差四類。當然,具體怎樣分法需要這方面的專業人士來定。
反正,就拿過來這樣一堆數據,根據這組數據情況呢把病人給分成四類。
也就是說,我們的目標就是將這900多條數據用K-Means算法給分成4類。
02
—
實現步驟
Step1,當然是把需要用到的第三方庫給import進來
import pandas as pdimport matplotlib.pyplot as pltfrom sklearn.cluster import KMeans
KMeans就是要用到第三行。
Step2,當然是把數據讀到pandas的dataframe中
datafile = u'../data/discretization_data.xls'data = pd.read_excel(datafile) #這個地方的data的類型是DataFramedata = data[u'肝氣鬱結證型係數'] #這裡的data已經是DataFrame的一列,變成了Series了
上面這個第三行是啥意思呢?因為我們待會要用到的KMeans的輸入數據類型是ndarray的行向量,所以先在這裡把data的一列拿出來。
Step3,創建KMeans的分類器並對Step2中的數據進行聚類。
請看代碼:
k = 4kmodel = KMeans(n_clusters = k, n_jobs = 2) #n_jobs是進程的數量,和cpu個數有關kmodel.fit(data.values.reshape((len(data),1)))c = pd.DataFrame(kmodel.cluster_centers_).sort_values(0) #對聚類中心排序w1 = c.rolling(2).mean().iloc[1:]w = [0] + list(w1[0]) + [data.max()]d_result = pd.cut(data, w, labels = range(k))
就這麼簡單,就7行就搞定了這個事。在這裡,我有必要把這幾行代碼簡要說一下。
第1-3行,就是拿Step2中的數據用KMeans算法給聚類,不是會得到4個分類麼?每個分類不是會有一個中心點麼?如果忘記了,請回過頭去看看這篇文章:數據離散化及其KMeans算法實現的理解。
拿這4個圓心也是存放在第2行創建的這個KMeans的對象kmodel中,確切說在它的cluster_centers_中。它的值是下面圖這樣的,然後再對它們從小到大排序給到c。
第4行,然後我們再把它轉成DataFrame類型,再排一下序(就是代碼第4行幹的事)
第5行,是做窗口平均的,也就是說以rolling的輸入2為窗口大小求平均值。更直白一點,就是第c的(第1個值+第2個值)/2作為新的第2個值,第1個值就沒了,c經過rolling(2)窗口平均後的結果是這樣的。
然後我們把上圖中的第1個值NaN給切掉後再賦給w1。
第6行,是將0作為最小,將data中的最大值作為最大,加入到w1中,w就變成5個值了,c\w1\w分別如下圖的左、中、右。
第7行,所有前面6行都是為這一行服務的,就是要把我們對data分類的5個分類的界限(值)確定下來之後,用cut函數將data分成5類。
Step4:把分類好後的結果給畫出來。代碼如下:
defcluster_plot(d, k): plt.rcParams['font.sans-serif']=['SimHei'] #正常顯示中文標籤 plt.rcParams['axes.unicode_minus'] = False#正常顯示負號 plt.figure(figsize=(8,3))for j in range(0,k): plt.plot(data[d==j],[j for i in d[d==j]],'o') plt.ylim(-0.5, k-0.5)return pltcluster_plot(d_result,k).show()
這裡呢,定義了一個函數cluster_plot的函數,返回一個畫好了cluster的pyplot。
繪製的結果見「03 效果分析」。
03
—
效果分析
下面這個圖就是聚類完成的結果圖。可以看出來,我們通過KMeans算法找到的幾個分界點將900多個數據給很好的分成了4類。
在沒聚類之前的原始數據是這樣的:
上面那個圖看著舒服多了。
在這篇文章中,我們用KMeans算法對數據進行聚類是非常簡單、粗暴的。並沒有指定距離的計算方法、初始的中心點、結束條件等,都是使用了sklearn.cluster中KMeans的默認值,如果需要更詳細的了解需要去看看sklearn的官方文檔。
04
—
小結
用Python做數據分析的感覺就是:做之前沒頭緒、做之後感覺挺簡單。