继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

感知机对偶形式C++实现

森栏
关注TA
已关注
手记 344
粉丝 101
获赞 475

1
2
3
4
下面直接上代码,此处我用的是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内容如下:
5
运行结果如下:
6
以上核心代码其实只有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);
        }
}

原文出处

打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP

热门评论

看来还是慕课人数多啊,我在CSDN上这篇文章原创也才几百流量?

查看全部评论