感知算法的训练过程就是对判断好的样本集求解权矢量W,这实际是一个线性联立不等式的求解问题。
具体算法如下:
1. 初始权矢量 W = 0;
2. 第k次输入一个样本X(K), 计算第k次迭代的过为:
d[X(k)] = W'[k] * X(k),
3. 根据欲划分类和d值进行权值修正:
当d<=0时: W[k+1] = W[k] + X[k];
当d>0时: W[k+1] = W[k] - X[k];
4. 循环执行第二步,直到输入所有样本后,权重都不需要修改为止。
本代码的测试用例为,胃病和非胃病测试样例(1为胃病,-1为非胃病)
228 134 20 11 1 1
245 134 10 40 1 1
200 167 12 27 1 1
170 150 7 8 1 1
100 167 20 14 1 1
150 117 7 6 1 -1
165 142 5 3 1 -1
185 108 2 12 1 -1
120 133 10 26 1 -1
160 100 5 10 1 -1
185 115 5 19 1 -1
170 125 6 4 1 -1
待测样品为:
225 125 7 14 1 0
100 117 7 2 1 0
130 100 6 12 1 0
c代码如下:(训练会需要一些时间)
#include "stdio.h"
#include "stdlib.h"
#include "math.h"
#include "vector"
using namespace std;
typedef vector<double> doubleVector;
#define alpha 0.2
#define dimNum 6 //样本的维数
vector<doubleVector> getSample(char *File); //获取样本
double matMul(doubleVector Mat1, doubleVector Mat2); //矩阵相乘
doubleVector matAdd(doubleVector Mat1, doubleVector Mat2); //矩阵相加
void Perceptron(vector<doubleVector> sample); //感知算法开始引擎
doubleVector matSub(doubleVector Mat1, doubleVector Mat2); //矩阵相减
void main()
{
char *File = "胃病.txt";
vector<doubleVector> sample;
sample = getSample(File);
Perceptron(sample);
}
//感知算法开始引擎
void Perceptron(vector<doubleVector> sample)
{
doubleVector W(dimNum-1, 0); //权重
double mulResult;
int i;
bool flag = false;
while(!flag) //输入所有样本后权重都不改变
{
flag = true;
for(i=0; i<sample.size(); i++)
{
mulResult = matMul(W, sample[i]); //计算权值
if(sample[i][dimNum-1]==1)
{
if(mulResult<=0)
{
W = matAdd(W, sample[i]);
flag = false;
}
}
else
{
if(mulResult>0)
{
W = matSub(W, sample[i]);
flag = false;
}
}
}
}
vector<doubleVector> test;
char *File = "待判样品.txt";
test = getSample(File);
for(i=0; i<test.size(); i++)
{
mulResult = matMul(W, test[i]);
if(mulResult>0)
printf("胃病\n");
else
printf("非胃病\n");
}
}
//获取样本
vector<doubleVector> getSample(char *File)
{
int i=1;
vector<doubleVector> dst;
doubleVector temp;
FILE *fp = fopen(File, "r");
if(fp == NULL)
{
printf("Open file error!!!\n");
return dst;
}
double num;
while(fscanf(fp, "%lf", &num)!=EOF)
{
temp.push_back(num);
if(i%dimNum==0)
{
dst.push_back(temp);
temp.clear();
}
i++;
}
return dst;
}
//矩阵相乘
double matMul(doubleVector Mat1, doubleVector Mat2)
{
int i;
double sum=0;
for(i=0; i<dimNum-1; i++)
sum += Mat1[i]*Mat2[i];
return sum;
}
//矩阵相加
doubleVector matAdd(doubleVector Mat1, doubleVector Mat2)
{
int i;
doubleVector dstMat;
for(i=0; i<dimNum-1; i++)
dstMat.push_back(Mat1[i]+Mat2[i]*alpha);
return dstMat;
}
//矩阵相减
doubleVector matSub(doubleVector Mat1, doubleVector Mat2)
{
int i;
doubleVector dstMat;
for(i=0; i<dimNum-1; i++)
dstMat.push_back(Mat1[i]-Mat2[i]*alpha);
return dstMat;
}