代码编织梦想

引言

基本术语

1.

监督学习与无监督学习

在这里插入图片描述

在这里插入图片描述

监督学习

在这里插入图片描述
在这里插入图片描述

无监督学习

在这里插入图片描述

在这里插入图片描述

线性回归

基本形式

在这里插入图片描述

单变量线性回归

在这里插入图片描述
在这里插入图片描述

代价函数

在这里插入图片描述
在这里插入图片描述

代价函数推导

在这里插入图片描述

代价函数直观理解

  1. 如图 2.4的假设函数
    在这里插入图片描述

梯度下降

梯度下降

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

线性回归的梯度下降

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

线性代数回顾

矩阵与向量

在这里插入图片描述
在这里插入图片描述

加法和标量乘法

在这里插入图片描述

矩阵向量乘法

在这里插入图片描述

矩阵乘法

在这里插入图片描述

矩阵乘法特征

在这里插入图片描述
在这里插入图片描述

多元线性回归

多元线性回归

在这里插入图片描述
在这里插入图片描述

多元梯度下降

在这里插入图片描述
在这里插入图片描述

多元梯度下降法演练 1 - 特征缩放

在这里插入图片描述
在这里插入图片描述

多元梯度下降法演练 2 - 学习率

在这里插入图片描述
在这里插入图片描述

特征和多项式回归

在这里插入图片描述
在这里插入图片描述

正规方程

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

正规方程与矩阵不可逆

在这里插入图片描述

逻辑回归 (Logistic Regression)

分类问题

在这里插入图片描述

假设陈述

在这里插入图片描述
在这里插入图片描述

决策界限

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

代价函数

在这里插入图片描述
在这里插入图片描述

梯度下降

在这里插入图片描述
在这里插入图片描述

高级优化

在这里插入图片描述

多元分类: 一对多

在这里插入图片描述
在这里插入图片描述

正则化 (Regularization)

过拟合的问题

在这里插入图片描述
在这里插入图片描述

代价函数

在这里插入图片描述
在这里插入图片描述

线性回归的正则化

在这里插入图片描述
在这里插入图片描述

逻辑回归的正则化

在这里插入图片描述

损失函数与代价函数

在这里插入图片描述

常见的损失函数

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

常见的代价函数

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

神经网络: 表述

神经网络: 表述

在这里插入图片描述

神经元和大脑

在这里插入图片描述

模型表示 1

在这里插入图片描述
在这里插入图片描述

模型表示 2

在这里插入图片描述

神经网络的学习

聚类(Clustering)

在监督学习中,数据集是带标签的,我们的目标是找到能够区分正样本和负样本的决策边界。即在监督学习中,我们需要根据一系列标签拟合一个假设函数。而在无监督学习中,数据集是没有附带任何标签的,如图 1.1
在这里插入图片描述
图上有一系列点,但它们没有标签 y,因此该数据集可以表示位:{x(1), x(2), x(3), . . . , x(m)};则在无监督学习中,将这类数据集运用到算法中,而算法的任务计算找到隐含在数据中的内在结构。如图上的数据看起来可以分成两个分开的点集(称为簇),而这个能找到这些簇的算法,就被称为聚类算法。当然,除聚类算法外还有其他无监督学习算法,它们可以为我们找到其他类型的结构或者其他的一些模式,而不只是簇。

K-均值算法 (K-means)

基本定义

K-均值算法是一种迭代求解的聚类分析算法,算法接受一个未标记的数据集 (即数据集不带 y),然后将数据聚类成不同的组 (簇)。其步骤是预将分层 K 组,则会随机选取 K 个对象作为初始的聚类中心,然后计算每个对象与各个聚类中心之间的距离,把每个对象分配给距离它最近的聚类中心,此时数据集会分成了 K 个簇,然后计算这个簇中所有点的均值,并将该簇的聚类中心移动到这个均值上。不断重复这个过程,直至中心点不再变化为止。

K-均值算法会做两件事:1. 簇分配;2. 移动聚类中心。

例如:假设有一个无标签的数据集,想将其分为两个簇,执行 K-均值算法。如图 1.3 所示,首先随机生成两点,作为聚类中心,然后根据距离将样本分配给距离最近的聚类中心,然后将聚类中心移动到对应簇的均值上,不断迭代该过程,直至中心点不再变化为止
在这里插入图片描述
K-Means 算法步骤
1.输入:
①样本集: D = { X 1 ⃗ , X 2 ⃗ , … , X m ⃗ } D=\{\vec{X_1},\vec{X_2},\dots,\vec{X_m}\} D={X1 ,X2 ,,Xm }。其中,每个样本 X j ⃗ \vec{X_j} Xj 是由 n n n个属性组成的特征向量 ( x j 1 ; x j 2 ; … , x j n ) (x_{j1};x_{j2};\dots,x_{jn}) (xj1;xj2;,xjn)
② 聚类簇数 k k k

