直方图进行数据离散化实验数据2.docx
《直方图进行数据离散化实验数据2.docx》由会员分享,可在线阅读,更多相关《直方图进行数据离散化实验数据2.docx(13页珍藏版)》请在冰豆网上搜索。
直方图进行数据离散化实验数据2
实验题目:
直方图进行数据离散化
1实验目的
直方图使用分箱来近似数据分布,是数据规约的一种形式。
通过本实验,需要掌握不同直方图的数学原理和构造方法。
同时,掌握使用不同直方图对数据进行离散化的原理和方法。
最后,利用实验数据实现一种直方图并进行评估。
2实验步骤
2.1算法原理
首先,假设有N个自然数的集合U={x|x∈N},其中最大值为
。
〔1〕等宽度直方图
对数据进行分箱。
假设按等宽度的方法进行分箱〔宽度w=1〕,那么对于N个数据,按其值
分别放入到相应的箱中,箱子的数目
。
设每个箱中的统计数据为
,按照坐标值/频率对〔
〕表示在二维坐标上,那么可以得到该组数据的单桶直方图。
其中,
。
一般情况下,为了进一步压缩数据,通常进行数据分箱时,每一个桶代表的是连续的属性值,即取宽度
。
在这种分箱方法下,分箱数目
。
那么按照公式
,其中
,令
所得到的值/频率对
,
的宽度为q的直方图,即为常见的等宽度直方图。
〔2〕等深度直方图
与等宽度直方图相比,等深度直方图仅仅是在创立数据桶时与其不同。
等深度直方图的数据桶的创立思想是:
使得每个桶的频率粗略的为常数,即每个桶中包含大致相当的样本数据数目。
设分箱的数目为K,那么对于每一个桶,有
,其中
。
只有在这种情况下,才满足
大致相当。
所要求的是每一个桶的边界
,
。
求边界的过程:
首先对该集合U进行排序〔由小到大〕,由于每桶的数目相等,所以每间隔c个数据,取一次数据值,即为一个有效的边界值。
对于排序后的序列,有
。
所得到的二维
值对,即是等深度直方图。
2.2算法步骤
用户输入数据分桶的数目K,然后按如下步骤计算:
〔1〕对样本数据进行排序
〔2〕计算宽度w和c
〔2〕对数据进行扫描和计算等宽度直方图的数目值
和等深度直方图的边界
2.3程序流程图
开始
获取分桶数目k
读入文件数据
计算桶宽度w
逐个扫描数据,
统计数目
结束
图1等宽度直方图流程图
在图1中,数据的分桶数目是用户输入的数据,预先由用户设定。
样本数据存放在文本文件eggs.txt中,由程序运行时读入。
在实验中,通过对样本数据的考察,计算桶宽度w的方法是
。
统计结果存放在数组中,返回统计结果。
获取分桶数目k
读入文件数据
数据顺序排序
计算桶的深度p,每个桶的数目c
开始
结束
间隔c个数目在数据中一个值,作为边界值
图2等深度直方图流程图
在图2中,数据的分桶数目是用户输入的数据,预先由用户设定。
样本数据存放在文本文件eggs.txt中,由程序运行时读入。
每个桶的数据量c的计算公式
,N表示原始数据的数据个数。
边界计算结果存放在数组e中,返回边界数组,计算过程结束。
3实验结果分析
图3等宽度直方图〔K=10〕统计结果
图4等宽度直方图〔K=20〕统计结果
图5等深度直方图〔K=10〕统计结果
图6等深度直方图〔K=20〕统计结果
上面的图分别表示K=10和K=20的情况下eggs.txt中数据的等宽度和等深度直方图的统计结果。
直方图的使用是为了离散化数据。
在实验中,使用每个桶的中值来代表该桶中数据的离散结果。
在K=10的情况下:
使用等宽度直方图,样本数据离散值为{550,1650,2750,3850,4950,6050,7150,8250,9350,10450};使用等深度直方图,样本数据的离散值为{3,43,182,403,643,981,1378,1803,2365,6770}。
在K=20的情况下,使用等宽度直方图,样本数据离散值为{275,825,1375,1650,1925,2475,3025,3575,4125,4675,5225,5775,6325,6875,7425,7975,8525,9075,9625,10175,10725};使用等深度直方图,样本数据的离散值为{0,2,17,50,108,199,308,412,539,683,842,1051,1221,1368,1552,1776,2035,2338,2742,6915}。
实验说明:
对于采用不同的直方图和不同的桶数目K,得到不同的离散化结果。
4实验结论
对于上述的四种离散化结果,如何来判定哪种离散化数据的效果更好呢?
一般的,离散后的数据越接近样本原始数据,那么效果越好。
数据离散化后,与原始数据肯定存在差异,一般用误差度量这种差异大小。
在这里,定义平均相对误差和最大相对误差来表示离散数据逼近原始样本数据的程度,作为离散化的评判标准。
平均相对误差E定义如下:
,其中,
和
分别表示第i个值的离散值和真实值,N表示数据总量。
最大相对误差M定义如下:
,其中,
,
,N的定义和平均相对误差中的相同。
对于K=10,根据等宽度和等深度的方法,可以得到两组不同的离散值T1和T2。
对于这两组离散值,通过计算,得到平均相对误差E1=8.538418,E2=0.399769,最大相对误差M1=549.00,M2=2.00。
由上述两组比拟可得,在对该样本数据进行离散化时,采用等宽度直方图的方法,效果更好。
对于等宽度直方图,当K=10和K=20的情况下,可得到两组不同的离散值T1和T2。
通过上述方法计算可得,平均相对误差E1=8.538418,E2=4.261210,最大相对误差M1=549.00,M2=274.00。
对于上述两组数据,对于采用直方图进行数据离散化,在桶数目多的情况下,误差较小。
当K=N时,数据即为原始数据,此时,误差E和M都为0。
但是这样的数据离散化时无意义的,在比拟K不同时,还需要考虑另一项指标:
数据压缩比率。
在实验中,对于每个桶中的数据,取离散值的方法是取中值。
如果改变取值方法,比方用桶内样本的平均值来表示离散值,那么会得到不同的E和M,但是结论不会改变。
5实验心得体会
1、使用程序读入文本数据方法
读入数据问题,使用的数据是从dat文件转换过来的txt文件,每行的数据都是换行后的,所以可以直接通过getline函数获取每行值,然后使用atoi函数转换为整型数据。
2、为何在实验结论中的评价标准不使用绝对误差?
绝对误差对于离群点敏感,不能代表整体逼近效果。
3、对于一簇样本数据,应采用何种直方图划分更为合理?
对于数据的划分,在实验中是采用用户的一个预设值,可以通过数学的方法获取一个较为良好的K值吗?
参考文献
[1]数据挖掘:
概念与技术/〔加〕韩家炜,〔加〕坎伯〔Kamber,M.〕著;范明等译.-北京:
机械工业出版社,2001.8
附录〔源代码〕
//读入数据
BOOLCDrawHistogramDoc:
:
ReadFile(CStringfilePath)
{
fstreaminfile("eggs.txt");
if(!
infile)
returnFALSE;
charch_num[10];
//inti=0;
//infile.seekg
while(!
infile.eof())
{
infile.getline(ch_num,sizeof(ch_num));
vt_data_org.push_back(atoi(ch_num));
}
infile.close();
returnTRUE;
}
//等宽度直方图统计
voidCDrawHistogramDoc:
:
WidthEqualCate(vectorvt,intmin,intmax,intnum)
{
if(max<=0||num==0)
return;
intinterval=max/(int)num;
//申请数组,初始化为0
int*array=newint[num];
for(intpos=0;pos{
array[pos]=0;
}
for(inti=0;i<(int)vt.size();i++)
{
if(vt[i]/intervalarray[vt[i]/interval]++;
}
this->vt_data_width.assign(array,array+num);
delete[]array;
}
//等深度直方图计算边界
voidCDrawHistogramDoc:
:
DepthEqualCate(vectorvt,intmin,intmax,intnum)
{
if(max<=0||num==0)
return;
//首先排序,然后查找值,默认升序
sort(vt.begin(),vt.end());
intsize=(int)vt.size();
intinterval=(int)vt.size()/num;
inti=interval;
for(intj=0;j{
this->vt_data_depth.push_back(vt[i]);
i+=interval;
}
this->vt_data_depth.push_back(vt[size-1]);
}
//直方图绘制
voidCDrawHistogramView:
:
DrawEqualWidthHistogram(intx_size)
{
//this->OnInitialUpdate();
//this->Invalidate();
CDrawHistogramDoc*pDoc=GetDocument();
ASSERT_VALID(pDoc);
CClientDCdc(this);
vector:
:
iteratorptr;
inti=0;
for(ptr=pDoc->vt_data_width.begin();ptr!
=pDoc->vt_data_width.end();ptr++)
{
//计算矩形区域
CRectrect(this->orgPoint.x+i*x_size,this->orgPoint.y-(pDoc->vt_data_width[i])/this->y_ratio,this->orgPoint.x+(i+1)*x_size,this->orgPoint.y);
CBrush*myBrush=newCBrush;
myBrush->CreateSolidBrush(RGB(i*45%255,i*75%255,i*5));
//填充区域
dc.FillRect(&rect,myBrush);
i++;
}
//显示统计值
CStringstr;
for(intj=0;jvt_data_width.size();j++)
{
str.Format("%d",pDoc->vt_data_width[j]);
dc.TextOut(orgPoint.x+X_LENGTH,orgPoint.y-Y_LENGTH+20*j,str);
}
}
voidCDrawHistogramView:
:
DrawEqualDepthHistogram()
{
//this->OnInitialUpdate();
CDrawHistogramDoc*pDoc=GetDocument();
ASSERT_VALID(pDoc);
CClientDCdc(this);
vector:
:
iteratorptr;
inti=0;
if(pDoc->vt_data_depth[pDoc->vt_data_depth.size()-1]/this->x_ratio>X_LENGTH)
{
this->Invalidate();
MessageBox("坐标和数据不符合!
","错误",MB_OK|MB_ICONERROR);
return;
}
//最后一个数是终点边界
for(ptr=pDoc->vt_data_depth.begin();ptr!
=pDoc->vt_data_depth.end();ptr++)
{
//绘制0-vt_data_depth[0]
if(i==0)
{
CRectrect(this->orgPoint.x,this->orgPoint.y-200,this->orgPoint.x+pDoc->vt_data_depth[0]/this->x_ratio,this->orgPoint.y);
CBrush*myBrush=newCBrush;
myBrush->CreateSolidBrush(RGB(i*25,i*75,i*5));
dc.FillRect(&rect,myBrush);
}
else
{//计算矩形区域
CRectrect(this->orgPoint.x+pDoc->vt_data_depth[i-1]/this->x_ratio,this->orgPoint.y-200,this->orgPoint.x+pDoc->vt_data_depth[i]/this->x_ratio,this->orgPoint.y);
CBrush*myBrush=newCBrush;
myBrush->CreateSolidBrush(RGB(i*45%255,i*75%255,i*5));
//MessageBox("aaa");
//填充区域
dc.FillRect(&rect,myBrush);
}
i++;
}
//显示统计值
CStringstr;
for(intj=0;jvt_data_depth.size();j++)
{
str.Format("%d",pDoc->vt_data_depth[j]);
dc.TextOut(orgPoint.x+X_LENGTH,orgPoint.y-Y_LENGTH+20*j,str);
}
}
内容总结