Ir para o conteúdo
  • Revista PROGRAMAR: Já está disponível a edição #60 da revista programar. Faz já o download aqui!

WolfmanZ

algoritmo Knn erro de programação

Mensagens Recomendadas

WolfmanZ

Boas

Estou a fazer um trabalho onde o algoritmo KNN (vizinhos + proximos através de distancia euclidiana) é para ser usado a minha duvida não é o algoritmo em si mas um erro que me está a escapar.

o programa tem um conjunto de dados numa matriz e vai ler outros dados de um ficheiro que vai ser lida para outra matriz com o proposito de dizer se é X ou Y.

compara cada linha do ficheiro com todas as linhas da matrizTreino e no fim se o vector tiver mais X que Y a amostra (linha do ficheiro é X) e faz isso para todas as linhas do ficheiro no final a soma de X e Y é o numero de linha do ficheiro.

O meu problema é que o programa da sempre resultados X e nao é suposto, visto que tenho 2 ficheiros de controlo.

int KNN(float **matrizNV, float **mTreino, int *contNV, int *contTr){
int k=15,l,i,j,cM,cB,h,p,g,cMR=0,cBR=0,s;
float *vec_dis=NULL, d=0;
int *diag=NULL;
for(i=0;i<contTr-1;i++){
    printf("$%f! ",mTreino[i][1]);
}

vec_dis = (float*) malloc(k*sizeof(float)); //vector que guarda os menores valores para as distancias euclidiana calculadas
diag = (int*) malloc(k*sizeof(int)); // vector que guarda se é X ou Y da disntancia que foi guardada no outro vector
for(l=0;l<contNV;l++){ //percorre linhas da matriz do ficheiro
    cM=0; //contador
    cB=0; // contador
//inicializa vector por cada linha do ficheiro
    for(h=0;h<k;h++){
        vec_dis[h] = 100000;
        diag[h]=-1;
    }
    for(i=0;i<contTr;i++){ //percorre linhas da matriz dados
        d=0;
        for(j=2;j<32;j++){
            d = d + pow((matrizNV[l][j]-mTreino[i][j]),2); // calcula distancia euclidiana
        }
        d=sqrt(d);
        //compara e ordena com o vector distancias
        for(p=0;p<k;p++){
                if(d<=vec_dis[p]){
                    for(g=k-1;g>=p;g--){
                        vec_dis[g] = vec_dis[g-1];
                        diag[g] = diag[g-1];
                    }
                    vec_dis[p] = d;
                    diag[p] = i;
                    break;
                }
        }
    }//if i
printf("\n");
    for(s=0;s<k;s++){
        printf("%d$ ",diag[s]);
    }
    printf("\n");
    for(s=0;s<k;s++){
        printf("%f! ",mTreino[diag[s]][1]);
        if(mTreino[diag[s]][1]==0){
            cB++;
        }
        if(mTreino[diag[s]][1]==1){
            cM++;
        }
    }
    if (cM>cB)
            cMR++;
        else
            cBR++;
    printf("Linha %d : M=%d | B=%d \n",l+1,cM,cB);
    }//if l

    printf("Total: M=%d | B=%d \n",cMR,cBR);
    printf("Casos analisados: %d \n\n", contNV);

}

Obrigado desde já

Editado por pmg
Falta LP

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
HappyHippyHippo

tu calculas a distância, mas não parece fazeres nada com ela

ps : para a próxima apresenta o código com a tag para código C ...


IRC : sim, é algo que ainda existe >> #p@p

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
WolfmanZ

a distancia sao calculada para inserir as menores no vector vec_dis[] e na mesma posiçao do vector diag[] guarda a informaçao se é X ou Y

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
HappyHippyHippo

e na mesma posiçao do vector diag[] guarda a informaçao se é X ou Y

for(i=0;i<contTr;i++){ //percorre linhas da matriz dados
// ...
  diag[p] = i;
// ...
}

não parece ...

o teu código de registar uma distância e ordenação é uma confusão