2.算法目标:确定最优的聚类中心

3.算法过程:
①从数据集 D D D中随机选择k个样本作为初始聚类中心: { μ 1 ⃗ , μ 2 ⃗ , … , μ k ⃗ } \{ \vec{\mu_1},\vec{\mu_2},\dots,\vec{\mu_k}\} {μ1 ,μ2 ,,μk },(相当于图中红色和蓝色叉的位置)
② 定义k个簇类的空集合,用于存储本簇的样本。即令 C i = ∅ ( 1 ≤ i ≤ k ) C_i=\varnothing (1\leq i \leq k) Ci=(1ik)
③分别计算每个聚类样本 X j ⃗ \vec{X_j} Xj 到各聚类中心 μ i ⃗ ( 1 ≤ i ≤ k ) \vec{\mu_i}(1\leq i \leq k) μi (1ik)的距离(欧氏距离): d j i = ∣ ∣ x j − μ i ∣ ∣ 2 d_{ji}=||x_j-\mu_i||_2 dji=∣∣xjμi2;并找到与该样本的距离最近的聚类中心: λ j = a r g   m i n i i n { 1 , 2 , … , k } d j i \lambda_j= arg\ min_{i in\{1,2,\dots,k\}}d_{ji} λj=arg miniin{1,2,,k}dji,然后将该样本 X j ⃗ \vec{X_j} Xj 划入对应的簇中: C λ j = C λ j ∪ { X j ⃗ } C_{\lambda j}=C_{\lambda j} \cup \{\vec{X_j}\} Cλj=Cλj{Xj }
④ 重新计算每个聚类中心, μ ‘ = 1 ∣ c ( i ) ∣ ∑ x ∈ c ( i ) x \mu`=\frac{1}{|c^{(i)}|}\sum_{x \in c^{(i)}}x μ=c(i)1xc(i)x
⑤ 如果聚类中心 μ ‘ ≠ μ i \mu` \neq \mu_i μ=μi,则更新聚类中心 μ i \mu_i μi μ ‘ \mu` μ
⑥如果聚类中心 μ ‘ = μ i \mu` = \mu_i μ=μi,则保持聚类中心不变
⑦ 重复步骤 ( 1 − 6 ) (1-6) (16),直到达到最大迭代次数或者聚类中心不再变化,则停止,否则,继续操作。
⑧输出最终簇划分 C = { C 1 , C 2 , … , C k } C=\{C_1,C_2,\dots,C_k\} C={C1,C2,,Ck}

K-均值算法伪代码

Repeat {
 for i = 1 to m
 	c ( i ) := index ( form 1 to K ) of cluster centroid closest to x ( i )
 for k = 1 to K
 	k := average ( mean ) of points assigned to cluster k
 }

K-均值算法的关键:
内循环中,第一个for循环(即步骤2)是簇分配步骤,用 c ( i ) c^{(i)} c(i)来表示第1到第 k k k个最接近 x ( i ) x^{(i)} x(i)的聚类中心,该循环会根据它离哪个聚类中心近一些,将其分配给对应聚类中心的簇。另一种表达方式是:想要计算 c ( i ) c^{(i)} c(i),就要用第 i i i个样本 x ( i ) x^{(i)} x(i),然后计算出这个样本距离每个聚类中心的距离,找出能够最小化距离的聚类中心的k值,赋值给 c ( i ) c^{(i)} c(i),数学表达如下:
c ( i ) = m i n k ∣ ∣ x ( i ) − μ k ∣ ∣ 2 c^{(i)}=\mathop{min}\limits_{k}||x^{(i)}-\mu_k||_2 c(i)=kmin∣∣x(i)μk2
第二个for循环(即步骤4-6)是移动聚类中心, μ k \mu_k μk表示这个簇中所有点的均值,即 μ k = 1 ∣ c ( i ) ∣ ∑ x ∈ c ( i ) x \mu_k=\frac{1}{|c^{(i)}|}\sum_{x \in c^{(i)}}x^{} μk=c(i)1xc(i)x,其中 x x x为簇 c ( i ) c^{(i)} c(i)的均值向量。例如存在 x ( 1 ) , x ( 5 ) , x ( 6 ) x^{(1)},x^{(5)},x^{(6)} x(1),x(5),x(6)对应的 c ( 1 ) = 2 , c ( 5 ) = 2 , c ( 6 ) = 2 c^{(1)}=2,c^{(5)}=2,c^{(6)}=2 c(1)=2,c(5)=2,c(6)=2,即表示样本1,5,6分配给了聚类中心2,则移动聚类中心时 μ 2 = [ x ( 1 ) + x ( 5 ) + x ( 6 ) ] 3 \mu_2 = \frac{[x^{(1)}+x^{(5)}+x^{(6)}]}{3} μ2=3[x(1)+x(5)+x(6)],此时 μ 2 \mu_2 μ2为n维向量,因为 x ( i ) x^{(i)} x(i)都是n维向量,计算出均值后 μ 2 \mu_2 μ2就会移动到这个均值上
那么如果存在一个没有点的聚类中心,最常见的做法是直接移除这个聚类中心,但如果这么做的话,会得到K-1个簇而不是K个簇。如果确实需要K个簇,那么可以重新随机初始化这个聚类中心。

