1. 程式人生 > >k-means k均值聚類 及二分k均值聚類

k-means k均值聚類 及二分k均值聚類

from numpy import *
def load_data(file_name):
    data=[]
    fr=open(file_name)
    for line in fr.readlines():
        cur_line=line.strip().split('\t')
        flt_line=map(float,cur_line)
        data.append(flt_line)
    return data
def distance(a,b):
    '''計算倆向量的歐式距離'''
    return sqrt(sum(power(a-b,2)))
def rand_cent(data,k):
    n=shape(data)[1]
    #n資料的列數
    centroids=mat(zeros((k,n)))
    #初始質點矩陣,k為質點數
    for j in range(n):
        min_j=min(data[:,j])
        #選出第j列中最小的數
        range_j=float(max(data[:,j])-min_j)
        #用j列中最大的減去最小的
        centroids[:,j]=min_j+range_j*random.rand(k,1)
        #獲得隨機質點,質點在資料範圍之內
    return centroids
def k_means(data,k,distance=distance,create_cent=rand_cent):
    '''k均值聚類演算法'''
    m=shape(data)[0]
    cluster_assment=mat(zeros((m,2)))
    #cluster_assment第一列為質點,第二列為距離
    centroids=create_cent(data,k)
    cluster_changed=True
    while cluster_changed:
        cluster_changed=False
        
        for i in range(m):
            min_distance=inf;min_index=-1
            #初始最小距離為正無窮,最小索引為-1
            for j in range(k):
                #j 相當於質點腳標
                #k為4 ,則就有4個質點,j就是每個質點的腳標
                dist_ji=distance(centroids[j,:],data[i,:])
                #計算每個隨機質點與各資料的距離
                if dist_ji<min_distance:
                    #若隨機質點與資料的距離 ji 小於最小距離,則最小距離就繼承ji
                    #最小索引為j
                    min_distance=dist_ji;min_index=j
            if cluster_assment[i,0]!=min_index:cluster_changed=True
            #cluster_assment 第i行第1個值是質點的腳標,就是這行資料屬於哪個質點往哪聚
            #若這行資料的質點不等於上面得出的質點,則 cluster_changed為真\
            #這個while還要在迴圈一下,迴圈到判斷不成立為止
            cluster_assment[i,:]=min_index,min_distance**2
            #讓第i行資料的質點等於上面得到的質點,第二個引數是距離的平方
        print centroids
        #質點是在變換的
        for cent in range(k):
            pts_in_clust=data[nonzero(cluster_assment[:,0].A==cent)[0]]
            #pts_in_clust是資料中質點等於cent且非零的那一行元素所構成的矩陣
            centroids[cent,:]=mean(pts_in_clust,axis=0)
            #更新質點為(x,y);x=pts_in_clust第一列的平均數;y=pts_in_clust第二列的平均數
            #這一步也就是k均值聚類的核心,所謂的均值
            #就是說質點是接近於這一類資料的平均數,想想圓心就明白了
            #各資料到質點的距離要短,每一叢集的點都是到這一質點距離最短的點
    return centroids,cluster_assment
