回归方程数据处理.docx
《回归方程数据处理.docx》由会员分享,可在线阅读,更多相关《回归方程数据处理.docx(20页珍藏版)》请在冰豆网上搜索。
回归方程数据处理
回归方程数据处理
实验
姓名:
沟超辉
学号:
101001106
一、实验目的
回归分析是数理统计中的一个重要分支,在工农业生产和科学研究中有着广泛的应用。
通过本次实验要求掌握一元线性回归和一元非线性回归。
二、实验原理
回归分析是处理变量之间相关关系的一种数理统计方法。
即用数学的方法,对大量的观测数据进行处理,从而得出比较符合事物内部规律的数学表达式。
利用最小二乘估计,得到一元线性回归的回归方程为
^
y=b0+bx
式中b0,b为回归方程的回归系数,y代表抗剪强度。
求出∑xi,∑yi,∑xi2,∑yi2,∑xiyi,∑xi∑yi
于是x=1/n∑xi,y=1/n∑yi
lxx=∑xi2–(∑xi)2/n
lxy=∑xiyi–(∑xi∑yi)/n
b=lxy/lxx
b0=y-bx
三、实验内容及程序结果
(一)
(1)材料的抗剪强度与材料承受的正应力有关。
对某种材料试验的数据如下
正应力x/pa
26.8
25.4
23.6
27.7
抗剪强度y/pa
26.5
27.3
27.1
23.6
23.9
24.7
28.1
26.9
27.4
22.6
25.6
25.9
26.3
22.5
21.7
21.4
25.8
24.9
假设正应力是精确的,求抗剪强度与正应力的线性回归方程
当正应力为24.5pa时,抗剪强度的估计值?
程序及运行结果:
fori=0
X=[26.825.423.627.723.924.728.126.927.422.625.6];
Y=[26.527.327.123.625.926.322.521.721.425.824.9];
N=length(X);
lxx=sum(X.*X)-sum(X).^2./N;
lxy=sum(X.*Y)-sum(X).*sum(Y)/N;
b=lxy./lxx;
b0=mean(Y)-b.*mean(X);
x=(21:
0.01:
31);
y=b.*x+b0;
plot(X,Y,'b*',x,y,'r-')
end
实验结果:
lxx=43.0467
lxy=-29.5333
b=-0.6861
b0=42.5818
材料的抗剪强度与材料承受的正应力关系为:
y=42.5818-0.6861x
实验内容及程序结果
(二)
(2)下表给出在不同质量下弹簧长度的观测值(设质量的观测值无误差):
质量/g
5
10
15
20
25
30
长度/cm
7.25
8.12
8.95
9.90
10.9
11.8
做散点图,观察质量与长度之间是否呈线性关系;求弹簧的刚性系数和自由状态下的长度。
程序及运行结果:
fori=0
X=[51015202530];
Y=[7.258.128.959.9010.911.8];
N=length(X);
lxy=sum(X.*Y)-sum(X).*sum(Y)./N;
lxx=sum(X.*X)-((sum(X)).^2)./N;
b=lxy./lxx;
b0=mean(Y)-b.*mean(X);
x=(5:
0.01:
30);
y=b.*x+b0;
plot(X,Y,'b*',x,y,'r-')
end
以刚性系数k=b=0.1831,自由长度x0=b0=6.2827
四、实验小结
一元回归是处理两个变量之间的关系,即两个变量x和y之间若存在一定的关系,则可通过实验的方法,分析所得数据,找出两者之间关系的经验公式。
假如两个变量之间的关系是线性的就称为一元线性回归,这就是工程上和科研中场遇到的直线拟合问题。
Java实现k-means
1.数据来源描述
本数据集中一共包含600组数据,每一组数据都有60个分量,也就是数据是60维的。
数据一共可以分成6个聚类,分别是:
1-100Normal(正常)
101-200Cyclic(循环)
201-300Increasingtrend(增加趋势)
301-400Decreasingtrend(减少趋势)
401-500Upwardshift(上升变化)
501-600Downwardshift(下降变化)
2.数据预处理
由于本数据集的数据维数较多,所以本实验采用了结构体来存储60维的数据,并使用指针来进行对数据的操作,以提高速度。
在数据预处理过程中,首先将数据从data文件中读出,后依次存入结构体数组dataset[600]中。
3.k-means聚类算法
k-means算法接受参数k;然后将事先输入的n个数据对象划分为k个聚类以便使得所获得的聚类满足:
同一聚类中的对象相似度较高;而不同聚类中的对象相似度较小。
聚类相似度是利用各聚类中对象的均值所获得一个“中心对象”(引力中心)来进行计算的。
K-means算法是最为经典的基于划分的聚类方法,是十大经典数据挖掘算法之一。
K-means算法的基本思想是:
以空间中k个点为中心进行聚类,对最靠近他们的对象归类。
通过迭代的方法,逐次更新各聚类中心的值,直至得到最好的聚类结果。
(1)算法思路:
首先从n个数据对象任意选择k个对象作为初始聚类中心;而对于所剩下其它对象,则根据它们与这些聚类中心的相似度(距离),分别将它们分配给与其最相似的(聚类中心所代表的)聚类;然后再计算每个所获新聚类的聚类中心(该聚类中所有对象的均值);不断重复这一过程直到标准测度函数开始收敛为止。
一般都采用均方差作为标准测度函数.k个聚类具有以下特点:
各聚类本身尽可能的紧凑,而各聚类之间尽可能的分开。
该算法的最大优势在于简洁和快速。
算法的关键在于初始中心的选择和距离公式。
(2)算法步骤:
step.1---初始化距离K个聚类的质心(随机产生)
step.2---计算所有数据样本与每个质心的欧氏距离,将数据样本加入与其欧氏距离最短的那个质心的簇中(记录其数据样本的编号)
step.3---计算现在每个簇的质心,进行更新,判断新质心是否与原质心相等,若相等,则迭代结束,若不相等,回到step2继续迭代。
4.数据挖掘实现的源代码
//111060850.cppKMeans聚类算法
//
#include"stdafx.h"
#include
#include
#include
#include
#include
#include
usingnamespacestd;
constintN=36000;//数据个数
constintD=60;//数据维度
structDataSet{//用来存储数据的结构体
doublearg[D];
};
constintK=6;//集合个数
int*CenterIndex;//质心索引集合
//structDataSet*Center;//质心集合
//structDataSet*CenterCopy[];
DataSetCenter[K];//保存现在的质心
DataSetCenterCopy[K];//保存上一次迭代中的质心
//double*DataSet;
intCluster[6][N/D];//保存每个簇包含的数据的索引值
int*Top;
ifstreamfin;
charch;
stringfDataSet[N/D][D];
/*算法描述:
kmeans聚类算法采用的是给定类的个数K,将N个元素(对象)分配到K个类中去
使得类内对象之间的相似性最大,而类之间的相似性最小*/
//数据存储在结构体中
//函数声明部分
voidInitData(structDataSet*dataset);
//对数据集进行初始化,从文件中将其读取出后转化为double型依次存入结构体中
voidInitCenter(structDataSet*dataset);
//初始化质心
voidCreateRandomArray(intn,intk,int*centerIndex);
//随机产生一组索引值,用于初始化质心
voidCopyCenter(structDataSet*dataset);
//复制保存上一次迭代的质心
voidUpdateCluster(structDataSet*dataset);
//更新簇
voidUpdateCenter(structDataSet*dataset);
//更新质心
intGetIndex(structDataSet*dataset,structDataSet*centerIndex);
//本程序的核心,计算每一数据元素属于哪一个聚类,并返回其索引值
voidAddtoCluster(intindex,intvalue);
//根据索引值将数据元素的索引加入到簇之中
voidprint(structDataSet*dataset);
boolIsEqual(structDataSet*value1,structDataSet*value2);
//判断现有质心和上一次迭代的质心是否相等
doubleDoubletoString(constchar*str);
//string转化为double型的函数
doubleEuclidean(structDataSet*value1,structDataSet*value2);
//计算欧几里得距离函数
intmain(intargc,char*argv[])
{
intFlag=1;
doublettime=0,start=0,end=0;
start=clock();
DataSetdataset[N/D];
InitData(dataset);
/*for(inti=0;i{for(intj=0;jcout<cout<}*/
while(Flag)
{
UpdateCluster(dataset);
UpdateCenter(dataset);
if(IsEqual(Center,CenterCopy))
{
Flag=0;
}
else
{
CopyCenter(dataset);
}
}
end=clock();
ttime=(double)(end-start)/CLOCKS_PER_SEC;
print(dataset);
getchar();
return0;
}
voidInitData(structDataSet*dataset)
{
inti=0,j=0;
CenterIndex=newint[sizeof(int)*K];
Top=newint[sizeof(int)*K];
//Cluster=newint*[sizeof(int*)*K];
//从文件中读入数据,存入fDataSet数组中,此数组为string类型
//然后通过转化成double型存入DataSet数组之中。
cout<<"开始从文件读入数据"<fin.open("synthetic_control.data");
for(i=0;ifor(j=0;j{
while(fin.peek()!
='\n'&&fin.peek()!
='')//从文件中取出数字(字符串形式),略过空格和换行
{fin>>ch;
fDataSet[i][j]=fDataSet[i][j]+ch;
dataset[i].arg[j]=DoubletoString(fDataSet[i][j].c_str());
}
while(fin.peek()=='\n'||fin.peek()=='')
fin.get();
}
fin.close();
cout<<"数据已读入"<InitCenter(dataset);
UpdateCluster(dataset);
}
voidInitCenter(structDataSet*dataset)
{
inti=0;
//产生随即的K个CreateRandomArray(N/D,K,CenterIndex);
for(i=0;i{
for(intj=0;jCenter[i].arg[j]=dataset[CenterIndex[i]].arg[j];
//cout<
}
CopyCenter(dataset);
}
voidCreateRandomArray(intn,intk,int*centerIndex)
{
inti=0,j=0;
for(i=0;i{
inta=rand()%n;
for(j=0;j
{
if(centerIndex[j]==a)
break;
}
if(j>=i)
{
centerIndex[i]=a;
}
else
{
i--;
}
}
}
voidCopyCenter(structDataSet*dataset)
{
inti=0;
for(i=0;i{
CenterCopy[i]=Center[i];
}
}
voidUpdateCluster(structDataSet*dataset)
{
inti=0;
inttindex;
for(;i{
Top[i]=0;
}
for(i=0;i{
tindex=GetIndex(&dataset[i],Center);//tindex是指dataset[i]属于第tindex个簇
AddtoCluster(tindex,i);//把dataset[i]加入到所属的簇当中
}
}
intGetIndex(structDataSet*value,structDataSet*center)
{
inti=0;
intindex=i;
//doublemin=fabs(value-center[i]);
doublemin=Euclidean(value,¢er[i]);
for(i=0;i{
if(Euclidean(value,¢er[i]){
index=i;
min=Euclidean(value,¢er[i]);
}
}
returnindex;
}
voidAddtoCluster(intindex,intvalue)
{
Cluster[index][Top[index]]=value;
Top[index]++;
}
doubleDoubletoString(constchar*str)
{
doubletemp=0.0,wt=10.0;
boolflag=true;
inti;
for(i=0;i<*(str+i)!
='\0';i++)
{
if(flag&&*(str+i)==46)//若遇到小数点则置标志位为false,则后面读入的
flag=false;//char转化为小数形式
elseif(flag)//整数部分
temp=(int)(*(str+i)-48)+temp*10;
else{
temp=temp+(int)(*(str+i)-48)/wt;//小数部分
wt=wt*10;
}
}
returntemp;
}
doubleEuclidean(structDataSet*value1,structDataSet*value2)
{
doubletemp=0,sum=0;
for(inti=0;isum=(value1->arg[i]-value2->arg[i])*(value1->arg[i]-value2->arg[i]);
temp=sqrt(sum);
returntemp;
}
boolIsEqual(structDataSet*value1,structDataSet*value2)
{
inti;
for(i=0;i{
for(intj=0;jif(value1[i].arg[j]!
=value2[i].arg[j])
return0;
}
return1;
}
voidUpdateCenter(structDataSet*dataset)
{
inti=0,j=0;
doublesum;
for(i=0;i{
for(intd=0;d{
sum=0.0;
for(j=0;j{
sum+=dataset[Cluster[i][j]].arg[d];
}
if(Top[i]>0)
{
Center[i].arg[d]=sum/Top[i];
}
}
}
}
voidprint(structDataSet*dataset)
{
inti,j,d;
ofstreamfout("result.txt");
cout<<"===================================="<fout<<"===================================="<for(i=0;i{
cout<<"第"<
质心为:
";
for(d=0;dcout<
cout<cout<<"数据元素为:
\n";
//--------------------------------------------
//输入文件中
fout<<"第"<
质心为:
";
for(d=0;dfout<
fout<fout<<"数据元素为:
\n";
for(j=0;j{for(d=0;dcout<fout<//fout<}
cout<fout<}
cout<fout<}
fout<<"总共用时:
"<fout.close();
}
5.获取的模型的描述
首先,准备数据,对数据进行预处理,选用合适的数据结构存储数据元组,然后设定参数,数据的总量N,维度D,聚类类别数量K,然后随机产生K个D维的数据作为质心,计算每个数据与质心距离,并加入所属的簇中,经多次迭代后,质心不变后,得到分类后的结果。
6.实验运行结果和实验分析
数据挖掘对处理后的数据采用k-means聚类算法,将聚类后的结果输入到文件中(图1),实验的结果:
图1
结果将数据元组分成了6类,按期每个分量的变化规律分别表示上文所说的6个类别。
在文档最后输出聚类分析花费的时间(图2)是1762毫秒。
图2
由于初始化质心是随机的,所以每次运行聚类分析花费的时间略有不同,本实验采用结构体来存储数据,聚类的操作多应用指针来实现,在选择所属的簇,并加入簇中,加入的是数据的索引值,提高了效率,在一步中如果使用指针指向数据可以进一步提高效率。
总体上说算法的运行时间还是比较令人满意。