K-均值算法也可以用来分离不佳的簇,如下图数据集与前面不同的是没有明显的分组,但同样可以应用该算法将其分成几个簇。
在这里插入图片描述

优化目标

K-均值最小化问题是要最小化所有的数据点与其所关联的聚类中心点之间的距离之和,因此K-均值的代价函数(又称畸变函数)为
J ( c ( 1 ) , … , c ( m ) , μ 1 , … , μ k ) = 1 m ∑ i = 1 m ∣ ∣ x ( i ) − μ c ( i ) ∣ ∣ 2 J(c^{(1)},\dots,c^{(m)},\mu_1,\dots,\mu_k)=\frac 1m \sum_{i=1}^{m}||x^{(i)}-\mu_{c^{(i)}}||^2 J(c(1),,c(m),μ1,,μk)=m1i=1m∣∣x(i)μc(i)2

其中 μ c ( i ) \mu_{c^{(i)}} μc(i)代表与 x ( i ) x^{(i)} x(i)最近的聚类中心点。例如 x ( i ) = 5 x^{(i)}=5 x(i)=5,则其 c ( i ) = 5 c^{(i)}=5 c(i)=5,也就是说 x ( i ) x^{(i)} x(i)被分配到第五个簇,因此 μ c ( i ) = μ 5 \mu_{c^{(i)}}=\mu_5 μc(i)=μ5
 我们的优化目标是要找出使得代价函数最小的 c ( 1 ) , … , c ( m ) , μ 1 , … , μ k c^{(1)},\dots,c^{(m)},\mu_1,\dots,\mu_k c(1),,c(m),μ1,,μk,即:
m i n c ( 1 ) , … , c ( m ) , μ 1 , … , μ k J ( c ( 1 ) , … , c ( m ) , μ 1 , … , μ k ) \mathop{min}\limits_{c^{(1)},\dots,c^{(m)},\mu_1,\dots,\mu_k} J(c^{(1)},\dots,c^{(m)},\mu_1,\dots,\mu_k) c(1),,c(m),μ1,,μkminJ(c(1),,c(m),μ1,,μk)
在K-均值算法中,第一个循环实际上是在最小化代价函数 J J J中的 c ( i ) c^{(i)} c(i)参数,此时要保持最近的聚类中心,即 μ 1 , … , μ k \mu_1,\dots,\mu_k μ1,,μk的位置不变,该循环会选出 c ( 1 ) , … , c ( m ) c^{(1)},\dots,c^{(m)} c(1),,c(m)来最小化代价函数;第二个循环是选择 μ \mu μ来最小化代价函数 J J J μ 1 , … , μ k \mu_1,\dots,\mu_k μ1,,μk。在迭代的过程中,每一次的代价函数应该都在减小或者保持不变,如果出现代价函数增大的情况,则说明实现的过程可能存在错误

随机初始

在进行k-均值的过程中,首先要随机初始化所有的聚类中心点,初始点选择的不同,可能会得到不同的聚类结果,在初始化时应该注意以下两点:

  1. 我们应该选择 K < m K<m K<m,即聚类中心点的个数要小于所有训练集样本的数量
  2. 随机选择 K K K个训练样本,然后令 K K K个聚类中心 ( μ 1 , … , μ k ) (\mu_1,\dots,\mu_k) (μ1,,μk)分别与这 K K K个训练样本相等

K-均值的一个问题在于,它有可能会得到一个局部最优值,而这取决于初始化的情况,初始不同,得到的局部最优值也不同,如下图。
在这里插入图片描述
图 1.6 中 1、2、3 采用了不同的初始化聚类中心。而 1. 是全局最优的聚类、2. 和 3. 则是比较失败的聚类,它们只收敛到了局部最优解,而没达到全局最优。
为了解决这个问题,我们通常需要多次运行 K-均值算法,每一次都重新进行随机初始化,最后再比较多次运行 K-均值的结果,选择代价函数最小的结果。
在这里插入图片描述
 上式中循环次数$ i 设为 100 ,一般取 50 − 1000 之间,应该选择 设为100,一般取50-1000之间,应该选择 设为100,一般取501000之间,应该选择K < m $。如果K 在2至10,一般可得到比较好的局部最优解;如果K比较大(比10大很大),那么多次随机初始化对聚类结果不会有太大的改善

选择聚类数

选择聚类数的方法,通常是需要根据不同的问题,人工进行选择的,选择能最好服务于聚类目的的数量。