def bisection_kmeans(data,k):
    '''二分k-均值聚類演算法'''
    m=shape(data)[0]
    cluster_assment=mat(zeros((m,2)))
    #初始聚類估值矩陣
    centroid0=mean(data,axis=0).tolist()[0]
    #初始質點為所有資料的平均數.僅一個點
    #資料有兩列,正好兩個平均值構成一個二維點
    #tolist()轉換成列表
    cent_list=[centroid0]
    #質點列表
    for j in range(m):
        #各資料點到預估質點的歐式距離的平方
        #平方是為了拉開差距,有利於二分。使小於1的越小,大於1的越大
        cluster_assment[j,1]=distance(mat(centroid0),data[j,:])**2
    while (len(cent_list)<k):
        #不應該自定義k
        lowest_sse=inf
        #最低sse
        #sse誤差平方和
        for i in range(len(cent_list)):
            pts_in_curr_cluster=data[nonzero(cluster_assment[:,0].A==i)[0],:]
            #取出非零下預估的質點為i的資料
            centroid_mat,split_clust_ass=k_means(pts_in_curr_cluster,2,distance)
            #再根據k均值聚類法把上面取出的資料再分下,k設為2就是為了二分
            #因為是二分所以centroid_mat有兩個質點
            sse_after_split=sum(split_clust_ass[:,1])
            #劃分後sse
            #split_clust_ass[:,1]這一列是各資料點到各自質點的距離
            #怎麼才是最佳聚類,就是讓這個所有的距離和最小
            #以每個資料點為質點距離和為0,但就不是聚類的
            #所以最佳的聚類是要質點的數量與距離和之間的平衡點
            sse_before_split=sum(cluster_assment[nonzero(cluster_assment[:,0].A!=i)[0],1])
            #劃分前sse
            #取出估值中質點不等於i的距離值,然後求和
            print 'sse after and before split',sse_after_split,sse_before_split
            if (sse_after_split+sse_before_split)<lowest_sse:
                #以此來判斷是否需要再分下去
                #若劃分前後的資料sse之和小於最低sse
                #則更新最佳劃分質點,最佳質點矩陣,最佳預估結果,最低sse
                best_cent_to_split=i
                best_new_cents=centroid_mat.tolist()
                best_clust_ass=split_clust_ass.copy()
                lowest_sse=sse_after_split+sse_before_split
        best_clust_ass[nonzero(best_clust_ass[:,0].A==1)[0],0]=len(cent_list)
        #最佳預估結果的中質點等於1的更改為質點len(cent_list)
        #因為質點列表程增長狀態(二分法)
        best_clust_ass[nonzero(best_clust_ass[:,0].A==0)[0],0]=best_cent_to_split
        #最佳預估結果中質點等於0 的更改為上面得出的最佳質點,因為0是預設值
        print 'the best_cent_to_split is :',best_cent_to_split
        print 'the len of best_clust_ass is :',len(best_clust_ass)
        cent_list[best_cent_to_split]=best_new_cents[0]
        #更新質點列表
        cent_list.append(best_new_cents[1])
        cluster_assment[nonzero(cluster_assment[:,0].A==best_cent_to_split)[0],:]=best_clust_ass
    return cent_list,cluster_assment
def test():
    data=load_data('testSet2.txt')
    data=mat(data)
    cent,clus=k_means(data,3)
    cent_list,cluster_assment=bisection_kmeans(data,3)
    s= mat(cent_list)
    #print s
    #print 'centroids',cent
   # print 'cluster',clus
    import matplotlib.pyplot as plt
    fig=plt.figure()
    ax=fig.add_subplot(111)
    x=[float(i) for i in data[:,0]]
    y=[float(i) for i in data[:,1]]
    ax.scatter(x,y)   
    x1=s[:,0]
    y1=s[:,-1]
    #print x1,y1
    x2=cent[:,0]
    y2=cent[:,1]
    ax.plot(x1,y1,'+',c='red')
    ax.plot(x2,y2,'*',c='green')
    plt.show()    
test()

圖中紅色十字為二分法為質點,綠星味均值法質點。兩者能得到相同的結果。


樣本資料:

