• No results found

3 Hydrological Modeling of Forested Catchments

3.3 Parameter estimation for hydrological models

/*Este evalua_prob se va a diferenciar del evalua en que aquí, si me encuentro con un caso en el que la distancia mínima del ejemplo en estudio a uno de la BD con la que ha entrenado no es cero (es decir, no se encuentra ese ejemplo en la BD), se dará como solución la más probable*/

#include <assert.h> #include "silabica.h" #include <string.h> #include <stdio.h> #include <values.h> #include <math.h> #include <mem.h> #include "portable.h" #include "portimpr.h" #include "flh.h" #include "tildes.h" TEjemplo *ejemplos;

TIndiceEj NumEjemplos; //Nº de ejemplos de la BD de entrenamiento TDistancia *pesos;

TIndiceRasgos NumRasgos = 0; //Variable con el n'umero de rasgos que lee desde el fichero BD de ejemplos

TValorSolucion SolucionEvaluada;

TValorSolucion SolucionMasProbable; //Sol. más probable en el fich. de entren. (para la pal. en estudio)

TFrecuencia frecSolucMasProbable=0; //Guarda la frec. de la soluc + probable para cada vantana evaluada

TDistancia distMin=0; //Guarda la dist. min. de cada ventana de rasgos a los ej de dist mínima char FicheroPruebas[MAXPATH]="fich_ej_prue.dic"; //Fichero con todos las palabras para evaluar (pasado por el traductor)

char FicheroBDEjemplos[MAXPATH]="bd_ej.dic";//Fichero con ejemplos y soluciones char FicheroPesos[MAXPATH]="pesos.dic"; //Fichero con los pesos

char FicheroEvaluacion[MAXPATH]="evaluacion_prob.est"; //Fichero con todas las ventanas evaluadas. /*El formato de evaluacion.est es: nºrasgos, 1er rasgo,...,último rasgo, solución según se