另一种方法是使用“肘部原则”,但不能期望它每次都有效果。我们所需要做的是改变 K值,也就是聚类类别数目的总数,然后运行 K-均值算法,并计算畸变函数 J。
在这里插入图片描述
图 1.7 中的左图是情况较好的,像一个人的肘部。这就是“肘部法则”所做的。从图中可以看出它的畸变值会迅速下降,从 1 到 2,从 2 到 3 之后,在 3 的时候达到一个肘点。在此之后,畸变值就下降的非常慢,那么我们就选 K=3。当你应用“肘部法则”的时候,如果你得到了一个像上面这样的图,那么这将是一种用来选择聚类个数的合理方法。但是有时候会得到像右图一样的曲线,它没有明显的肘点,那么将无法使用该方法选择聚类数

K-均值算法实例

假设存在一个不带标签的数据集,如图 1.8。其中横轴 (x 轴) 为西瓜密度,纵轴 (y 轴)为西瓜含糖量 现在目的是将数据集分成 3 个簇,
在这里插入图片描述

在这里插入图片描述
如图1.9,算法首先在样本集中随机选取3个样本作为聚类中心,然后计算各个样本与这3个聚类中心的距离,然后把各个样本划分给距离该样本最近的聚类中心所对应的簇。例如某样本与3个聚类中KaTeX parse error: Expected '}', got 'EOF' at end of input: …},\vec{\mu_3}\}的距离为: 0.283 , 0.506 , 0.032 0.283,0.506,0.032 0.283,0.506,0.032,因为该样本与 μ 3 ⃗ \vec{\mu_3} μ3 的距离最近,所以将该样本划分给 μ 3 ⃗ \vec{\mu_3} μ3 对应的 C 3 C_3 C3类别中,计算完全部样本后,更新聚类中心,让聚类中心往其对应簇的中心移动。不断迭代,直至达到最大迭代次数或者全部聚类中心不在变化时,则停止算法,如图中迭代第三次时,可以说已经收敛不在变化了。则此时的三个聚类中心为最优聚类中心,由此将样本集分成3个簇。
在这里插入图片描述

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

# 解决中文显示问题
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False


# 功能: 计算样本与聚类中心的距离, 返回离簇中心最近的类别
# params: sample: 单个数据样本, centers: k个簇中心
# return: 返回的是当前的样本数据属于那一个簇中心的id或者索引
def distance(sample1, centers1):
    # 这里使用欧氏距离计算公式
    dist = np.sqrt(np.sum(np.square(sample1 - centers1), axis=1))
    minIdx = np.argmin(dist)
    return minIdx


# 功能: 对当前的分类集进行可视化展示
def clusters_show(clusters, center, step):
    color = ["g", "b", "y"]
    plt.figure(figsize=(8, 8))
    plt.title("迭代次数: {}".format(step))
    plt.xlabel("密度", loc="center")
    plt.ylabel("糖含量", loc="center")
    # 用颜色区分k个簇的数据样本
    for i, cluster in enumerate(clusters):
        cluster = np.array(cluster)
        plt.scatter(center[:, 0], center[:, 1], marker='x', color='red', s=100)
        plt.scatter(cluster[:, 0], cluster[:, 1], c=color[i], marker='.', s=150)


# 功能: 根据输入的样本集与划分的簇数,分别返回k个簇样本
# params: samples:样本集, k:聚类簇数
# return:返回是每个簇的簇类中心
def k_means(samples, k):
    data_number = len(samples)
    centers_flag = np.zeros((k,))
    # 随机在数据中选择k个聚类中心
    center = samples[np.random.choice(data_number, k, replace=False)]
    plt.title("初始化原型向量")
    plt.xlabel("密度", loc="center")
    plt.ylabel("糖含量", loc="center")
    plt.scatter(center[:, 0], center[:, 1], marker='x', color='red', s=100)
    plt.scatter(samples[:, 0], samples[:, 1], c='black')
    step = 0
    while True:
        # 计算每个样本距离簇中心的距离, 然后分到距离最短的簇中心中
        clusters = [[] for i in range(k)]
        for sample1 in samples:
            ci = distance(sample1, center)
            clusters[ci].append(sample1)
        # 可视化当前的聚类结构
        clusters_show(clusters, center, step)
        # 分完簇之后更新每个簇的中心点, 得到了簇中心继续进行下一步的聚类
        for i, sub_clusters in enumerate(clusters):
            new_center = np.array(sub_clusters).mean(axis=0)
            # 如果数值有变化则更新, 如果没有变化则设置标志位为1,当所有的标志位为1则退出循环
            if (center[i] != new_center).all():
                center[i] = new_center
            else:
                centers_flag[i] = 1
        step += 1
        if centers_flag.all():
            break
    return center


