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