ha leído del texto de pruebas, solucion estimada por el evaluador, frecuencia acumulada de lo/s ejemplo/s de dist. mínima cuya solución se ha tomado como la más probable, distancia mínima a lo/s ejemplo/s de dist. mínima y comentario (palabra leída del texto de pruebas, de la que se ha obtenido la ventana en estudio*/

char FicheroEstadisticasEvaluacion[MAXPATH]="estadis_prob.est"; // Fichero con las estad'isticas char FicheroProbEntren[MAXPATH]="prob_entren.dic"; // Fichero con las prob. de cada solución TDistancia DistanciaRasgos(TValorRasgo a, TValorRasgo b)

{ if (a==b) return 0; else return 1; }

TDistancia distancia(TValorRasgo *ejemp1, TValorRasgo *ejemp2) {

TIndiceRasgos i; TDistancia Distancia;

for (i=0,Distancia=0; i<NumRasgos; i++) {

Distancia+=pesos[i]*DistanciaRasgos(ejemp1[i],ejemp2[i]); }

return Distancia; }

/*Esta funcion busca el primer ejemplo de distancia minima*/ TIndiceEj BuscaMinimo(TValorRasgo *rasgos)

{

TDistancia distMin=MAXFLOAT; TIndiceEj indMin=-MAXLONG; TIndiceEj i;

for (i=0; i<NumEjemplos; i++) { if (distancia(ejemplos[i].rasgos,rasgos)<distMin) { distMin=distancia(ejemplos[i].rasgos,rasgos); indMin=i; } } assert(indMin>=0); return indMin; }

int comparaEjemplos(const void *x, const void *y) {

TEjemplo *ej=(TEjemplo *)y; for (int i=0; i<NumRasgos; i++)

{ if (vent[i]>ej->rasgos[i]) return 1; else if (vent[i]<ej->rasgos[i]) return -1; } return 0; }

/*Esta funcion da los indices de los ejemplos que han dado distancia minima. ConjuntoMinimo contiene los indices de los ejemplos de distancia minima, hasta que haya un -1 (ahi acaba la lista de ejemplos)*/

TIndiceEj *BuscaKMinimos(TValorRasgo *rasgos) {

TEjemplo EjAuxiliar; TIndiceEj PrimerIndMin;

for (TIndiceEj i=0; i<NumRasgos && rasgos[i]!=FINALIZADOR; i++) {

EjAuxiliar.rasgos[i]=rasgos[i]; if (i<NumRasgos-1)

EjAuxiliar.rasgos[i+1]=FINALIZADOR; }

TEjemplo * ej=(TEjemplo * )bsearch((const void*)&EjAuxiliar,(const void*)ejemplos,NumEjemplos,sizeof(ejemplos[0]),comparaEjemplos);

/* TEjemplo * ej=(TEjemplo * )lfind((const void*)&EjAuxiliar,(const void*)ejemplos,(unsigned int*)&NumEjemplos,sizeof(ejemplos[0]),comparaEjemplos);*/ if (ej!=NULL) { PrimerIndMin=((int32)ej-(int32)ejemplos)/(int32)(sizeof(ejemplos[0])); } else { PrimerIndMin=BuscaMinimo(rasgos); } distMin=distancia(ejemplos[PrimerIndMin].rasgos,rasgos); #if defined(__WIN32__)

TIndiceEj *ConjuntoMinimo=new TIndiceEj [NumEjemplos+1]; #else

TIndiceEj *ConjuntoMinimo=(TIndiceEj *)farmalloc (sizeof(TIndiceEj)*(NumEjemplos+1)); #endif

TIndiceEj i;

TIndiceEj j; /* falta k-NN */

for (i=PrimerIndMin, j=0; i<NumEjemplos; i++) { if (distancia(ejemplos[i].rasgos,rasgos)==distMin) { ConjuntoMinimo[j++]=i; } else if (ej!=NULL) break; } if (ej!=NULL) {

for (i=PrimerIndMin-1; i>=0; i--) { if (distancia(ejemplos[i].rasgos,rasgos)==distMin) { ConjuntoMinimo[j++]=i; } else if (ej!=NULL) break; } } if (j<=0) assert(0); else ConjuntoMinimo[j]=FINALIZADOR; return ConjuntoMinimo; }

/*Esta función devuelve los ejemplos que han dado distancia mínima.

Soluciones: lista de ejemplos hasta que haya un finalizador en la solución del último ejemplo*/

TEjemplo *BuscaSoluciones(TValorRasgo *rasgos) {

TEjemplo *soluciones=new TEjemplo[NumEjemplos+1]; TIndiceEj *ConjuntoMinimo=BuscaKMinimos(rasgos); TIndiceEj i;

for (i=0; ConjuntoMinimo[i] != FINALIZADOR; i++) { soluciones[i].solucion=ejemplos[ConjuntoMinimo[i]].solucion; soluciones[i].frecuencia=ejemplos[ConjuntoMinimo[i]].frecuencia; memcpy(soluciones[i].rasgos,ejemplos[ConjuntoMinimo[i]].rasgos, sizeof(soluciones[i].rasgos)); } if (i<=0) assert(0);

else

soluciones[i].solucion=FINALIZADOR; delete []ConjuntoMinimo;

return soluciones; }

/*Estas funciones recorren la variable ejemplos, para dar las soluc. max y min*/ TValorSolucion CalculaMinSoluc()

{

TValorSolucion MinSoluc = ejemplos[0].solucion; TIndiceEj i;

for (i=0; i<NumEjemplos; i++) {

if (ejemplos[i].solucion < MinSoluc) MinSoluc = ejemplos[i].solucion; }

return MinSoluc; }

TValorSolucion CalculaMaxSoluc() {

TValorSolucion MaxSoluc = ejemplos[0].solucion; TIndiceEj i;

for (i=0; i<NumEjemplos; i++) {

if (ejemplos[i].solucion > MaxSoluc) MaxSoluc = ejemplos[i].solucion; }

return MaxSoluc; }

/*A esta funci'on se le pasa un array de contadores, y devuelve el indice del contador m'as alto*/

TValorSolucion BuscaSolMasProbable(TFrecuencia *contador,TIndiceEj rangoSoluc,TIndiceEj minSoluc) {

TIndiceEj i; TIndiceEj indice=0; TIndiceEj maximo=0;

for (i=0; i<rangoSoluc; i++) { if (contador[i] > maximo) { indice = i+minSoluc; maximo=contador[i]; } } return indice; }

/*A esta función se le pasa una ventana de rasgos y devuelve la solución

estimada para el rasgo (letra) central. Utiliza el array de frecuencias Contador: cada posición se corresponde con una solución (de la mín a la máx), y contiene la frecuencia acumulada con que se da esa solución dentro del conjunto de ejemplos que han dado distancia mínima a la ventana en estudio*/

TValorSolucion DecisionSolucion(TValorRasgo *rasgos) { TEjemplo *soluciones=BuscaSoluciones(rasgos); TIndiceEj maxSoluc=CalculaMaxSoluc(); TIndiceEj minSoluc=CalculaMinSoluc(); TIndiceEj rangoSoluc=maxSoluc-minSoluc+1; TValorSolucion resultado;

TFrecuencia *Contador=new TFrecuencia[rangoSoluc];

memset(Contador,0,rangoSoluc*sizeof(TFrecuencia)); //Inicializo el arrray Contador TIndiceEj i;

for (i=0; soluciones[i].solucion!=FINALIZADOR; i++) { Contador[soluciones[i].solucion-minSoluc]+=soluciones[i].frecuencia; } resultado = BuscaSolMasProbable(Contador,rangoSoluc,minSoluc); frecSolucMasProbable=Contador[resultado]; delete [] soluciones; delete [] Contador; return resultado; }

/*Funcion que calcula el número de ejemplos (es decir, el número de líneas del fichero de la base de datos de ejemplos*/

TIndiceEj CalculaNumEjemplos(char *directorio, char *NomFichero) {

TIndiceEj i;

TIndiceEj contador=0; char *linea=new char [1000];

FILE *fichero=flhOpen(directorio,NomFichero,"rt"); if (fichero==NULL)

{

errorPrintf("falta el fichero %s",NomFichero); }

for (i=0; feof(fichero)==0; i++) {

if (fgets(linea,1000,fichero)!=NULL) contador++; else break; } flhClose(fichero); delete [] linea; return contador; }

float LeeFlotante(char *token, int i) {

float float_aux;

if(sscanf(token,"%f",(float*)&float_aux)!=1) {

errorPrintf("error de formato en l'inea %d",(long)i); }

return float_aux; }

int LeeSolucion(char *token, int i) {

int int_aux;

if(sscanf(token,"%d",(int*)&int_aux)!=1) {

errorPrintf("error de formato en l'inea %d",(long)i); }

return int_aux; }

/*Esta funcion carga en la variable ejemplos los datos del fichero diccionario de ejemplos (que contiene en cada linea un ejemplo (una ventana de rasgos), una solucion y la frecuencia de ese ejemplo). Cada linea del fichero de entrada es como sigue: nº de rasgos por ejemplo, blanco, nº de 1er rasgo, blanco,..., solucion, blanco, frecuencia, blanco, comentario*/

TEjemplo* CargaEjemplos(char *directorio, char *NomFichero) {

TIndiceEj i;

char *linea=new char [1000];

NumEjemplos=CalculaNumEjemplos(directorio, NomFichero); if (NumEjemplos<=0)

{

errorPrintf("fichero vac'io: %s",NomFichero); return NULL;

}

ejemplos=new TEjemplo[NumEjemplos];

FILE *fichero=flhOpen(directorio, NomFichero, "rt"); if (fichero==NULL)

{

errorPrintf("falta el fichero %s",NomFichero); }

for (i=0; feof(fichero)==0 && i<NumEjemplos; i++) {

if (i%100==0)

printf("Llevo cargados %ld ejemplos\n",(long)i); if (fgets(linea,1000,fichero)!=NULL)

{

TIndiceRasgos j; char *token=linea; token=strtok(token," ");

NumRasgos = atoi(token); //Aqui queda ya cargada la var. global NumRasgos token = NULL; for (j=0; j<NumRasgos; j++) { token=strtok(token," "); if (token==NULL) {

errorPrintf("error de formato en l'inea %d",(long)i); } float aux=LeeFlotante(token,i); ejemplos[i].rasgos[j] = aux; token=NULL; } token=strtok(NULL," "); if (token==NULL) {

errorPrintf("error de formato en l'inea %d",(long)i); }

ejemplos[i].solucion = LeeSolucion(token,i); token=strtok(NULL," ");

if (token==NULL) {

errorPrintf("error de formato en l'inea %d",(long)i); }

ejemplos[i].frecuencia = LeeFlotante(token,i); if (ejemplos[i].frecuencia<=0)

{

errorPrintf("error de formato en l'inea %ld",(long)i); }

token=strtok(NULL,"\n"); if (token==NULL)

errorPrintf("error de formato en l'inea %d",(long)i); } strcpy(ejemplos[i].comentario,token); } else { break; } } flhClose(fichero); delete [] linea;

