`
fufeng
  • 浏览: 75713 次
社区版块
存档分类
最新评论

聚类分析(七)离群点分析

阅读更多

一、             什么是离群点分析

1 、什么是离群点?

在样本空间中,与其他样本点的一般行为或特征不一致的点,我们称为离群点。

2 、离群点产生的原因?

第一,   计算的误差或者操作的错误所致,比如:某人的年龄 -999 岁,这就是明显由误操作所导致的离群点;

第二,   数据本身的可变性或弹性所致,比如:一个公司中 CEO 的工资肯定是明显高于其他普通员工的工资,于是 CEO 变成为了由于数据本身可变性所导致的离群点。

3 、为什么要对离群点进行检测?

“一个人的噪声也许是其他的信号”。换句话说,这些离群点也许正是用户感兴趣的,比如在欺诈检测领域,那些与正常数据行为不一致的离群点,往往预示着欺诈行为,因此成为执法者所关注的。

4 、离群点检测遇到的困难?

第一,   在时间序列样本中发现离群点一般比较困难,因为这些离群点可能会隐藏在趋势、季节性或者其他变化中;

第二,   对于维度为非数值型的样本,在检测过程中需要多加考虑,比如对维度进行预处理等;

第三,   针对多维数据,离群点的异常特征可能是多维度的组合,而不是单一维度就能体现的。

二、             几类离群点检测方法

1 、基于统计分布的离群点检测

这类检测方法假设样本空间中所有数据符合某个分布或者数据模型,然后根据模型采用不和谐校验( discordancy test )识别离群点。不和谐校验过程中需要样本空间数据集的参数知识( eg: 假设的数据分布),分布的参数知识( eg: 期望和方差)以及期望的离群点数目。

不和谐校验分两个过程:工作假设和备选假设

工作假设指的是如果某样本点的某个统计量相对于数据分布的是显著性概率充分小,那么我们则认为该样本点是不和谐的,工作假设被拒绝,此时备用假设被采用,它声明该样本点来自于另一个分布模型。

如果某个样本点不符合工作假设,那么我们认为它是离群点。如果它符合备选假设,我们认为它是符合某一备选假设分布的离群点。

基于统计分布的离群点检测的缺点:

第一,   在于绝大多数不和谐校验是针对单个维度的,不适合多维度空间;

第二,   需要预先知道样本空间中数据集的分布特征,而这部分知识很可能是在检测前无法获得的。

2 、基于距离的离群点检测

基于距离的离群点检测指的是,如果样本空间 D 中至少有 N 个样本点与对象 O 的距离大于 dmin, 那么称对象 O 是以 { 至少 N 个样本点 } dmin 为参数的基于距离的离群点。

其实可以证明,在大多数情况下,如果对象 O 是根据基于统计的离群点检测方法发现出的离群点,那么肯定存在对应的 N dmin ,是它也成为基于距离的离群点。

Eg: 假设标准正态分布,如果离均值偏差 3 或更大的对象认为是离群点,根据正态曲线概率密度函数, P |x-3|<=dmin <1-N/ 总点数,即 P 3-dim=<x<=3+dmin <1-N/ 总点数,假设 dmin=0.13, 则该 dmin 领域表示 [2.87,3.13] 的范围,假设总点数 =10000, N=12.

基于距离的离群点检测的缺点 :

要求数据分布均匀,当数据分布非均匀时,基于距离的离群点检测将遇到困难。

3 、基于密度的局部离群点检测

什么是局部离群点?

一个对象如果是局部离群点,那么相对于它的局部领域,它是远离的。

不同于前面的方法,基于密度的局部离群点检测不将离群点看做一种二元性质,即不简单用 Yes or No 来断定一个点是否是离群点,而是用一个权值来评估它的离群度。

它是局部的,意思是该程度依赖于对象相对于其领域的孤立情况。这种方法可以同时检测出全局离群点和局部离群点。

通过基于密度的局部离群点检测就能在样本空间数据分布不均匀的情况下也可以准确发现离群点。

4 、基于偏差的离群点检测

基于偏差的离群点检测,它通过检查一组对象的主要特征来识别离群点,“偏差”这种特征的点我们认为是离群点。

通常有两种技术:

第一,   顺序异常技术

第二,   采用 OLAP 数据立方体技术

三、             基于密度的局部离群点检测

前面介绍了什么叫做基于密度的局部离群点检测,以及它的优势。现在详细介绍下它的一些概念。

1、   对象 p 的第 k 距离

对于正整数 k, 对象 p 的第 k 距离可记作 k-distance(p)

在样本空间中,存在对象 o ,它与对象 p 之间的距离记作 d(p,o) 。如果满足以下两个条件,我们则认为 k-distance(p)= d(p,o)

1)  在样本空间中,至少存在 k 个对象 q, 使得 d(p,q)<= d(p,o);

2)  在样本空间中,至多存在 k-1 个对象 q, 使得 d(p,q)<d(p,o)

换句话说,满足这两个标准的 k-distance(p) 其实就是计算样本空间中其他对象与对象 p 之间的距离,然后找到第 k 大的那个距离,即为 k-distance(p) 。显而易见,如果使用 k-distance(p) 来量化对象 p 的局部空间区域范围,那么对于对象密度较大的区域, k-distance(p) 值较小,而对象密度较小的区域, k-distance(p) 值较大。

2、   对象 p 的第 k 距离领域( k-distance neighborhood of an object p

已知对象 p 的第 k 距离,那么,与对象 p 之间距离小于等于 k-distance(p) 的对象集合称为对象 p 的第 k 距离领域,记作: Nkdis(p) (p)

该领域其实是以 p 为中心, k-distance(p) 为半径的区域内所有对象的集合(不包括 P 本身)。由于可能同时存在多个第 k 距离的数据,因此该集合至少包括 k 个对象。

可以想象,离群度较大的对象 Nkdis(p) (p) 范围往往比较大,而离群度小的对象 Nkdis(p) (p) 范围往往比较小。对于同一个类簇中的对象来说,它们涵盖的区域面积大致相当。

3、   对象 p 相对于对象 o 的可达距离

可达距离 reachdisk (p,o)=max{ k-distance(o),d(p,o)}, k-distance(o) d(p,o) 值较大的那个。

4、   局部可达密度是基于 p k 最近邻点的平均可达密度的倒数。如下

聚类分析(七)离群点分析

可以发现,如果对象 p 的离群度较小,那么对于同一类簇的数据对象 reachdisk (p,o) k-distance(o) 可能性较大,因此它们的 Lrdk (p) 值波动性较小;而如果对象 p 的利群度较大,那么 reachdisk (p,o) d(p,o) 的可能性较大,对于同一类簇的数据对象,它们的 Lrdk (p) 值波动性也比较大,并且 Lrdk (p) 值较小。

5、   局部离群点因子( LOF

聚类分析(七)离群点分析

它代表了 p 为离群点的程度。如果对象 p 的离群程度较大,则它 k 领域中大多数是离对象 p 较远且处于某一个类簇的数据对象,那么这些数据对象的 lrd 应该是偏大,而对象 p 本身的 lrd 是偏小,最后所得的 LOF 值也是偏大。反之,如果对象 p 的离群程度较小,对象 o lrd 和对象 p lrd 相似,最后所得的 lof 值应该接近 1.

四、             算法实现

算法:基于密度的局部离群点检测( lof 算法)

输入:样本集合 D ,正整数 K (用于计算第 K 距离)

输出:各样本点的局部离群点因子

过程: 1 )计算每个对象与其他对象的欧几里得距离

       2 )对欧几里得距离进行排序,计算第 k 距离以及第 K 领域

       3 )计算每个对象的可达密度

       4 )计算每个对象的局部离群点因子

5 )对每个点的局部离群点因子进行排序,输出。

 -------------------------------------------------------------------

源码:

package com.lof;

import java.util.ArrayList;
import java.util.List;

public class Node {
    private String nodeName; // 样本点名
    private double[] dimensioin; // 样本点的维度
    private double kDistance; // k-距离
    private List<Node> kNeighbor=new ArrayList<Node>();// k-领域
    private double distance; //到给定点的欧几里得距离
    private double reachDensity;// 可达密度
    private double reachDis;// 可达距离


    private double lof;//局部离群因子

    public Node(){

    }

    public Node(String nodeName,double[] dimensioin){
        this.nodeName=nodeName;
        this.dimensioin=dimensioin;
    }

    public String getNodeName() {
        return nodeName;
    }

    public void setNodeName(String nodeName) {
        this.nodeName = nodeName;
    }

    public double[] getDimensioin() {
        return dimensioin;
    }

    public void setDimensioin(double[] dimensioin) {
        this.dimensioin = dimensioin;
    }

    public double getkDistance() {
        return kDistance;
    }

    public void setkDistance(double kDistance) {
        this.kDistance = kDistance;
    }

    public List<Node> getkNeighbor() {
        return kNeighbor;
    }

    public void setkNeighbor(List<Node> kNeighbor) {
        this.kNeighbor = kNeighbor;
    }


    public double getDistance() {
        return distance;
    }

    public void setDistance(double distance) {
        this.distance = distance;
    }

    public double getReachDensity() {
        return reachDensity;
    }

    public void setReachDensity(double reachDensity) {
        this.reachDensity = reachDensity;
    }

    public double getReachDis() {
        return reachDis;
    }

    public void setReachDis(double reachDis) {
        this.reachDis = reachDis;
    }

    public double getLof() {
        return lof;
    }

    public void setLof(double lof) {
        this.lof = lof;
    }

}

package com.lof;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;


public class OutlierNodeDetect {
    private static int MIN_PTS=5;

    //1.找到给定点与其他点的欧几里得距离
    //2.对欧几里得距离进行排序,找到前5位的点,并同时记下k距离
    //3.计算每个点的可达密度
    //4.计算每个点的局部离群点因子
    //5.对每个点的局部离群点因子进行排序,输出。
    public List<Node> getOutlierNode(List<Node> allNodes){

       List<Node> kdAndKnList=getKDAndKN(allNodes);
       calReachDis(kdAndKnList);
       calReachDensity(kdAndKnList);
       calLof(kdAndKnList);
       Collections.sort(kdAndKnList, new LofComparator());

       return kdAndKnList;
    }

   
    private void calLof(List<Node> kdAndKnList){
        for(Node node:kdAndKnList){
             List<Node> tempNodes=node.getkNeighbor();
             double sum=0.0;
             for(Node tempNode:tempNodes){
                 double rd=getRD(tempNode.getNodeName(),kdAndKnList);
                 sum=rd/node.getReachDensity()+sum;
             }
             sum=sum/(double)MIN_PTS;
             node.setLof(sum);
        }
    }

   
    private void calReachDensity(List<Node> kdAndKnList){
        for(Node node:kdAndKnList){
             List<Node> tempNodes=node.getkNeighbor();
             double sum=0.0;
             double rd=0.0;
             for(Node tempNode:tempNodes){
                 sum=tempNode.getReachDis()+sum;
             }
             rd=(double)MIN_PTS/sum;
             node.setReachDensity(rd);
        }
    }

   
    private void calReachDis(List<Node> kdAndKnList){
       for(Node node:kdAndKnList){
           List<Node> tempNodes=node.getkNeighbor();
           for(Node tempNode:tempNodes){
              double kDis=getKDis(tempNode.getNodeName(),kdAndKnList);
              if(kDis<tempNode.getDistance()){
                  tempNode.setReachDis(tempNode.getDistance());
              }else{
                  tempNode.setReachDis(kDis);
              }
           }
       }
    }
   
    private double getKDis(String nodeName,List<Node> nodeList){
        double kDis=0;
        for(Node node:nodeList){
            if(nodeName.trim().equals(node.getNodeName().trim())){
                kDis=node.getkDistance();
                break;
            }
        }
        return kDis;

    }

   
    private double getRD(String nodeName,List<Node> nodeList){
        double kDis=0;
        for(Node node:nodeList){
            if(nodeName.trim().equals(node.getNodeName().trim())){
                kDis=node.getReachDensity();
                break;
            }
        }
        return kDis;

    }

   
    private List<Node> getKDAndKN(List<Node> allNodes){
       List<Node> kdAndKnList=new ArrayList<Node>();
       for(int i=0;i<allNodes.size();i++){
           List<Node> tempNodeList=new ArrayList<Node>();
           Node nodeA=new Node(allNodes.get(i).getNodeName(),allNodes.get(i).getDimensioin());
           for(int j=0;j<allNodes.size();j++){
              Node nodeB=new Node(allNodes.get(j).getNodeName(),allNodes.get(j).getDimensioin());
              double tempDis=getDis(nodeA,nodeB);
              nodeB.setDistance(tempDis);
              tempNodeList.add(nodeB);
           }

           //对tempNodeList进行排序
           Collections.sort(tempNodeList, new DistComparator());
           for(int k=1;k<MIN_PTS;k++){
               nodeA.getkNeighbor().add(tempNodeList.get(k));
               if(k==MIN_PTS-1){
                   nodeA.setkDistance(tempNodeList.get(k).getDistance());
               }
           }
           kdAndKnList.add(nodeA);
       }

       return kdAndKnList;
    }

   
    private double getDis(Node A,Node B){
        double dis=0.0;
        double[] dimA=A.getDimensioin();
        double[] dimB=B.getDimensioin();
        if (dimA.length == dimB.length) {
            for (int i = 0; i < dimA.length; i++) {
                double temp = Math.pow(dimA[i] - dimB[i], 2);
                dis = dis + temp;
            }
            dis=Math.pow(dis, 0.5);
        }
        return dis;
    }

    class DistComparator implements Comparator<Node>{
        public int compare(Node A, Node B){
           return A.getDistance()-B.getDistance()<0?-1:1;
        }
    }

    class LofComparator implements Comparator<Node>{
        public int compare(Node A, Node B){
           return A.getLof()-B.getLof()<0?-1:1;
        }
    }

    public static void main(String[] args){
        ArrayList<Node> dpoints = new ArrayList<Node>();
       
        double[] a={2,3};
        double[] b={2,4};
        double[] c={1,4};
        double[] d={1,3};
        double[] e={2,2};
        double[] f={3,2};

        double[] g={8,7};
        double[] h={8,6};
        double[] i={7,7};
        double[] j={7,6};
        double[] k={8,5};

        double[] l={100,2};//孤立点


        double[] m={8,20};
        double[] n={8,19};
        double[] o={7,18};
        double[] p={7,17};
        double[] q={8,21};

        dpoints.add(new Node("a",a));
        dpoints.add(new Node("b",b));
        dpoints.add(new Node("c",c));
        dpoints.add(new Node("d",d));
        dpoints.add(new Node("e",e));
        dpoints.add(new Node("f",f));

        dpoints.add(new Node("g",g));
        dpoints.add(new Node("h",h));
        dpoints.add(new Node("i",i));
        dpoints.add(new Node("j",j));
        dpoints.add(new Node("k",k));

        dpoints.add(new Node("l",l));

        dpoints.add(new Node("m",m));
        dpoints.add(new Node("n",n));
        dpoints.add(new Node("o",o));
        dpoints.add(new Node("p",p));
        dpoints.add(new Node("q",q));

        OutlierNodeDetect lof=new OutlierNodeDetect();

        List<Node> nodeList=lof.getOutlierNode(dpoints);

        for(Node node:nodeList){
            System.out.println(node.getNodeName()+"  "+node.getLof());
        }

    }
}

测试结果:

0.7459309435620392
p  0.7459309435620392
e  0.7485293162241347
k  0.7518479734971145
i  0.7518479734971146
c  0.7693717709826069
b  0.7693717709826069
g  0.7836550344036045
o  0.8175878600290553
m  0.8175878600290553
a  0.827181166228103
d  0.8497518729207414
f  0.8588773305030418
j  0.8625820667657609
h  0.8625820667657609
n  0.8866630038097529
l  39.309353884068194

分享到:
评论

相关推荐

    计算机研究 -基于近似密度构造的聚类分析与离群点检测算法研究.pdf

    ### 计算机研究 - 基于近似密度构造的聚类分析与离群点检测算法研究 #### 一、研究背景与意义 在信息技术迅速发展的半个世纪中,计算机科学与技术的进步不仅极大地改变了人类的生活方式,还为科学研究和社会发展...

    一种基于密度聚类的分布式离群点检测算法.pdf

    在本文中,作者刘亚梅和闫仁武结合传统局部离群点检测算法LOF(Local Outlier Factor)与Hadoop分布式计算框架,提出了基于密度聚类的分布式离群点检测算法。该算法通过引入MapReduce编程模型实现了并行化策略,显著...

    基于数据模式聚类算法的离群点检测 (2007年)

    ### 基于数据模式聚类算法的离群点检测 #### 概述 本文介绍了一种名为PCOT(Pattern-based Clustering for Outlier Detection)的新算法,该算法旨在解决传统模式挖掘算法中存在的问题——即在事务包含模式定义时...

    maoci.rar_电压 聚类_离群点

    此外,R语言是数据科学和统计分析的强大工具,提供了许多内置函数和库来支持聚类和离群点检测。例如,`cluster`包提供了多种聚类算法,而`outliers`和`ROCR`包则可以用于离群点检测和阈值设定。在这个项目中,开发者...

    论文研究-基于遗传聚类算法的离群点检测.pdf

    传统的多尺度主元分析方法没有建立故障传感器数据重构模型,在相关传感器信号的所有尺度上建立主元分析模型进行传感器故障诊断的基础上,将主元分析模型的重构结果组合后进行小波逆变换,设计了能够实现故障传感器...

    k-means离群点剔除法matlab代码

    k-means离群点剔除法是数据预处理过程中常用的一种技术,特别是在机器学习和数据分析领域。这种方法基于聚类算法,通过将数据点分配到不同的簇来识别那些远离大多数其他点的异常值。Matlab是一种强大的编程环境,常...

    基于残差分析的离群点检测算法matlab

    基于残差分析的离群点检测算法,适用具有线性回归关系的二维数据,可以对数据中的离群点进行有效剔除检测。

    matlab离群点检测

    在MATLAB中,离群点检测可以通过多种算法实现,包括基于统计的方法、聚类方法和距离度量等。例如,常用的统计方法有Z-score法和IQR(四分位距)法。Z-score法通过计算每个数据点与均值的标准化距离来识别离群点,而...

    基于云计算技术的大规模数据聚类分析.pdf

    在这些集合中,算法不断循环删除那些局部密度低于平均密度的离群点,得到聚类中心。聚类中心是数据聚类分析中的一个核心概念,它代表了一个簇的中心位置,簇中的数据点分布围绕在聚类中心附近。 在确定了聚类中心...

    高维数据流的聚类离群点检测算法研究

    针对基于聚类的离群点检测算法在处理高维数据流时效率和精确度低的问题,提出一种高维数据流的聚类离群点检测(CODHD-Stream)算法.该算法首先采用滑动窗口技术对数据流划分,然后通过属性约简算法对高维数据集降维;其次...

    聚类离群点挖掘技术在内部审计信息化中的应用——一个来自商业银行信用卡审计的实例.pdf

    【聚类离群点挖掘技术】是数据挖掘领域的一个重要组成部分,主要目的是在大量数据中找出与正常模式显著不同的异常数据。在内部审计信息化中,这项技术被用来识别潜在的欺诈、错误或风险,帮助审计人员从海量电子数据...

    数据挖掘之聚类分析算法综述.pdf

    数据挖掘主要包含数据预处理、关联分析、分类、聚类分析、离群点检测等过程。聚类分析作为数据挖掘中的重要一环,其目标是将具有相似属性的对象聚合在一起形成类或簇。 聚类分析可以分为硬划分、软划分和基于密度的...

    数据挖掘论文集,很多论文打包

    交易数据的聚类分析.pdf 基于粗糙集理论的数据挖掘算法研究.pdf 基于粗糙集的数据挖掘与决策支持方法研究.pdf 基于粗糙集的数据挖掘方法研究.pdf 基于自然计算的模糊聚类新...高维数据流聚类分析及离群点检测研究.pdf

    离群点检测数据集.zip

    这些数据集的多样性使得它们适用于各种数据分析任务,如聚类分析、离群点检测和分类问题。通过使用这些数据集,研究人员和实践者可以测试和比较不同的离群点检测算法,以确定哪种方法在特定场景下表现最佳。 在离群...

    基于属性聚类的离群数据挖掘算法.pdf

    在这类数据中,传统的离群挖掘算法往往会因为数据的高维度和大数据量而效率低下,难以准确地发现那些只在多维相关性空间中表现异常的数据点。 属性聚类作为一种处理高维数据的技术,已经被证明在减少数据的复杂性...

    离群点挖掘方法综述_薛安荣.pdf

    3. **基于聚类的方法**:利用聚类算法将相似的数据点分组,位于小规模或远离其他簇的数据点被认为是离群点。这种方法适用于多模态数据集。 - **优点**:能够处理复杂的数据分布。 - **缺点**:聚类算法的选择和...

Global site tag (gtag.js) - Google Analytics