机器学习(5)——Kmeans VS KNN

在这里插入图片描述

聚类

一种无监督学习,把无分类的数据分为K类
在这里插入图片描述
在这里插入图片描述

Kmeans(K均值)

1.指定K值,也就是最终要分成K类就指定K为几;
2.初始化K个中心点:随机找K个样本x1,x2,……xk,作为未来K类的K个中心点c1,c1……ck;
3.计算剩余样本所属类别:每个样本距离step2中选的K个中心点c1,c1……ck的距离d,谁的距离最近就归为哪一类;
4.重新选取中心点:step2中选取的中心点是随机初始化选的,不具有准确性,所以需要优化选择新的中心点。由于step3中已经初步分好了K类,对这些类别重新计算新的中心点。
5.重复step4、step5,直至中心点的位置不再变动。

Kmeans代码

1.导入必要的库

from sklearn import datasets
import matplotlib.pyplot as plt
import numpy as np
import math
import random
from IPython import display

2.人工创造数据点

def createData():
    X, y = datasets.make_blobs(n_samples=1000, n_features=2,\
                               centers=[[2,0],[1,1],[2,2],[5,5],[4,1]], cluster_std=[0.3,0.3,0.5,0.1,0.5])
    return X, y
X,y = createData()
plt.scatter(X[:,0],X[:,1],c=y,s=10)
plt.show()

在这里插入图片描述
3.定义初始化中心点的函数

def init_centers(data, k):
    m,n = np.shape(data)
    centers_ids = np.random.choice(m, k)
    centers = data[centers_ids]
    return centers

4.定义求点到点距离的函数

def cal_dist(ptA, ptB):
    return np.linalg.norm(ptA - ptB)

5.kmeans实现

def KMeans(data, k):
    m,n = np.shape(data)
    # 最后的返回结果,一共两维,第一维是所属类别,第二维是到簇中心的距离
    pred_y = np.zeros((m, ))
    
    centers = init_centers(data, k) #step1:随机初始化中心点
    keep_changing = True            #迭代停止flag,标记中心点的变化情况,不变化了就停止迭代
    iteration = 0                   #记录迭代次数
    while keep_changing:            #只要中心点还变化就进行
        # 遍历所有样本
        keep_changing = False       
        for i in range(m):
            min_dist = np.inf       #初始化距离为无穷,先选取一个大的值,后继用求的dist更新
            # 遍历到各个簇中心的距离
            for center in range(k):
                dis = cal_dist(centers[center,:], data[i, :])
                if dis < min_dist:
                    min_dist = dis  #更新距离
                    idx = center    
            # 如果所属类别发生变化
            if pred_y[i] != idx:
                keep_changing = True
            pred_y[i] = idx
        # 更新簇中心的坐标
        for center in range(k):
            cluster_data = data[pred_y == center]
            centers[center,:] = np.mean(cluster_data, axis=0)
        plt.scatter(data[:,0],data[:,1],c=pred_y,s=10)
        plt.title(f'iteration {iteration}')
        iteration +=1
        plt.pause(1)
        display.clear_output(wait=True)
    return centers, pred_y

6.测试函数

centers,pred_y = KMeans(X,5)

在这里插入图片描述

Kmeans缺点

  1. K值要指定,通常这个值我们是事先不知道的,很难指定一个准确的K值
  2. 收敛的结果和初始值有关,不同的初始值瘦脸的效果是不一样的,这显然不是我们想看到的一个数据模型的学习效果。

Kmeans++

对Kmeans算法进行了改进,改进的是选中心点步骤:

1.从数据集中随机选择一个样本作为初始聚类中心
2.计算每个样本到最近聚类中心的距离
3.每一个样本都有一个长度,长度越大的样本,被选为下一个聚类中心的概率越高。

4.重复step2、3,直到得到预设的K个初始质心
在这里插入图片描述
假设有8个样本,分布如下图所示:
在这里插入图片描述
假设第一步选第一初始聚类中心的时候选中了6号点;
第二步要计算其他样本到6号样本的距离及其被选为聚类中心的概率:
在这里插入图片描述

其中P(x)就是每个样本被选为下一个聚类中心的概率,最后一行的Sum是概率P(x)的累加和。

轮盘法选择出第二个聚类中心:随机产生出一个0~1之间的随机数,判断它属于哪个区间,该区间对应的序号就是被选择出来的第二个聚类中心。(https://www.cnblogs.com/wang2825/articles/8696830.html)

KNN (K近邻)

把KNN写在Kmeans下面是为了防止两者混淆,两者毛关系都没有!Kmeans是无监督的聚类算法,KNN是有监督的分类算法。KNN是一种懒惰算法,“抄旁边人的答案”。基本思想是:取离新的预测点最近的K个点,对这K个点的结果进行统计,类别最多的那个类别就认为是这个新点的类别。所以KNN算法没有学习过程,就是一个单纯的vote。
在这里插入图片描述
在这里插入图片描述
通常距离公式采用欧式距离:

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值