首页 > 解决方案 > 考虑到 DBSCAN 算法中所有特征对的组合,为什么考虑所有特征不会复制?

问题描述

我试图看到,在 DBSCAN 算法中,考虑到所有 n 个特征,我得到的噪声点数是否类似于所有 nC2 特征的组合?

我使用以下术语:
假设,n 是特征的数量。
1.整体模型:考虑所有特征(n)的
模型 2.组合模型:考虑所有特征对组合(所有nC2组合)的模型。如果一个样本被认为是任何组合模型中的噪声点,则该点被标记为异常。
3.异常:如果样本是噪声点,则认为它是异常的
4.正常:任何非异常点

为了更清楚,假设我有 3 个特征:f1、f2、f3。整体模型在聚类时考虑了所有 3 个特征。组合模型使用 3 个模型 (f1,f2) 、 (f2,f3) 和 (f1,f3)。如果这 3 个模型中的任何一个将样本标记为噪声,则该点被认为是“异常”;否则为“正常”。

我的假设是组合模型会给我与整体模型相同数量的噪声点,但它给出的噪声点更少。在组合模型中被认为是噪声点的点在整体模型中也被标记为噪声点。

虽然我使用相同的超参数,但为什么它没有给我相同的解决方案?

我的实施有什么问题吗?我的python代码段:

### libraries
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from sklearn.cluster import DBSCAN
from sklearn import metrics
import matplotlib.pyplot as plt


def func(data_file,eps,minPts, number_of_features):    
    print("For ", str(number_of_features)," features: ")

    ### loading dataset
    dataset = pd.read_csv(data_file)

    ### tracking label of all combination of feature relation considering 2 at a time
    labels_arr=[]

    ### checking all combination of feature relation considering 2 at a time using dbscan algorithm
    for i in range(number_of_features-1):
        for j in range(i+1,number_of_features):
            features = dataset.iloc[0:1000, np.r_[ [i,j] ]].values
            db = DBSCAN(eps=eps, min_samples=minPts).fit(features)
            labels = db.labels_
            labels_arr.append(labels)

    ### counting number of positive (and noise) samples in combined model    
    cnt=0
    comb_model=[]
    comb_abnormal_cnt=[]
    for j in range(len(labels)):
        flg=0
        abnormal_cnt=0
        for i in range(len(labels_arr)):
            # if any data point is noise for any model, that data point is considered noise for the propose model
            if labels_arr[i][j]==-1:
                abnormal_cnt+=1
                flg=-1
                #print(j,i)
        comb_abnormal_cnt.append(abnormal_cnt)
        if flg==0:
            cnt+=1
            comb_model.append("Normal")
        else:
            comb_model.append("Abnormal")        
    print("Number of positives in combined model",cnt)


    ### counting number of positive (and noise) samples in overall model    
    new_model=[]
    features = dataset.iloc[0:1000, 0:number_of_features].values
    db = DBSCAN(eps=eps, min_samples=minPts).fit(features)
    labels = db.labels_
    cnt=0
    for val in labels:
        if val==-1:
            new_model.append("Abnormal")
        else:
            new_model.append("Normal")
            cnt+=1
    print("Number of positives in overall model",cnt)

    ### checking matches in both model    
    cnt=0
    for i in range(len(new_model)):
        if new_model[i]==comb_model[i]:
            cnt+=1
    print("Number of matches in both",cnt)


func("test.csv",.2,5,3)
func("test.csv",1,3,23)    

这段代码的输出看起来像这样

For  3  features: 
Number of positives in combined model 995
Number of positives in overall model 983
Number of matches in both 988
For  23  features: 
Number of positives in combined model 840
Number of positives in overall model 528
Number of matches in both 688

你能帮我解决我所说的问题的数学基础吗?

标签: dbscan

解决方案


您无法跨不同子空间比较 epsilon。我什至对结果的分歧不止于此感到惊讶。

请注意,DBSCAN 并不专注于可靠地检测异常 - 而是使用异常检测方法。DBSCAN 中的噪声点是那些不能很好地拟合集群的点,但背景噪声并不总是异常的,它可能非常普遍。


推荐阅读