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()
  • 相关阅读:
    剑指offer的前16题-java版
    JAVA基本数据类型所占字节数是多少?(32位系统)
    二叉树的镜像
    阿里简历问题
    javaSE基础总结
    小心情
    九九乘法表-for循环和while循环
    Python PEP8 编码规范及中文版
    比大小和猜数字
    猜拳游戏
  • 原文地址:https://www.cnblogs.com/jgua/p/14853591.html
Copyright © 2011-2022 走看看