標籤:樣本 port 筆記 優勢 ++ each code output san
一、 什麼是聚類
聚類簡單的說就是要把一個文檔集合根據文檔的相似性把文檔分成若干類,但是究竟分成多少類,這個要取決於文檔集合裡文檔自身的性質。下面這個圖就是一個簡單的例子,我們可以把不同的文檔彙總為3類。另外聚類是典型的無指導學習,所謂無指導學習是指不需要有人幹預,無須人為文檔進行標註。
二、聚類演算法:from sklearn.cluster import KMeans
def __init__(self, n_clusters=8, init=‘k-means++‘, n_init=10, max_iter=300,tol=1e-4,precompute_distances=‘auto‘,verbose=0, random_state=None, copy_x=True, n_jobs=1):
(一)輸入參數:
(1)n_clusters:要分成的簇數也是要產生的質心數
類型:整數型(int)
預設值:8
n_clusters : int, optional, default: 8
The number of clusters to form aswell as the number of centroids to generate.
(2)init:初始化質心,
類型:可以是function 可以是array(random or ndarray)
預設值:採用k-means++(一種產生初始質心的演算法)
kmeans++:種子點選取的第二種方法。
kmedoids(PAM,PartitioningAround Medoids)
能夠解決kmeans對雜訊敏感的問題。kmeans尋找種子點的時候計算該類中所有樣本的平均值,如果該類中具有較為明顯的離群點,會造成種子點與期望偏差過大。例如,A(1,1),B(2,2),C(3,3),D(1000,1000),顯然D點會拉動種子點向其位移。這樣,在下一輪迭代時,將大量不該屬於該類的樣本點錯誤的劃入該類。
為瞭解決這個問題,kmedoids方法採取新的種子點選取方式,1)只從樣本點中選;2)選取標準能夠提高聚類效果,例如上述的最小化J函數,或者自訂其他的代價函數。但是,kmedoids方法提高了聚類的複雜度。
init : {‘k-means++‘, ‘random‘or an ndarray}
Methodfor initialization, defaults to ‘k-means++‘:
‘k-means++‘ : selects initial clustercenters for k-mean clustering in a smart way to speed up convergence. Seesection Notes in k_init for more details.
(3)n_init: 設定選擇質心種子次數,預設為10次。返回質心最好的一次結果(好是指計算時間長度短)
類型:整數型(int)
預設值:10
目的:每一次演算法運行時開始的centroid seeds是隨機產生的, 這樣得到的結果也可能有好有壞. 所以要運行演算法n_init次, 取其中最好的。
n_init : int,default: 10
Number of time the k-means algorithm will be run with different centroid seeds.The final results will be the best output of n_init consecutive runs in termsof inertia.
(4)max_iter:每次迭代的最大次數
類型:整型(int)
預設值:300
max_iter : int,default: 300
Maximum number of iterations of the k-means algorithm for a
single run.
(5)tol: 容忍的最小誤差,當誤差小於tol就會退出迭代(演算法中會依賴資料本身)
類型:浮點型(float)
預設值:le-4(0.0001)
Relativetolerance with regards to inertia to declare convergence
(6)precompute_distances: 這個參數會在空間和時間之間做權衡,如果是True 會把整個距離矩陣都放到記憶體中,auto 會預設在資料樣本大於featurs*samples 的數量大於12e6 的時候False,False時核心實現的方法是利用Cpython 來實現的
類型:布爾型(auto,True,False)
預設值:“auto”
Precomputedistances (faster but takes more memory).
‘auto‘ : do not precompute distances if n_samples * n_clusters > 12 million.This corresponds to about 100MB overhead per job usingdouble precision.
(7)verbose:是否輸出詳細資料
類型:布爾型(True,False)
預設值:False
verbose : boolean, optional
Verbositymode.
(8)random_state: 隨機產生器的種子 ,和初始化中心有關
類型:整型或numpy(RandomState, optional)
預設值:None
random_state :integer or numpy.RandomState, optional
The generator used to initialize the centers. If an integer is given, it fixesthe seed. Defaults to the global numpy random number generator.
(9)copy_x:bool 在scikit-learn 很多介面中都會有這個參數的,就是是否對輸入資料繼續copy 操作,以便不修改使用者的輸入資料。這個要理解Python 的記憶體機制才會比較清楚。
類型:布爾型(boolean,optional)
預設值:True
Whenpre-computing distances it is more numerically accurate to center the datafirst. If copy_x is True, then theoriginal data is not modified. If False,the original data is modified, and put back before the function returns, butsmall numerical differences may be introduced by subtracting and then addingthe data mean.
(10)n_jobs: 使用進程的數量,與電腦的CPU有關
類型:整數型(int)
預設值:1
The number of jobs to use for thecomputation. This works by computing
each of the n_init runs in parallel.
If -1 all CPUs are used. If 1 isgiven, no parallel computing code is used at all, which is useful for debugging.For n_jobs below -1,(n_cpus + 1 + n_jobs) are used. Thus for n_jobs = -2, allCPUs but one
are used.
(二)輸出參數:
(1)label_:每個樣本對應的簇類別標籤
樣本:r1 = pd.Series(model.labels_).value_counts() #統計各個類別的數目
(2)cluster_centers_:聚類中心
傳回值:array, [n_clusters, n_features]
樣本:r2 = pd.DataFrame(model.cluster_centers_) #找出聚類中心
使用樣本:
#-*- coding: utf-8 -*-#使用K-Means演算法聚類消費行為特徵資料import pandas as pd#參數初始化inputfile = ‘../data/consumption_data.xls‘ #銷量及其他屬性資料outputfile = ‘../tmp/data_type.xls‘ #儲存結果的檔案名稱k = 3 #聚類的類別iteration = 500 #聚類最大迴圈次數data = pd.read_excel(inputfile, index_col = ‘Id‘) #讀取資料data_zs = 1.0*(data - data.mean())/data.std() #資料標準化from sklearn.cluster import KMeansmodel = KMeans(n_clusters = k, n_jobs = 4, max_iter = iteration) #分為k類, 並發數4model.fit(data_zs) #開始聚類#簡單列印結果r1 = pd.Series(model.labels_).value_counts() #統計各個類別的數目r2 = pd.DataFrame(model.cluster_centers_) #找出聚類中心r = pd.concat([r2, r1], axis = 1) #橫向串連(0是縱向), 得到聚類中心對應的類別下的數目r.columns = list(data.columns) + [u‘類別數目‘] #重新命名表頭print(r)#詳細輸出未經處理資料及其類別r = pd.concat([data, pd.Series(model.labels_, index = data.index)], axis = 1) #詳細輸出每個樣本對應的類別r.columns = list(data.columns) + [u‘聚類類別‘] #重新命名表頭r.to_excel(outputfile) #儲存結果
三、群集演算法的評價
(一)實現目標:其目標是實現組內的對象相互之間是相似的(相關的),而不同組中的對象是不同的(不相關的)。組內的相似性越大,組間差別越大,聚類效果就越好。
(二)評價方法:
既然聚類是把一個包含若干文檔的文檔集合分成若干類,像如果聚類演算法應該把文檔集合分成3類,而不是2類或者5類,這就設計到一個如何評價聚類結果的問題。
認為x代表一類文檔,o代表一類文檔,方框代表一類文檔,完美的聚類顯然是應該把各種不同的圖形放入一類,事實上我們很難找到完美的聚類方法,各種方法在實際中難免有偏差,所以我們才需要對聚類演算法進行評價看我們採用的方法是不是好的演算法。
(1) purity評價法:
purity方法是極為簡單的一種聚類評價方法,只需計算正確聚類的文檔數佔總文檔數的比例:
其中Ω ={ω1,ω2, . . . ,ωK}是聚類的集合ωK表示第k個聚類的集合。C = {c1, c2, . . . , cJ}是文檔集合,cJ表示第J個文檔。N表示文檔總數。
如的purity =( 3+ 4 + 5) / 17 = 0.71
其中第一類正確的有5個,第二個4個,第三個3個,總文檔數17。
purity方法的優勢是方便計算,值在0~1之間,完全錯誤的聚類方法值為0,完全正確的方法值為1。同時,purity方法的缺點也很明顯它無法對退化的聚類方法給出正確的評價,設想如果聚類演算法把每篇文檔單獨聚成一類,那麼演算法認為所有文檔都被正確分類,那麼purity值為1!而這顯然不是想要的結果。
(2) RI評價法:
實際上這是一種用排列組合原理來對聚類進行評價的手段,公式如下:
其中TP是指被聚在一類的兩個文檔被正確分類了,TN是只不應該被聚在一類的兩個文檔被正確分開了,FP只不應該放在一類的文檔被錯誤的放在了一類,FN指不應該分開的文檔被錯誤的分開了。對
TP+FP = C(2,6) + C(2,6) +C(2,5) = 15 + 15 + 10 = 40
其中C(n,m)是指在m中任選n個的組合數。
TP = C(2,5) + C(2,4) + C(2,3)+ C(2,2) = 20
FP = 40 - 20 = 20
同理:
TN+FN= C(1,6) * C(1,6)+C(1,6)* C(1,5) + C(1,6)* C(1,5)=96
FN= C(1,5) * C(1,3)+ C(1,1)*C(1,4) + C(1,1)* C(1,3)+ C(1,1)* C(1,2)=24
TN=96-24=72
所以RI = ( 20 + 72) / ( 20 + 20 + 72 +24) = 0.68
(三):F值評價法
這是基於上述RI方法衍生出的一個方法,
註:p是查全率,R是查准率,當β>1時查全率更有影響,當β<1時查准率更有影響,當β=1時退化為標準的F1,詳細查閱機器學習P30
RI方法有個特點就是把準確率和召回率看得同等重要,事實上有時候我們可能需要某一特性更多一點,這時候就適合F值方法
Precision=TP/(TP+FP)
Recall=TP/(TP+FN)
F1=2×Recall×Precision/(Recall+Precision)
Precision=20/40=0.5
Recall=20/44=0.455
F1=(2*0.5*0.455)/(0.5+0.455)=0.48
四、群集結果的降維可視化—TSNE
我們總喜歡能夠直觀地展示研究結果,聚類也不例外。然而,通常來說輸入的特徵數是高維的(大於3維),一般難以直接以原特徵對聚類結果進行展示。而TSNE提供了一種有效資料降維方式,讓我們可以在2維或者3維的空間中展示聚類結果。
範例程式碼:接上文範例程式碼
#-*- coding: utf-8 -*-#接k_means.pyfrom sklearn.manifold import TSNEtsne = TSNE()tsne.fit_transform(data_zs) #進行資料降維tsne = pd.DataFrame(tsne.embedding_, index = data_zs.index) #轉換資料格式import matplotlib.pyplot as pltplt.rcParams[‘font.sans-serif‘] = [‘SimHei‘] #用來正常顯示中文標籤plt.rcParams[‘axes.unicode_minus‘] = False #用來正常顯示負號#不同類別用不同顏色和樣式繪圖d = tsne[r[u‘聚類類別‘] == 0]plt.plot(d[0], d[1], ‘r.‘)d = tsne[r[u‘聚類類別‘] == 1]plt.plot(d[0], d[1], ‘go‘)d = tsne[r[u‘聚類類別‘] == 2]plt.plot(d[0], d[1], ‘b*‘)plt.show()
:
資料來源:《Python機器學習實戰》 《Python資料採礦實戰》
Python—kmeans演算法學習筆記