知名企业门户网站建设服务公司,怎么拥有自己的小程序,做网站如何让盈利,汽车4s销售网站模板传统机器学习(四)聚类算法DBSCAN
1.1 算法概述
DBSCAN#xff08;Density-Based Spatial Clustering of Applications with Noise#xff0c;具有噪声的基于密度的聚类方法#xff09;是一种基于密度的空间聚类算法。
该算法将具有足够密度的区域划分为簇#xff0c;并在…传统机器学习(四)聚类算法DBSCAN
1.1 算法概述
DBSCANDensity-Based Spatial Clustering of Applications with Noise具有噪声的基于密度的聚类方法是一种基于密度的空间聚类算法。
该算法将具有足够密度的区域划分为簇并在具有噪声的空间数据库中发现任意形状的簇它将簇定义为密度相连的点的最大集合。
1.1.1 基本概念
核心对象: 若某个点的密度达到算法设定的阈值则其为核心点(即r 邻域内点的数量不小于 minPts )
e-邻域的距离阈值:设定的半径
直接密度可达: 若某点p在点q的 r 域内且q是核心点则p-q直接密度可达
密度可达: 若有一个点的序列q0、q1、…qk对任意qi-qi-1是直接密度可达的则称从q0到qk密度可达这实际上是直接密度可达的“传播”
边界点:属于某一个类的非核心点,不能发展下线了
噪声点: 不属于任何一个类簇的点从任何一个核心点出发都是密度不可达的 上面这些点是分布在样本空间的众多样本现在我们的目标是把这些在样本空间中距离相近的聚成一类。
我们发现A点附近的点密度较大红色的圆圈根据一定的规则在这里滚啊滚最终收纳了A附近的5个点标记为红色也就是定为同一个簇。
其它没有被收纳的根据一样的规则成簇。
形象来说我们可以认为这是系统在众多样本点中随机选中一个围绕这个被选中的样本点画一个圆规定这个圆的半径以及圆内最少包含的样本点如果在指定半径内有足够多的样本点在内那么这个圆圈的圆心就转移到这个内部样本点继续去圈附近其它的样本点类似传销一样继续去发展下线。
等到这个滚来滚去的圈发现所圈住的样本点数量少于预先指定的值(minPts)就停止了。那么我们称最开始那个点为核心点如A停下来的那个点为边界点如B、C没得滚的那个点为离群点如N。
基于密度这点有什么好处呢
我们知道kmeans聚类算法只能处理球形的簇也就是一个聚成实心的团这是因为算法本身计算平均距离的局限。但往往现实中还会有各种形状比如下面图环形和不规则形这个时候那些传统的聚类算法显然就悲剧了。 1.1.2 DBSCAN工作流程 1.1.3 参数选择及可视化
参数选择
DBSCAN算法的两个参数这两个参数比较难指定 半径 半径是最难指定的 大了圈住的就多了簇的个数就少了反之簇的个数就多了这对我们最后的结果是有影响的。这个时候K距离可以帮助我们来设定半径r也就是要找到突变点。 首先选中一个点计算它和所有其它点的距离,从小到大排序,d1,d2,d3,d4等等假如我们发现 d3 和 d4 之间的差异很大于是认为前面的距离是比较合适的那么就可以指定出来 r 半径的大小。虽然是一个可取的方式但是有时候比较麻烦 大部分还是都试一试进行观察用k距离需要做大量实验来观察很难一次性把这些值都选准。
MinPts 这个参数就是圈住的点的个数也相当于是一个密度一般这个值都是偏小一些然后进行多次尝试。
可视化
有一个网站(https://www.naftaliharris.com/blog/visualizing-dbscan-clustering/)可以把我们DBSCAN的迭代过程动态图画出来 设置好参数点击GO! 就开始聚类了 1.1.4 DNSCAN优缺点
优点 不需要指定簇个数 可以发现任意形状的簇 擅长找到离群点( 检测任务) 两个参数就够了
缺点 高维数据有些困难(可以做降维) 参数难以选择(参数对结果的影响非常大) Sklearn中效率很慢(数据削减策略)
1.2 DBScan算法案例
1.2.1 不同半径对算法结果影响
1.2.1.1 利用sklearn中make_moons方法产生数据集
make_moons是函数用来生成数据集在sklearn.datasets里具体用法如下
sklearn.datasets.make_moons(n_samples100, *, shuffleTrue, noiseNone, random_stateNone)主要参数作用如下
n_numbers:生成样本数量
shuffle:是否打乱类似于将数据集random一下
noise:默认是false数据集是否加入高斯噪声
random_state:生成随机种子给定一个int型数据能够保证每次生成数据相同。
import numpy as np
import os
%matplotlib inline
import matplotlib
import matplotlib.pyplot as plt
plt.rcParams[axes.labelsize] 14
plt.rcParams[xtick.labelsize] 12
plt.rcParams[ytick.labelsize] 12
import warnings
warnings.filterwarnings(ignore)
np.random.seed(42)# 导入make_moons
from sklearn.datasets import make_moons
X, y make_moons(n_samples1000, noise0.05, random_state42)# 绘制图像
plt.plot(X[:,0],X[:,1],b.)1.2.2.2 DBScan算法
from sklearn.cluster import DBSCAN# 设置半径为0.05阈值为5
dbscan DBSCAN(eps 0.05,min_samples5)
dbscan.fit(X)不同半径对聚类结果的影响
dbscan2 DBSCAN(eps 0.2,min_samples5)
dbscan2.fit(X)# 图像展示
def plot_dbscan(dbscan, X, size, show_xlabelsTrue, show_ylabelsTrue):core_mask np.zeros_like(dbscan.labels_, dtypebool)core_mask[dbscan.core_sample_indices_] Trueanomalies_mask dbscan.labels_ -1non_core_mask ~(core_mask | anomalies_mask)cores dbscan.components_anomalies X[anomalies_mask]non_cores X[non_core_mask]plt.scatter(cores[:, 0], cores[:, 1],cdbscan.labels_[core_mask], markero, ssize, cmapPaired)plt.scatter(cores[:, 0], cores[:, 1], marker*, s20, cdbscan.labels_[core_mask])plt.scatter(anomalies[:, 0], anomalies[:, 1],cr, markerx, s100)plt.scatter(non_cores[:, 0], non_cores[:, 1], cdbscan.labels_[non_core_mask], marker.)if show_xlabels:plt.xlabel($x_1$, fontsize14)else:plt.tick_params(labelbottomoff)if show_ylabels:plt.ylabel($x_2$, fontsize14, rotation0)else:plt.tick_params(labelleftoff)plt.title(eps{:.2f}, min_samples{}.format(dbscan.eps, dbscan.min_samples), fontsize14)plt.figure(figsize(12, 4))plt.subplot(121)
plot_dbscan(dbscan, X, size100)plt.subplot(122)
plot_dbscan(dbscan2, X, size600, show_ylabelsFalse)plt.show()1.2.2 鸢尾花数据集的DBSCAN的聚类案例
import pandas as pd
from sklearn.datasets import load_iris
# 导入数据,sklearn自带鸢尾花数据集
iris load_iris().data
iris[:5]from sklearn.cluster import DBSCAN
iris_db DBSCAN(eps0.6,min_samples4).fit_predict(iris)# 设置半径为0.6最小样本量为2建模
db DBSCAN(eps10, min_samples2).fit(iris)# 统计每一类的数量
counts pd.value_counts(iris_db,sortTrue)
counts# 可视化
import matplotlib.pyplot as plt
plt.rcParams[font.sans-serif] [uMicrosoft YaHei]fig,ax plt.subplots(1,2,figsize(12,12))# 画真实数据结果
ax1 ax[0]
ax1.scatter(xiris[:,0],yiris[:,1],s250,cload_iris().target)
ax1.set_title(真实分类,fontsize20)# 画聚类后的结果
ax2 ax[1]
ax2.scatter(xiris[:,0],yiris[:,1],s250,ciris_db)
ax2.set_title(DBSCAN聚类结果,fontsize20)plt.show()我们可以从上面这个图里观察聚类效果的好坏但是当数据量很大或者指标很多的时候观察起来就会非常麻烦。
这时候可以使用轮廓系数来判定结果好坏聚类结果的轮廓系数定义为S是该聚类是否合理、有效的度量。
聚类结果的轮廓系数的取值在[-1,1]之间值越大说明同类样本相距约近不同样本相距越远则聚类效果越好。
轮廓系数以及其他的评价函数都定义在sklearn.metrics模块中在sklearn中函数silhouette_score()计算所有点的平均轮廓系数。
from sklearn import metrics# 就是下面这个函数可以计算轮廓系数
score metrics.silhouette_score(iris,iris_db)
score# 0.423002591790790751.2.3 k-means和DBSCAN聚类对比
import matplotlib.pyplot as plt
from sklearn.cluster import DBSCAN
from sklearn.cluster import KMeans
from sklearn import datasets
# 生成数据
x, y datasets.make_circles(n_samples2000, factor0.5, noise0.05)# k-means方法聚类
kmeans_model KMeans(n_clusters2)
kmeans_model.fit(x)
kmeans_result kmeans_model.predict(x)# DBSCAN方法聚类
dbscan_model DBSCAN(eps0.2, min_samples50)
dbscan_model.fit(x)
dbscan_result dbscan_model.fit_predict(x)# 绘制图像
plt.figure(figsize(12, 4))
plt.subplot(121)
plt.scatter(x[:, 0], x[:, 1], ckmeans_result)
plt.title(kmeans_model)plt.subplot(122)
plt.scatter(x[:, 0], x[:, 1], cdbscan_result)
plt.title(dbscan_result)plt.show()