📄 nn.c
字号:
p->next = dummy->next;
dummy->next = p;
cl = cl->next;
};
}; /* end for class */
#ifndef UNIX
interrupt(849);
#endif
protolist = dummy->next;
}
NODE *nn(trainpoint,answer) /* finds the nearest prototype */
NODE *trainpoint;
int answer;
{
register REAL *protovec, *trainvec;
register REAL diff, sum;
register short i,j;
register REAL min;
NODE *protopoint, *place;
min = MAXVAL;
place = NULL;
protopoint = protolist;
while (protopoint != NULL)
{
if (answer == -1 || protopoint->class == answer)
{
protovec = protopoint->vector;
trainvec = trainpoint->vector;
sum = 0.0;
for (j=1;j<=length;j++) /* find difference, square and sum */
{
diff = *trainvec++ - *protovec++;
sum = sum + diff * diff;
};
if (sum < min)
{
min = sum;
place = protopoint;
};
};
protopoint = protopoint->next;
};
return(place); /* the pointer to the closest prototype */
}
/* the learning vector quantization 1 algorithm */
void lvq1(point,nearestproto,ans)
NODE *point,*nearestproto;
int ans;
{
register REAL ralpha, *trainvec, *protovec;
register short j;
ralpha = alpha;
if (nearestproto->class != ans) /* nearest neighbor is wrong */
{
trainvec = point->vector;
protovec = nearestproto->vector;
for (j=1;j<=length;j++)
{
*protovec = *protovec - ralpha * (*trainvec++ - *protovec);
protovec++;
}
}
else /* nearest neighbor is right */
{
trainvec = point->vector;
protovec = nearestproto->vector;
for (j=1;j<=length;j++)
{
*protovec = *protovec + ralpha * (*trainvec++ - *protovec);
protovec++;
};
};
}
/* decision surface mapping from March 1991 IEEE Trans on NN */
void dsm(trainpoint,nearestpoint,ans)
NODE *trainpoint, *nearestpoint;
int ans;
{
register REAL *trainvec, *protovec;
register REAL ralpha;
register short j;
NODE *correct;
ralpha = alpha;
/* wrong answers require a correction; right ones do not */
if (nearestpoint->class != ans) /* if wrong */
{ /* move nearest prototype away */
trainvec = trainpoint->vector;
protovec = nearestpoint->vector;
for (j=1;j<=length;j++)
{
*protovec = *protovec - ralpha * (*trainvec++ - *protovec);
protovec++;
};
/* find nearest prototype in the correct class */
correct = nn(trainpoint,ans);
trainvec = trainpoint->vector;
protovec = correct->vector;
/* move it closer */
for (j=1;j<=length;j++)
{
*protovec = *protovec + ralpha * (*trainvec++ - *protovec);
protovec++;
};
};
}
int nonetwork()
{
if (length == 0 || nclasses == 0)
{pg("there is no network.\n"); return(1);}
else return(0);
}
int nopatterns(list)
int list;
{
if (list == TRAIN && trainlist != NULL) return(0);
else if (list == TEST && testlist != NULL) return(0);
else {pg("there are no patterns\n"); return(1);};
}
int noprotos()
{if (protolist == NULL) return(1); else return(0);}
void evalone(list, thepat)
int list, thepat;
{
NODE *point, *nearest;
int i, answer, rtanswer;
REAL *coord;
sprintf(outstr,"%5d ",thepat);
pg(outstr);
if (list == TRAIN) point = trainlist; point = testlist;
for (i=1;i<=(thepat-1);i++) point = point->next;
nearest = nn(point,-1);
coord = point->vector;
for (i=1;i<=length;i++)
{
sprintf(outstr,"%8.4f ",*coord++);
pg(outstr);
};
answer = nearest->class;
rtanswer = point->class;
sprintf(outstr,"%5d ",answer);
pg(outstr);
if (answer == rtanswer)
{
if (pg("ok\n")) return;
}
else if (pg("\n")) return;
}
void eval(list, printing)
int list, printing;
{
NODE *nearestproto, *point;
int answer, rtanswer, right, wrong, i, patcount, stop;
REAL pct, *coord;
if (noprotos()) return;
patcount = 0;
right = 0;
wrong = 0;
for (i=0;i<=nclasses;i++) *(errtotal + i) = 0;
for (i=0;i<=errmatsize-1;i++) *(errmat + i) = 0;
if (list == TRAIN) point = trainlist; else point = testlist;
while (point != NULL)
{
rtanswer = point->class;
nearestproto = nn(point,-1);
answer = nearestproto->class;
point->nn = answer;
if (answer == rtanswer) right = right + 1;
else wrong = wrong + 1;
if (printing)
{
patcount = patcount + 1;
sprintf(outstr,"%5d ",patcount);
pg(outstr);
coord = point->vector;
if (listpat == '+')
{
for (i=1;i<=length;i++)
{
sprintf(outstr,"%8.4f ",*coord++);
pg(outstr);
};
};
sprintf(outstr,"%5d ",answer);
pg(outstr);
if (answer == rtanswer)
{
stop = pg("ok\n");
if (stop == 1) return;
}
else
{
stop = pg("\n");
if (stop == 1) return;
};
};
point = point->next;
};
pct = 100.0 * right / (right + wrong);
sprintf(outstr,"pct = %6.2f right = %d wrong = %d\n",pct,right,wrong);
pg(outstr);
s[list].iterno = s[TRAIN].iterno;
s[list].right = right;
s[list].wrong = wrong;
s[list].pctright = pct;
}
void makecopy() /* of the original prototypes */
{
NODE *list, *lastnode, *newnode, *orig;
REAL *vec, *newvector, *origvector;
int j;
FILE *patterns;
/* get rid of any old prototypes */
if (initialprotos != NULL)
{
list = initialprotos;
while (list != NULL)
{
newnode = list->next;
vec = list->vector;
free(vec);
free(list);
list = newnode;
};
};
/* set up an unused node at the beginning */
initialprotos = (NODE *) malloc(sizeof(NODE));
lastnode = initialprotos;
/* copy the original set of prototypes */
orig = protolist;
while (orig != NULL)
{
newnode = (NODE *) malloc(sizeof(NODE));
newvector = (REAL *) malloc(sizeof(REAL) * length);
newnode->vector = newvector;
newnode->next = NULL;
newnode->nn = 0;
lastnode->next = newnode;
origvector = orig->vector;
for (j=1;j<=length;j++) *newvector++ = *origvector++;
newnode->class = orig->class;
lastnode = newnode;
orig = orig->next;
};
initialprotos = initialprotos->next;
}
void run(passes)
int passes;
{
NODE *nearestproto, *point;
int i,j,p,answer;
REAL decrease, changes;
alpha = highalpha;
changes = passes * npats;
decrease = (highalpha - lowalpha) / changes;
outofdate = 1;
pg("running ...\n");
for (p=1;p<=passes;p++)
{
point = trainlist;
while (point != NULL)
{
answer = point->class;
nearestproto = nn(point,-1);
if (algorithm == 'd') dsm(point,nearestproto,answer);
else lvq1(point,nearestproto,answer);
point = point->next;
alpha = alpha - decrease;
};
s[TRAIN].iterno = s[TRAIN].iterno + 1;
eval(TRAIN,(int) 0);
#ifndef UNIX
if (kbhit() && getch() == 27) return;
#endif
}
}
void printmatrix(list)
int list;
{int i, j, p, ipct, rtanswer, answer;
NODE *point;
REAL pct;
INT32 *addr;
if (list == TRAIN) point = trainlist; else point = testlist;
if (s[list].iterno == 0) eval(list,(int) 0);
else if (list == TEST && s[list].iterno != s[TRAIN].iterno)
eval(list,(int) 0);
while (point != NULL)
{
rtanswer = point->class;
answer = point->nn;
addr = errmat + (answer - 1) * (nclasses + 1) + rtanswer;
*addr = *addr + 1;
*(errtotal + answer) = *(errtotal + answer) + 1;
point = point->next;
};
/* print the error matrix; when the program claims class i (row i)
is the answer, what percentage of the time is it really class j
(column j) */
pg(" ");
for (i=1;i<=nclasses;i++) {sprintf(outstr,"%3d",i); pg(outstr);};
pg("\n");
for (i=1;i<=nclasses;i++)
{
sprintf(outstr,"%3d",i); pg(outstr);
for (j=1;j<=nclasses;j++)
{
addr = errmat + (i - 1) * (nclasses + 1) + j;
if (*(errtotal + i) == 0) pg(" *");
else
{
ipct = (*addr * 100.0) / *(errtotal + i) + 0.5;
sprintf(outstr,"%3d",ipct); pg(outstr);
};
};
pg("\n");
};
pg(" ");
for (i=1;i<=nclasses;i++) {sprintf(outstr,"%3d",i); pg(outstr);};
pg("\n\n");
pct = 100.0 * right / (right + wrong);
sprintf(outstr,"pct = %8.4f right = %d wrong = %d\n",pct,right,wrong);
}
void help()
{
int ch2;
putchar('\n');
do ch2 = readch(); while (ch2 == ' ' && ch2 != '\n');
switch (ch2) {
default:
pg("For help type h followed by the letter of the command.\n");
if (ch2 == '\n') bufferptr = bufferptr - 1;
break;
case '?':
pg("? prints program status and parameters.\n");
break;
case '*':
pg("* at the beginning of a line makes the line a comment.\n");
break;
case '!':
pg("Enter system command after the !\n");
break;
case 'A':
pg("A l sets the algorthm to lvq 1.\n");
pg("A d sets the algorithm to dsm.\n");
break;
case 'a':
pg("a <real> sets alpha to <real>.\n");
break;
case 'C':
pg("C <real1> <real2> <real3> uses the training set to form prototypes using\n");
pg(" a simple clustering algorithm with lambda = <real1>,\n");
pg(" <real1> / 2 and <real1> / 4 with maxdist = <real2>.\n");
pg(" Clusters with less than <real3> * number of patterns are deleted.\n");
break;
case 'c':
pg("c (clear) resets the prototypes and the other parameters.\n");
break;
case 'd':
pg("d <real> does one pass of DSM with alpha = <real>.\n");
pg("d <real1> <real2> <int> does <int> passes of dsm starting with\n");
pg(" alpha = <real1> and ending with alpha = <real2>.\n");
break;
case 'f':
pg("f c+ makes a copy of all I/O on the file, copy.\n");
pg("f c- stops making a copy of all I/O.\n");
pg("f e+ echos input.\nf e- stops echoing input.\n");
pg("f P <int> sets page size to <int>.\n");
pg("f P 0 stops paging.\n");
pg("f s+ to summarize training and testing results (knn only).\n");
pg("f s- to list all training and testing patterns (knn only).\n");
pg("f w+ writes patterns when evaluating them with p and t\n");
pg("f w- does not write patterns when evaluating them with p and t\n");
break;
case 'h':
pg("h <char> gives help with command, <char>.\n");
break;
case 'i':
pg("i <filename> takes commands from <filename>.\n");
break;
case 'l':
pg("l <real> does one pass of lvq1 with alpha = <real>.\n");
pg("l <real1> <real2> <int> does <int> passes of lvq1 starting with\n");
pg(" alpha = <real1>\n and ending with alpha = <real2>.\n");
break;
case 'm':
pg("m <int1> <int2> ""makes a network"" with <int1> input units (the\n");
pg(" length of the pattern) and <int2> output units (the\n");
pg(" number of classes.\n");
break;
case 'n':
pg("<int> n or <int> nn classifies training set patterns using the\n");
pg(" <int> nearest neighbors using the training set as\n");
pg(" prototypes but excluding the training set point itself.\n");
pg("<int> n <pattern> or <int> nn <pattern>\n");
pg(" classifies the <pattern> using the <int> nearest neighbors.\n");
pg("<int> n <input pattern> > <file>\n");
pg("<int> nn <input pattern> > <file> writes the <int> nearest training\n");
pg(" set vectors to the <file> with the distance written\n");
pg(" out preceeded by an *. If no file is given the last\n");
pg(" file named is used or if no file has been named, the\n");
pg(" file, nearest is used.\n");
break;
case 'p':
pg("p prints training patterns and their answers.\n");
pg("p0 evaluates the training patterns and summarizes the results.\n");
pg("p <int> evaluates training pattern <int>.\n");
pg("pm prints the confusion matrix.\n");
break;
case 'P':
pg("P <pattern> classifies the pattern using its nearest prototype\n");
break;
case 'q':
pg("q quits the program.\n");
break;
case 'r':
pg("rp <filename> reads prototype vectors (""weights"").\n\n");
pg("rt <filename> reads training set vectors from <filename>.\n\n");
pg("rw <filename> reads prototype vectors (""weights"").\n\n");
pg("r <real> runs one pass through the training set using alpha =");
pg(" <real>.\n");
pg("r <real1> <real2> <int> runs <int> passes through the training ");
pg("set starting\n with alpha = <real1> and ending with alpha = ");
pg("<real2>.\n");
break;
case 's':
pg("sp saves prototypes to the current prototype file.\n");
pg("sp <filename> saves prototypes to the file <filename>.\n");
pg("sw saves prototypes (""weights"") to the current prototype file.\n");
pg("sw <filename> saves prototypes to the file <filename>.\n");
break;
case 't':
pg("t evaluates and prints all the test patterns.\n");
pg("t 0 evaluates test patterns and summarizes the results.\n");
pg("t <int> evaluates test pattern <int>.\n");
pg("t m prints the confusion matrix for the test patterns.\n");
pg("tf <filename> reads the test patterns on <filename>.\n");
break;
}
pg("\n");
}
void scanrun()
{ REAL rtemp;
int itemp;
if (protolist == NULL) {pg("there are no prototypes\n"); return;};
if (trainlist == NULL)
{pg("there are no training patterns\n"); return;};
if (ch == '\n' || ch == '*') {npasses = 1; run(npasses); return;}
else
{
bufferptr = bufferptr - 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -