感知器算法+C代码
2015-07-29 21:50
309 查看
感知算法的训练过程就是对判断好的样本集求解权矢量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;
}
具体算法如下:
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;
}
相关文章推荐
- 指针和引用的区别(More Effective c++ )
- MATLAB view函数详解
- java编程思想恶心的enum状态机示例
- php设计模式入门-单例模式
- python处理网页时的unicode编码问题
- 一些C/C++开源项目网址
- 编程算法 - 切割排序 代码(C)
- Scala 深入浅出实战经典 第44讲: scala中view bounds代码实例
- C语言字符串截取函数strtok和strtok_r
- C++的引用类型的变量到底占不占用内存空间?
- C++的引用类型的变量到底占不占用内存空间?
- 初识JAVA
- LeetCode-Reverse Linked List
- PCI/PCIe接口卡Windows驱动程序(4)- 驱动程序代码(源文件)
- 利用QT中Qpainter画点,直线,弧线等简单图形
- C#中的WebBrowser控件的使用
- 《learning python the hard way》习题46 项目骨架搭建 问题小结(一)之软件包的安装
- Java多线程编程总结(学习博客)
- Action中如何通过@Autowired自动注入spring bean ?
- java ee中使用dbcp