2023.10.3学习

本文介绍了无监督学习中的三种聚类方法:KMeans、Meanshift和DBSCAN。KMeans通过预先设定聚类数,计算每个点到中心的距离;Meanshift则自动发现类别数量,中心点根据周围密度移动;DBSCAN基于密度而非固定数量的类别。文中还展示了这些方法在实际数据集上的应用和与监督学习(如KNN)的对比。
摘要由CSDN通过智能技术生成

2023.10.3学习

人工智能基础学习

无监督学习

机器学习的一种方法,没有给定事先标记过的训练示例,自动对输入的数据进行分类或分群。(寻找数据的共同点,结果没有对错之分)

优点:算法不受监督信息的约束;不需要标签数据,数据样本大。

主要应用:聚类分析、关联规则、维度缩减。

聚类分析

聚类分析又称群分析,根据对象某些属性的相似度,将其自动划分为不同的类别。

常用算法

(1)KMeans聚类(K均值聚类)

  • 根据数据与中心点距离划分类别
  • 基于类别数据更新中心点
  • 重复过程直到收敛

特点:实现简单、收敛快;需要指定划分为几类

(2)Meanshift(均值漂移聚类)

  • 在中心点一定区域检索数据点
  • 更新中心
  • 重复流程到中心点稳定

特点:自动发现类别数量(几类数据),不需要人工选择;需要指定区域半径

(3)DBSCAN算法(基于密度的空间聚类算法)

  • 基于区域点密度筛选有效数据
  • 基于有效数据向周边扩张,直到没有新点加入

特点:过滤噪音数据;不需要人为指定类别数量;数据密度不同的时候会影响结果。

K均值聚类

以空间中k个点为中心进行聚类,对最靠近他们的对象归类。

from sklearn.cluster import KMeans
  1. 数学公式:

数据点与各簇中心点的距离(ujt : t状态下第 j 区域中心):
d i s t ( x i , u j t ) dist(x_i,u_j^t) dist(xi,ujt)
根据距离归类(该数据点属于离它最近的数据中心所在的区域):
x i ∈ u n e a r e s t t x_i \in u^t_{nearest} xiunearestt
中心更新(Sj :t 时刻第 j 个区域簇;k:包含在Sj范围内点的个数):取区域中所有点的平均值作为新的中心点
u j t + 1 = 1 k ∑ x i ∈ S j ( x i ) u_j^{t+1} = \frac 1 k \sum\limits_{x_i \in S_j}(x_i) ujt+1=k1xiSj(xi)

  1. 算法流程:

(1)选择聚类的个数k

(2)确定聚类中心(随机选定)

(3)根据各点到聚类中心的距离确定各点所属类别(聚类)

(4)根据各个类别数据更新聚类中心

(5)重复步骤3-4,直到聚类中心收敛

  1. 特点

​ 优点:原理简单,实现容易,收敛速度快;参数少,使用方便

​ 缺点:必须设置簇(区域)的数量;随机选择初始聚类中心,结果可能缺乏一致性。

  1. 代码
import pandas as pd
from matplotlib import pyplot as plt
import numpy as np
from sklearn.cluster import KMeans
from sklearn.metrics import accuracy_score

data = pd.read_csv('data.csv')
print(data.head())

fig1 = plt.figure()
plt.scatter(data.loc[:, 'V1'], data.loc[:, 'V2'])
plt.title('un-labeled data')
plt.show()

# 赋值
X = data.drop('label', axis=1)
print(X.head())
y = data.loc[:, 'label']

# pd.value_counts(y)  # 此方法将被废除,使用下一行代码的方法pd.Series.value_counts()以代替
print(pd.Series.value_counts(y))  # 显示y列有多少类别的数据

# 绘制实际的分类图
fig2 = plt.figure()
label0 = plt.scatter(data.loc[:, 'V1'][y == 0], data.loc[:, 'V2'][y == 0])
label1 = plt.scatter(data.loc[:, 'V1'][y == 1], data.loc[:, 'V2'][y == 1])
label2 = plt.scatter(data.loc[:, 'V1'][y == 2], data.loc[:, 'V2'][y == 2])
plt.title('labeled data')
plt.legend((label0, label1, label2),('label0', 'label1', 'label2'))
plt.show()

# 建立KMeans模型
KM = KMeans(n_clusters=3, random_state=0)  # 创建实例。参数n_clusters为指定将数据归为几类;random_state=0确保每次训练效果保持一致
print(X.shape, y.shape)  # 检查维度
KM.fit(X)  # 模型训练

# 获得聚类的中心点并显示
centers = KM.cluster_centers_

fig3 = plt.figure()
plt.scatter(centers[:, 0], centers[:, 1])
label0 = plt.scatter(data.loc[:, 'V1'][y == 0], data.loc[:, 'V2'][y == 0])
label1 = plt.scatter(data.loc[:, 'V1'][y == 1], data.loc[:, 'V2'][y == 1])
label2 = plt.scatter(data.loc[:, 'V1'][y == 2], data.loc[:, 'V2'][y == 2])
plt.title('labeled data')
plt.legend((label0, label1, label2), ('label0', 'label1', 'label2'))
plt.show()