eu efectuava as seguintes alterações ao teu código:

- usa uma estrutura para cada elemento da lista e não duas listas separadas:

//vec_dis = (float*) malloc(k*sizeof(float));
//diag = (int*) malloc(k*sizeof(int));

typedef struct
{
 float dist;
 int diag;
}Elem;

// ...

vector = malloc(k * sizeof(Elem));

- adicinar sempre no fim dos elementos da lista

- efectuar a ordenação do array numa função separada


IRC : sim, é algo que ainda existe >> #p@p

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
WolfmanZ

ok isto ja tem haver com tentativas de emendar o erro tentei ir pela posição na matriz o original é

diag[p] = mTreino[i][1];

o trabalho é para usar matrizes dinâmicas por isso é que não usei listas e estruturas

Editado por WolfmanZ

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
HappyHippyHippo

o trabalho é para usar matrizes dinâmicas por isso é que não usei listas e estruturas

vector = malloc(k * sizeof(Elem)); // <------------------ e isto não é dinâmico ???


IRC : sim, é algo que ainda existe >> #p@p

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
WolfmanZ

sim é dinâmico mas não há necessidade de usar structs

o codigo original é este:

int KNN(float **matrizNV, float **mTreino, int *contNV, int *contTr){
int k=15,l,i,j,cM,cB,h,p,g,cMR=0,cBR=0,s;
float *vec_dis=NULL, d=0;
int *diag=NULL;
 for(i=0;i<contTr-1;i++){
	printf("$%f!  ",mTreino[i][1]);
 }

vec_dis = (float*) malloc(k*sizeof(float));
diag = (int*) malloc(k*sizeof(int));
for(l=0;l<contNV;l++){
	cM=0;
	cB=0;
//inicializa vector por cada linha do ficheiro
	for(h=0;h<k;h++){
	 vec_dis[h] = 100000;
		diag[h]=-2;
	}
	for(i=0;i<contTr;i++){
		d=0;
		for(j=2;j<32;j++){
			d = d + pow((matrizNV[l][j]-mTreino[i][j]),2);
		}
		d=sqrt(d);
		//compara com o vector distancias
		for(p=0;p<k;p++){
				if(d<=vec_dis[p]){
					for(g=k-1;g>=p;g--){
						vec_dis[g] = vec_dis[g-1];
						diag[g] = diag[g-1];
					}
					vec_dis[p] = d;
					diag[p] = mTreino[i][1];
					break;
				}
		}
	}//if i
	for(s=0;s<k;s++){
		if(diag[s]==0){
			cB++;
		}
		if(diag[s]==1){
			cM++;
		}
	}
	if (cM>cB)
			cMR++;
		else
			cBR++;
	printf("Linha %d : M=%d | B=%d \n",l+1,cM,cB);
   }//if l

  printf("Total: M=%d | B=%d \n",cMR,cBR);
  printf("Casos analisados: %d \n\n", contNV);

}

há alteraçoes em relaçao ao outro na parte de meter para o vector e na parte de verificar se é X ou Y

Editado por WolfmanZ

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
HappyHippyHippo

não há necessidade, mas é uma questão de simplificação.

tipo aqueles métodos que se usam para simplificar o código e a sua leitura, como dar nomes com significao às variáveis, para que quando venha uma segunda pessoa, não tenha problemas em perceber rapidamente o que está escrito.


IRC : sim, é algo que ainda existe >> #p@p

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites
WolfmanZ

sim ok.

acho que o problema esta na passagem para os vectores pk fiz um teste onde mandei imprimir o vector diag[] e so aparecem 1 e tem que haver tambem 0 nesse vector pois se so encontra 1 é natural que de so malignos

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!

Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.

Entrar Agora

×

Aviso Sobre Cookies

Ao usar este site você aceita os nossos Termos de Uso e Política de Privacidade. Este site usa cookies para disponibilizar funcionalidades personalizadas. Para mais informações visite esta página.