完整word版离群点检测基于距离实验报告Word下载.docx
《完整word版离群点检测基于距离实验报告Word下载.docx》由会员分享,可在线阅读,更多相关《完整word版离群点检测基于距离实验报告Word下载.docx(14页珍藏版)》请在冰豆网上搜索。
异常检测的方法:
(1)基于模型的技术:
首先建立一个数据模型,异常是那些同模型不能完美拟合的对象;
如果模型是簇的集合,则异常是不显著属于任何簇的对象;
在使用回归模型时,异常是相对远离预测值的对象;
(2)基于邻近度的技术:
通常可以在对象之间定义邻近性度量,异常对象是那些远离其他对象的对象;
(3)基于密度的技术:
仅当一个点的局部密度显著低于它的大部分近邻时才将其分类为离群点。
三、实验要求
改写一种简单的半监督方法,用于离群点检测。
使用一种你熟悉的程序设计语言,如C++或Java,实现该方法,并在两种不同的数据集上进行讨论
(1)只有一些被标记的正常对象;
(2)只有一些被标记的离群点实例。
四、实验环境
Win7旗舰版+VisualStudio2012
语言:
C++
五、算法描述
K-means算法是很典型的基于距离的聚类算法,采用距离作为相似性的评价指标,即认为两个对象的距离越近,其相似度就越大。
该算法认为簇是由距离靠近的对象组成的,因此把得到紧凑且独立的簇作为最终目标。
1、算法思路
K-means算法
先随机选取K个对象作为初始的聚类中心。
然后计算每个对象与各个种子聚类中心之间的距离,把每个对象分配给距离它最近的聚类中心。
聚类中心以及分配给它们的对象就代表一个聚类。
一旦全部对象都被分配了,每个聚类的聚类中心会根据聚类中现有的对象被重新计算。
这个过程将不断重复直到满足某个终止条件。
终止条件可以是以下任何一个:
1)没有(或最小数目)对象被重新分配给不同的聚类。
2)没有(或最小数目)聚类中心再发生变化。
3)误差平方和局部最小。
2、算法步骤
a.从数据集中随机挑K个数据当簇心;
b.对数据中的所有点求到这K个簇心的距离,假如点Pi离簇心Si最近,那么Pi属于Si对应的簇;
c.根据每个簇的数据,更新簇心,使得簇心位于簇的中心;
d.重复步骤e和步骤f,直到簇心不再移动(或其他条件,如前后两次距离和不超过特定值),继续下一步;
e.计算每个簇的正常半径,即阀值(此程序阀值为每个簇的平均距离与1.5倍标准差之和);
f.从每个簇中,找出大于阀值的点,即离群点。
六、数据结构
Node类,定义了二维空间中的一个点,pos_x,pos_y三成员变量分别为x,y,轴的值,且为double型。
Node类作为基本数据结构,使用在KMean类里。
KMean类封装了一系列成员变量和函数,实现了KMean算法。
具体成员变量和函数详细说明如下:
classKMean
{
private:
intcluster_num;
//生成的簇的数量。
vector<
Node>
mean_nodes;
//均值点
data;
//所有的数据点
*clusters;
//簇,key为簇的下标,value为该簇中所有点
intcount;
//记录迭代次数
*cutData;
double*radio;
//初始化函数(首先随即生成代表点)
voidInit_Means();
//聚类过程,将空间中的点分到不同的簇中
voidClusterProcess();
//获取当前结点的簇下标
intgetIndexOfCluster(vector<
means,Nodeactive);
//获取每个点到各自簇中心的距离和
doublegetSumOfDist(vector<
*clusters,vector<
mean_nodes);
//生成均值
NodegetMeans(intcluster_index);
//获取两个点之间的距离doublegetDistance(Nodeactive,Nodeother);
public:
//构造函数,c_num为簇个数,node_vector为原始数据
KMean(intc_num,vector<
node_vector);
~KMean();
//找出离群点只要距离大于平均距离+标准差,则视为离群点voidcut();
//显示剪枝结果
voidshowCutResult();
};
程序代码图
注:
代码图中相关函数的说明见KMean类的方法说明
七、程序截图
随机生成50个数据,随机选取4个簇心,如上图所示
经过聚类,簇1、簇2的中心已改变,算出的阀值、检测到的离群点如上图
所示。
簇3、簇4聚类后,正常点和离群点如图所示。
八、实验总结
实验程序,是在聚类完成之后,基于距离筛选出了离群点。
在数据挖掘过程中,将离群点数据丢弃,更有利于分析获取有用的数据。
从实验结果看,部分离群点的距离远大于正常距离,丢弃这些数据,避免无效数据干扰,显得非常有意义。
九、附件
1.程序源码
main.cpp主程序入口
#include<
iostream>
vector>
#include"
k-mean.h"
ctime>
usingnamespacestd;
//输入数据
voidinput(vector<
&
vecData,intnum);
intmain()
srand((int)time(0));
vector<
intnum,k;
cout<
<
"
请依次输入数据量、聚类个数(数据随机产生)\n"
;
cin>
>
num>
k;
input(data,num);
KMeankmean(k,data);
kmean.cut();
kmean.showCutResult();
system("
pause"
);
return0;
}
vecData,intnum)
for(inti=0;
i<
num;
i++)
Nodenode;
node.pos_x=(rand()%5000);
node.pos_y=(rand()%5000);
vecData.push_back(node);
k-mean.hkmean类和Node类声明
//k-mean.h
#pragmaonce
//空间点的定义classNode{
public:
doublepos_x;
doublepos_y;
Node()
pos_x=0.0;
pos_y=0.0;
friendbooloperator<
(constNode&
first,constNode&
second)
//对x轴的比较if(first.pos_x<
second.pos_x){
returntrue;
elseif(first.pos_x>
second.pos_x)
returnfalse;
//对y轴的比较
else
{if(first.pos_y<
second.pos_y){
friendbooloperator==(constNode&
{if(first.pos_x==second.pos_x&
first.pos_y==second.pos_y){
}else
classKMean
private:
intcluster_num;
//生成的簇的数量。
vector<
/均/值点vector<
//所有的数据点vector<
//簇,key为簇的下标,value为该簇中所有点intcount;
//记录迭代次数vector<
double*radio;
//初始化函数(首先随即生成代表点)
//聚类过程,将空间中的点分到不同的簇中voidClusterProcess();
//获取当前结点的簇下标
intgetIndexOfCluster(vector<
//获取每个点到各自簇中心的距离和doublegetSumOfDist(vector<
*clusters,vector<
//生成均值
NodegetMeans(intcluster_index);
//获取两个点之间的距离doublegetDistance(Nodeactive,Nodeother);
//构造函数,c_num为簇个数,node_vector为原始数据
KMean(intc_num,vector<
~KMean();
//找出离群点只要距离大于平均距离+标准差,则视为离群点
voidcut();
//显示剪枝结果
k-mean.cppkmean类的成员函数具体定义
cstdlib>
algorithm>
cmath>
iomanip>
KMean:
:
node_vector)
{cluster_num=c_num;
data=node_vector;
clusters=newvector<
[cluster_num];