离群点检测(基于距离)实验报告
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
{
return true;
}
else if (first.pos_x > second.pos_x)
{
return false;
}
//对y轴的比较
else
{
if(first.pos_y < second.pos_y)
{
return true;
}
else
{
return false;
}
}
}
friend bool operator == (const Node& first,const Node& second)
异常检测的方法:
(1)基于模型的技术:首先建立一个数据模型,异常是那些同模型不能完美拟合的对象;如果模型是簇的集合,则异常是不显著属于任何簇的对象;在使用回归模型时,异常是相对远离预测值的对象;
(2)基于邻近度的技术:通常可以在对象之间定义邻近性度量,异常对象是那些远离其他对象的对象;
(3)基于密度的技术:仅当一个点的局部密度显著低于它的大部分近邻时才将其分类为离群点。
kmean.showCutResult();
system("pause");
return 0;
}
void input(vector<Node>& vecData,int num)
{
for(int i =0;i<num;i++)
{
Node node;
node.pos_x = (rand() % 5000 );
{
cluster_num = c_num;
data = node_vector;
clusters = new vector<Node>[cluster_num];
cutData = new vector<Node>[cluster_num];
radio = new double[cluster_num];
intcount;//记录迭代次数
vector<Node>* cutData;
double* radio;
//初始化函数(首先随即生成代表点)
voidInit_Means();
//聚类过程,将空间中的点分到不同的簇中
voidClusterProcess();
//获取当前结点的簇下标
intgetIndexOfCluster(vector<Node> means,Nodeactive);
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <iostream>
#include <iomanip>
using namespace std;
KMean::KMean(int c_num,vector<Node> node_vector)
~KMean();
//找出离群点只要距离大于平均距离+标准差,则视为离群点
void cut();
//显示剪枝结果
void showCutResult();
};
k-mean.cppkmean类的成员函数具体定义
#include "k-mean.h"
#include <vector>
#include <ctime>
//生成均值
Node getMeans(int cluster_index);
//获取两个点之间的距离
double getDistance(Node active,Node other);
public:
//构造函数,c_num为簇个数,node_vector为原始数据
KMean(int c_num,vector<Node> node_vector);
{
if(mean_nodes[j] == data[pos])
{
insert_flag = false;
break;
}
}
if(insert_flag )
{
mean_nodes.push_back(data[pos]);
i++;
}
}
cout.setf(ios::fixed);
cout << setprecision(1);
1)没有(或最小数目)对象被重新分配给不同的聚类。
2)没有(或最小数目)聚类中心再发生变化。
3)误差平方和局部最小。
2、
a.从数据集中随机挑K个数据当簇心;
b.对数据中的所有点求到这K个簇心的距离,假如点Pi离簇心Si最近,那么Pi属于Si对应的簇;
c.根据每个簇的数据,更新簇心,使得簇心位于簇的中心;
{
public:
double pos_x;
double pos_y;
Node()
{
pos_x = 0.0;
pos_y = 0.0;
}
friend bool operator < (const Node& first,const Node& second)
{
//对x轴的比较
if(first.pos_x < second.pos_x)
{
if(first.pos_x == second.pos_x && first.pos_y == second.pos_y)
{
return true;
}
else
{
return false;
}
}
};
class KMean
{
private:
int cluster_num;//生成的簇的数量。
vector<Node> mean_nodes;//均值点
Init_Means();
ClusterProcess();//进行聚类过程
}
KMean::~KMean()
{
delete [] clusters;
delete [] cutData;
delete [] radio;
}
void KMean::Init_Means()//初始化函数(首先随即生成代表点)
//获取每个点到各自簇中心的距离和
doublegetSumOfDist(vector<Node>* clusters,vector<Node> mean_nodes);
//生成均值
NodegetMeans(intcluster_index);
//获取两个点之间的距离
doublegetDistance(Nodeactive,Nodeother);
public:
//构造函数,c_num为簇个数,node_vector为原始数据
KMean(intc_num,vector<Node> node_vector);
~KMean();
//找出离群点只要距离大于平均距离+标准差,则视为离群点
voidcut();
//显示剪枝结果
voidshowCutResult();
};
程序代码图
注:代码图中相关函数的说明见KMean类的方法说明。
七、
随机生成50个数据,随机选取4个簇心,如上图所示。
经过聚类,簇1、簇2的中心已改变,算出的阀值、检测到的离群点如上图所示。
簇3、簇4聚类后,正常点和离群点如图所示。
八、
实验程序,是在聚类完成之后,基于距离筛选出了离群点。在数据挖掘过程中,将离群点数据丢弃,更有利于分析获取有用的数据。从实验结果看,部分离群点的距离远大于正常距离,丢弃这些数据,避免无效数据干扰,显得非常有意义。
一、
1.深刻理解离群点,了解离群点检测的一般方法;
2.掌握基于距离的离群点检测算法;
3.锻炼分析问题、解决问题的思维,提高动手实践的能力。
二、
异常对象被称作离群点。异常检测也称偏差检测和例外挖掘。
常见的异常成因:数据来源于不同的类(异常对象来自于一个与大多数数据对象源(类)不同的源(类)的思想),自然变异,以及数据测量或收集误差。
{
int num = data.size();
srand((int)time(0));
for(int i =0 ;i<cluster_num;)
{
int pos = rand()%num;
bool insert_flag = true;
//首先判断选中的点是否是中心点
for(unsigned int j = 0;j< mean_nodes.size();j++)
1、
K-means算法
先随机选取K个对象作为初始的聚类中心。然后计算每个对象与各个种子聚类中心之间的距离,把每个对象分配给距离它最近的聚类中心。聚类中心以及分配给它们的对象就代表一个聚类。一旦全部对象都被分配了,每个聚类的聚类中心会根据聚类中现有的对象被重新计算。这个过程将不断重复直到满足某个终止条件。终止条件可以是以下任何一个:
node.pos_y = (rand() % 5000 );
vecData.push_back(node);
}
}
k-mean.hkmean类和Node类声明
//k-mean.h
#pragma once
#include <vector>
using namespace std;
//空间点的定义
class Node
九、
1.程序源码
main.cpp主程序入口
#inБайду номын сангаасlude <iostream>
#include <vector>
#include "k-mean.h"
#include <ctime>
using namespace std;
//输入数据
void input(vector<Node>& vecData,int num);
int main()
{
srand((int) time(0));
vector<Node> data;
int num,k;
cout << "请依次输入数据量、聚类个数(数据随机产生)\n";
cin >> num >> k;
input(data,num);
KMean kmean(k,data);
kmean.cut();
三、
改写一种简单的半监督方法,用于离群点检测。使用一种你熟悉的程序设计语言,如C++或Java,实现该方法,并在两种不同的数据集上进行讨论(1)只有一些被标记的正常对象;(2)只有一些被标记的离群点实例。
四、
Win7旗舰版+Visual Studio 2012
语言:C++
五、
K-means算法是很典型的基于距离的聚类算法,采用距离作为相似性的评价指标,即认为两个对象的距离越近,其相似度就越大。该算法认为簇是由距离靠近的对象组成的,因此把得到紧凑且独立的簇作为最终目标。
cout << "随机产生的数据如下:\n";
for (int i = 0; i < num; i++)
{
cout << "(" << data[i].pos_x << ", " << data[i].pos_y << ")\t\t";
d.重复步骤e和步骤f,直到簇心不再移动(或其他条件,如前后两次距离和不超过特定值),继续下一步;
e.计算每个簇的正常半径,即阀值(此程序阀值为每个簇的平均距离与1.5倍标准差之和);
f.从每个簇中,找出大于阀值的点,即离群点。
六、
Node类,定义了二维空间中的一个点,pos_x,pos_y三成员变量分别为x,y,轴的值,且为double型。Node类作为基本数据结构,使用在KMean类里。
//聚类过程,将空间中的点分到不同的簇中
void ClusterProcess();
//获取当前结点的簇下标
int getIndexOfCluster(vector<Node> means, Node active);
//获取每个点到各自簇中心的距离和
double getSumOfDist(vector<Node>* clusters, vector<Node> mean_nodes);
题 目
离群点检测(基于距离)
学生姓名
学生学号
专业班级
指导教师
2015-1-17
此实验是在实验三的基础上,修改完成。实验算法与上次相同,但增加了离群点检测。离群点检测方法为:在聚类完成之后,计算簇中的点到各自簇心的距离。当簇中的一点到簇心的距离大于该簇的平均距离与1.5倍标准差的和时,则认为该点为离群点,即阀值平均距离与1.5倍标准差的和。
KMean类封装了一系列成员变量和函数,实现了KMean算法。具体成员变量和函数详细说明如下:
classKMean
{
private:
intcluster_num;//生成的簇的数量。
vector<Node> mean_nodes;//均值点
vector<Node> data;//所有的数据点
vector<Node>* clusters;//簇,key为簇的下标,value为该簇中所有点
vector<Node> data;//所有的数据点
vector<Node>* clusters;//簇,key为簇的下标,value为该簇中所有点
int count;//记录迭代次数
vector<Node>* cutData;
double* radio;
//初始化函数(首先随即生成代表点)
void Init_Means();
return true;
}
else if (first.pos_x > second.pos_x)
{
return false;
}
//对y轴的比较
else
{
if(first.pos_y < second.pos_y)
{
return true;
}
else
{
return false;
}
}
}
friend bool operator == (const Node& first,const Node& second)
异常检测的方法:
(1)基于模型的技术:首先建立一个数据模型,异常是那些同模型不能完美拟合的对象;如果模型是簇的集合,则异常是不显著属于任何簇的对象;在使用回归模型时,异常是相对远离预测值的对象;
(2)基于邻近度的技术:通常可以在对象之间定义邻近性度量,异常对象是那些远离其他对象的对象;
(3)基于密度的技术:仅当一个点的局部密度显著低于它的大部分近邻时才将其分类为离群点。
kmean.showCutResult();
system("pause");
return 0;
}
void input(vector<Node>& vecData,int num)
{
for(int i =0;i<num;i++)
{
Node node;
node.pos_x = (rand() % 5000 );
{
cluster_num = c_num;
data = node_vector;
clusters = new vector<Node>[cluster_num];
cutData = new vector<Node>[cluster_num];
radio = new double[cluster_num];
intcount;//记录迭代次数
vector<Node>* cutData;
double* radio;
//初始化函数(首先随即生成代表点)
voidInit_Means();
//聚类过程,将空间中的点分到不同的簇中
voidClusterProcess();
//获取当前结点的簇下标
intgetIndexOfCluster(vector<Node> means,Nodeactive);
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <iostream>
#include <iomanip>
using namespace std;
KMean::KMean(int c_num,vector<Node> node_vector)
~KMean();
//找出离群点只要距离大于平均距离+标准差,则视为离群点
void cut();
//显示剪枝结果
void showCutResult();
};
k-mean.cppkmean类的成员函数具体定义
#include "k-mean.h"
#include <vector>
#include <ctime>
//生成均值
Node getMeans(int cluster_index);
//获取两个点之间的距离
double getDistance(Node active,Node other);
public:
//构造函数,c_num为簇个数,node_vector为原始数据
KMean(int c_num,vector<Node> node_vector);
{
if(mean_nodes[j] == data[pos])
{
insert_flag = false;
break;
}
}
if(insert_flag )
{
mean_nodes.push_back(data[pos]);
i++;
}
}
cout.setf(ios::fixed);
cout << setprecision(1);
1)没有(或最小数目)对象被重新分配给不同的聚类。
2)没有(或最小数目)聚类中心再发生变化。
3)误差平方和局部最小。
2、
a.从数据集中随机挑K个数据当簇心;
b.对数据中的所有点求到这K个簇心的距离,假如点Pi离簇心Si最近,那么Pi属于Si对应的簇;
c.根据每个簇的数据,更新簇心,使得簇心位于簇的中心;
{
public:
double pos_x;
double pos_y;
Node()
{
pos_x = 0.0;
pos_y = 0.0;
}
friend bool operator < (const Node& first,const Node& second)
{
//对x轴的比较
if(first.pos_x < second.pos_x)
{
if(first.pos_x == second.pos_x && first.pos_y == second.pos_y)
{
return true;
}
else
{
return false;
}
}
};
class KMean
{
private:
int cluster_num;//生成的簇的数量。
vector<Node> mean_nodes;//均值点
Init_Means();
ClusterProcess();//进行聚类过程
}
KMean::~KMean()
{
delete [] clusters;
delete [] cutData;
delete [] radio;
}
void KMean::Init_Means()//初始化函数(首先随即生成代表点)
//获取每个点到各自簇中心的距离和
doublegetSumOfDist(vector<Node>* clusters,vector<Node> mean_nodes);
//生成均值
NodegetMeans(intcluster_index);
//获取两个点之间的距离
doublegetDistance(Nodeactive,Nodeother);
public:
//构造函数,c_num为簇个数,node_vector为原始数据
KMean(intc_num,vector<Node> node_vector);
~KMean();
//找出离群点只要距离大于平均距离+标准差,则视为离群点
voidcut();
//显示剪枝结果
voidshowCutResult();
};
程序代码图
注:代码图中相关函数的说明见KMean类的方法说明。
七、
随机生成50个数据,随机选取4个簇心,如上图所示。
经过聚类,簇1、簇2的中心已改变,算出的阀值、检测到的离群点如上图所示。
簇3、簇4聚类后,正常点和离群点如图所示。
八、
实验程序,是在聚类完成之后,基于距离筛选出了离群点。在数据挖掘过程中,将离群点数据丢弃,更有利于分析获取有用的数据。从实验结果看,部分离群点的距离远大于正常距离,丢弃这些数据,避免无效数据干扰,显得非常有意义。
一、
1.深刻理解离群点,了解离群点检测的一般方法;
2.掌握基于距离的离群点检测算法;
3.锻炼分析问题、解决问题的思维,提高动手实践的能力。
二、
异常对象被称作离群点。异常检测也称偏差检测和例外挖掘。
常见的异常成因:数据来源于不同的类(异常对象来自于一个与大多数数据对象源(类)不同的源(类)的思想),自然变异,以及数据测量或收集误差。
{
int num = data.size();
srand((int)time(0));
for(int i =0 ;i<cluster_num;)
{
int pos = rand()%num;
bool insert_flag = true;
//首先判断选中的点是否是中心点
for(unsigned int j = 0;j< mean_nodes.size();j++)
1、
K-means算法
先随机选取K个对象作为初始的聚类中心。然后计算每个对象与各个种子聚类中心之间的距离,把每个对象分配给距离它最近的聚类中心。聚类中心以及分配给它们的对象就代表一个聚类。一旦全部对象都被分配了,每个聚类的聚类中心会根据聚类中现有的对象被重新计算。这个过程将不断重复直到满足某个终止条件。终止条件可以是以下任何一个:
node.pos_y = (rand() % 5000 );
vecData.push_back(node);
}
}
k-mean.hkmean类和Node类声明
//k-mean.h
#pragma once
#include <vector>
using namespace std;
//空间点的定义
class Node
九、
1.程序源码
main.cpp主程序入口
#inБайду номын сангаасlude <iostream>
#include <vector>
#include "k-mean.h"
#include <ctime>
using namespace std;
//输入数据
void input(vector<Node>& vecData,int num);
int main()
{
srand((int) time(0));
vector<Node> data;
int num,k;
cout << "请依次输入数据量、聚类个数(数据随机产生)\n";
cin >> num >> k;
input(data,num);
KMean kmean(k,data);
kmean.cut();
三、
改写一种简单的半监督方法,用于离群点检测。使用一种你熟悉的程序设计语言,如C++或Java,实现该方法,并在两种不同的数据集上进行讨论(1)只有一些被标记的正常对象;(2)只有一些被标记的离群点实例。
四、
Win7旗舰版+Visual Studio 2012
语言:C++
五、
K-means算法是很典型的基于距离的聚类算法,采用距离作为相似性的评价指标,即认为两个对象的距离越近,其相似度就越大。该算法认为簇是由距离靠近的对象组成的,因此把得到紧凑且独立的簇作为最终目标。
cout << "随机产生的数据如下:\n";
for (int i = 0; i < num; i++)
{
cout << "(" << data[i].pos_x << ", " << data[i].pos_y << ")\t\t";
d.重复步骤e和步骤f,直到簇心不再移动(或其他条件,如前后两次距离和不超过特定值),继续下一步;
e.计算每个簇的正常半径,即阀值(此程序阀值为每个簇的平均距离与1.5倍标准差之和);
f.从每个簇中,找出大于阀值的点,即离群点。
六、
Node类,定义了二维空间中的一个点,pos_x,pos_y三成员变量分别为x,y,轴的值,且为double型。Node类作为基本数据结构,使用在KMean类里。
//聚类过程,将空间中的点分到不同的簇中
void ClusterProcess();
//获取当前结点的簇下标
int getIndexOfCluster(vector<Node> means, Node active);
//获取每个点到各自簇中心的距离和
double getSumOfDist(vector<Node>* clusters, vector<Node> mean_nodes);
题 目
离群点检测(基于距离)
学生姓名
学生学号
专业班级
指导教师
2015-1-17
此实验是在实验三的基础上,修改完成。实验算法与上次相同,但增加了离群点检测。离群点检测方法为:在聚类完成之后,计算簇中的点到各自簇心的距离。当簇中的一点到簇心的距离大于该簇的平均距离与1.5倍标准差的和时,则认为该点为离群点,即阀值平均距离与1.5倍标准差的和。
KMean类封装了一系列成员变量和函数,实现了KMean算法。具体成员变量和函数详细说明如下:
classKMean
{
private:
intcluster_num;//生成的簇的数量。
vector<Node> mean_nodes;//均值点
vector<Node> data;//所有的数据点
vector<Node>* clusters;//簇,key为簇的下标,value为该簇中所有点
vector<Node> data;//所有的数据点
vector<Node>* clusters;//簇,key为簇的下标,value为该簇中所有点
int count;//记录迭代次数
vector<Node>* cutData;
double* radio;
//初始化函数(首先随即生成代表点)
void Init_Means();