Você está na página 1de 4

HEADER //escolhe qual o metodo que vai ser analisado

#define METHOD KNN


#include <stdio.h>
#include <stdlib.h>
//faz comparacao de dois registros de distancias
#include <math.h>
int cmpRegDist(const void *a, const void *b) {
#include <cv.h>
RegDist *r1 = (RegDist *) a;
#include <highgui.h>
RegDist *r2 = (RegDist *) b;
#include "defs.h"
if (r1->dist < r2->dist)
return +1;
#define MAXSET 2000
if (r1->dist > r2->dist)
#define MAXBUFF 512
return -1;
#define MAXCLASS 10
return 0;
#define MAXERROS 600
}
#define MIN(a,b) (((a)<(b))?(a):(b))
//constantes com arquivos de entrada
#define DIR_OUT_BASE "c:/mo446/projeto/output/img" Processa arquivos de entrada
#define FILE_NIST_TEST "c:/mo446/projeto/input/optdigits.tes"
#define FILE_TEST_ARFF "C:/mo446/projeto/input/optdigits_test2.arff"
#define FILE_TEST "c:/mo446/projeto/input/optdigits.tes.in" //transforma um arquivo csv para um arquivo separado por espacos apenas.
#define FILE_NIST_TRAINING "c:/mo446/projeto/input/optdigits.tra" void limpaArquivo(FILE *in, FILE *out) {
#define FILE_TRAINING "c:/mo446/projeto/input/optdigits.tra.in" char c;
while (true) {
//dimensao da imagem DIMxDIM if (fscanf(in, "%c", &c)<1)
#define DIM 8 break;
//zoom para exibicao da imagem do digito if (c>='0' && c<='9' || c == ' ' || c == '\n')
#define ZOOM 10 fprintf(out, "%c", c);
else if (c==',')
//registro de uma instancia fprintf(out, " ");
typedef struct { }
int inst; //id da instancia }
double dist; //distancia mahalanobis
int classe; //classe original (actual) //limpa os arquivos do NIST para processar mais facilmente
int predicted; //classe calculada pelo weka void limpaArquivosNIST() {
} RegDist;
FILE *fin = fopen(FILE_NIST_TEST,"rt");
//variaveis globais FILE *fout = fopen(FILE_TEST,"wt");
int M[MAXSET][DIM][DIM]; limpaArquivo(fin, fout);
int D[MAXSET]; fclose(fout);
int V[MAXSET][DIM*DIM]; fclose(fin);
int ACERTOS[MAXCLASS][MAXSET], ERROS[MAXCLASS][MAXSET], TACERTOS[MAXCLASS], fin = fopen(FILE_NIST_TRAINING,"rt");
TERROS[MAXCLASS]; fout = fopen(FILE_TRAINING,"wt");
int TINST=0; limpaArquivo(fin, fout);
int PREDICTED[MAXSET]; fclose(fout);
fclose(fin);
//possibilidades de metodos para analisar }
#define KNN 0
#define NAIVEBAYES 1 //carrega um arquivo com os digitos
#define DECTREE 2 void carregaArquivoDigitos(FILE *in) {
if (in == NULL) {
//arquivos onde possui dados de classificacao e de distancia mahalanobis printf("erro abrindo arquivo");
char *ARQUIVOS_CLASSIF_MAHALA[][2] = { { return;
"C:/mo446/projeto/output/knn/knn_treina_teste.txt", }
"C:/mo446/projeto/output/analise/knn_mahalanobis.out" }, { TINST = 1;
"C:/mo446/projeto/output/naivebayes/naiveb_treina_teste.txt", while (true) {
"C:/mo446/projeto/output/analise/naivebayes_mahalanobis.out" }, {
"C:/mo446/projeto/output/dectree/dectree_treina_testa.txt", //le a matriz
"C:/mo446/projeto/output/analise/dectree_mahalanobis.out" }, for (int i=0; i<DIM; i++)
}; for (int j=0; j<DIM; j++)
if (fscanf(in, "%d", &M[TINST][i][j]) < 1) for (int c=0; c<MAXCLASS; c++) {
return; if (fscanf(in, "%d", &inst) == EOF)
return;
//le qual digito se trata if (inst == -1)
if (fscanf(in, "%d", &D[TINST])<1) break;
return;
registros[c][totalRegistros[c]].inst = inst;
TINST++; registros[c][totalRegistros[c]].classe = c;
} registros[c][totalRegistros[c]].dist = dist[c][totalRegistros[c]];
} registros[c][totalRegistros[c]].predicted = PREDICTED[inst];
totalRegistros[c]++;
}
Processa arquivo gerado com todas distâncias de if (inst == -1)
Mahalanobis break;

