public Regla(Regla cpy) { predicado = cpy.predicado; precondiciones = new List<Literal>(cpy.precondiciones.Select(x => x.Clone())); }
private bool cubre(Regla nuevaRegla, Literal faltaAceptar) { Dictionary<string, List<string> > valores_vars = new Dictionary<string, List<string> >(); for(int i = 0; i<nuevaRegla.Predicado.nAtt; i++) { valores_vars.Add(nuevaRegla.Predicado.Atributos[i], new List<string> { faltaAceptar.Atributos[i] }); } foreach( var condicion in nuevaRegla.Precondiciones) { if (!cubre(condicion, valores_vars)) return false; } return true; }
private double ganancia(Literal candidato, Regla nuevaRegla, float p0, float n0) { /* * p0 = numero de ej+ cubiertos por R * n0 = numero de ej- cubiertos por R * p1 = numero de ej+ cubiertos por R' * n1 = numero de ej- cubiertos por R' * t = numero ej+ cuebiertos en R tb cubiertos en R' * */ Regla reglaConCandidato = new Regla(nuevaRegla); reglaConCandidato.Precondiciones = new List<Literal> { candidato }; float p1 = (from positivo in conocimientoPos where cubre(reglaConCandidato, positivo) select positivo).Count(), n1 = (from negativo in conocimientoNeg where cubre(reglaConCandidato, negativo) select negativo).Count(), t = (from positivo in conocimientoPos where cubre(nuevaRegla, positivo) && cubre(reglaConCandidato, positivo) select positivo).Count(); if (t == 0) return 0; else return t*( Math.Log(p1/(p1+n1)) - Math.Log(p0 / (p0 + n0)) ); }
public List<Regla> Foil(bool recursive) { List<Regla> reglasAprendidas = new List<Regla>(); bool añadir = recursive; while( conocimientoPos.Any() ) { int nAtt_objetivo = conocimientoPos[0].nAtt; Literal pred_objetivo = new Literal(objetivo, nAtt_objetivo); int ultima_var = nAtt_objetivo; string[] atributos = new string[nAtt_objetivo]; HashSet<string> usados = new HashSet<string>(); for (int i = 0; i < nAtt_objetivo; i++) { atributos[i] = ""+i; usados.Add(""+i); } pred_objetivo.Atributos = atributos; Regla nuevaRegla = new Regla(pred_objetivo); List<Literal> negativosAceptados = conocimientoNeg; while( negativosAceptados.Any() ) { List<Literal> candidatos = generarCandidatos(predicados, usados); float p0 = (from positivo in conocimientoPos where cubre(nuevaRegla, positivo) select positivo).Count(), n0 = (from negativo in conocimientoNeg where cubre(nuevaRegla, negativo) select negativo).Count(); double mejorGanancia = ganancia(candidatos[0], nuevaRegla, p0, n0); Literal mejorLiteral = candidatos[0]; candidatos.RemoveAt(0); foreach(var candidato in candidatos) { double gan = ganancia(candidato, nuevaRegla, p0, n0); Console.WriteLine(candidato + " -> " + gan); if(gan > mejorGanancia) { mejorGanancia = gan; mejorLiteral = candidato; } } nuevaRegla.Precondiciones = new List<Literal> { mejorLiteral }; foreach( var variable in mejorLiteral.Atributos ) { usados.Add(variable); } negativosAceptados = (from aceptados in negativosAceptados where cubre(nuevaRegla, aceptados) select aceptados).ToList(); if (añadir) { predicados.Add(new Literal(objetivo, conocimientoPos[0].nAtt)); añadir = false; } } reglasAprendidas.Add(nuevaRegla); conocimientoPos = (from faltaAceptar in conocimientoPos where !cubre(nuevaRegla, faltaAceptar) select faltaAceptar).ToList(); Console.WriteLine(nuevaRegla + "\n \t\t -> faltan = " + conocimientoPos.Count()); predicados.RemoveWhere(T => T.Nombre == objetivo); añadir = recursive; } return reglasAprendidas; }