K-means聚类算法

k-mearns算法以k为参数,把n个对象分成k个簇,使簇内具有较高的相似度,而簇间的相似度较低。

1、随机选择k个点作为初始的聚类中心
2、对于剩下的点,根据其与聚类中心的距离,将其归入最近的簇
3、对每个簇,计算所有点的均值作为新的取类中心
4、重复2、3直到取类中心不再发生改变

拓展

计算两条数据相似性时,sklearn.K-Means默认用欧式距离
虽然还有余弦相似度,马氏距离等多种方法,但没有设定计算距离方法的参数。

数据介绍:

现有1999年全国31个省份城镇居民家庭平均每月全年消费性支出的八个主要变量数据,这八个变量分别是食品、衣着、家庭设备用品、服务、医疗保健、交通、通讯、娱乐教育文化服务、居住以及杂项商品和服务。

利用已有数据,对31个省份进行聚类。

实验目的:

通过聚类,了解1999年各个省份的消费水平在国内的情况。

from sklearn.cluster import KMeans
import numpy as np

def load_data(file_path):  
    '''
    读取txt文件,返回城市名和对应的消费数据
    '''
    with open(file_path,'r') as file:
        lines = file.readlines()
        
    city_name = []
    spend_data = []
    for line in lines:
        items = line.strip().split(',')
        city_name.append(items[0])
        spend_data.append([items[i] for i in range(1,len(items))])
        
    return city_name,spend_data


def cluster(data,cluster_num):
    '''
    构造KMeans聚类,返回聚类簇和对应的族中心坐标加和
    '''
    km = KMeans(n_clusters = cluster_num)
    label = km.fit_predict(data) 
    
    # 每个簇中心的坐标 cluster_centers_,做一个加和,代表每个类中八种消费的中心总和
    expenses = np.sum(km.cluster_centers_,axis=1) 
    
    # 构造存放cluster_num个聚类的列表
    city_cluster = []
    for i in range(cluster_num):
        city_cluster.append([])
    
    for i in range(len(city_name)):
        city_cluster[label[i]].append(city_name[i])
    
    return city_cluster,expenses

def main():
    file_path = './city.txt'
    cluster_num = 5
    city_name,spend_data = load_data(file_path)
    city_cluster,expenses = cluster(spend_data,cluster_num)
        
    for i in range(len(city_cluster)):
        print("expenses:%.2f" %expenses[i])
        print(city_cluster[i])

if __name__== '__main__':
    main()

expenses:3788.76
['河北', '山西', '内蒙古', '辽宁', '吉林', '黑龙江', '江西', '山东', '河南', '贵州', '陕西', '甘肃', '青海', '宁夏', '新疆']
expenses:4615.82
['江苏', '安徽', '湖南', '湖北', '广西', '海南', '重庆', '四川', '云南']
expenses:6847.34
['北京', '天津', '浙江', '广东']
expenses:8247.69
['上海']
expenses:5287.90
['福建', '西藏']