qsort(ejemplos, NumEjemplos, sizeof(ejemplos[0]),comparaEjemplos); return ejemplos;

}

/*Esta funci'on devuelve para que se cargue en la variable global pesos los pesos de cada rasgo desde el fichero de pesos generado anterioemente a partir de la BD, para su posterior utilizaci'on en el c'alculo de la distancia entre ventanas de rasgos*/ TDistancia *InicializaPesos(char *directorio, char *NomFichero)

{

TDistancia *pesos=new TDistancia[NumRasgos]; TIndiceRasgos i;

TIndiceRasgos NumRasgosFichPesos; char *linea=new char [1000];

FILE *fichero=flhOpen(directorio, NomFichero, "rt"); if (fichero==NULL)

{

errorPrintf("falta el fichero %s",NomFichero); } if (fgets(linea,1000,fichero)!=NULL) { char *token=linea; token=strtok(token," "); if (token==NULL) {

errorPrintf("error de formato en el fichero de pesos"); }

NumRasgosFichPesos = LeeFlotante(token,1); if (NumRasgos != NumRasgosFichPesos)

{

errorPrintf("error de formato en el fichero de pesos"); }

token = NULL;

for (i=0; i<NumRasgos; i++) {

token=strtok(token," "); if (token==NULL)

{

errorPrintf("error de formato en el fichero de pesos"); } pesos[i] = LeeFlotante(token,i); token=NULL; } } flhClose(fichero); delete [] linea; return pesos; }

