DBSCAN无法正常工作

时间:2014-10-25 19:22:23

标签: java cluster-analysis data-mining dbscan

我在java中实现DBSCAN。我遵循here (Wikipedia)给出的算法。我认为我说得对,但由于某种原因,只形成一个集群。 Java代码看起来像

ArrayList<ArrayList<Node>> dbcluster = new ArrayList<>();
ArrayList<Node> points; // this contains my data assume
int min =10, esp =50;
int clustcount =0;
for(int i=0;i<points.size();i++){               
    Node tempdb = points.get(i);                
    if(tempdb.visited==false){
        tempdb.visited=true;
        ArrayList<Node> myNeighbors = getNeigbhors(tempdb,points, esp);
        if(myNeighbors.size() < min){
            tempdb.noise = true;
        }else{
            //ArrayList<Node> tempclust = new ArrayList<>();
            dbcluster.add(new ArrayList<Node>());
            expandCluster(tempdb,points,myNeighbors,dbcluster,esp,min,clustcount);
            clustcount++;
        }
}

public static ArrayList<Node> getNeigbhors(Node p ,ArrayList<Node> data,int  esp){
        ArrayList<Node> tempReturn =  new ArrayList<>();
        for(int i=0;i<data.size();i++){
            Node temptemp = data.get(i);            
            if(p.x != temptemp.x && p.y !=temptemp.y){
                double distance =Math.sqrt(((p.x - temptemp.x)*(p.x - temptemp.x))+((p.y - temptemp.y)*(p.y - temptemp.y)));
                if(distance <=esp){
                    tempReturn.add(temptemp);
                }
            }
        }       
        return tempReturn;      
}

public static void expandCluster(Node p, ArrayList<Node> data, ArrayList<Node> N, ArrayList<ArrayList<Node>> allCluster,int esp, int min,int clustcount){

    //ArrayList<Node> tempSmallClust = new ArrayList<>();
    //tempSmallClust.add(p);
    allCluster.get(clustcount).add(p);
    for(int i=0;i<N.size();i++){
        Node tempP = N.get(i);
        if(tempP.visited == false){
            tempP.visited=true;
            ArrayList<Node> tempNewNeighbors = new ArrayList<>();
            tempNewNeighbors = getNeigbhors(tempP, data, esp);
            if(tempNewNeighbors.size() >= min){
                ArrayList<Node> tempN=new ArrayList<>();
                tempN=mergeNeighbors(N, tempNewNeighbors);
                N = new ArrayList<>();
                N=tempN;                    
            }
        }
        if(!checkInCluster(tempP,allCluster)) {
            allCluster.get(clustcount).add(tempP);
        }
     }          
    //return tempSmallClust;
}

public static boolean checkInCluster(Node p, ArrayList<ArrayList<Node>> allCluster){

    for(int i=0;i<allCluster.size();i++){           
        ArrayList<Node> tempList = allCluster.get(i);
        if(tempList.contains(p)){                
            return true;
        }           
    }
    return false;
}

public static ArrayList<Node> mergeNeighbors(ArrayList<Node> N,ArrayList<Node> NewN){
    ArrayList<Node> tmpR = N;
    for(int i=0;i<NewN.size();i++){
        if(!N.contains(NewN.get(i))){
            tmpR.add(NewN.get(i));
        }
    }       
    return tmpR;
}

节点类很简单,使用int x int y和布尔噪声并访问。 这里提供的数据为here data

1 个答案:

答案 0 :(得分:1)

您的数据是统一分布的。

此数据集中没有群集。

恕我直言,将所有内容放在一个群集中是正确的(如果eps太高而且碎片太低)是正确的,或者将所有内容都置于噪音中(如果eps和minpts设置得恰当)。

所以也许它不是一个实现错误,但你的数据不合适。