3.2751542.957587
-3.3444652.603513
0.355083-3.376585
1.8524353.547351
-2.0789732.552013
-0.993756-0.884433
2.6822524.007573
-3.0877762.878713
-1.565978-1.256985
2.4416110.444826
-0.6594873.111284
-0.459601-2.618005
2.1776802.387793
-2.9209692.917485
-0.028814-4.168078
3.6257462.119041
-3.9123631.325108
-0.551694-2.814223
2.8558083.483301
-3.5944482.856651
0.421993-2.372646
1.6508213.407572
-2.0829023.384412
-0.718809-2.492514
4.5136233.841029
-4.8220114.607049
-0.656297-1.449872
1.9199014.439368
-3.2877493.918836
-1.576936-2.977622
3.5981431.975970
-3.9773294.900932
-1.791080-2.184517
3.9146543.559303
-1.9101084.166946
-1.226597-3.317889
1.1489463.345138
-2.1138643.548172
0.845762-3.589788
2.6290623.535831
-1.6407172.990517
-1.881012-2.485405
4.6069993.510312
-4.3664624.023316
0.765015-3.001270
3.1219042.173988
-4.0251394.652310
-0.559558-3.840539
4.3767544.863579
-1.8743084.032237
-0.089337-3.026809
3.9977872.518662
-3.0829782.884822
0.845235-3.454465
1.3272243.358778
-2.8899493.596178
-0.966018-2.839827
2.9607693.079555
-3.2755181.577068
0.639276-3.412840

相關推薦

k-means k均值 二分k均值

from numpy import * def load_data(file_name): data=[] fr=open(file_name) for line in fr.readlines(): cur_line=line.st

機器學習實戰:K-均值二分K-均值演算法

# coding=utf-8 ''' Created on Feb 16, 2011 k Means Clustering for Ch10 of Machine Learning in Action #@author: Peter Harrington ''' from

K-means演算法(將表中的點分為n

客戶分類: 1、將客戶分為三類:超級VIP、vip、普通使用者 2、需要你將不同的類的資料,在圖上顯示出來,用不同的顏色 3、返回三個類中,各包含哪些點 資料在下面的的表中,因為無法上傳表格所以截了個圖! import matplotlib.pyplot as plt

K-MEANS演算法的工作原理流程

K-MEANS演算法:輸入:聚類個數k,以及包含 n個數據物件的資料庫。輸出:滿足方差最小標準的k個聚類。處理流程:        (1)  從 n個數據物件任意選擇 k 個物件作為初始聚類中心;(2)  迴圈(3)到(4)直到每個聚類不再發生變化為止(3)  根據每個聚類物件的均值(中心物件),計算每個物件

C#修改MAC地址操作網絡卡

using System; using System.Collections.Generic; using System.Linq; using System.Text; using Microsoft.Win32; using System.Net.NetworkInformation; using S

k-means(k均值)演算法介紹實現(c++)

基本介紹: k-means 演算法接受輸入量 k ;然後將n個數據物件劃分為 k個聚類以便使得所獲得的聚類滿足:同一聚類中的物件相似度較高;而不同聚類中的物件相似度較小。聚類相似度是利用各聚類中物件的均值所獲得一個“中心物件”(引力中心)來進行計算的。 工作過程:   k

四種方法程式碼實現。K-means 高斯 密度 均值漂移

四種方法的matlab程式碼實現:連結: https://pan.baidu.com/s/1b6pKH65rYrRcBLnczz-EnA 密碼: 4iag1.K-means聚類:演算法步驟: (1) 首先我們選擇一些類/組,並隨機初始化它們各自的中心點。中心點是與每個資料點向

K-均值K-means算法

簡單 read 原理 包含 append 添加 url 學習 readlines 聚類是一種無監督的學習,它將相似的對象歸到同一個簇中。 這篇文章介紹一種稱為K-均值的聚類算法,之所以稱為K-均值是因為它可以發現k個不同的簇,且每個簇的中心采用簇中所含值的均值計算而成。 聚

通過IDEAhadoop平臺實現k-means算法

綜合 tle tostring html map apache cnblogs cos textfile 有段時間沒有操作過,發現自己忘記一些步驟了,這篇文章會記錄相關步驟,並隨時進行補充修改。 1 基礎步驟,即相關環境部署及數據準備 數據文件類型為.csv文件,excel

K均值K-means)和高斯混合(Mixture of Gaussian Models)

math del 一個 ans line k-均值聚類 初始化 gaussian 樣本 K-means算法流程 給定條件: ????example set: \((x_1, y_1), (x_2, y_2), \dots, (x_N, y_N)\) 初始化: ????K個簇

