zoukankan      html  css  js  c++  java
  • 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:UsersAdministratorDesktop三年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()
  • 相关阅读:
    vue中的 computed 和 watch 的区别
    mysql8.0 初始化数据库及表名大小写问题
    sql server alwayson 调整数据文件路径
    zabbix 自定义监控 SQL Server
    mysql 创建用户及授权
    mysql 设置从库只读模式
    mysql8.0 主从复制安装及配置
    centos8.0安装mysql8.0
    centos8替换阿里数据源
    npm publish 报错 【you or one of your dependencies are requesting a package version that is forbidden by your security policy】
  • 原文地址:https://www.cnblogs.com/jgua/p/14853591.html
Copyright © 2011-2022 走看看