python——k-means算法

1.scikit-learn库实现K-means算法

import pandas as pd
from sklearn.cluster import KMeans
import matplotlib.pyplot as plt

"通过pandas导入相关数据"
df = pd.read_csv(r'C:\Users\Administrator\Desktop\三年5000车\起点最多城市切分\8-删除异常运输链.csv',encoding="GB2312")
x = df[['途径城市数量(不重复城市)','途经省份数量','里程','复杂度']]   #选择聚类的指标

"超参数"
k = 5

"训练模型"
model = KMeans(n_clusters=k,        #簇的个数,即你想聚成几类
     init='k-means++',              #初始簇中心的获取方法
    n_init=10,                      #获取初始簇中心的更迭次数,为了弥补初始质心的影响,算法默认会初始10个质心,实现算法,然后返回最好的结果。
    max_iter=300,                   #最大迭代次数(因为kmeans算法的实现需要迭代)
    tol=0.0001,                     # 容忍度,即kmeans运行准则收敛的条件
    precompute_distances='auto',    #是否需要提前计算距离,这个参数会在空间和时间之间做权衡,如果是True 会把整个距离矩阵都放到内存中,auto 会默认在数据样本大于featurs*samples 的数量大于12e6 的时候False,False 时核心实现的方法是利用Cpython 来实现的
    verbose=0,                      # 冗长模式
    random_state=None,              #随机生成簇中心的状态条件。
    copy_x=True,                    #对是否修改数据的一个标记,如果True,即复制了就不会修改数据。bool 在scikit-learn 很多接口中都会有这个参数的,就是是否对输入数据继续copy 操作,以便不修改用户的输入数据。
    n_jobs=1,                       #并行设置
    algorithm='auto'                #kmeans的实现算法,有:’auto’, ‘full’, ‘elkan’, 其中 ‘full’表示用EM方式实现
)

km = model.fit(x)                   #进行聚类

df['聚类结果'] = km.labels_         #km.labels_  获得聚类标签(数字形式)
result = model.predict(x)           #可以用来获得聚类标签,也可以用来预测新数据

centers = model.cluster_centers_    #获得簇的中心点坐标


"结果可视化(聚类指标少于等于三个指标时可用)"
plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False #用来正常显示负号

"三个聚类指标时"
ax = plt.axes(projection='3d')
#中心点颜色标记
mark4 = ['b','g','r','k']
mark5 = ['b','g','r','k','y',]
mark6 = ['b','g','r','k','y','c']
mark7 = ['b','g','r','k','y','c','m']

#画出各个数据点,用不同颜色表示分类
for x,y,z,c in zip(df['载重'],df['总里程'],df['途经省份数量'],df['聚类结果']):
        ax.scatter3D(x,y,z,color = mark5[c])

#画出中心点,用不同颜色表示分类
for j, center in enumerate(centers):
    ax.scatter3D(center[0], center[1],center[2],color = mark5[j])

ax.set_xlabel('途径城市数量')
ax.set_ylabel('途经省份数量')
ax.set_zlabel('趟次里程')

"两个聚类指标时"
#画出中心点
for i, center in enumerate(centers):
    plt.scatter(center[0],center[1],color = mark5[i])
plt.xlabel('途经省份数量')
plt.ylabel('总里程')


plt.show()

2.聚类数量效果评估

(1)肘方法(拐点处为聚类效果最好的聚类数量)

import numpy as np
from sklearn.cluster import KMeans
import matplotlib.pyplot as plt
import pandas as pd
#读取数据
df = pd.read_csv(r"H:\数据处理结果\三年数据合并.csv",encoding="GB2312")
X = df[['途径城市数量(不重复城市)','途经省份数量','里程','复杂度']]   #X为DataFrame数据
X = np.array(X)     #转换成numpy array,否则在 X[group,:] 处会报错,或者改成X[group]

distance = []
k = []
#簇的数量
for n_clusters in range(1,10):
    cls = KMeans(n_clusters).fit(X)

    #曼哈顿距离
    def manhattan_distance(x,y):
        return np.sum(abs(x-y))

    distance_sum = 0
    for i in range(n_clusters):
        group = cls.labels_ == i
        members = X[group,:]
        for v in members:
            distance_sum += manhattan_distance(np.array(v), cls.cluster_centers_[i])
    distance.append(distance_sum)
    k.append(n_clusters)
plt.scatter(k, distance)
plt.plot(k, distance)
plt.xlabel("k")
plt.ylabel("distance")
plt.show()

(2)轮廓系数(数值越高,聚类效果越好)

from sklearn.cluster import KMeans
import pandas as pd
from sklearn.metrics import silhouette_score
import matplotlib.pyplot as plt


df = pd.read_csv(r"D:\数据\货运数据\中心城市切分运输链\三年数据\5000辆车抽样\5000辆车抽样-1.csv",encoding="GB2312")
X = df[['途径城市数量(不重复城市)','途经省份数量','里程','复杂度']]

Scores = []  # 存放轮廓系数
for k in range(2,10):
    kmeans = KMeans(n_clusters=k)  # 构造聚类器
    kmeans.fit(X)
    Scores.append(silhouette_score(X,kmeans.labels_,metric='euclidean'))
X = range(2,10)

plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcparams['axes.unicode_minus'] = False

plt.xlabel('k值——簇数量')
plt.ylabel('轮廓系数')
plt.plot(X,Scores,'o-')
plt.show()

 

上一篇:KMeans 算法


下一篇:GBK均值聚类算法【含Matlab源码】