分析(二)k-meansmatlab程式

1.介紹 k-means是一種常見的基於劃分的聚類演算法。劃分方法的基本思想是:給定一個有N個元組或者記錄的資料集,將資料集依據樣本之間的距離進行迭代分裂,劃分為K個簇,其中每個簇至少包含一條實驗資料。 2.k-means原理分析 2.1工作原理 (1)首先,k-means方法從資料集中隨機

ml課程:概述K-means講解(含程式碼實現)

以下是我的學習筆記,以及總結,如有錯誤之處請不吝賜教。 本文主要介紹聚類以及K均值演算法的推倒過程,最後有相關程式碼案例。 說到聚類就不得不先說說機器學習的分類。 機器學習主要分為三類: 監督學習:分類、迴歸... 無監督學習:聚類、降維... 強化學習。  

機器學習-*-K均值程式碼實現

KMeans聚類 在聚類演算法中,最出名的應該就是k均值聚類(KMeans)了,幾乎所有的資料探勘/機器學習書籍都會介紹它,有些初學者還會將其與KNN等混淆。k均值是一種聚類演算法,屬於無監督學習的一種,而KNN是有監督學習/分類學習的一種。 聚類:顧名思義,就是講某些相似的事物聚在

機器學習——K-均值K-means)演算法

本文轉載自:https://www.cnblogs.com/ybjourney/p/4714870.html 一 K-均值聚類(K-means)概述 聚類 “類”指的是具有相似性的集合。聚類是指將資料集劃分為若干類,使得類內之間的資料最為相似,各類之間的資料相

ML-61: 機器學習之K均值(K-Means)演算法含原始碼

機器學習之K均值聚類演算法1 演算法原理2 演算法例項3 典型應用參考資料 機器學習分為監督學習、無監督學習和半監督學習(強化學習)。無監督學習最常應用的場景是聚類(clustering)和降維(dimension reduction)。聚類演算法包括:K均值

《機器學習實戰》二分-kMeans演算法(二分K均值

首先二分-K均值是為了解決k-均值的使用者自定義輸入簇值k所延伸出來的自己判斷k數目,其基本思路是: 為了得到k個簇,將所有點的集合分裂成兩個簇,從這些簇中選取一個繼續分裂,如此下去,直到產生k個簇。 虛擬碼: 初始化簇表,使之包含由所有的點組成的簇。 repeat   &n

K-means的演算法原理實現

原地址 1、如何理解K-Means演算法? 2、如何尋找K值及初始質心? 3、如何應用K-Means演算法處理資料?K-means聚類的演算法原理 K-Means是聚類演算法中的一種,其中K表示類別數,Means表示均值。顧名思義K-Means是一種通過均值對資料點進行聚類的演算法。K-Me

單機環境分散式環境下K-Means演算法的執行例項

  單機環境下的K-Means聚類演算法執行例項 參考書籍《Mahout in Action》:要資源的可以找我~(中英文都有) 在eclipse平臺上實現K-Means例項 程式碼如下: package kmeans; import java.io.File; im

機器學習 (Clustering)____K-均值演算法(K-means Clustering) 層次(Hierarchical Clustering)

____tz_zs學習筆記聚類(Clustering) 顧名思義,就是將相似樣本聚合在一起,屬於機器學習中的非監督學習 (unsupervised learning) 問題。聚類的目標是找到相近的資料點,並將相近的資料點聚合在一起。實現聚類的演算法主要有:1.K-均值聚類演算

分析層次k-means演算法

參考文獻: [1]Jure Leskovec,Anand Rajaraman,Jeffrey David Ullman.大資料網際網路大規模資料探勘與分散式處理(第二版) [M]北京:人民郵電出版社,2015.,190-199; [2]蔣盛益,李霞,鄭琪.資料探勘原理與實踐 [M]北京:電子工業出版社,20