基于Python的K-means算法及案例

  • 算法简介

k-means算法也被称为k-平均或k-均值,是一种得到最广泛使用的聚类算法。算法的主要思想是通过迭代过程把数据集划分为不同的类别,使得评价聚类性能的准则函数达到最优,从而使生成的每个类内紧凑,类间独立。

算法主要步骤如下:

1)输入类的数目k和包含m个对象的数据库。

2 随机选取k个样本点作为k个类的中心

3 分别对m个样本点计算该点到k个中心的距离,根据距离的最小值决定样本属于哪个类。  

4)更新每个类的中心

5 重复3-4),直到所有类的中心不再改变。

  • 算法实现
import numpy as np

#计算两个向量之间的距离
def Dist( A, B ):
    err = A - B
    dist = np.dot( err, err )
    return dist
#K-means算法(一次聚类)
def Category( initData, center, k ):
    mMax = np.max( initData )
    mMin = np.min( initData )
    [m, n] = np.shape( initData )
    [m_c, n_c] = np.shape( center )

    #数据归一化处理
    mMaxMatrix = np.ones( [m, 1], int ) * mMax
    mMinMatrix = np.ones( [m, 1], int ) * mMin
    rangeValue = mMaxMatrix- mMinMatrix
    normalData = ( initData - mMinMatrix ) / rangeValue
    mMaxCenter = np.ones( [m_c, 1], int ) * mMax
    mMinCenter = np.ones( [m_c, 1], int ) * mMin
    center1 = ( center - mMinCenter ) / ( mMaxCenter - mMinCenter )
    
    #计算每个数据到中心的距离,及距离的最小值
    temp_dist = np.zeros( [m, m_c] )
    for k in range( m_c ):
        for i in range( m ):
            temp_dist[i, k] = Dist( normalData[i, :], center1[k, :] )
    
    err = np.zeros( [m] )
    for i in range( m ):
        err[i] = np.min( temp_dist[i, :] )
    
    #根据距离的最小值进行分类
    category = np.zeros( [m] )
    
    for i in range( m ):
        for j in range( m_c ):
            if temp_dist[i, j] == err[i]:
                category[i] = j
    
    return category

def main():
    #对数据进行聚类,本案例仅做一次聚类处理,实际应用中应该做多次聚类处理
    #数据包括数值型数据和字符型数据两块
    numData = np.array( [ [50, 50, 9], 
                          [28, 9, 4], 
                          [17, 15, 3],
                          [25, 40, 5],
                          [28, 40, 2],
                          [50, 50, 1],
                          [50, 40, 9],
                          [50, 40, 9],
                          [40, 40, 5],
                          [50, 50, 9],
                          [50, 50, 5],
                          [50, 50, 9],
                          [40, 40, 9],
                          [40, 32, 17],
                          [50, 50, 9]
                       ] )
    strData = ['coutry1',  'coutry2',  'coutry3',  'coutry4',  'coutry5',
               'coutry6',  'coutry7',  'coutry8',  'coutry9',  'coutry10',
               'coutry11', 'coutry12', 'coutry13', 'coutry14', 'coutry15' ]
    #初始类别的中心,因为分成三类,所以选取三个中心坐标
    center =  np.array( [ [28, 9, 4], [40, 40, 9], [50, 50, 9] ] )
    strCategory = ['第一类', '第二类', '第三类']
    
    [m_c, n_c] = np.shape( center )
    [m, n] = np.shape( numData )
    
    print( '\n分类之前的数据:\n' )
    for i in range( m ):
        print( numData[i], strData[i] )

    category = Category( numData, center, 3 )

    print( '\n分类之后的数据:\n' )
    for j in range( m_c ):
        for i in range( m ):
            if category[i] == j:
                print( strCategory[j], ':', strData[i] )
                
if __name__ == '__main__':
    main()

作者:YangYF

你可能感兴趣的:(Python在石油工程中应用,智能钻完井,油田大数据)