# 预测指定点(V1 = 80, V2 = 60)的数据类别
y_test_predict = KM.predict([[80, 60]])
print(y_test_predict)

# 验证准确率
y_predict = KM.predict(X)
print(pd.value_counts(y_predict), pd.value_counts(y))  # 打印y_predict和y的数据分布
accuracy = accuracy_score(y, y_predict)
print(accuracy)

# 可视化结果
fig4 = plt.subplot(122)
label0 = plt.scatter(data.loc[:, 'V1'][y_predict == 0], data.loc[:, 'V2'][y_predict == 0])
label1 = plt.scatter(data.loc[:, 'V1'][y_predict == 1], data.loc[:, 'V2'][y_predict == 1])
label2 = plt.scatter(data.loc[:, 'V1'][y_predict == 2], data.loc[:, 'V2'][y_predict == 2])
plt.scatter(centers[:, 0], centers[:, 1])
plt.title('predicted data')
plt.legend((label0, label1, label2), ('label0', 'label1', 'label2'))

fig5 = plt.subplot(121)  # 原始数据
plt.scatter(centers[:, 0], centers[:, 1])
label0 = plt.scatter(data.loc[:, 'V1'][y == 0], data.loc[:, 'V2'][y == 0])
label1 = plt.scatter(data.loc[:, 'V1'][y == 1], data.loc[:, 'V2'][y == 1])
label2 = plt.scatter(data.loc[:, 'V1'][y == 2], data.loc[:, 'V2'][y == 2])
plt.title('labeled data')
plt.legend((label0, label1, label2), ('label0', 'label1', 'label2'))
plt.show()

# 数据校正
y_corrected = []
for i in y_predict:
    if i == 0:
        y_corrected.append(1)
    elif i == 1:
        y_corrected.append(2)
    else:
        y_corrected.append(0)

print(pd.value_counts(y_corrected), pd.value_counts(y))

print(accuracy_score(y, y_corrected))

# 再次可视化结果
y_corrected = np.array(y_corrected)  # 转化为数组格式

fig6 = plt.subplot(122)
label0 = plt.scatter(data.loc[:, 'V1'][y_corrected == 0], data.loc[:, 'V2'][y_corrected == 0])
label1 = plt.scatter(data.loc[:, 'V1'][y_corrected == 1], data.loc[:, 'V2'][y_corrected == 1])
label2 = plt.scatter(data.loc[:, 'V1'][y_corrected == 2], data.loc[:, 'V2'][y_corrected == 2])
plt.scatter(centers[:, 0], centers[:, 1])
plt.title('corrected data')
plt.legend((label0, label1, label2), ('label0', 'label1', 'label2'))

fig7 = plt.subplot(121)  # 原始数据
plt.scatter(centers[:, 0], centers[:, 1])
label0 = plt.scatter(data.loc[:, 'V1'][y == 0], data.loc[:, 'V2'][y == 0])
label1 = plt.scatter(data.loc[:, 'V1'][y == 1], data.loc[:, 'V2'][y == 1])
label2 = plt.scatter(data.loc[:, 'V1'][y == 2], data.loc[:, 'V2'][y == 2])
plt.title('labeled data')
plt.legend((label0, label1, label2), ('label0', 'label1', 'label2'))
plt.show()

对比:KNN算法(K近邻分类模型)(监督学习:已对已有数据分好类别)

​ 给定一个训练数据集,对新的输入实例,在训练数据集中找到与该实例最邻近的k个实例,这k个实例的多数属于某个类,就把该输入实例分入某个类。

from sklearn.neighbors import KNeighborsClassifier
from matplotlib import pyplot as plt
import pandas as pd
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import accuracy_score

data = pd.read_csv('data.csv')
print(data.head())

X = data.drop('label', axis=1)
y = data.loc[:, 'label']

fig1 = plt.figure()
label0 = plt.scatter(X.loc[:, 'V1'][y == 0], X.loc[:, 'V2'][y == 0])
label1 = plt.scatter(X.loc[:, 'V1'][y == 1], X.loc[:, 'V2'][y == 1])
label2 = plt.scatter(X.loc[:, 'V1'][y == 2], X.loc[:, 'V2'][y == 2])
plt.title('labeled data')
plt.legend((label0, label1, label2), ('label0', 'label1', 'label2'))
plt.show()

# 建立KNN模型
KNN = KNeighborsClassifier(n_neighbors=3)  # 创建KNN实例,需要在参数n_neighbors中说明数据分为几类
KNN.fit(X, y)

# 预测数据V1 = 80, V2 = 60数据哪个类别
y_predict_knn_test = KNN.predict([[80, 60]])
print(y_predict_knn_test)

