#-*- coding: utf-8 -*-#使用K-Means算法聚类消费行为特征数据import numpy as npimport pandas as pd#参数初始化inputfile = '../data/consumption_data.xls' #销量及其他属性数据k = 3 #聚类的类别threshold = 2 #离散点阈值iteration = 500 #聚类最大循环次数data = pd.read_excel(inputfile, index_col = 'Id') #读取数据data_zs = 1.0*(data - data.mean())/data.std() #数据标准化from sklearn.cluster import KMeansmodel = KMeans(n_clusters = k, n_jobs = 4, max_iter = iteration) #分为k类,并发数4model.fit(data_zs) #开始聚类#标准化数据及其类别r = pd.concat([data_zs, pd.Series(model.labels_, index = data.index)], axis = 1) #每个样本对应的类别r.columns = list(data.columns) + [u'聚类类别'] #重命名表头norm = []for i in range(k): #逐一处理 norm_tmp = r[['R', 'F', 'M']][r[u'聚类类别'] == i]-model.cluster_centers_[i] norm_tmp = norm_tmp.apply(np.linalg.norm, axis = 1) #求出绝对距离 norm.append(norm_tmp/norm_tmp.median()) #求相对距离并添加norm = pd.concat(norm) #合并import matplotlib.pyplot as pltplt.rcParams['font.sans-serif'] = ['SimHei'] #用来正常显示中文标签plt.rcParams['axes.unicode_minus'] = False #用来正常显示负号norm[norm <= threshold].plot(style = 'go') #正常点discrete_points = norm[norm > threshold] #离群点discrete_points.plot(style = 'ro')for i in range(len(discrete_points)): #离群点做标记 id = discrete_points.index[i] n = discrete_points.iloc[i] plt.annotate('(%s, %0.2f)'%(id, n), xy = (id, n), xytext = (id, n))plt.xlabel(u'编号')plt.ylabel(u'相对距离')plt.show()