【Python資料探勘課程】三.Kmeans聚類程式碼實現、作業及優化
一. 案例實現
這裡不再贅述,詳見第二篇文章,直接上程式碼,這是我的學生完成的作業。
資料集:
下載地址:KEEL-dataset - Basketball data set
籃球運動員資料,每分鐘助攻和每分鐘得分數。通過該資料集判斷一個籃球運動員屬於什麼位置(控位、分位、中鋒等)。
完整程式碼:assists_per_minute height time_played age points_per_minute 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 5 0.1671 201 34.10 31 0.5835 6 0.1906 193 36.20 30 0.5276 7 0.1061 191 36.75 27 0.5523 8 0.2446 185 38.43 29 0.4007 9 0.1670 203 33.54 24 0.4770 10 0.2485 188 35.01 27 0.4313 11 0.1227 198 36.67 29 0.4909 12 0.1240 185 33.88 24 0.5668 13 0.1461 191 35.59 30 0.5113 14 0.2315 191 38.01 28 0.3788 15 0.0494 193 32.38 32 0.5590 16 0.1107 196 35.22 25 0.4799 17 0.2521 183 31.73 29 0.5735 18 0.1007 193 28.81 34 0.6318 19 0.1067 196 35.60 23 0.4326 20 0.1956 188 35.28 32 0.4280
# -*- coding: utf-8 -*- from sklearn.cluster import Birch from sklearn.cluster import KMeans X = [[0.0888, 0.5885], [0.1399, 0.8291], [0.0747, 0.4974], [0.0983, 0.5772], [0.1276, 0.5703], [0.1671, 0.5835], [0.1906, 0.5276], [0.1061, 0.5523], [0.2446, 0.4007], [0.1670, 0.4770], [0.2485, 0.4313], [0.1227, 0.4909], [0.1240, 0.5668], [0.1461, 0.5113], [0.2315, 0.3788], [0.0494, 0.5590], [0.1107, 0.4799], [0.2521, 0.5735], [0.1007, 0.6318], [0.1067, 0.4326], [0.1956, 0.4280] ] print X # Kmeans聚類 clf = KMeans(n_clusters=3) y_pred = clf.fit_predict(X) print(clf) print(y_pred) import numpy as np import matplotlib.pyplot as plt x = [n[0] for n in X] print x y = [n[1] for n in X] print y # 視覺化操作 plt.scatter(x, y, c=y_pred, marker='x') plt.title("Kmeans-Basketball Data") plt.xlabel("assists_per_minute") plt.ylabel("points_per_minute") plt.legend(["Rank"]) plt.show()
執行結果:
從圖中可以看到聚整合三類,紅色比較厲害,得分很高;中間藍色是一類,普通球員;右小角綠色是一類,助攻高得分低,是控位。
程式碼分析:
from sklearn.cluster import KMeans
表示在sklearn中處理kmeans聚類問題,用到 sklearn.cluster.KMeans 這個類。X = [[164,62],[156,50],...]
X是資料集,包括2列20行,即20個球員的助攻數和得分數。clf = KMeans(n_clusters=3)
表示輸出完整Kmeans函式,包括很多省略引數,將資料集分成類簇數為3的聚類。y_pred =clf.fit_predict(X)
輸出聚類預測結果,對X聚類,20行資料,每個y_pred對應X的一行或一個孩子,聚成3類,類標為0、1、2。print(y_pred)
輸出結果:[0 2 0 0 0 0 0 0 1 0 1 0 0 0 1 0 0 0 0 0 1]import matplotlib.pyplot as plt
matplotlib.pyplot是用來畫圖的方法,matplotlib是視覺化包。x = [n[0] for n in X]
y = [n[1] for n in X]
獲取第1列的值, 使用for迴圈獲取 ,n[0]表示X第一列。獲取第2列的值,使用for迴圈獲取 ,n[1]表示X第2列。
plt.scatter(x, y, c=y_pred, marker='o')
繪製散點圖(scatter),橫軸為x,獲取的第1列資料;縱軸為y,獲取的第2列資料;c=y_pred對聚類的預測結果畫出散點圖,marker='o'說明用點表示圖形。plt.title("Kmeans-Basketball Data")
表示圖形的標題為Kmeans-heightweight Data。plt.xlabel("assists_per_minute")
表示圖形x軸的標題。plt.ylabel("points_per_minute")
表示圖形y軸的標題。plt.legend(["Rank"])
設定右上角圖例。plt.show()
表示顯示圖形。二. 學生圖例
下面簡單展示學生做的作業及分析,感覺還是不錯,畢竟才上幾節課而且第一次作業,希望後面的作業更加精彩吧。因為學生的專業分佈不同,所以儘量讓學生設計他們專業的內容。
eg 遺傳學身高體重資料
第一列表示孩子的身高,單位cm;第二列表示孩子的體重,單位kg。從上圖可以看出,資料集被分為了三類。綠色為一類、藍色為一類,紅色為一類。
eg 微博資料集
第一列代表微博中某條資訊的轉發量,第二列代表微博中某條資訊的評論數。從上圖可以看出,總共分為3類,共三種顏色,綠色一層說明該資訊轉發量與評論數都很高。
eg 上市公司財務報表
第一列表示公司利潤率;第二列表示公司資產規模。從上圖可以看出,總共分為4類,共四種顏色。暗紅色為資產規模最大,依次至藍色資產規模減小。
eg 世界各國家人均面積與土地面積
第一列表示各國家的人均面積(人/ 平方公里);第二列表示各國家的土地面積(萬平方公里)。從上圖可以看出,總共分為3類,共三種顏色。紅色表示的國家相對來說最擁擠,可能是孟加拉這樣土地面積少且人口眾多的國家;藍色就是地廣人稀的代表,比如俄羅斯、美國、、墨西哥、巴西;綠色表示人口密度分佈比較平均的國家。
eg employee salaries資料集
第一列表示員工工資;第二列表示員工年齡數。從上圖可以看出,總共分為5類,共5種顏色。總體呈現正相關性,年齡越大,工資越高;除個別外,總體正線性關係。
eg 學生英語成績資料集
第一列表示學生英語平時成績;第二列表示學生英語期末成績。從上圖可以看出,總共分為4類,共四種顏色。黃色一層,平時成績和末考成績都很高,屬於“學霸”級別的人物;其次,藍色一層和紅色一層;最後,天藍色一層,暫且稱之為“學渣”。
三. Matplotlib繪圖優化
Matplotlib程式碼的優化:
1.第一部分程式碼是定義X陣列,實際中是讀取檔案進行的,如何實現讀取檔案中資料再轉換為矩陣進行聚類呢?
2.第二部分是繪製圖形,希望繪製不同的顏色及型別,使用legend()繪製圖標。
假設存在資料集如下圖所示:data.txt
資料集包括96個運動員的資料,源自:KEEL-dataset - Basketball data set
現需要獲取第一列每分鐘助攻數、第五列每分鐘得分數存於矩陣中。
0.0888 201 36.02 28 0.5885
0.1399 198 39.32 30 0.8291
0.0747 198 38.8 26 0.4974
0.0983 191 40.71 30 0.5772
0.1276 196 38.4 28 0.5703
0.1671 201 34.1 31 0.5835
0.1906 193 36.2 30 0.5276
0.1061 191 36.75 27 0.5523
0.2446 185 38.43 29 0.4007
0.167 203 33.54 24 0.477
0.2485 188 35.01 27 0.4313
0.1227 198 36.67 29 0.4909
0.124 185 33.88 24 0.5668
0.1461 191 35.59 30 0.5113
0.2315 191 38.01 28 0.3788
0.0494 193 32.38 32 0.559
0.1107 196 35.22 25 0.4799
0.2521 183 31.73 29 0.5735
0.1007 193 28.81 34 0.6318
0.1067 196 35.6 23 0.4326
0.1956 188 35.28 32 0.428
0.1828 191 29.54 28 0.4401
0.1627 196 31.35 28 0.5581
0.1403 198 33.5 23 0.4866
0.1563 193 34.56 32 0.5267
0.2681 183 39.53 27 0.5439
0.1236 196 26.7 34 0.4419
0.13 188 30.77 26 0.3998
0.0896 198 25.67 30 0.4325
0.2071 178 36.22 30 0.4086
0.2244 185 36.55 23 0.4624
0.3437 185 34.91 31 0.4325
0.1058 191 28.35 28 0.4903
0.2326 185 33.53 27 0.4802
0.1577 193 31.07 25 0.4345
0.2327 185 36.52 32 0.4819
0.1256 196 27.87 29 0.6244
0.107 198 24.31 34 0.3991
0.1343 193 31.26 28 0.4414
0.0586 196 22.18 23 0.4013
0.2383 185 35.25 26 0.3801
0.1006 198 22.87 30 0.3498
0.2164 193 24.49 32 0.3185
0.1485 198 23.57 27 0.3097
0.227 191 31.72 27 0.4319
0.1649 188 27.9 25 0.3799
0.1188 191 22.74 24 0.4091
0.194 193 20.62 27 0.3588
0.2495 185 30.46 25 0.4727
0.2378 185 32.38 27 0.3212
0.1592 191 25.75 31 0.3418
0.2069 170 33.84 30 0.4285
0.2084 185 27.83 25 0.3917
0.0877 193 21.67 26 0.5769
0.101 193 21.79 24 0.4773
0.0942 201 20.17 26 0.4512
0.055 193 29.07 31 0.3096
0.1071 196 24.28 24 0.3089
0.0728 193 19.24 27 0.4573
0.2771 180 27.07 28 0.3214
0.0528 196 18.95 22 0.5437
0.213 188 21.59 30 0.4121
0.1356 193 13.27 31 0.2185
0.1043 196 16.3 23 0.3313
0.113 191 23.01 25 0.3302
0.1477 196 20.31 31 0.4677
0.1317 188 17.46 33 0.2406
0.2187 191 21.95 28 0.3007
0.2127 188 14.57 37 0.2471
0.2547 160 34.55 28 0.2894
0.1591 191 22.0 24 0.3682
0.0898 196 13.37 34 0.389
0.2146 188 20.51 24 0.512
0.1871 183 19.78 28 0.4449
0.1528 191 16.36 33 0.4035
0.156 191 16.03 23 0.2683
0.2348 188 24.27 26 0.2719
0.1623 180 18.49 28 0.3408
0.1239 180 17.76 26 0.4393
0.2178 185 13.31 25 0.3004
0.1608 185 17.41 26 0.3503
0.0805 193 13.67 25 0.4388
0.1776 193 17.46 27 0.2578
0.1668 185 14.38 35 0.2989
0.1072 188 12.12 31 0.4455
0.1821 185 12.63 25 0.3087
0.188 180 12.24 30 0.3678
0.1167 196 12.0 24 0.3667
0.2617 185 24.46 27 0.3189
0.1994 188 20.06 27 0.4187
0.1706 170 17.0 25 0.5059
0.1554 183 11.58 24 0.3195
0.2282 185 10.08 24 0.2381
0.1778 185 18.56 23 0.2802
0.1863 185 11.81 23 0.381
0.1014 193 13.81 32 0.1593
程式碼如下:# -*- coding: utf-8 -*-
"""
By: Eastmount CSDN 2016-10-12
該部分講資料集讀取,然後賦值給X變數
讀取檔案data.txt 儲存結果為X
"""
import os
data = []
for line in open("data.txt", "r").readlines():
line = line.rstrip() #刪除換行
#刪除多餘空格,儲存一個空格連線
result = ' '.join(line.split())
#獲取每行五個值 '0 0.0888 201 36.02 28 0.5885' 注意:字串轉換為浮點型數
s = [float(x) for x in result.strip().split(' ')]
#輸出結果:['0', '0.0888', '201', '36.02', '28', '0.5885']
print s
#資料儲存至data
data.append(s)
#輸出完整資料集
print u'完整資料集'
print data
print type(data)
'''
現在輸出資料集:
['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'
]
'''
print u'第一列 第五列資料'
L2 = [n[0] for n in data]
print L2
L5 = [n[4] for n in data]
print L5
'''
X表示二維矩陣資料,籃球運動員比賽資料
總共96行,每行獲取兩列資料
第一列表示球員每分鐘助攻數:assists_per_minute
第五列表示球員每分鐘得分數:points_per_minute
'''
#兩列資料生成二維資料
print u'兩列資料合併成二維矩陣'
T = dict(zip(L2,L5))
type(T)
#dict型別轉換為list
print u'List'
X = list(map(lambda x,y: (x,y), T.keys(),T.values()))
print X
print type(X)
"""
KMeans聚類
clf = KMeans(n_clusters=3) 表示類簇數為3,聚成3類資料,clf即賦值為KMeans
y_pred = clf.fit_predict(X) 載入資料集X,並且將聚類的結果賦值給y_pred
"""
from sklearn.cluster import Birch
from sklearn.cluster import KMeans
clf = KMeans(n_clusters=3)
y_pred = clf.fit_predict(X)
print(clf)
#輸出聚類預測結果,96行資料,每個y_pred對應X一行或一個球員,聚成3類,類標為0、1、2
print(y_pred)
"""
視覺化繪圖
Python匯入Matplotlib包,專門用於繪圖
import matplotlib.pyplot as plt 此處as相當於重新命名,plt用於顯示影象
"""
import numpy as np
import matplotlib.pyplot as plt
#獲取第一列和第二列資料 使用for迴圈獲取 n[0]表示X第一列
x = [n[0] for n in X]
print x
y = [n[1] for n in X]
print y
#繪製散點圖 引數:x橫軸 y縱軸 c=y_pred聚類預測結果 marker型別 o表示圓點 *表示星型 x表示點
#plt.scatter(x, y, c=y_pred, marker='x')
#座標
x1 = []
y1 = []
x2 = []
y2 = []
x3 = []
y3 = []
#分佈獲取類標為0、1、2的資料 賦值給(x1,y1) (x2,y2) (x3,y3)
i = 0
while i < len(X):
if y_pred[i]==0:
x1.append(X[i][0])
y1.append(X[i][1])
elif y_pred[i]==1:
x2.append(X[i][0])
y2.append(X[i][1])
elif y_pred[i]==2:
x3.append(X[i][0])
y3.append(X[i][1])
i = i + 1
#四種顏色 紅 綠 藍 黑
plot1, = plt.plot(x1, y1, 'or', marker="x")
plot2, = plt.plot(x2, y2, 'og', marker="o")
plot3, = plt.plot(x3, y3, 'ob', marker="*")
#繪製標題
plt.title("Kmeans-Basketball Data")
#繪製x軸和y軸座標
plt.xlabel("assists_per_minute")
plt.ylabel("points_per_minute")
#設定右上角圖例
plt.legend((plot1, plot2, plot3), ('A', 'B', 'C'), fontsize=10)
plt.show()
輸出結果如下圖所示:三個層次很明顯,而且右上角也標註。四. Spyder常見問題
下面是常見遇到的幾個問題:
1.Spyder軟體如果Editor編輯框不在,如何調出來。
2.會缺少一些第三方包,如lda,如何匯入。使用cd ..去到C盤根目錄,cd去到Anaconda的Scripts目錄下,輸入"pip install selenium"安裝selenium相應的包,"pip install lda"安裝lda包。
學生告訴我另一個更方便的方法:
3.執行時報錯,缺少Console,點選如下。
4.如果Spyder安裝點選沒有反應,重新安裝也沒有反應,建議在執行下試試。
實在不行解除安裝再重灌:pip uninstall spyder
pip install spyder
5.Spyder如何顯示繪製Matplotlib中文。
from matplotlib.font_manager import FontProperties
font = FontProperties(fname="C:\Windows\Fonts/msyh.ttf", size=10)
#繪製標題 fontproperties表示字型型別,用於顯示中文字元,下同
plt.title(u'世界各國家人均面積與土地面積',fontproperties=font)
#繪製x軸和y軸座標
plt.ylabel(u'人均面積(人/ 平方公里)',fontproperties=font)
plt.xlabel(u'面積(萬平方公里)',fontproperties=font)