# 功能: 根据簇类中心对簇进行分类,获取最后的分类结果
# params: samples是全部的数据样本,centers是聚类好的簇中心
# return: 返回的是子数组
def split_data(samples, centers1):
    # 根据中心样本得知簇数
    k = len(centers1)
    clusters = [[] for i in range(k)]
    for samples in samples:
        ci = distance(samples, centers1)
        clusters[ci].append(samples)
    return clusters


if __name__ == '__main__':
    # 功能: 设置随机种子, 确保结果可复现
    np.random.seed(5)
    data = pd.read_csv('watermelon4.0.csv', header=None)
    sample = data.iloc[:, 1:3].values
    centers = k_means(sample, 3)
    plt.show()

学习向量量化 (LVQ)

基本定义

“学习向量量化 (LVQ)”算法目标是通过找到一组原型向量来代表聚类的中心。与其他聚类算法不同的是,LVQ 是有标签的聚类。即假设每个样本是有类别标签的,LVQ 通过这些假设的标签来辅助聚类。

基本思想:
(1) 初始化 q 个原型向量(q 代表需要聚类的类别个数):根据样本的类别标记,从各类中
分别随机选出一个样本作为该类簇的原型,从而组成了一个原型特征向量组。
(2) 对原型向量进行优化:在每一轮迭代中,从样本集中随机挑选一个样本,计算其与原型向量组中每个向量的距离,并选取距离最小的原型向量所在的类簇作为它的划分结果,再与真实类标比较。若划分结果正确,则对应原型向量向这个样本靠近一些;若划分结果不正确,则对应原型向量向这个样本远离一些。

缺点:因为一般使用欧氏距离,各特征的权重是相同的,无法反映不同特征的重要性差异。