/*Esta función calcula cuál de las 2 soluciones (acentuada o no acentuada) es la más probable para la palabra ambigua que se está evaluando, a partir del fichero de probabilidades prob_entren.dic*/

TValorSolucion CalculaSolMasProbEntren(char *directorio, char *NomFichero) {

TValorSolucion solucion; TIndiceEj ContAcen=0; TIndiceEj ContDesacen=0;

char *linea=new char [1000]; char *token;

FILE *fichero=flhOpen(directorio, NomFichero, "rt"); if (fichero==NULL)

{

errorPrintf("falta el fichero %s",NomFichero); } if (fgets(linea,1000,fichero)!=NULL) { token=linea; token=strtok(token," "); if (token==NULL) {

errorPrintf("Error de formato en el fichero de probabilidades"); }

ContAcen = LeeFlotante(token,1); if (ContAcen < 0)

{

errorPrintf("error de formato en el fichero de probabilidades"); }

token = NULL; }

if (fgets(linea,1000,fichero)!=NULL) {

token=linea;

token=strtok(token," "); if (token==NULL)

{

errorPrintf("Error de formato en el fichero de probabilidades"); }

ContDesacen = LeeFlotante(token,1); if (ContDesacen < 0)

{

errorPrintf("error de formato en el fichero de probabilidades"); } } if (ContAcen>ContDesacen) solucion = ES_INTERROG; else if (ContAcen<ContDesacen) solucion = NO_ES_INTERROG; else solucion = INDEFINIDO; flhClose(fichero); delete [] linea; return solucion; }

