源程序
《机器学习与神经网络》一书的代码中有生成半月形数据用于训练与测试。我将原matlab代码转为C/C++的代码,方便后续程序。
原matlab代码如下:
function [data, data_shuffled] = halfmoon(rad,width,d,n_samp)
% A function to generate the halfmoon data
% where Input:
% rad - central radius of the half moon
% width - width of the half moon
% d - distance between two half moon
% n_samp - total number of the samples
% Output:
% data - output data
%data_shuffled - shuffled data
% For example
% halfmoon(10,2,0,1000) will generate 1000 data of
% two half moons with radius [9-11] and space 0.
% Copyright
% Yanbo Xue
% Adaptive Systems Laboratory
% McMaster University
% yxue@soma.mcmaster.ca
% Feb. 22, 2007
if rad < width/2,
error('The radius should be at least larger than half the width');
end
if mod(n_samp,2)~=0,
error('Please make sure the number of samples is even');
end
aa = rand(2,n_samp/2);
radius = (rad-width/2) + width*aa(1,:);
theta = pi*aa(2,:);
x = radius.*cos(theta);
y = radius.*sin(theta);
label = 1*ones(1,length(x)); % label for Class 1
x1 = radius.*cos(-theta) + rad;
y1 = radius.*sin(-theta) - d;
label1= -1*ones(1,length(x)); % label for Class 2
data = [x, x1;
y, y1;
label, label1];
[n_row, n_col] = size(data);
shuffle_seq = randperm(n_col);
for i = (1:n_col),
data_shuffled(:,i) = data(:,shuffle_seq(i));
end;
C/C++程序
// moon_generator.cpp : Defines the entry point for the console application.
//
int half_moon_samples(int rad,int width,int distance,int num_samp)
{
int i,j;
double **aa=new double*[2];
double **data=new double*[3];
double *radius=new double[num_samp/2];
double *theta=new double[num_samp/2];
double *x1=new double[num_samp/2];
double *y1=new double[num_samp/2];
double *label1=new double[num_samp/2];
double *x2=new double[num_samp/2];
double *y2=new double[num_samp/2];
double *label2=new double[num_samp/2];
srand(time(0)); //置随机数种子。
if (rad<width/2)
{
cout<<"Error! The radius should be at least larger than half the width."<<endl;
return -1;
}
if (num_samp % 2!=0)
{
cout<<"Please make sure the number of samples is even."<<endl;
return -1;
}
for(i=0;i<2;i++)
{
aa[i]=new double[num_samp/2];
}
for (i=0;i<3;i++)
{
data[i]=new double[num_samp];
}
for (i=0;i<2;i++)
{
for (j=0;j<num_samp/2;j++)
{
aa[i][j]=rand()%100*0.01; //取得整数1到x之间的随机数。
if (i==0)
{
radius[j]=(rad-width/2)+width*aa[i][j];
}
else
{
theta[j]=3.14*aa[i][j];
x1[j]=radius[j]*cos(theta[j]);
y1[j]=radius[j]*sin(theta[j]);
label1[j]=1;
x2[j]=radius[j]*cos(-theta[j])+rad;
y2[j]=radius[j]*sin(-theta[j])-distance;
label2[j]=-1;
}
}
}
for (i=0;i<num_samp;i++)
{
if (i<num_samp/2)
{
data[0][i]=x1[i];
data[1][i]=y1[i];
data[2][i]=label1[i];
}
else
{
data[0][i]=x2[i-num_samp/2];
data[1][i]=y2[i-num_samp/2];
data[2][i]=label2[i-num_samp/2];
}
}
/*****************随机洗牌(K次两两交换),对data中的数据进行重新分配*******************/
double temp[3];
int K=6000;
int p1,p2;
for (i=0;i<K;i++)
{
p1=rand()%(num_samp-1);
p2=rand()%(num_samp-1);
temp[0]=data[0][p1];
temp[1]=data[1][p1];
temp[2]=data[2][p1];
data[0][p1]=data[0][p2];
data[1][p1]=data[1][p2];
data[2][p1]=data[2][p2];
data[0][p2]=temp[0];
data[1][p2]=temp[1];
data[2][p2]=temp[2];
}
/*****************将数据输出到文本*******************/
ofstream fout;
fout.open("data.txt");
for (i=0;i<num_samp;i++)
{
fout<<data[2][i]<<" "<<data[0][i]<<" "<<data[1][i]<<endl;
}
fout.close();
return 0;
}
结果
将生成的data.txt用matlab程序plot出的结果为:
其中,半径=10,宽度=6,距离=1,总样本数=3000。
代码下载
http://download.csdn.net/detail/tyj88tcai/6834253