LVQ算法实现:
1.输入:
①样本集: D = ( X 1 ⃗ , y 1 ) , ( X 2 ⃗ , y 2 ) , … , ( X m ⃗ , y m ) D={(\vec{X_1},y_1),(\vec{X_2},y_2),\dots,(\vec{X_m},y_m)} D=(X1 ,y1),(X2 ,y2),,(Xm ,ym)。其中,每个样本 X j ⃗ \vec{X_j} Xj 是由 n n n个属性组成的特征向量 ( x j 1 ; x j 2 ; … , x j n ) (x_{j1};x_{j2};\dots,x_{jn}) (xj1;xj2;,xjn), y i ∈ γ y_i \in \gamma yiγ是样本 X j ⃗ \vec{X_j} Xj 的类别标签。
② 原型向量的个数 q q q,各原型向量预设的类别标记 { t 1 , t 2 , … , t q } \{t_1,t_2,\dots,t_q\} {t1,t2,,tq}
③ 学习率 η ∈ ( 0 , 1 ) \eta \in (0,1) η(0,1)
2.目标:学得一组 n n n维原型向量 { p 1 ⃗ , p 2 ⃗ , … , p q ⃗ } \{ \vec{p_1},\vec{p_2},\dots,\vec{p_q}\} {p1 ,p2 ,,pq },每个原型向量代表一个聚类簇,簇标记 t i ∈ γ t_i \in \gamma tiγ
3.算法过程:
①初始化一组原型向量 { p 1 ⃗ , p 2 ⃗ , … , p q ⃗ } \{ \vec{p_1},\vec{p_2},\dots,\vec{p_q}\} {p1 ,p2 ,,pq }
②从样本集中随机选取样本 ( X i ⃗ , y i ) (\vec{X_i},y_i) (Xi ,yi)
③ 计算样本 X i ⃗ \vec{X_i} Xi p i ⃗ ( 1 ≤ i ≤ q ) \vec{p_i} (1\leq i \leq q) pi (1iq)的距离: d j i = ∣ ∣ X i ⃗ − p i ⃗ ∣ ∣ 2 = ∑ u = 1 n ∣ x i u − x j u ∣ 2 d_{ji}=|| \vec{X_i}-\vec{p_i} ||_2=\sqrt{\sum_{u=1}^{n}|x_{iu}-x_{ju}|^2} dji=∣∣Xi pi 2=u=1nxiuxju2
④ 找出与 X i ⃗ \vec{X_i} Xi 距离最近的原型向量 p i ∗ p_{i*} pi,其中 i ∗ = a r g   m i n i ∈ { 1 , 2 , … , q } d j i i* = arg\ min_{i \in \{1,2,\dots,q\} } d_{ji} i=arg mini{1,2,,q}dji
⑤ 如果样本的标签 y j = = t i ∗ y_j==t_{i*} yj==ti,即 X j ⃗ \vec{X_j} Xj p i ∗ p_{i*} pi的类别相同,则 p ‘ = p i ∗ + η ⋅ ( X j ⃗ − p i ∗ ⃗ ) p`=p_{i*}+\eta\cdot( \vec{X_j}-\vec{p_{i*}}) p=pi+η(Xj pi ),即聚类中心向 X j ⃗ \vec{X_j} Xj 靠近
⑥如果样本的标签 y j ≠ t i ∗ y_j \neq t_{i*} yj=ti,即 X j ⃗ \vec{X_j} Xj p i ∗ p_{i*} pi的类别不同,则 p ‘ = p i ∗ − η ⋅ ( X j ⃗ − p i ∗ ⃗ ) p`=p_{i*}-\eta\cdot( \vec{X_j}-\vec{p_{i*}}) p=piη(Xj pi ),即聚类中心向 X j ⃗ \vec{X_j} Xj 远离
⑦将原型向量 p i ∗ p_{i*} pi更新为 p ‘ p` p
⑧重复步骤 2 − 7 2-7 27直到满足停止条件(一般是原型向量不再变动或者变动很小,或者达到了最大的迭代次数)
⑨ 输出原型向量 { p 1 ⃗ , p 2 ⃗ , … , p q ⃗ } \{ \vec{p_1},\vec{p_2},\dots,\vec{p_q}\} {p1 ,p2 ,,pq }

LVQ 算法的关键:
其循环内的操作(即步骤 2 − 7 2-7 27)是在更新原型向量。即对于样本 x j ⃗ \vec{x_j} xj ,如果最近的原型向量 p i ∗ p_{i*} pi x j ⃗ \vec{x_j} xj 的类别相同,则 p i ∗ p_{i*} pi x j ⃗ \vec{x_j} xj 的方向靠拢,即步骤5所示,此时新的原型向量为:
p ‘ = p i ∗ + η ⋅ ( X j ⃗ − p i ∗ ⃗ ) p`=p_{i*}+\eta\cdot( \vec{X_j}-\vec{p_{i*}}) p=pi+η(Xj pi )
此时 p ‘ 与 X j ⃗ p`\text{与}\vec{X_j} pXj 的距离为:
在这里插入图片描述

因为 η ∈ ( 0 , 1 ) \eta \in (0,1) η(0,1),所以距离 ∣ ∣ p ‘ − X j ⃗ ∣ ∣ 2 < ∣ ∣ p i ∗ − X j ⃗ ∣ ∣ 2 || p`-\vec{X_j} ||_2< || p_{i*}-\vec{X_j}||_2 ∣∣pXj 2<∣∣piXj 2,即原型向量更新为 p ‘ p` p后距离 x j ⃗ \vec{x_j} xj 更近了。

同理,如果最近的原型向量 p i ∗ p_{i*} pi x j ⃗ \vec{x_j} xj 的类别不同,则更新后的原型向量与 x j ⃗ \vec{x_j} xj 的距离为: ( 1 + η ) ⋅ ∣ ∣ p i ∗ − X j ⃗ ∣ ∣ 2 (1+\eta)\cdot|| p_{i*}-\vec{X_j}||_2 (1+η)∣∣piXj 2,距离变大了,也就是说更远离 x j ⃗ \vec{x_j} xj

一次循环(即步骤 2 − 7 2-7 27)生成一组新原型向量后,即实现对样本空间 χ \chi χ进行簇划分,对于任意样本 X ⃗ \vec{X} X ,将被划分到与其距离最近的原型向量所代表的簇中;也就是说,对于每个原型向量 p i p_{i} pi都定义了区域 R i R_i Ri,在这个区域内每个样本与 p i p_{i} pi的距离小于该样本与其他原型向量 p i ‘ ( i ‘ ≠ i ) p_{i`} (i` \neq i ) pi(i=i)的距离,即
R i = { x ⃗ ∈ χ ∣   ∣ ∣ x ⃗ − p i ⃗ ∣ ∣ 2 ≤ ∣ ∣ x ⃗ − p i ‘ ⃗ ∣ ∣ 2 , i ‘ ≠ i } R_i = \{\vec{x}\in \chi|\ ||\vec{x}-\vec{p_i}||_2 \leq ||\vec{x}-\vec{p_i`}||_2,i` \neq i\} Ri={x χ ∣∣x pi 2∣∣x pi 2,i=i}
由此形成对样本空间 χ \chi χ的簇划分 { R 1 , R 2 , … , R q } \{R_1,R_2,\dots,R_q \} {R1,R2,,Rq},该簇划分通常称为``Voronoi部分’’。

LVQ 算法实例

假设存在一个带标签的数据集,如图\ref{C10}。其中横轴(即 x x x轴)为西瓜密度,纵轴(即 y y y轴)为西瓜含糖量;不同颜色代表不同类别标记,记黄色的类别标记为 c 1 c1 c1(好瓜=否),黑色的类别标记为 c 2 c2 c2(好瓜=是)
现在目的是将数据集分成5个簇,即 q = 5 q=5 q=5。也就是说要找到5个原型向量 { p 1 ⃗ , p 2 ⃗ , p 3 ⃗ , p 4 ⃗ , p 5 ⃗ } \{ \vec{p_1},\vec{p_2},\vec{p_3},\vec{p_4},\vec{p_5}\} {p1 ,p2 ,p3 ,p4 ,p5 },并定义其对应的类别标记为: c 1 , c 2 , c 3 , c 4 , c 5 c_1,c_2,c_3,c_4,c_5 c1,c2,c3,c4,c5,(即分成3个’‘好瓜=是’'的簇和2个``好瓜=否’’的簇)
在这里插入图片描述
如图,算法首先在样本集中随机选取5个样本作为原型向量,然后计算各个样本与这5个原型向量的距离,然后把各个样本划分给距离该样本最近的原型向量。例如某样本与5个原型向量 { p 1 ⃗ , p 2 ⃗ , p 3 ⃗ , p 4 ⃗ , p 5 ⃗ } \{ \vec{p_1},\vec{p_2},\vec{p_3},\vec{p_4},\vec{p_5}\} {p1 ,p2 ,p3 ,p4 ,p5 }的距离为: 0.283 , 0.506 , 0.434 , 0.260 , 0.032 0.283,0.506,0.434,0.260,0.032 0.283,0.506,0.434,0.260,0.032,因为该样本与 p 5 ⃗ \vec{p_5} p5 的距离最近,所以将该样本划分给 p 5 ⃗ \vec{p_5} p5 对应的 c 1 c_1 c1类别中,然后 p 5 ⃗ \vec{p_5} p5 就会向该样本靠近,更新后的新原型向量 p 5 ⃗ \vec{p_5} p5 为(此处学习率为0.1):
在这里插入图片描述

如图中所示通过不断迭代更新,最终会划分成5个不同簇,迭代到500次以后基本上已经收敛了
在这里插入图片描述

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd


def LVQ(X1, y1, pNum, learningRate=0.1):
    # 随机选择pNum个样本作为p向量
    idx = np.random.choice(X1.shape[0], pNum)
    p = X1[idx, :]
    # 获取p的标签
    py = y1[idx]
    # 画图用
    fig, ax = plt.subplots(3, 3, figsize=(12, 12), sharex='all', sharey='all')
    # 解决中文显示问题
    plt.rcParams['font.sans-serif'] = ['SimHei']
    plt.rcParams['axes.unicode_minus'] = False
    # 初始化原型向量图
    ax[0, 0].scatter(X1[:, 0], X1[:, 1], c=y1)
    ax[0, 0].scatter(p[:, 0], p[:, 1], marker='x', color='red', s=100)
    ax[0, 0].set_title("初始化原型向量")
    ax[0, 0].set_xlim(xlim)
    ax[0, 0].set_ylim(ylim)
    j = 0
    for i in range(2001):
        # 随机选择一个样本xi
        idx = np.random.choice(X1.shape[0], 1)
        xi = X1[idx, :]
        # 计算xi到各个p向量的距离
        dist = np.sqrt(np.sum(np.square(xi - p), axis=1))
        # 找到最小距离p向量的索引
        minIdx = np.argmin(dist)
        # 如果xi的标签与该向量的标签相等,则靠近,不然就原理
        if y1[idx] == py[minIdx]:
            p[minIdx] = p[minIdx] + learningRate * (xi - p[minIdx])
        else:
            p[minIdx] = p[minIdx] - learningRate * (xi - p[minIdx])
        # 每循环500次画图
        if (i > 0) and (i in [20, 50, 100, 200, 500, 1000, 1500, 2000]):
            j += 1
            clusters = []
            # 对于样本里的每一个x,找到它属于哪个类
            for x in X1:
                dist = np.sqrt(np.sum(np.square(x - p), axis=1))
                label = np.argmin(dist)
                clusters.append(label)
            if j < 3:
                k = 0
            elif j < 6:
                k = 1
            else:
                k = 2
            if not ((k == 0) and ((j % 3) == 0)):
                ax[k, j % 3].scatter(X[:, 0], X[:, 1], c=clusters)
                ax[k, j % 3].scatter(p[:, 0], p[:, 1], marker='x', color='red', s=100)
                ax[k, j % 3].set_title("迭代次数: %d" % i)
                ax[k, j % 3].set_xlim(xlim)
                ax[k, j % 3].set_ylim(ylim)


if __name__ == "__main__":
    data = pd.read_csv('watermelon4.0.csv', header=None)
    data['y'] = np.zeros((data.shape[0], 1), dtype=int)
    data.iloc[9:22, 3] = 1
    X = data.iloc[:, 1:3].values
    y = data.iloc[:, 3].values

    plt.scatter(X[:, 0], X[:, 1], c=y)
    xlim = (plt.axis()[0], plt.axis()[1])
    ylim = (plt.axis()[2], plt.axis()[3])

    LVQ(X, y, 5)
    plt.show()

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_66397563/article/details/127178902

当小样本遇上机器学习 fewshot learning_mao_feng的博客-爱代码爱编程_小样本机器学习

引言    深度学习(deep learning)已经广泛应用于各个领域,解决各类问题,例如在图像分类问题下,如图1,区分这10类目标的准确率目前可以轻松做到94%。然而,deep learning是一种data hungry的技术,需要大量的标注样本才能发挥作用。 图1    现实世界中,有很多问题是没有这么多的标注数据的,获取标注数据的成本

机器学习(概述一)——定义_张连海的博客-爱代码爱编程_机器学习定义

何谓机器学习不同人的认知与人类认知过程的对比基本定义基本概念 机器学习能用来干吗机器学习的常见应用框架机器学习的分类基于学习形式分类基于目的分类 机器学习中的十大经典算法补充术语关系 总结 机器学

学习曲线 机器学习_机器学习的学习曲线-爱代码爱编程

学习曲线 机器学习 Diagnose Bias and Variance to Reduce Error 诊断偏差和方差以减少误差 When building machine learning models, we want to keep error as low as possible. Two major sources of er

机器学习算法——线性回归(超级详细且通俗)-爱代码爱编程

通俗理解线性回归 回归分析 什么是回归分析呢?这是一个来自统计学的概念。回归分析是指一种预测性的建模技术,主要是研究自变量和因变量的关系。通常使用线/曲线来拟合数据点,然后研究如何使曲线到数据点的距离差异最小。 例如,存在以下数据 然后我们拟合一条曲线f(x): 回归分析的目标就是要拟合一条曲线,让图中红色线段加起来的和最小。 线性回归(简介) 线

机器学习 第一讲 机器学习概述-爱代码爱编程

文章目录 一、机器学习与应用1.“人工智能之父”--艾伦.图灵2.人工智能的知识图谱二、AI,ML,DL的关系1.机器学习是实现人工智能的一种方法,深度学习是机器学习一个分支2.机器学习领域3.机器学习库和框架4.什么是机器学习?5.为什么需要机器学习?5.1 解放生产力,智能客服5.2 解决专业问题,ET医疗5.3 提供社会便利,城市大脑三、机器

机器学习一词是由谁提出的?关于机器学习,你需要了解的那些事儿!-爱代码爱编程

为了方便交流,建了个鹅群: 953882093,有人工智能方面的问题可询群内大佬 【导读】:全面介绍机器学习发展的历史,从感知机、神经网络、决策树、SVM、Adaboost到随机森林、Deep Learning。  自科学技术和人工智能最初发展开始,科学家Blaise Pascal和Von Leibniz就思考着如何制造一台像人类一样具有智力的机器

机器学习心得-爱代码爱编程

一. 机器学习的概念: 解释1:机器学习是一门通过编程让计算机从数据中进行学习的学科。 解释2:机器学习是一个研究领域,让计算机无须进行明确的编程就具备学习能力。 解释2:一个计算机程序利用经验E来学习任务T,性能是P,如果针对任务T的性能P随着经验E不断增长,则称之为机器学习。 二 . 我理解的过程: 解决一个问题-> 发现规律->

机器学习和深度学习的区别-爱代码爱编程

Python微信订餐小程序课程视频 https://edu.csdn.net/course/detail/36074 Python实战量化交易理财系统 https://edu.csdn.net/course/detail/35475 终于考上人工智能的研究僧啦,不知道机器学习和深度学习有啥区别,感觉一切都是深度学习挖槽,听说学长已经调了10个月的参

十大机器学习算法-爱代码爱编程

初学者应该知道的十大机器学习算法 来源:https://builtin.com/data-science/tour-top-10-algorithms-machine-learning-newbies 机器学习算法被描述为学习一个目标函数 (f),它最好地将输入变量 (X) 映射到输出变量 (Y):Y = f(X) 最常见的机器学习类型是学

“机器学习”名字的由来-爱代码爱编程

 阿瑟·萨缪尔(Arthur Samuel, 1901-1990) 阿瑟·萨缪尔是人工智能研究的先驱。 从1949年到1960年代后期,他在让计算机从经验中学习方面做了最出色的工作,而他的研究工具是跳棋游戏。(玩游戏的程序通常在人工智能研究中扮演果蝇在遗传学中所扮演的角色。果蝇对遗传学很方便,因为它们繁殖速度快,饲养成本低,而游戏对人工智能很方便,因

李宏毅2021&2022机器学习-爱代码爱编程

重磅须知  (重磅须知,统一说明)为方便所有网课资料与优质电子书籍的实时更新维护,创建了一个在线实时网盘文件夹,放在公众号【啥都会一点的研究生】,本节课对应序号【05】。    UP将2021&2022所有作业的数据资料整理打包好了,由于文件太大,已同步放在上述所提在线网盘。    在线网盘能满足该课程所需资料的全部需求,链接挂掉也会