K-Means(从样例操作到认识理论)

K均值(K-Means)

是聚类算法中最为简单、高效的,属于无监督学习算法。
公式
在这里插入图片描述

K 簇类数
u_k 质心
k 簇类中心索引
第i个样本到质心距离的平方
c^(i) 第i个簇类,c^(i)=2 样本分给了第2簇类

模型算法核心

始中心的选择->k-leans++就是一种选择方式,有以随机点的,或者以数据源的
簇类数->不会超过源数据数目,有轮廓函数作为选择
距离类型->欧式距离,曼哈夫距离,取决于p
类均值迭代次数->大部分到达一定程度的迭代就会大大降低效率,肘部定律可知,
存在轮廓函数验证

样例

超市积分与顾客信息分析
在这里插入图片描述

特征选择

这个一般取决于数据分析,要拥有正确的数据特征

请添加图片描述
请添加图片描述

可视化(各种表)



多数据柱形表
plt.rcParams['figure.figsize'] = (18, 8)  # 创建画布大小
plt.subplot(1, 1, 1) # 选取1行1列1号位置图操作
sns.set(style='whitegrid')  # 格式位置
sns.displot(data['Annual Income (k$)'])  # 数据展示
plt.title('Annual Income', fontsize=20)
plt.xlabel('range of Annual Income')
plt.ylabel('count')
plt.show()

单数据柱形图
plt.rcParams['figure.figsize'] = (15, 8)
sns.countplot(data['Age'], palette='hsv') # 以柱形图显示每个类别的数量
plt.title("Age", fontsize=20)
plt.show()



饼状图
以数据的性别为例
labels = ['Female', 'Male']  # 给标签
size = data['Gender'].value_counts()  # 性别统计
colors = ['lightgreen', 'orange']  # 配置颜色
explode = [0, 0.1]  # 饼图参数
plt.rcParams['figure.figsize'] = (9, 9)  # 创建画布并大小
plt.pie(size, colors=colors, explode=explode, labels=labels, shadow=True, autopct="%.2f%%")
plt.title('Gender', fontsize=20)  # 标题
plt.axis('off')  # 关闭坐标轴
plt.legend()  # 显示标签解析
plt.show()


相关系数,热图heatMap
plt.rcParams['figure.figsize'] = (15, 8)
sns.heatmap(data.corr(), cmap='Wistia', annot=True)
plt.title('Heatmap for data', fontsize=20)  # 标题
plt.show()


哑铃图
plt.rcParams['figure.figsize'] = (18, 7)
sns.boxenplot(data['Gender'], data['Spending Score (1-100)'], palette='hsv')
plt.title('Gender vs Spending Score', fontsize=20)  # 标题
plt.show()


曲线对比图/也可以单线曲线
x = data['Annual Income (k$)']
y = data['Age']
z = data['Spending Score (1-100)']

sns.lineplot(x, y, color='blue')
sns.lineplot(x, z, color='green')
plt.title('Annual Income vs Spending Score', fontsize=20)  #
plt.show()

簇类数K

根据轮廓函数选择
不过感觉取决于实质问题的本身

range_values = np.arange(2, 10)  # 初始化聚类个数
for i in range_values:
    kmeans = KMeans(init='k-means++', n_clusters=i, max_iter=300, n_init=10, random_state=0)
    '''
    n_clusters: 即我们的k值,一般需要多试一些值以获得较好的聚类效果。
    max_iter:最大的迭代次数,一般如果是凸数据集的话可以不管这个值,
        如果数据集不是凸的,可能很难收敛,
        此时可以指定最大的迭代次数让算法可以及时退出循环。
    n_init:用不同的初始化质心运行算法的次数。
        由于K-Means是结果受初始值影响的局部最优的迭代算法,
        因此需要多跑几次以选择一个较好的聚类效果,默认是10,一般不需要改。
        如果你的k值较大,则可以适当增大这个值。
    init: 即初始值选择的方式,可以为完全随机选择’random’,
        优化过的’k-means++‘或者自己指定初始化的k个质心。
        一般建议使用默认的’k-means++’。
    algorithm:有“auto”, “full” or “elkan”三种选择。
        “full"就是我们传统的K-Means算法, “elkan”是elkan K-Means算法。
        默认的"auto"则会根据数据值是否是稀疏的,来决定如何选择"full"和“elkan”。
        一般数据是稠密的,那么就是 “elkan”,否则就是"full”。一般来说建议直接用默认的"auto"

    '''
    kmeans.fit(X)
    score = silhouette_score(X, kmeans.labels_, metric='euclidean', sample_size=len(X))
    '''
    metric为欧式距离的选择
    samplesize 为样本数量
    '''
    # 计算得分
    scores.append(score)

# 可视化得分
plt.figure()
plt.bar(range_values, scores, width=0.6, color='b', align='center')
plt.title('K-comparation')
plt.show()

请添加图片描述

k-means简单实现

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from pandas import plotting
import seaborn as sns

from scipy.spatial.distance import cdist
import warnings
warnings.filterwarnings('ignore')

# 默认欧式距离
# 重点在簇类的变换,k的取值
# 初始质心选择原始数据点,不作随机的讨论

class KMeans(object):
    # K簇类数目,最大迭代,初始质心
    def __init__(self, n_clusters, max_iter, centroids):
        self.n_clusters = n_clusters
        self.max_iter = max_iter
        self.centroids = np.array(centroids, dtype=np.float)

    # 簇类变换
    def fit(self, data):
        if self.centroids.shape == (0, ):  # 0行矩阵
            # random.randint(a,b,c)方法随机生成一个整数,从a到b,生成c个
            self.centroids = data[np.random.randint(0, data.shape[0], self.n_clusters), :]
            # data.shape[0]为data行数,
            # 如果大于数据数的簇类过于奇怪了
            # 生成self.n_clusters个即K

        # 迭代次数循环,也是簇类质心移动关键
        for i in range(self.max_iter):
            distances = cdist(data, self.centroids)
            # 对距离按由近到远排序,选取最近的质心点的类别作为当前点的分类
            c_index = np.argmin(distances, axis=1)
            # axis=1每一行取最小值,最后结果保存为一列(100*1的矩阵)

            # 对每一类数据进行均值计算,更新质心点坐标
            for j in range(self.n_clusters):
                # 首先排除掉没有出现在c_index里的类别(即所有的点都没有离这个质心最近)
                if j in c_index:  # j为0-K
                    # 选出所有类别是j的点,取data里面坐标的均值,更新第j个质心
                    self.centroids[j] = np.mean(data[c_index == j], axis=0)
                    # 布尔索引。axis=0得到一行的数据,将每一列做均值计算,列数不变





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值