感知机的算法我就不多说了,不是几句话能够解释的清楚,这里就直接给出代码,方便下次要用的学生们直接抄。。。
注:这次作业是某校的一次小作业,任课老师叫做: TonghuaSu.如果你知道这点了。。。你就可以抄了。。。数据集某网站上面有
全部是自己写的,没有一点抄袭成分,格式啥的没太注意,希望大家见谅
#include <iostream>
#include <fstream>
#include <string>
#include <cmath>
using namespace std;
struct DATA{
double x[22];
int y;
}D[35000],D1[35000];
double center_x1[22],center_x2[22]; //中心点个数
double matrix(double w[],double x[]){
double num = 0;
for(int i=0;i<22;i++){
num+=w[i]*x[i];
}
return num;
}
void StringToDouble(string str,int count,int temp,struct DATA *D){
double number = 0;
int kk = 1; //kk用来计算位数
for(int i=2;i<str.length();i++){
number += (str[i]-'0')/(pow(10,kk));
kk++;
}
D[count].x[temp] = number;
// cout<<D[count].x[temp]<<" ";
// cout<<number<<" "; //输出信息
}
void StringToInt(string str,int count,int temp,struct DATA *D){
int number = 0;
if(str.length()==2){
D[count].y = (str[1]-'0');
}
else{
D[count].y = 0-(str[0]-'0');
}
// cout<<D[count].y<<endl;
// cout<<D[count].y<<endl;
}
void split(char *s,int count,struct DATA *D){
int temp = 0; //temp用来记录到了第几个,方便计数
string str="";
for(int i=0;i<strlen(s);i++){
if(s[i]!=','){
str+=s[i];
}
else{
// cout<<str<<" ";
StringToDouble(str,count,temp,D);
str ="";
temp++;
}
}
if(temp==22){
// cout<<str;
StringToInt(str,count,temp,D);
}
}
void StringToDouble1(string str,int count,int temp,struct DATA *D1){
double number = 0;
int kk = 1; //kk用来计算位数
for(int i=2;i<str.length();i++){
number += (str[i]-'0')/(pow(10,kk));
kk++;
}
D1[count].x[temp] = number;
// cout<<D[count].x[temp]<<" ";
// cout<<number<<" "; //输出信息
}
void StringToInt1(string str,int count,int temp,struct DATA *D1){
int number = 0;
if(str.length()==2){
D1[count].y = (str[1]-'0');
}
else{
D1[count].y = 0-(str[0]-'0');
}
// cout<<D[count].y<<endl;
// cout<<D[count].y<<endl;
}
void split1(char *s,int count,struct DATA *D1){
int temp = 0; //temp用来记录到了第几个,方便计数
string str="";
for(int i=0;i<strlen(s);i++){
if(s[i]!=','){
str+=s[i];
}
else{
// cout<<str<<" ";
StringToDouble1(str,count,temp,D1);
str ="";
temp++;
}
}
if(temp==22){
// cout<<str;
StringToInt1(str,count,temp,D1);
}
}
void FindCenter(int count){
int center_count1=0,center_count2 = 0; //计算中心点个数
for(int i =0;i<22;i++){
center_x1[i] = 0;
center_x2[i] = 0;
}
for( i=0;i<count;i++){ //
if(D[i].y==1){
center_count1++;
for(int j=0;j<22;j++){
center_x1[j] +=D[i].x[j];
}
}
else{
center_count2++;
for(int j=0;j<22;j++){
center_x2[j] +=D[i].x[j];
}
}
}
//
for(i=0;i<22;i++){
// cout<<center_x1[i]<<" "<<center_x2[i]<<endl;
center_x1[i]/=center_count1;
center_x2[i]/=center_count2;
// cout<<"1 "<<center_x1[i]<<" 2 "<<center_x2[i]<<endl;
} //到这行为止,中心值已经求证正确
}
int FindClose(double x1[],double x2[],double point[]){
double Distance1=0,Distance2=0 ;
for(int i=0;i<22;i++){
Distance1+=(point[i]-x1[i])*(point[i]-x1[i]);
Distance2+=(point[i]-x2[i])*(point[i]-x2[i]);
}
if(Distance1>Distance2){
return -1; //第二个近传回去0
}
else
return 1; //第一个近传回去1
}
int main(){
//前面的统计数据模型
char s[1000];
double w[22] ={-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
double b = -5;
double ITA = 0.99;
fstream f("d:\\1.txt",ios::in |ios::out);
if(!f){ return 0;}
int count = 0;
while(!f.eof()){
f.getline(s,1000);
// cout<<strlen(s)<<endl;
split(s,count,D);
count++;
}
f.close();
FindCenter(count);
for(int _i=0;_i<10;_i++){
for(int i=0;i<count;i++){ //这里是学习的过程,我这里学习了10次
if(D[i].y*(matrix(w,D[i].x)+b)<=0){
for(int j=0;j<22;j++){
w[j] = w[j] + ITA*D[i].y*D[i].x[j];
}
b = b +ITA*D[i].y;
}
}
}
for(int i=0;i<22;i++){
cout<<w[i]<<" ";
}
cout<<b;
cout<<endl;
//缺一个验证的过程
//缺一个中心分类的验证比较过程 先读进来,后面传参
//先读进来
fstream f1("d:\\2.txt",ios::in |ios::out);
if(!f1){ return 0;}
int count1 = 0;
while(!f1.eof()){
f1.getline(s,1000);
// cout<<strlen(s)<<endl;
split1(s,count1,D1);
count1++;
}
f1.close();
cout<<count1<<endl;
//感知器学习算法验证过程
int perceton_count = 0;
for(i=0;i<count1;i++){
if((D1[i].y*(matrix(w,D1[i].x)+b))>0){
perceton_count++;
}
}
cout<<"perceton_count: "<<perceton_count<<endl;
//中心分类器验证过程
int _TruePoint=0;
for(i=0;i<count1;i++){
if((FindClose(center_x1,center_x2,D1[i].x)*D1[i].y)>0){
_TruePoint++;
}
}
cout<<_TruePoint<<endl; //得出分类数据对的大概是9500多个
}