我尝试使用DBSCAN来检测异常值,根据我的理解,DBSCAN会将-1输出为异常值,1输出为内点,但在我运行代码后,我得到的不是-1或1的数字,有人能解释一下为什么吗?另外,使用试错法来找到最佳的eps值是否正常,因为我找不到确定最佳eps值的方法。
import numpy as npimport pandas as pdimport matplotlib.pyplot as plt%matplotlib inlinefrom sklearn.cluster import DBSCANdf = pd.read_csv('Final After Simple Filtering.csv',index_col=None,low_memory=True)# Dropping columns with low feature importancedel df['AmbTemp_DegC']del df['NacelleOrientation_Deg']del df['MeasuredYawError']#applying DBSCANDBSCAN = DBSCAN(eps = 1.8, min_samples =10,n_jobs=-1)df['anomaly'] = DBSCAN.fit_predict(df)np.unique(df['anomaly'],return_counts=True)
(array([ -1, 0, 1, ..., 8462, 8463, 8464]),array([1737565, 3539278, 4455734, ..., 13, 8, 8]))
谢谢你。
回答:
嗯,你实际上并没有真正理解DBSCAN的概念。
这是从维基百科复制的内容:
如果在距离ε内至少有minPts个点(包括点p本身),那么点p就是一个核心点。
如果点q在核心点p的距离ε内,则点q可以从p直接到达。只有从核心点出发的点才被称为直接可达的点。
如果存在一条路径p1, …, pn,其中p1 = p且pn = q,且每个pi+1都可以从pi直接到达,则点q可以从p到达。请注意,这意味着路径上的所有点都必须是核心点,除了q可能不是核心点。
所有无法从任何其他点到达的点都被视为异常值或噪声点。
用更简单的语言来说,DBSCAN的理念是这样的:
-
任何在距离epsilon内拥有min_samples个邻居的样本都是核心样本。
-
任何不是核心样本,但至少有一个核心邻居(距离小于eps)的数据样本是直接可达样本,可以被添加到聚类中。
-
任何不是直接可达也不是核心样本,但至少有一个直接可达邻居(距离小于eps)的数据样本是可达样本,并将被添加到聚类中。
-
所有其他样本都被认为是噪声、异常值或其他任何你想称呼的名字(这些将被标记为-1)。
根据聚类的参数(eps和min_samples),你很可能会有超过两个的聚类。这就是你在聚类结果中看到除了0和-1之外的其他值的原因。
关于你的第二个问题
另外,使用试错法来找到最佳的eps值是否正常,
如果你指的是在已知聚类标签或可以近似正确聚类的一组数据上进行交叉验证,是的,我认为这是正常的做法。
附注:这篇论文非常好且全面。我强烈建议你看看。祝你好运。