//processa o arquivo com todas distancias calculadas }


//de mahalanobis para as instancias que houve erro.
//escolhe as n piores e imprime o id da instancia, a imagem e a classificacao limpaArquivosNIST();
void processaArqMahalanobis(int nPiores) { FILE *inTeste = fopen(FILE_TEST,"rt");
char *fname = ARQUIVOS_CLASSIF_MAHALA[METHOD][1]; carregaArquivoDigitos(inTeste);
char strMetodo[MAXBUFF]; fclose(inTeste);
RegDist registros[MAXCLASS][MAXERROS];
for (int c=0; c<MAXCLASS; c++)
//carrega em memoria a classificacao feita qsort(registros[c], totalRegistros[c], sizeof(RegDist), cmpRegDist);
carregaClassificacao();
printf("Metodo: %s\n", strMetodo);
FILE *in = fopen(fname, "rt");
if (in == NULL) { char prefixArqImg[MAXBUFF];
printf("erro abrindo arquivo"); for (int c=0; c<MAXCLASS; c++) {
return; //printf("classe: %d\n", c);
} int nMostrar= MIN(nPiores,totalRegistros[c]);
nMostrar = totalRegistros[c];
if (fscanf(in, "@%s\n", strMetodo) == EOF) for (int i=0; i<nMostrar; i++) {
return; if (registros[c][i].dist == 0)
int totalErros[MAXCLASS]; continue;
int totalRegistros[MAXCLASS];
for (int i=0; i<MAXCLASS; i++) printf("#%d d=%lf c=%d\n", registros[c][i].inst,
totalRegistros[i] = totalErros[i]=0; registros[c][i].dist, registros[c][i].predicted);
//printf("%s,%d,%lf\n", strMetodo,c,registros[c][i].dist);
double dist[MAXCLASS][MAXERROS]; sprintf(prefixArqImg, "erro_%s_c%d_id%d_p%d", strMetodo, c,
while (true) { registros[c][i].inst, registros[c][i].predicted);
bool parar = false; renderizaDigito(registros[c][i].inst, prefixArqImg, false);
for (int c=0; c<MAXCLASS; c++) { }
if (fscanf(in, "%lf", &dist[c][totalErros[c]]) == EOF) //printf("#\n");
return; }
if (dist[c][totalErros[c]] == -1) {
parar = true; fclose(in);
} else }
totalErros[c]++;
} Gera Arquivo em Scilab para cálcula das distâncias de
if (parar) Mahalanobis
break;
//gera um script em scilab (clone do mathlab - freeware) com
} //o calculo da distancia de mahalanobis para as instancias classificadas
//incorretamente. Manda para a saida padrao
while (true) { int geraScriptMahalanobisScilab(void) {
int inst = -1; char *arqNomeTeste= FILE_TEST_ARFF;
printf("M_C%d=mean(ACC_C%d,'r')\n", c, c);
carregaClassificacao(); printf("sigma_C%d=varcovar(ACC_C%d)\n", c, c);
printf("inv_sigma_C%d=pinv(sigma_C%d)\n", c, c);
//abre arquivo de teste com os dados dos vetores for (int i=0; i<TERROS[c]; i++) {
FILE *arqTeste = fopen(arqNomeTeste, "rt"); int inst = ERROS[c][i];
if (arqTeste == NULL) { printf(
printf("erro abrindo arquivo"); "mahab_C(%d,%d) = sqrt((ERR_C%d_%d-M_C%d)*inv_sigma_C%d*(ERR_C%d_
return 0; %d-M_C%d)')\n",
} i+1, c+1, c, i, c, c, c, i, c);
printf("ref_C(%d,%d)=%d\n", i+1, c+1, inst);
//parseia arquivo de testes com dados dos digitos }
while (true) { }
char buff[MAXBUFF];
if (fscanf(arqTeste, "%s", buff) == EOF) fclose(arqTeste);
break; return 0;

if (strcmp(buff, "@data") == 0) { }
int inst=1, actual;
while (true) { Gera uma imagem de um digito a partir de uma matriz
for (int i=0; i<64; i++)
if (fscanf(arqTeste, "%d,", &V[inst][i]) == EOF)
break; //dada uma matriz que representa o digito, cria uma imagem
if (fscanf(arqTeste, "D%d\n", &actual) == EOF) void criaDigitoImagem(IplImage *digito, int m[DIM][DIM]) {
break; for (int i=0; i<DIM; i++) {
inst++; for (int j=0; j<DIM; j++) {
}
printf("lidos %d instancias no arquivo de teste\n", inst-1); //monta a imagem com ZOOM
break; for (int dx=0; dx<ZOOM; dx++)
} for (int dy=0; dy<ZOOM; dy++)
} digito->imageData[i*ZOOM + dx + (j*ZOOM + dy)*digito->widthStep] =
255
//gera,para cada classe, uma matriz com os digitos acertados - (unsigned char) 255*((double)m[j][i]/16.0);
for (int c=0; c<MAXCLASS; c++) {
printf("ACC_C%d=[", c); }
for (int i=0; i<TACERTOS[c]; i++) { }
int inst = ACERTOS[c][i]; }
for (int j=1; j<64; j++) {
printf("%d ", V[inst][j]); //renderiza um digito, salva em arquivo e mostra na tela
} void renderizaDigito(int inst, char *prefixoNomeArq, bool mostrarTela) {
printf(";\n");
} if (inst > TINST || inst <=0) {
printf("]\n\n"); printf("valor invalido para instancia, nao renderizou.");
} return;
}
//gera um script com vetores para cada digito errado por classe
for (int c=0; c<MAXCLASS; c++) { char outfname[255];
for (int i=0; i<TERROS[c]; i++) { IplImage *digito = cvCreateImage(cvSize(8*ZOOM, 8*ZOOM), IPL_DEPTH_8U, 1);
printf("ERR_C%d_%d=[", c, i); //rotina que processa a matriz do digito
int inst = ERROS[c][i]; //if (mostrarTela)
for (int j=1; j<64; j++) { // mostraDigitoTexto(D[inst], M[inst]);
printf("%d ", V[inst][j]);
} criaDigitoImagem(digito, M[inst]);
printf("]\n\n");
} //mostra a imagem na tela
} if (mostrarTela) {
cvNamedWindow("mainWin", CV_WINDOW_AUTOSIZE);
//gera o calculo das distancias de mahalanobis para cada digito errado, por cvMoveWindow("mainWin", 8, 8);
classe. cvShowImage("mainWin", digito);
for (int c=0; c<MAXCLASS; c++) { cvWaitKey(0);
} if (parar)
break;
//escreve no arquivo
sprintf(outfname, "%s/%s.bmp", DIR_OUT_BASE, prefixoNomeArq); actual--;
cvSaveImage(outfname, digito); predicted--;
//libera imagem PREDICTED[inst] = predicted;
cvReleaseImage(&digito); //monta uma lista de acertos e erros com o id da instancia
if (actual == predicted) {
} ACERTOS[actual][TACERTOS[actual]++] = inst;
} else {
//mostra a matriz que representa o digito na tela em modo texto ERROS[actual][TERROS[actual]++] = inst;
void mostraDigitoTexto(int d, int m[DIM][DIM]) { }
printf("D=%d\n", d); }
for (int i=0; i<DIM; i++) {
for (int j=0; j<DIM; j++) break;
printf("%02d ", m[i][j]); }
printf("\n");
} }
printf("\n\n"); fclose(arqClass);
}
}
Carrega arquivo com as classificações
//carrega em memoria a classificacao feita pelo weka.
void carregaClassificacao() {
char *arqNomeClass = ARQUIVOS_CLASSIF_MAHALA[METHOD][0];

for (int i = 0; i<MAXCLASS; i++)


TACERTOS[i] = TERROS[i] = 0;

FILE *arqClass = fopen(arqNomeClass, "rt");


if (arqClass == NULL) {
printf("erro abrindo arquivo");
return;
}
//parseia o arquivo de classificacao e monta listas de acertos e erros
while (true) {
char str1[MAXBUFF], str2[MAXBUFF], linha[MAXBUFF];
int inst, actual, predicted;

if (fscanf(arqClass, "%s %s", str1, str2) == EOF)


break;
//encontra o ponto onde comeca a classificacao
if (strcmp(str1, "probability") == 0 && strcmp(str2, "distribution")
== 0) {

//le todas classificacoes


while (true) {
fscanf(arqClass, "%d %d:%s %d:%s %[^\n]", &inst, &actual, str1,
&predicted, str2, linha);
fscanf(arqClass, "%[^\n]s", linha);
int len = strlen(linha);
bool parar = true;
for (int i=0; i<len; i++)
if (linha[i] >='0' && linha[i] <= '9') {
parar = false;
break;
}

Você também pode gostar