算法实现
·采用VC++进行编写
文档的读取
#include “data.h”
//函数定义
double **DataRead(char*name,int row,intcol)
{
double**p=new double* [row];
ifstreaminfile;
infile.open(name,ios::in);
for(inTI=0;i《row;i++)
{
p[i]=newdouble[col];
for(intj=0;j《col;j++)
{
infile》》p[i][j];
}
}
infile.close();
cout《《“成功读取数据文件:”《《name《《“!\n”;
returnp;
//释放内存
for(i=0;i《row;i++)
{
delete[]p[i];
}
delete[]p;
}
文档的保存
#include “data.h”
void DataSave(double**data,int row,intcol,char*name)
{
inTI,j;
ofstreamoutfile;
//打开文件,输出数据
outfile.open(name,ios::out);
outfile.setf(ios::fixed);
outfile.precision(4);
for(i=0;i《row;i++)
{
for(j=0;j《col;j++)
{
outfile《《data[i][j]《《“”;
}
outfile《《endl;
}
outfile《《endl《《endl;
outfile.close();
}
数据标准化处理
#include “data.h”
double **Standardize(double **data,introw,int col)
{
inTI,j;
double*a=new double[col]; //矩阵每列的最大值
double*b=new double[col]; //矩阵每列的最小值
double*c=new double[row]; //矩阵列元素
for(i=0;i《col;i++)
{
//取出数据矩阵的各列元素
for(j=0;j《row;j++)
{
c[j]=Data[j][i];
}
a[i]=c[0],b[i]=c[0];
for(j=0;j《row;j++)
{
//取出该列的最大值
if(c[j]》a[i])
{
a[i]=c[j];
}
//取出该列的最小值
if(c[j]《b[i])
{
b[i]=c[j];
}
}
}
//数据标准化
for(i=0;i《row;i++)
{
for(j=0;j《col;j++)
{
data[i][j]=(data[i][j]-b[j])/(a[j]-b[j]);
}
}
cout《《“完成数据极差标准化处理!\n”;
delete[]a;
delete[]b;
delete[]c;
returndata;
}
生成样本虑属矩阵
#include “data.h”
void IniTIalize(double **u, int k, introw)
{
inti,j;
//初始化样本隶属度矩阵
srand(time(0));
for(i=0;i《k;i++)
{
for(j=0;j《row;j++)
{
u[i][j]=(double)rand()/RAND_MAX;//得到一个小于1的小数隶属度
}//rand()函数返回0和RAND_MAX之间的一个伪随机数
}
}
数据归一化处理
#include “data.h”
void Normalize(double **u,int k,intcol)
{
inti,j;
double*sum=new double[col];
//矩阵U的各列元素之和
for(j=0;j《col;j++)
{
doubledj=0;
for(i=0;i《k;i++)
{
dj=dj+U[i][j];
sum[j]=dj;//隶属度各列之和
}
}
for(i=0;i《k;i++)
{
for(j=0;j《col;j++)
{
u[i][j]=U[i][j]/sum[j];
}//规一化处理(每列隶属度之和为1)
}
}
迭代过程
#include “data.h”
#include “func.h”//对模糊C均值进行迭代运算,并返回有效性评价函数的值
doubleUpdate(double**u,double**data,double**center,int row,int col, int k)
{
inti,j,t;
double**p=NULL;
for(i=0;i《k;i++)
{
for(j=0;j《row;j++)
{
//模糊指数取2
u[i][j]=pow(u[i][j],2);
}
}
//根据隶属度矩阵计算聚类中心
p=MatrixMul(u,k,row,data,row,col);
for(i=0;i《k;i++)
{
//计算隶属度矩阵每行之和
doublesi=0;
for(j=0;j《row;j++)
{
si+=u[i][j];
}
for(t=0;t《col;t++)
{
center[i][t]=p[i][t]/si; //类中心
}
}
//计算各个聚类中心i分别到所有点j的距离矩阵dis(i,j)
double*a=new double[col]; //第一个样本点
double*b=new double[col]; //第二个样本点
double**dis=newdouble*[k]; //中心与样本之间距离矩阵
for(i=0;i《k;i++)
{
dis[i]=newdouble[row];
}
for(i=0;i《k; i++)
{
//聚类中心
for(t=0;t《col; t++)
{
a[t]=center[i][t]; //暂存类中心
}
//数据样本
for(j=0;j《row; j++)
{
for(t=0;t《col; t++)
{
b[t]=data[j][t];//暂存一样本
}
doubled=0;
//中心与样本之间距离的计算
for(t=0;t《col; t++)
{
d+=(a[t]-b[t])*(a[t]-b[t]); //d为一中心与所有样本的距离的平方和
}
dis[i][j]=sqrt(d); //距离
}
}
//根据距离矩阵计算隶属度矩阵
for(i=0;i《k;i++)
{
for(j=0;j《row;j++)
{
doubletemp=0;
for(t=0;t《k;t++)
{
//dis[i][j]依次除以所在列的各元素,加和;
//模糊指数为2.0
temp+=pow(dis[i][j]/dis[t][j],2/(2.0-1));//一个类中心和一个元素的距离平方与
}
u[i][j]=1/temp;//所有类与该元素距离平方的和的商
}
}
//计算聚类有效性评价函数
doublefunc1=0;
for(i=0;i《k;i++)
{
doublefunc2=0;
for(j=0;j《row;j++)
{
func2+=pow(u[i][j],2.0)*pow(dis[i][j],2);
}
func1+=func2;
}
doubleobj_fcn=1/(1+func1);
returnobj_fcn;
//内存释放
delete[]a;
delete[]b;
for(i=0;i《k;i++)
{
delete[]dis[i];
}
delete[]dis;
}
详细过程
#include “data.h”
#include “func.h”
#include “max.h”
//全局变量定义
double **Data; //数据矩阵
double **Center; //聚类中心矩阵
double **U; //样本隶属度矩阵
int m; //样本总数
int n; //样本属性数
int k; //设定的划分类别数
int main()
{
intLab; //数据文件标号
intnum; //算法运行次数
///
cout《《“模糊C均值聚类算法:”《《endl;
cout《《“1-iris.txt; 2-wine.txt; 3-ASD_12_2.txt; 4-ASD_14_2.txt”《《endl;
cout《《“请选择数据集: Lab=”;
cin》》Lab;
cout《《“设定运行次数: mum=”;
cin》》num;
//各次运行结束后的目标函数
double*Index=new double[num];
//各次运行结束后的聚类正确率
double*R=new double [num];
//num次运行的平均目标函数及平均正确率
doubleM_Index=0;
doubleM_R=0;
//FCM聚类算法运行num次,并保存记录与结果
for(inti=0;i《num;i++)
{
intj;
doubleepsilon=1e-4;
inte=0;
intnx=0;
//记录连续无改进次数
intE[200]={0};
if(i》0)
{
cout《《endl《《endl;
cout《《setfill(‘#’)《《setw(10)《《endl;
}
cout《《“第”《《i+1《《“次运行记录:”《《endl;
//读取数据文件
if(Lab==1)
{
m=150;
n=4;
k=3;
Data=DataRead(“dataset\\iris.txt”,m,n);
}
elseif(Lab==2)
{
m=178;
n=13;
k=3;
Data=DataRead(“dataset\\wine.txt”,m,n);
}
elseif(Lab==3)
{
m=535;
n=2;
k=12;
Data=DataRead(“dataset\\ASD_12_2.txt”,m,n);
}
elseif(Lab==4)
{
m=685;
n=2;
k=14;
Data=DataRead(“dataset\\ASD_14_2.txt”,m,n);
}
//数据极差标准化处理
Data=Standardize(Data,m,n);
//聚类中心及隶属度矩阵,内存分配
Center=newdouble*[k];
U=newdouble *[k];
for(j=0;j《k;j++)
{
Center[j]=newdouble[n];
U[j]=newdouble[m];
}
//隶属度矩阵的初始化
Initialize(U,k, m);
//对隶属度矩阵进行归一化
Normalize(U,k,m);
//历次迭代过程中的目标函数
doubleObjfcn[100]={0};
cout《《“第”《《i+1《《“次运行记录:”《《endl;
cout《《“开始迭代过程!”《《endl;
cout《《“*******************************”《《endl;
//输出精度为小数点后5位
cout.precision(5);
//固定格式
cout.setf(ios::fixed);
//目标函数连续20代无改进,停止该次聚类迭代过程
while(e《20)
{
nx++;
//聚类迭代过程
Objfcn[nx]=Update(U,Data,Center,m,n,k);
//统计目标函数连续无改进次数e
if(nx》0&& Objfcn[nx]-Objfcn[nx-1]《epsilon )
{
e++;
}
else
{
e=0;
}
E[nx]=e;
}
//输出结果到文件,保存
ofstreamoutfile(“运行记录.txt”,ios::app);
outfile《《“第”《《i+1《《“次运行记录:”《《endl;
outfile《《“开始迭代过程!”《《endl;
outfile《《“*******************************”《《endl;
outfile.precision(5);
outfile.setf(ios::fixed);
for(intn1=1;n1《=nx;n1++)
{
cout《《“e[”《《setw(2)《《n1《《“]=”《《setw(2)《《E[n1]《《“ Objfcn[”
《《setw(2)《《n1《《“]=”《《Objfcn[n1]《《“\n”;
//保存数据文件
outfile《《“e[”《《setw(2)《《n1《《“]=”《《setw(2)《《E[n1]《《“ Objfcn[”
《《setw(2)《《n1《《“]=”《《Objfcn[n1]《《“\n”;
}
cout《《endl;
outfile《《endl;
outfile.close();
//本次运行的最大目标函数
Index[i]=Objfcn[nx];
//保存聚类正确率,输出聚类结果:
R[i]=Result(Lab,U, k, m, i);
//内存释放
for(j=0;j《k;j++)
{
delete[]Center[j];
delete[]U[j];
}
delete[]Center;
delete[]U;
}
//统计平均///
doubletemp1=0, temp2=0;
for(i=0;i《num;i++)
{
temp1+=Index[i];
temp2+=R[i];
}
//计算各次结果的统计平均
M_Index=(double)temp1/num;
M_R=(double)temp2/num;
cout《《“//”《《endl;
cout《《num《《“次运行,平均聚类正确率: ”《《100*M_R《《“%”《《endl;
//输出精度为小数点后6位
cout.precision(6);
//固定格式
cout.setf(ios::fixed);
cout《《“平均目标函数:”《《M_Index《《endl;
//统计结果文件保存
ofstreamresultfile(“聚类结果.txt”,ios::app);
resultfile《《“//”《《endl;
resultfile《《num《《“次运行,平均聚类正确率: ”《《100*M_R《《“%”《《endl;
//输出精度为小数点后6位
resultfile.precision(6);
//固定格式
resultfile.setf(ios::fixed);
resultfile《《“平均目标函数:”《《M_Index《《endl;
return0;
}