下面直接上代码,此处我用的是C++代码用STL中的向量实现存储,当然也可以用数组或者其他方式,感知机的对偶形式代码如下:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <vector>
using namespace std;
void input_init();
void train();
bool judge(int i);
void output();
void gram();
void output_Gram();
void fun_output();
///****α、b、步长和训练集和Gram矩阵********
vector<int> Gram[1000];
vector<int> data[1000];
vector<int> a;
vector<int> w;
int b=0;
int len=1; ///步长
///****α、b、步长和训练集和Gram矩阵********
int n; //特征向量的维数
int N; //输入实例的个数
int k=0; //迭代次数
int main()
{
freopen("in.txt","r",stdin);
input_init();
train();
fun_output();
system("pause");
return 0;
}
void input_init(){
cout<<"请输入特征向量的维数:"<<endl;
cin>>n;
cout<<"请输入实例的个数:"<<endl;
cin>>N;
int tmp;
for(int i=0;i<N;i++){
cout<<"请输入第"<<i+1<<"个实例:"<<endl;
for(int j=0;j<=n;j++){
cin>>tmp;
data[i].push_back(tmp);
}
a.push_back(0); ///α表示第i个训练数据被误分类的次数
}
gram();
output_Gram();
cout<<endl<<"k\t"<<"data\t";
for(int i=0;i<N;i++)
cout<<"a"<<i+1<<"\t";
cout<<"b"<<endl;
cout<<"0"<<"\t \t"<<"0\t"<<"0\t"<<"0\t"<<endl;
}
void train(){
for(int i=0;i<N;i++)
if(!judge(i)){ //判断是否误分类
a[i] += len; //a<-a+n 此时步长len=1
b += len*data[i][n]; //b<-b+n*yi
cout<<++k<<"\t"<<" x"<<i+1<<"\t";
output();
i = -1; ///切记是-1不是0
}
}
bool judge(int i){
int sum = 0;
for(int j=0;j<N;j++) //原始形式中是for(int j=0;j<n;j++)
if(a[j]==0) continue;
else sum += a[j]*data[j][n]*Gram[j][i]; //sum = ∑aj*yj*xj*xi
return (data[i][n]*(sum+b)>0)? true:false; //yi(w.xi+b)<=0
}
void gram(){
for(int i=0;i<N;i++)
for(int j=0;j<N;j++){
int sum = 0;
for(int k=0;k<n;k++) //n表示特征空间维数
sum += data[i][k]*data[j][k];
Gram[i].push_back(sum);
}
}
void output_Gram(){
cout<<endl<<"Gram matrix如下:"<<endl;
for(int i=0;i<N;i++){
for(int j=0;j<N;j++){
cout<<Gram[i][j]<<"\t";
}
cout<<endl;
}
}
void output(){
for(int i=0;i<N;i++)
cout<<a[i]<<"\t";
cout<<b<<endl;
}
void fun_output(){
cout<<endl<<"感知机对偶形式模型:";
for(int i=0;i<n;i++){
w.push_back(0);
for(int j=0;j<N;j++)
w[i] += a[j]*data[j][n]*data[j][i]; //w = ∑aj*yj*xj
}
for(int i=0;i<n;i++){
if(w[i]>0){
if(i!=0) cout<<"+";
}
else if(w[i]<0)
cout<<"-";
else continue;
if(fabs(w[i])!=1.0)
cout<<abs(w[i]);
cout<<"x"<<i+1;
}
if(b!=0){
if(b>=0)
cout<<"+";
cout<<b;
}
cout<<endl<<endl;
}此处我输入的文件in.txt内容如下:
运行结果如下:
以上核心代码其实只有judge()、train()和gram(),去掉冗余输入输出后如下:
bool judge(int i){
int sum = 0;
for(int j=0;j<N;j++) //原始形式中是for(int j=0;j<n;j++)
if(a[j]==0) continue;
else sum += a[j]*data[j][n]*Gram[j][i]; //sum = ∑aj*yj*xj*xi
return (data[i][n]*(sum+b)>0)? true:false; //yi(w.xi+b)<=0
}void train(){
for(int i=0;i<N;i++)
if(!judge(i)){ //判断是否误分类
a[i] += len; //a<-a+n 此时步长len=1
b += len*data[i][n]; //b<-b+n*yi
i = -1; ///切记是-1不是0
}
}void gram(){
for(int i=0;i<N;i++)
for(int j=0;j<N;j++){
int sum = 0;
for(int k=0;k<n;k++) //n表示特征空间维数
sum += data[i][k]*data[j][k];
Gram[i].push_back(sum);
}
}
随时随地看视频
热门评论
-
TECHNOLOGY_net2020-03-31 0
查看全部评论看来还是慕课人数多啊,我在CSDN上这篇文章原创也才几百流量?