搞数据挖掘编的神经网络,用于分类预测。 #include <iostream> #include <fstream> #include <string> #include <cstring> #include <stack> #include <math.h> #include <vector> using namespace std; const double l=0.1;//学习率 const int trainItemNumber=20000;//训练对的数目 typedef double** iMatrixPointer; int HIDDENLAYERNUMBER; int* HIDDENLAYERNUMBERARR; int* inputLayer; //输入层 iMatrixPointer* weightArray; struct hiddenNode { double bias; double outputval; double err; }; hiddenNode** hiddenLayer; //隐藏层 hiddenNode* outputLayer; //输出层 struct item { int* inputArray; int category; }; vector<item> ncItems; vector<item> changeItems; vector<item> controlItems; //通过用户输入获取参数 void processInput() { //获取隐含层层数 cout<<"请输入隐藏层层数:"; cin>>HIDDENLAYERNUMBER; cout<<endl; weightArray = new iMatrixPointer[HIDDENLAYERNUMBER+1]; //获取每层的结点数 HIDDENLAYERNUMBERARR = new int[HIDDENLAYERNUMBER]; for(int i=1;i<=HIDDENLAYERNUMBER;i++) { cout<<"输入第"<<i<<"层的结点个数:"; cin>>HIDDENLAYERNUMBERARR[i-1]; cout<<endl; } } void InitializeMatrix() { int layerIndex; for(layerIndex=0;layerIndex<=HIDDENLAYERNUMBER;layerIndex++) { int currNumber,nextNumber; if(layerIndex==0) currNumber=14; else currNumber=HIDDENLAYERNUMBERARR[layerIndex-1]; if(layerIndex==HIDDENLAYERNUMBER) nextNumber=2; else nextNumber=HIDDENLAYERNUMBERARR[layerIndex]; iMatrixPointer matrix; //构造数组 matrix = new double*[currNumber]; for(int i=0;i<currNumber;i++) { matrix[i]=new double[nextNumber]; } //初始化 for(int i=0;i<currNumber;i++) for(int j=0;j<nextNumber;j++) matrix[i][j]=0.5; //给一个定值_____0.5_______ weightArray[layerIndex]=matrix; } } //初始化隐藏层 void InitializeHiddenLayer() { hiddenLayer = new hiddenNode*[HIDDENLAYERNUMBER]; for(int hLayerIndex=0;hLayerIndex<HIDDENLAYERNUMBER;hLayerIndex++) { int iLayerNodeNum = HIDDENLAYERNUMBERARR[hLayerIndex]; hiddenNode* nodeArray = new hiddenNode[iLayerNodeNum]; for(int hNodeIndex=0;hNodeIndex<iLayerNodeNum;hNodeIndex++) { nodeArray[hNodeIndex].bias = 0.5; //给一个定值_____0.5_______ nodeArray[hNodeIndex].outputval = 0; nodeArray[hNodeIndex].err=0; } hiddenLayer[hLayerIndex]=nodeArray; } } //初始化神经网络 void InitializeModel() { InitializeMatrix(); //初始化输入层 inputLayer = new int[14]; for(int i=0;i<14;i++) inputLayer[i]=0; //初始化隐藏层 InitializeHiddenLayer(); //初始化输出层 outputLayer = new hiddenNode[2]; outputLayer[0].bias=0.5; //给一个定值_____0.5_______ outputLayer[0].outputval=0; outputLayer[0].err=0; outputLayer[1].bias=0.5; //给一个定值_____0.5_______ outputLayer[1].outputval=0; outputLayer[1].err=0; } void forwardInput(int inputArray[]) { //处理输入层 for(int i=0;i<14;i++) { inputLayer[i]=inputArray[i]; } //处理隐藏层 for(int mi=0;mi<HIDDENLAYERNUMBER;mi++) { int currNum=HIDDENLAYERNUMBERARR[mi];//当前层结点个数 if(mi==0) { //第一层隐藏层 for(int nindex=0;nindex<currNum;nindex++) { //对于第一隐藏层每个结点进行计算 iMatrixPointer inputMatrix=weightArray[0];//输入--第一隐藏层权重数组 double sum=0; for(int findex=0;findex<14;findex++) { //取输入层结点累加 sum+=(double)inputLayer[findex]*inputMatrix[findex][nindex]; } hiddenLayer[0][nindex].outputval=sum;//记录输出值 } } else { iMatrixPointer prev_currMatrix=weightArray[mi]; int prevNodeNum=HIDDENLAYERNUMBERARR[mi-1]; for(int curindex=0;curindex<currNum;curindex++) { //对于当前每个结点进行计算 double sum=0; for(int previndex=0;previndex<prevNodeNum;previndex++) { double prevNWeight=prev_currMatrix[previndex][curindex]; double prevNOutput=hiddenLayer[mi-1][previndex].outputval; sum+=prevNWeight*prevNOutput; } //加上当前结点的偏倚值 sum+=hiddenLayer[mi][curindex].bias; //激励函数 double output=1/(1+exp(-sum)); //保存输出 hiddenLayer[mi][curindex].outputval=output; } }//else }//for //处理输出层 int lastHiddenNumber=HIDDENLAYERNUMBERARR[HIDDENLAYERNUMBER-1]; iMatrixPointer prev_currMatrix=weightArray[HIDDENLAYERNUMBER]; for(int curindex=0;curindex<2;curindex++) { double sum=0; for(int previndex=0;previndex<lastHiddenNumber;previndex++) { double prevNWeight=prev_currMatrix[previndex][curindex]; double prevNOutput=hiddenLayer[HIDDENLAYERNUMBER-1][previndex].outputval; sum+=prevNWeight*prevNOutput; } sum+=outputLayer[curindex].bias; double output=1/(1+exp(-sum)); outputLayer[curindex].outputval=output; } } void trainOneItem(int inputArray[],int category) { //向前传播输入 forwardInput(inputArray); //后向传播误差 double err; //输出层 double bit[2]; switch(category) { case 2: bit[0]=1; bit[1]=0; break; case 1: bit[0]=0; bit[1]=1; break; case 0: bit[0]=0; bit[1]=0; break; } for(int oindex=0;oindex<2;oindex++) { double output=outputLayer[oindex].outputval; double cbit=bit[oindex]; err=output*(1-output)*(cbit-output); outputLayer[oindex].err=err; } //计算隐藏层误差 for(int hindex=HIDDENLAYERNUMBER-1;hindex>=0;hindex--) { int nodeNumber=HIDDENLAYERNUMBERARR[hindex]; for(int nindex=0;nindex<nodeNumber;nindex++) { double curNodeOut=hiddenLayer[hindex][nindex].outputval;//取当前结点的输出 double errsum=0;//后节点的误差权重积的和 if(hindex==HIDDENLAYERNUMBER-1)//最后一层隐藏层 { //取输出层信息 for(int oindex=0;oindex<2;oindex++) { double oerr=outputLayer[oindex].err; iMatrixPointer omatrix=weightArray[HIDDENLAYERNUMBER]; double oweight=omatrix[nindex][oindex]; errsum+=oerr*oweight; } } else { //取下一层信息 iMatrixPointer cur_nextMatrix=weightArray[hindex+1]; int nextLayerNodeNum=HIDDENLAYERNUMBERARR[hindex+1]; for(int nextindex=0;nextindex<nextLayerNodeNum;nextindex++) { double nerr=hiddenLayer[hindex+1][nextindex].err; double nweight=cur_nextMatrix[nindex][nextindex]; errsum+=nerr*nweight; } } double curerr=curNodeOut*(1-curNodeOut)*errsum; hiddenLayer[hindex][nindex].err=curerr; }//for }//for //更新权重 for(int lindex=HIDDENLAYERNUMBER;lindex>=0;lindex--) { iMatrixPointer matrix=weightArray[lindex]; int curNum,nextNum; if(lindex==HIDDENLAYERNUMBER)//隐藏层最后一层 { nextNum=2; curNum=HIDDENLAYERNUMBERARR[HIDDENLAYERNUMBER-1]; for(int ci=0;ci<curNum;ci++) { for(int ni=0;ni<nextNum;ni++) { double nerr=outputLayer[ni].err; double coutput=hiddenLayer[HIDDENLAYERNUMBER-1][ci].outputval; double deltaw=l*nerr*coutput; matrix[ci][ni]+=deltaw; } } } else if(lindex==0)//输入层 { curNum=14; nextNum=HIDDENLAYERNUMBERARR[0]; for(int ci=0;ci<curNum;ci++) { for(int ni=0;ni<nextNum;ni++) { double nerr=hiddenLayer[0][ni].err; double coutput=inputLayer[ci]; double deltaw=l*nerr*coutput; matrix[ci][ni]+=deltaw; } } } else { curNum=HIDDENLAYERNUMBERARR[lindex-1]; nextNum=HIDDENLAYERNUMBERARR[lindex]; for(int ci=0;ci<curNum;ci++) { for(int ni=0;ni<nextNum;ni++) { double nerr=hiddenLayer[lindex][ni].err; double coutput=hiddenLayer[lindex-1][ci].outputval; double deltaw=l*nerr*coutput; matrix[ci][ni]+=deltaw; } } } } //更新偏倚 for(int lindex=HIDDENLAYERNUMBER+1;lindex>=1;lindex--) { if(lindex==HIDDENLAYERNUMBER+1)//输出层 { for(int i=0;i<2;i++) { double delta=l*outputLayer[i].err; outputLayer[i].bias+=delta; } } else { int number=HIDDENLAYERNUMBERARR[lindex-1]; for(int i=0;i<number;i++) { double delta=l*hiddenLayer[lindex-1][i].err; hiddenLayer[lindex-1][i].bias+=delta; } } } } void training() { //读文件 ifstream fin("TrainForm.txt"); if(!fin.is_open()) { cerr<<"打开文件错误"<<endl; exit(0); } char buf[80]; fin.getline(buf,80); char* token="/t"; while(fin.getline(buf,80)) { int index=0; int lineInput[14]; int lineIndex=0; char* result = strtok(buf,token); int category; while(result!=NULL) { index++; if(index==5) { if(strcmp(result,"nc")==0) category=0; else if(strcmp(result,"control")==0) category=1; else if(strcmp(result,"change")==0) category=2; } if(index!=1&&index!=5) { int num=atoi(result); //十进制转成二进制 stack<int> s; while(num!=0) { s.push(num%2); num/=2; } if(index==2||index==4) { if(s.size()!=5) { int vac=5-s.size(); for(int i=0;i<vac;i++) s.push(0); } } else if(index==3) { if(s.size()!=4) { int vac=4-s.size(); for(int i=0;i<vac;i++) s.push(0); } } while(!s.empty()) { lineInput[lineIndex]=s.top(); s.pop(); lineIndex++; } } result=strtok(NULL,token); }//while item i; i.inputArray=new int[14]; i.inputArray=lineInput; i.category=category; if(category==0) ncItems.push_back(i); else if(category==1) controlItems.push_back(i); else if(category==2) changeItems.push_back(i); //trainOneItem(lineInput,category); fin.getline(buf,80); }//while for(int i=0;i<trainItemNumber;i++) { //从nc,control,change中各取一条进行训练 int ncNumber,changeNumber,controlNumber,ncIndex,changeIndex,controlIndex; ncNumber=ncItems.size(); changeNumber=changeItems.size(); controlNumber=controlItems.size(); ncIndex=rand()%ncNumber; changeIndex=rand()%changeNumber; controlIndex=rand()%controlNumber; item ncit=ncItems.at(ncIndex); item controlit=controlItems.at(controlIndex); item changeit =changeItems.at(changeIndex); trainOneItem(ncit.inputArray,ncit.category); trainOneItem(changeit.inputArray,changeit.category); trainOneItem(controlit.inputArray,controlit.category); } } void forecastOneItem(int inputArr[]) { forwardInput(inputArr); cout<<outputLayer[0].outputval<<":"<<outputLayer[1].outputval<<endl; } int main() { processInput(); InitializeModel(); training(); int arr1[]={00101010000100};//change forecastOneItem(arr1); int arr2[]={00101100100011};//nc forecastOneItem(arr2); int arr3[]={00001100100011};//control forecastOneItem(arr3); return 0; }