您好,登錄后才能下訂單哦!
這篇文章將為大家詳細(xì)講解有關(guān)Python中k均值聚類(lèi)的示例分析,小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考,希望大家閱讀完這篇文章后可以有所收獲。
一.k-means算法
人以類(lèi)聚,物以群分,k-means聚類(lèi)算法就是體現(xiàn)。數(shù)學(xué)公式不要,直接用白話描述的步驟就是:
1.隨機(jī)選取k個(gè)質(zhì)心(k值取決于你想聚成幾類(lèi))
2.計(jì)算樣本到質(zhì)心的距離,距離質(zhì)心距離近的歸為一類(lèi),分為k類(lèi)
3.求出分類(lèi)后的每類(lèi)的新質(zhì)心
4.判斷新舊質(zhì)心是否相同,如果相同就代表已經(jīng)聚類(lèi)成功,如果沒(méi)有就循環(huán)2-3直到相同
用程序的語(yǔ)言描述就是:
1.輸入樣本
2.隨機(jī)去k個(gè)質(zhì)心
3.重復(fù)下面過(guò)程知道算法收斂:
計(jì)算樣本到質(zhì)心距離(歐幾里得距離)
樣本距離哪個(gè)質(zhì)心近,就記為那一類(lèi)
計(jì)算每個(gè)類(lèi)別的新質(zhì)心(平均值)
二.需求分析
數(shù)據(jù)來(lái)源:從國(guó)際統(tǒng)計(jì)局down的數(shù)據(jù),數(shù)據(jù)為城鄉(xiāng)居民家庭人均收入及恩格爾系數(shù)(點(diǎn)擊這里下載)
數(shù)據(jù)描述:
1.橫軸:城鎮(zhèn)居民家庭人均可支配收入和農(nóng)村居民家庭人均純收入,
2.縱軸:1996-2012年。
3.數(shù)據(jù)為年度數(shù)據(jù)
需求說(shuō)明:我想把這數(shù)據(jù)做個(gè)聚類(lèi)分析,看人民的收入大概經(jīng)歷幾個(gè)階段(感覺(jué)我好高大上啊)
需求分析:
1.由于樣本數(shù)據(jù)有限,就兩列,用k-means聚類(lèi)有很大的準(zhǔn)確性
2.用文本的形式導(dǎo)入數(shù)據(jù),結(jié)果輸出聚類(lèi)后的質(zhì)心,這樣就能看出人民的收入經(jīng)歷了哪幾個(gè)階段
三.Python實(shí)現(xiàn)
引入numpy模塊,借用其中的一些方法進(jìn)行數(shù)據(jù)處理,上代碼:
# -*- coding=utf-8 -*- """ authon:xuwf created:2017-02-07 purpose:實(shí)現(xiàn)k-means算法 """ import numpy as np import random '''裝載數(shù)據(jù)''' def load(): data=np.loadtxt('data\k-means.csv',delimiter=',') return data '''計(jì)算距離''' def calcDis(data,clu,k): clalist=[] #存放計(jì)算距離后的list data=data.tolist() #轉(zhuǎn)化為列表 clu=clu.tolist() for i in range(len(data)): clalist.append([]) for j in range(k): dist=round(((data[i][1]-clu[j][0])**2+(data[i][2]-clu[j][1])**2)*0.05,1) clalist[i].append(dist) clalist=np.array(clalist) #轉(zhuǎn)化為數(shù)組 return clalist '''分組''' def group(data,clalist,k): grouplist=[] #存放分組后的集群 claList=clalist.tolist() data=data.tolist() for i in range(k): #確定要分組的個(gè)數(shù),以空列表的形式,方便下面進(jìn)行數(shù)據(jù)的插入 grouplist.append([]) for j in range(len(clalist)): sortNum=np.argsort(clalist[j]) grouplist[sortNum[0]].append(data[j][1:]) grouplist=np.array(grouplist) return grouplist '''計(jì)算質(zhì)心''' def calcCen(data,grouplist,k): clunew=[] data=data.tolist() grouplist=grouplist.tolist() templist=[] #templist=np.array(templist) for i in range(k): #計(jì)算每個(gè)組的新質(zhì)心 sumx=0 sumy=0 for j in range(len(grouplist[i])): sumx+=grouplist[i][j][0] sumy+=grouplist[i][j][1] clunew.append([round(sumx/len(grouplist[i]),1),round(sumy/len(grouplist[i]),1)]) clunew=np.array(clunew) #clunew=np.mean(grouplist,axis=1) return clunew '''優(yōu)化質(zhì)心''' def classify(data,clu,k): clalist=calcDis(data,clu,k) #計(jì)算樣本到質(zhì)心的距離 grouplist=group(data,clalist,k) #分組 for i in range(k): #替換空值 if grouplist[i]==[]: grouplist[i]=[4838.9,1926.1] clunew=calcCen(data,grouplist,k) sse=clunew-clu #print "the clu is :%r\nthe group is :%r\nthe clunew is :%r\nthe sse is :%r" %(clu,grouplist,clunew,sse) return sse,clunew,data,k if __name__=='__main__': k=3 #給出要分類(lèi)的個(gè)數(shù)的k值 data=load() #裝載數(shù)據(jù) clu=random.sample(data[:,1:].tolist(),k) #隨機(jī)取質(zhì)心 clu=np.array(clu) sse,clunew,data,k=classify(data,clu,k) while np.any(sse!=0): sse,clunew,data,k=classify(data,clunew,k) clunew=np.sort(clunew,axis=0) print "the best cluster is %r" %clunew
四.測(cè)試
直接運(yùn)行程序就可以,k值可以自己設(shè)置,會(huì)發(fā)現(xiàn)k=3的時(shí)候結(jié)果數(shù)據(jù)是最穩(wěn)定的,這里我就不貼圖了
需要注意的是上面的代碼里面主函數(shù)里的數(shù)據(jù)結(jié)構(gòu)都是array,但是在每個(gè)小函數(shù)里就有可能轉(zhuǎn)化成了list,主要原因是需要進(jìn)行array的一下方法進(jìn)行計(jì)算,而轉(zhuǎn)化為list的原因是需要向數(shù)組中插入數(shù)據(jù),但是array做不到?。ㄖ辽傥覜](méi)找到怎么做)。于是這里就出現(xiàn)了一個(gè)問(wèn)題,那就是數(shù)據(jù)結(jié)構(gòu)混亂,到最后我調(diào)試了半天,干脆將主函數(shù)的數(shù)據(jù)結(jié)構(gòu)都轉(zhuǎn)化成array,在小函數(shù)中輸入的array,輸出的時(shí)候也轉(zhuǎn)化成了array,這樣就清晰多了
五.算法分析
單看這個(gè)算法還是較好理解的,但是算法的目的是聚類(lèi),那就要考慮到聚類(lèi)的準(zhǔn)確性,這里聚類(lèi)的準(zhǔn)確性取決于k值、初始質(zhì)心和距離的計(jì)算方式。
k值就要看個(gè)人經(jīng)驗(yàn)和多次試驗(yàn)了,算法結(jié)果在哪個(gè)k值的時(shí)候更穩(wěn)定就證明這個(gè)分類(lèi)更加具有可信度,其中算法結(jié)果的穩(wěn)定也取決于初始質(zhì)心的選擇
初始質(zhì)心一般都是隨機(jī)選取的,怎么更準(zhǔn)確的選擇初始質(zhì)心呢?有種較難實(shí)現(xiàn)的方法是將樣本中所有點(diǎn)組合起來(lái)都取一遍,然后計(jì)算算法收斂后的所有質(zhì)心到樣本的距離之和,哪個(gè)距離最小,哪個(gè)的聚類(lèi)就最為成功,相對(duì)應(yīng)的初始質(zhì)心就選取的最為準(zhǔn)確。但是這種方法有很大的計(jì)算量,如果樣本很大,維度很多,那就是讓電腦干到死的節(jié)奏
距離的計(jì)算方式取決于樣本的特征,有很多的選擇,入歐式距離,夾角余弦距離,曼哈頓距離等,具體的數(shù)據(jù)特性用具體的距離計(jì)算方式
六.項(xiàng)目評(píng)測(cè)
1.項(xiàng)目總結(jié)數(shù)據(jù)源的數(shù)據(jù)很干凈,不需要進(jìn)行過(guò)多的數(shù)據(jù)清洗和數(shù)據(jù)降噪,數(shù)據(jù)預(yù)處理的工作成本接近為0。需求基本實(shí)現(xiàn)
2.還能做什么:可以用計(jì)算最小距離之和的方法求出最佳k值,這樣就可以得到穩(wěn)定的收入階梯;可以引入畫(huà)圖模塊,將數(shù)據(jù)結(jié)果進(jìn)行數(shù)據(jù)可視化,顯得更加直觀;如果可能應(yīng)該引入更多的維度或更多的數(shù)據(jù),這樣得到的聚類(lèi)才更有說(shuō)服力。
關(guān)于“Python中k均值聚類(lèi)的示例分析”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,使各位可以學(xué)到更多知識(shí),如果覺(jué)得文章不錯(cuò),請(qǐng)把它分享出去讓更多的人看到。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。