下面直接上代码,此处我用的是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); } }
热门评论
看来还是慕课人数多啊,我在CSDN上这篇文章原创也才几百流量?