DBSACN定义
DBSCAN (Density-Based Spatial Clustering of Applications with Noise) :
它将簇定义为密度相连的点组成的最大集合,能够把具有足够高密度的区域划分为簇,并可在噪声的空间数据库中发现任意形状的聚类
1,可以聚成任意形状的簇
2,可以把噪声点排除在外,不属于任何簇(kmeans必须有一个簇)
=============================================================
面试考点:
DBSCAN和KMeans最大区别:
KMeans是1-1的,所有点必须有对应的簇
DBSCAN是1-0(噪声)或1-1
DBSCAN概念的8个重点:
========================================
调参思路
r小,m大:一般是半径r小一点,minpoints大一点
DBSCAN 函数
eps 半径
min_samples 最小样本点
主要参数:
.components_ 核心点
.labels_ 每个样本所属的簇
.core_sample_indices_ 核心点索引
DBSCAN代码
导入DBSCAN模块
import pandas as pd
from sklearn.cluster import DBSCAN
构建数据集
data = pd.read_csv('basketball.csv')
data
#看基本信息
data.shape #只有shape不打()
data.head()
data.info() #可以看到null数据有多少
DBSCAN聚类
tip:可以用DBSCAN?
查看默认参数
1,准备模型
db = DBSCAN()
db.fit(data)
2,查看模型属性
db.core_sample_indices_ #核心点
db.components_#核心点坐标
db.labels_#属于哪个簇 0,1,2是簇
这里发现核心点很多,每个点都是,太多了,因此尝试初步调参,思路是r小,m大
果然核心点数目减少了
db=DBSCAN(eps=0.04,min_samples=10)
练习
本次聚类,是否有剖噪声点;如果有噪声点,噪声点的个数是多少个,聚类了多少个簇?
1,是否有剖噪声点
2,噪声点的个数是多少个,聚类了多少个簇?
用.Series() 函数 把labels组装成一个series,用value_counts()计数 !注意Series()的S大写
pd.Series(db.labels_).value_counts()
噪声点的个数是多少个,就是value_counts() 后面加 [ ], 即 value_counts() [噪声点label]
pd.Series(db.labels_).value_counts() [-1]
————————————————————————方法2——————————————————
if函数 判断
.count() 某个元素,数字出现次数计数
len()计算字符,列表元素个数计数
set()数据去重
len(set())去重的数据计数,很适合计数总共用几个簇
A if 条件 else B ,条件满足返回A,否则返回B
调参
调参调的是 半径eps 和 最少点个数min_samples, 要用到俩循环
每次循环要做一次拟合要用到DBSCAN模型构建和fit(data)预测
每次循环结果追加用 .append() ,结果保存成字典{},用一个列表[ ]储存
result=[] #用一个空列表储存结果
for eps in range(1,11): #半径从1到10,步长默认1
for min_samples in range(10,51,5): #最小个数循环
db=DBSCAN(eps=eps*0.01,min_samples=min_samples) #模型准备,主要标注这俩变化的参数
db.fit(data)
d={"eps":0.01*eps,
"min_sample":min_samples,
"簇或噪声点":db.labels_,
"核心点坐标":db.components_,
}
result.append(d)
结果用.Dataframe()表示更直观
df=pd.Dataframe(result)
df
调参最后需要一个结果,我们希望给出想要几个簇,
比如n=3,就返回所需的eps和min_sample
在循环中加一个计算n个簇的代码 ,用set()
对labels_进行去重,就只剩下-1,0,1,2 去掉噪声点label=-1的用if i !=-1
,在遍历剩下的label,用len([ ])
来计算个数
用loc[ , ]
锁定那一行
df.loc[df.n==3,:] #n等于3那行所有列的信息
#df.loc[0, :],这样可以清楚的看出为第0行的所有记录,同样如果取第’A’列的所有记录,可以写df.loc[:, ‘A’]
全文代码
#导入模块
import pandas as pd
from sklearn.cluster import DBSCAN
#导入数据集
data = pd.read_csv('basketball.csv')
data
data.shape
data.info()
data.head()
### DBSCAN聚类
DBSCAN?
#构建模型
db=DBSCAN(eps=0.04,min_samples=10)
#训练模型
db.fit(data)
### 查看模型属性
db.core_sample_indices_ #核心点
db.components_#核心点坐标
db.labels_
labels = db.labels_ #出现两次保存为一个变量方便使用
#查看是否有噪声点
if -1 in labels:
print('有噪声点')
else:
print('没有噪声点')
#噪声点个数
noise = list(labels).count(-1)
print('噪声点个数:{}'.format(noise))
#簇的个数
n_clusters = len(set(labels) )- (1 if -1 in labels else 0)
print('簇的个数为:{}'.format(n_clusters))
### 本次聚类,是否有剖噪声点;如果有噪声点,噪声点的个数是多少个;聚类了多少个簇
pd.Series(db.labels_).value_counts()
pd.Series(db.labels_).value_counts()[-1]
### 调参
result=[]
for eps in range(1,11):
for min_samples in range(10,51,5):
db=DBSCAN(eps=eps*0.01,min_samples=min_samples)
db.fit(data)
n=len([i for i in set(db.labels_) if i !=-1]) #不是噪声点的 去重后的 簇的个数
d={"eps":0.01*eps,
"min_sample":min_samples,
"簇或噪声点":db.labels_,
"核心点坐标":db.components_,
'n':n #簇数
}
result.append(d)
result
df=pd.DataFrame(result)
df
df.loc[df.n==3,:]