# 预测准确率
y_predict_knn = KNN.predict(X)
print('knn_accuracy: ', accuracy_score(y, y_predict_knn))

print(pd.value_counts(y_predict_knn), pd.value_counts(y))

# 结果可视化
fig2 = plt.subplot(121)
label0 = plt.scatter(X.loc[:, 'V1'][y == 0], X.loc[:, 'V2'][y == 0])
label1 = plt.scatter(X.loc[:, 'V1'][y == 1], X.loc[:, 'V2'][y == 1])
label2 = plt.scatter(X.loc[:, 'V1'][y == 2], X.loc[:, 'V2'][y == 2])
plt.title('labeled data')
plt.legend((label0, label1, label2), ('label0', 'label1', 'label2'))

fig3 = plt.subplot(122)
label0 = plt.scatter(X.loc[:, 'V1'][y_predict_knn == 0], X.loc[:, 'V2'][y_predict_knn == 0])
label1 = plt.scatter(X.loc[:, 'V1'][y_predict_knn == 1], X.loc[:, 'V2'][y_predict_knn == 1])
label2 = plt.scatter(X.loc[:, 'V1'][y_predict_knn == 2], X.loc[:, 'V2'][y_predict_knn == 2])
plt.title('predicted_knn data')
plt.legend((label0, label1, label2), ('label0', 'label1', 'label2'))
plt.show()
均值漂移聚类

一种基于密度梯度上升的聚类算法(沿着密度上升方向寻找聚类中心点)

from sklearn.cluster import MeanShift, estimate_bandwidth
  1. 数学公式:

均值漂移(取所有点到中心点的距离的均值 为漂移距离)(Sh:以 u 为中心点,半径为 h 的高维球区域;k:包含在Sh范围内点个数):
M ( x ) = 1 k ∑ x i ∈ S h ( u − x i ) M(x) = \frac 1 k \sum_{x_i \in S_h}(u-x_i) M(x)=k1xiSh(uxi)
中心更新(Mt:t状态下求得的偏移均值,ut:t状态下的区域中心):
u t + 1 = M t + u t u^{t+1}=M^t+u^t ut+1=Mt+ut

  1. 算法流程:

(1)随机选择未被分类的点

(2)找出离中心点距离在带宽之内的点,记作集合S

(3)计算从中心点到集合S中每个元素的偏移向量M

(4)中心点以向量M移动

(5)重复步骤2-4,直到收敛

(6)重复步骤1-5,直到所有的点都被归类

(7)分类:根据每个类 对每个点的访问频率,取访问频率最大的那个类,作为当前点集的所属类。

  1. 代码
import pandas as pd
from matplotlib import pyplot as plt
from sklearn.cluster import MeanShift, estimate_bandwidth

data = pd.read_csv('data.csv')
print(data.head())

X = data.drop('label', axis=1)
y = data.loc[:, 'label']

fig1 = plt.figure()
label0 = plt.scatter(X.loc[:, 'V1'][y == 0], X.loc[:, 'V2'][y == 0])
label1 = plt.scatter(X.loc[:, 'V1'][y == 1], X.loc[:, 'V2'][y == 1])
label2 = plt.scatter(X.loc[:, 'V1'][y == 2], X.loc[:, 'V2'][y == 2])
plt.title('labeled data')
plt.legend((label0, label1, label2), ('label0', 'label1', 'label2'))
plt.show()

# 获取带宽
bw = estimate_bandwidth(X, n_samples=150)  # X为样本,n_samples为样本数量估计值
print(bw)

# 建立模型
ms = MeanShift(bandwidth=bw)
ms.fit(X)  # 训练数据

# 预测准确率
y_predict_ms = ms.predict(X)
print(pd.value_counts(y_predict_ms), pd.value_counts(y))

# 结果可视化
fig2 = plt.subplot(121)
label0 = plt.scatter(X.loc[:, 'V1'][y == 0], X.loc[:, 'V2'][y == 0])
label1 = plt.scatter(X.loc[:, 'V1'][y == 1], X.loc[:, 'V2'][y == 1])
label2 = plt.scatter(X.loc[:, 'V1'][y == 2], X.loc[:, 'V2'][y == 2])
plt.title('labeled data')
plt.legend((label0, label1, label2), ('label0', 'label1', 'label2'))

fig3 = plt.subplot(122)
label0 = plt.scatter(X.loc[:, 'V1'][y_predict_ms == 0], X.loc[:, 'V2'][y_predict_ms == 0])
label1 = plt.scatter(X.loc[:, 'V1'][y_predict_ms == 1], X.loc[:, 'V2'][y_predict_ms == 1])
label2 = plt.scatter(X.loc[:, 'V1'][y_predict_ms == 2], X.loc[:, 'V2'][y_predict_ms == 2])
plt.title('predicted_ms data')
plt.legend((label0, label1, label2), ('label0', 'label1', 'label2'))
plt.show()

控制方面,复习了超前校正、滞后校正、pid方面的知识

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值