统计学习方法 --- 感知机模型原理及c++实现
2014-12-25 21:34
465 查看
参考博客 Liam Q博客 和李航的《统计学习方法》
感知机学习旨在求出将训练数据集进行线性划分的分类超平面,为此,导入了基于误分类的损失函数,然后利用梯度下降法对损失函数进行极小化,从而求出感知机模型。感知机模型是神经网络和支持向量机的基础。下面分别从感知机学习的模型、策略和算法三个方面来介绍。
f(x)= sign(w*x+b)
其中,x为输入向量,sign为符号函数,括号里面大于等于0,则其值为1,括号里面小于0,则其值为-1。w为权值向量,b为偏置。求感知机模型即求模型参数w和b。感知机预测,即通过学习得到的感知机模型,对于新的输入实例给出其对应的输出类别1或者-1。
这里选择的损失函数是误分类点到分类超平面S的总距离。输入空间中任一点x0到超平面S的距离为:
感知机学习算法的对偶形式
感知机学习旨在求出将训练数据集进行线性划分的分类超平面,为此,导入了基于误分类的损失函数,然后利用梯度下降法对损失函数进行极小化,从而求出感知机模型。感知机模型是神经网络和支持向量机的基础。下面分别从感知机学习的模型、策略和算法三个方面来介绍。
1. 感知机模型
感知机模型如下:f(x)= sign(w*x+b)
其中,x为输入向量,sign为符号函数,括号里面大于等于0,则其值为1,括号里面小于0,则其值为-1。w为权值向量,b为偏置。求感知机模型即求模型参数w和b。感知机预测,即通过学习得到的感知机模型,对于新的输入实例给出其对应的输出类别1或者-1。
2. 感知机策略
假设训练数据集是线性可分的,感知机学习的目标就是求得一个能够将训练数据集中正负实例完全分开的分类超平面,为了找到分类超平面,即确定感知机模型中的参数w和b,需要定义一个损失函数并通过将损失函数最小化来求w和b。这里选择的损失函数是误分类点到分类超平面S的总距离。输入空间中任一点x0到超平面S的距离为:
#include <iostream> #include <vector> #include <algorithm> #define random(x) (rand()%(x)) //向量的点积 double dot_product(std::vector<double>& a, std::vector<double>& b){ if(a.size() != b.size()) return 0; double res = 0; for(int i = 0 ; i < a.size(); ++ i){ res +=a[i]*b[i]; } return res; } //感知机模型类 class Preception{ public: Preception(int iters = 100,int learnRate = 1,double initw = 0, double initb = 0){ iterators = iters; a.push_back(initw); b = initb; step = learnRate; } ~Preception(){ a.clear(); b = 0; } //训练数据 //如果迭代次数完,还没有找到a和b, 则认为数据集不是线性可分的,返回false //如果找到了a和b,则认为数据集是线性可分的,返回true bool train(std::vector<std::vector<double> >& train_x,std::vector<int>& train_y){ if(train_x.size() != train_y.size()) return false; initWeight(train_x.size()); std::vector<std::vector<double> > gram = productGram(train_x); for(int i = 0 ; i < a.size(); ++ i){ int iter = 0; while(iter < iterators){ double sum = b; for(int j = 0; j < a.size(); ++ j){ sum += a[j]*train_y[j]*gram[j][i]; } sum *= train_y[i]; if(sum <= 0) update(i,train_y[i]); else break; ++iter; } if(iter >= iterators) return false; } return true; } //批量预测数据 std::vector<int> predict(std::vector<std::vector<double> >& data_x){ std::vector<int> ret; for(int i = 0 ; i < data_x.size(); ++ i){ ret.push_back(predict(data_x[i])); } return ret; } //预测x int predict(std::vector<double>& x){ return dot_product(x,a)+ b > 0 ? 1 : -1; } //打印感知机模型 void printPreceptronModel(){ std::cout<<"原始形式感知机模型:f(x)=sign("; for(int i = 0 ; i < a.size(); ++ i){ if( i ) std::cout<<"+"; if(a[i]!=1) std::cout<<a[i]; std::cout<<"x"<<i+1; } if(b > 0) std::cout<<"+"; std::cout<<b<<")"<<std::endl; } private: //初始化向量a的维数 void initWeight(int size){ for(int i = 1; i < size; ++ i){ a.push_back(a[0]); } } //生成Gram矩阵 std::vector<std::vector<double> > productGram(std::vector<std::vector<double> >& train_x){ int n = train_x.size(); std::vector<std::vector<double> > gram(n, std::vector<double>(n,0)); for(int i = 0 ; i < n ; ++ i){ for(int j = 0 ; j < n; ++ j){ gram[i][j] = dot_product(train_x[i], train_x[j]); } } return gram; } //更新w和b void update(int index, double y){ a[index] +=1; b += step*y; } private: int iterators; //迭代次数 std::vector<double> a; //注意w是向量 double b; double step; //学习速率 }; int main(){ std::vector<std::vector<double> >test_x(3); test_x[0].push_back(3);test_x[0].push_back(3); test_x[1].push_back(4);test_x[1].push_back(3); test_x[2].push_back(1);test_x[2].push_back(1); std::vector<int> test_y(3); test_y[0] = 1; test_y[1] = 1; test_y[2] = -1; Preception *model = new Preception(); model->train(test_x,test_y); model->printPreceptronModel(); }
感知机学习算法的对偶形式
相关文章推荐
- 统计学习方法 --- 感知机模型原理及c++实现
- [笔记-统计学习方法]感知机模型(perceptron) 原理与实现
- C++对象模型之虚函数实现原理
- 全变分(TV)模型原理与C++实现
- 统计学习方法笔记1——感知机(perceptron)的Python实现
- 统计学习方法第二章例题2.2代码实践,感知机的对偶形式的代码实现
- C++ 多态的实现原理与内存模型
- 统计学习方法——感知机模型
- 统计学习方法 2-感知机模型
- 统计学习方法笔记二-----感知机算法(PLA)代码实现
- 《统计学习方法,李航》:2、感知机模型
- 统计学习方法笔记(2)——感知机模型
- C++对象模型之RTTI的实现原理
- 统计学习方法---感知机算法实现代码
- 感知机 python 代码实现 ----- 统计学习方法
- 使用C++实现一套简单的状态机模型——原理解析
- 统计学习方法--感知机模型 (perception)
- 深度学习基础模型算法原理及编程实现--01.感知机
- 【统计学习方法】-感知机模型推导
- [置顶] 【统计学习方法】 感知机Python 原始形式实现