void main(int argc,char *argv[]) { if (argc==1) { } else if (argc==6) { strcpy(FicheroPruebas,argv[1]); strcpy(FicheroBDEjemplos,argv[2]); strcpy(FicheroPesos,argv[3]); strcpy(FicheroEvaluacion,argv[4]); strcpy(FicheroEstadisticasEvaluacion,argv[5]); } ejemplos=CargaEjemplos(DIRECTORIO, FicheroBDEjemplos); if (ejemplos!=NULL) {

TEjemplo EjemploPrueba; //Contiene el ejemplo que se va leyendo del fichero de pruebas

TIndiceRasgos NumRasgosFichPruebas; //Nº de rasgos que lee del fichero de pruebas char *linea=new char [1000];

TIndiceEj contOK=0; TIndiceEj i; int k;

pesos = InicializaPesos(DIRECTORIO,FicheroPesos);

SolucionMasProbable = CalculaSolMasProbEntren(DIRECTORIO, FicheroProbEntren); FILE *fichero1=flhOpen(DIRECTORIO, FicheroEvaluacion, "wt"); if (fichero1==NULL)

{

errorPrintf("falta el fichero %s",FicheroEvaluacion); }

k=fprintf(fichero1,"%s\n\n","Num_Rasgos Rasgo1 ... RasgoN Soluc_Leida Soluc_Estimada Frec_SolMasProb Dist_Min Pal_leida");

if (k==EOF)

errorPrintf("error en la escritura del fichero %s",FicheroEvaluacion); FILE *fichero2=flhOpen(DIRECTORIO, FicheroPruebas, "rt");

if (fichero2==NULL) {

errorPrintf("falta el fichero %s",FicheroPruebas); }

FILE *fichero3=flhOpen(DIRECTORIO, FicheroEstadisticasEvaluacion, "wt"); if (fichero1==NULL)

{

errorPrintf("falta el fichero %s",FicheroEstadisticasEvaluacion); }

for (i=0; feof(fichero2)==0; i++) {

if (i%100==0)

printf("Llevo evaluados %ld ejemplos\n",(long)i); if (fgets(linea,1000,fichero2)!=NULL) { TIndiceRasgos j; char *token=linea; token=strtok(token," "); NumRasgosFichPruebas = atoi(token); if (NumRasgos != NumRasgosFichPruebas) {

errorPrintf("error de formato en el fichero de pruebas");

} token = NULL; for (j=0; j<NumRasgos; j++) { token=strtok(token," "); if (token==NULL) {

errorPrintf("error de formato en l'inea %d",(long)i);

}

float aux=LeeFlotante(token,i); EjemploPrueba.rasgos[j] = aux;

token=NULL; }

token=strtok(NULL," "); if (token==NULL)

{

errorPrintf("error de formato en l'inea %d",(long)i); }

EjemploPrueba.solucion = LeeSolucion(token,i); token=strtok(NULL," ");

if (token==NULL)

errorPrintf("error de formato en l'inea %d",(long)i); EjemploPrueba.frecuencia = LeeFlotante(token,i);

token=strtok(NULL,"\n"); if (token==NULL)

{

errorPrintf("error de formato en l'inea %d",(long)i); } strcpy(EjemploPrueba.comentario,token); } else { break; } SolucionEvaluada = DecisionSolucion(EjemploPrueba.rasgos); if (distMin>0 && SolucionMasProbable!=INDEFINIDO)

{

SolucionEvaluada = SolucionMasProbable; }

k=fprintf(fichero1,"%d ", (int)NumRasgos); if (k==EOF)

errorPrintf("error en la escritura del fichero %s",FicheroEvaluacion);

for (TIndiceRasgos j=0; j<NumRasgos; j++) {

k=fprintf(fichero1,"%.0f ", (float)EjemploPrueba.rasgos[j]); if (k==EOF)

errorPrintf("error en la escritura del fichero %s",FicheroEvaluacion); } if (SolucionEvaluada == EjemploPrueba.solucion) { contOK++; k=fprintf(fichero1,"%.0f _%.0f %.0f %f %s\n", (float)EjemploPrueba.solucion, (float)SolucionEvaluada, (float)frecSolucMasProbable, (float)distMin, EjemploPrueba.comentario); if (k==EOF)

errorPrintf("error en la escritura del fichero %s",FicheroEvaluacion); } else { k=fprintf(fichero1,"%.0f _%.0f %.0f %f %s_ERROR\n", (float)EjemploPrueba.solucion, (float)SolucionEvaluada, (float)frecSolucMasProbable, (float)distMin, EjemploPrueba.comentario); if (k==EOF)

errorPrintf("error en la escritura del fichero %s",FicheroEvaluacion);

}

}

k=fprintf(fichero3,"%s\n", "Estad'sticas de la evaluaci'on:"); if (k==EOF)

errorPrintf("error en la escritura del fichero %s",FicheroEstadisticasEvaluacion);

k=fprintf(fichero3," Tasa de aciertos (en%%): %f (%ld de %ld)\n",(contOK/(float)i)*100,contOK,(long)i);

if (k==EOF)

errorPrintf("error en la escritura del fichero %s",FicheroEstadisticasEvaluacion); flhClose(fichero1); flhClose(fichero2); flhClose(fichero3); delete [] linea; delete [] pesos; } delete [] ejemplos; }

C.4.2. Módulo de evaluación para tareas de tildado a partir de la