感知机模型
感知机是一个二类分类的线性分类模型。所谓二类分类就是它只能将实例分为正类和负类两个类别。那么为什么是线性分类模型呢,我的理解是感知机学习旨在求出可以将数据进行划分的分离超平面,而分离超平面的方程
![感知机模型](https://i-blog.csdnimg.cn/blog_migrate/e4cb0b0439c6def3bbc66cdc5faa4cda.png)
圈圈表示正类,而叉叉表示负类。圈圈与叉叉之间的直线即上文所说的分离超平面(注意分离超平面并不是唯一的!)它将所有的样本划分为两部分。位于分离超平面上方的为正类,记为+1,位于分离超平面下方的为负类,记为-1。也就是说,假设给一个样本的特征向量x,如果w⋅x+b>0w⋅x+b>0, 那么样本为正类(+1),反之若w⋅x+b<0w⋅x+b<0, 样本则属于负类(-1)。我们 引入符号函数sign(x),即
感知机学习策略
给定一个线性可分的数据集
为了确定感知机模型的参数 ww 和 bb ,需要确定一个学习策略,即定义一个损失函数并将损失函数极小化。感知机采用的损失函数为误分类点到超平面的总距离。首先写出输入空间 RnRn 中任一点 x0x0 到分离超平面的距离
其次对于误分类的数据 (xi,yi)(xi,yi) 来说,
感知机学习的策略是在假设空间中选取使损失函数最小的模型参数 w,bw,b 。
感知机学习算法
感知机学习算法是误分类驱动的,具体采用随机梯度下降法。首先,任意选取一个超平面w0,b0w0,b0,然后用梯度下降法不断地极小化损失函数。极小化过程中不是一次使M中所有误分类点的梯度下降,而是一次随机选取一个误分类点使其梯度下降。损失函数L(w,b)L(w,b)的梯度为
综上所述,得到如下算法(感知机学习算法的原始形式)
输入:训练集T={(x1,y1),(x2,y2),...(xN,yN)}T={(x1,y1),(x2,y2),...(xN,yN)},其中xi∈X=Rnxi∈X=Rn,yi∈Y={+1,−1}yi∈Y={+1,−1},i=1,2,3,...Ni=1,2,3,...N;学习率η(0<η≤1)η(0<η≤1);
输出:w,bw,b;感知机模型f(x)=sign(w⋅x+b)f(x)=sign(w⋅x+b)
(1)选取初值w0,b0w0,b0
(2)在训练集中选取数据(xi,yi)(xi,yi)
(3)如果yi(w⋅xi+b)≤0yi(w⋅xi+b)≤0
例子:如图所示,正实例点是x1=(3,3)T,x2=(4,3)Tx1=(3,3)T,x2=(4,3)T,负实例点是x3=(1,1)Tx3=(1,1)T,使用感知机算法求解感知机模型f(x)=sign(w⋅x+b)f(x)=sign(w⋅x+b)
代码如下
#include "stdafx.h"
#include <iostream>
using namespace std;
const double lr = 1;
const int dim = 2;
const int n = 3;
double w[dim] = {0, 0};
double b = 0;
double samples[n][dim] = {3,3, 4,3, 1,1};
int labels[n] = {1, 1, -1};
//计算两个向量的内积
double dot(double *w, double *feature)
{
double sum = 0;
for(int i = 0; i < dim; i++)
{
sum += (*w) * (*feature);
w++;
feature++;
}
return sum;
}
//感知机算法
void perceptron()
{
while(true)
{
int i;
for(i = 0; i < n; i++)
{
if(labels[i] * (dot(w, samples[i]) + b) <= 0)
{
cout << "w:(";
for(int j = 0; j < dim; j++)
{
w[j] = w[j] + lr*labels[i]*samples[i][j];
cout << w[j];
if( j != dim-1)
cout<<",";
}
b = b + lr*labels[i];
cout << ") b:"<<b << endl;
break;
}
}
if(i == n)
break;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
perceptron();
system("pause");
return 0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
运行结果如下
下面来介绍感知机算法的对偶形式
对偶形式的基本思想是,将ww和bb表示为实例xixi和yiyi的线性组合的形式,通过求解其系数而求得ww和bb。我们假设初始值w0w0和b0b0均为0,在原始形式中,对误分类点(xi,yi)(xi,yi)通过
综上所述,我们可以得到感知机学习算法的对偶形式
输入:训练集T={(x1,y1),(x2,y2),...(xN,yN)}T={(x1,y1),(x2,y2),...(xN,yN)},其中xi∈X=Rnxi∈X=Rn,yi∈Y={+1,−1}yi∈Y={+1,−1},i=1,2,3,...Ni=1,2,3,...N;学习率η(0<η≤1)η(0<η≤1);
输出:α,bα,b;感知机模型f(x)=sign(∑Nj=1αjyjxj⋅x+b)f(x)=sign(∑j=1Nαjyjxj⋅x+b),其中α=(α1,α2,.....αN)α=(α1,α2,.....αN)。
(1)α←0,b←0α←0,b←0
(2)在训练集中选取数据(xi,yi)(xi,yi)
(3)如果yi(∑Nj=1αjyjxj⋅x+b)≤0yi(∑j=1Nαjyjxj⋅x+b)≤0
我们依然使用上文给出的例子,利用感知机算法的对偶形式来求解,代码如下
#include "stdafx.h"
#include <iostream>
using namespace std;
// 学习率
const double lr = 1;
//特征维度
const int dim = 2;
//样本个数
const int n = 3;
//样本
double samples[n][dim] = {3,3, 4,3, 1,1};
//样本标记
int labels[n] = {1, 1, -1};
//Gram矩阵
double g[n][n];
double a[n] = {0};
double b = 0;
//计算两个向量的内积
double dot(double *w, double *feature)
{
double sum = 0;
for(int i = 0; i < dim; i++)
{
sum += (*w) * (*feature);
w++;
feature++;
}
return sum;
}
//求解Gram矩阵
void getGram()
{
for(int i = 0; i < n; i++)
{
for(int j = 0; j < n; j++)
{
g[i][j] = dot(samples[i],samples[j]);
}
}
}
double dot_antithesis(int subs)
{
double sum = 0;
for(int i = 0; i < n; i++)
{
sum += a[i]*labels[i]*g[i][subs];
}
return sum;
}
//感知机算法的对偶形式
void pereption_antithesis()
{
getGram();
while(true)
{
int i;
for(i = 0; i < n; i++)
{
if(labels[i] * (dot_antithesis(i) + b) <= 0)
{
a[i] += lr;
b = b + lr*labels[i];
cout << "a: ";
for(int j = 0; j < n; j++)
cout << a[j] << " ";
cout << "b: " << b << endl;
break;
}
}
if(i == n)
break;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
pereption_antithesis();
system("pause");
return 0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
程序运行结果如下