Ejemplo n.º 1
0
        /// <summary>
        /// Calcular a informação de ganho
        /// </summary>
        /// <returns></returns>
        private double CalcularGanho(double entropia, Atributo valoresClasseMeta, Atributo valoresAtributoCalculo)
        {
            double ganho = 0;
            //Lista com a soma dos (D)
            List <double> listaCalculoD = new List <double>();

            if (valoresAtributoCalculo.TipoAtributo == Tipo.Categorico)
            {
                #region Tipo diferente de número
                //Retorna os valores distintos dentro da coluna
                var valoresDistAtrCalculo = valoresAtributoCalculo.RetornaValoresDistintos();

                //Sobre cada atributo fazer cada possibilidade
                foreach (var valor in valoresDistAtrCalculo)
                {
                    //Total de casos deste valor dentro da coluna
                    float totalCasos = valoresAtributoCalculo.RetornaProporcaoCasos(valor.ToString());

                    //Retorna os diferentes valores contidos dentro da classeMeta para esse valor
                    var    casosClasseMeta = valoresAtributoCalculo.RetornaCasosOutroExemplo(valor.ToString(), valoresClasseMeta.valores);
                    double casosSomados    = 0;

                    foreach (var caso in casosClasseMeta)
                    {
                        double divisao = caso.Value / totalCasos;
                        casosSomados += divisao * (Math.Log(divisao, 2));
                    }

                    double calculoD = (totalCasos / valoresAtributoCalculo.valores.Count) * casosSomados;
                    listaCalculoD.Add(calculoD < 0 ? calculoD *= -1 : calculoD);
                }
                #endregion
            }
            else if (valoresAtributoCalculo.TipoAtributo == Tipo.Contínuo)
            {
                #region Ganho para números, realiza discretização
                double valorDiscretizado = Math.Round(valoresAtributoCalculo.Discretizar(), 2, MidpointRounding.AwayFromZero);

                //Conjunto maior
                float  totalMaior      = valoresAtributoCalculo.RetornaCasosConjunto(valorDiscretizado, true);
                var    casosClasseMeta = valoresAtributoCalculo.RetornaCasosOutroExemplo(valorDiscretizado, true, valoresClasseMeta.valores);
                double casosSomados    = 0;

                foreach (var caso in casosClasseMeta)
                {
                    float divisao = caso.Value / totalMaior;
                    casosSomados += divisao * (Math.Log(divisao, 2));
                }
                double calculoD = (totalMaior / valoresAtributoCalculo.valores.Count) * casosSomados;
                listaCalculoD.Add(calculoD < 0 ? calculoD *= -1 : calculoD);

                //Conjunto menor igual
                float totalMenorIgual = valoresAtributoCalculo.RetornaCasosConjunto(valorDiscretizado, false);
                casosClasseMeta = valoresAtributoCalculo.RetornaCasosOutroExemplo(valorDiscretizado, false, valoresClasseMeta.valores);
                casosSomados    = 0;

                foreach (var caso in casosClasseMeta)
                {
                    float divisao = caso.Value / totalMenorIgual;
                    casosSomados += divisao * (Math.Log(divisao, 2));
                }
                calculoD = (totalMenorIgual / valoresAtributoCalculo.valores.Count) * casosSomados;
                listaCalculoD.Add(calculoD < 0 ? calculoD *= -1 : calculoD);
                #endregion
            }
            else
            {
                #region Ganho para textos
                List <string> palavrasTop = new List <string>();
                foreach (var valor in valoresAtributoCalculo.RetornaValoresDistintos())
                {
                    if (!string.IsNullOrEmpty(valor.ToString()))
                    {
                        foreach (var palavra in valor.ToString().Split(','))
                        {
                            if (!string.IsNullOrEmpty(palavra) && palavrasTop.Count(p => p.Equals(palavra)) <= 0)
                            {
                                palavrasTop.Add(palavra);
                            }
                        }
                    }
                }
                palavrasTop.Add(string.Empty);

                //Sobre cada atributo fazer cada possibilidade
                foreach (var valor in palavrasTop)
                {
                    //Total de casos deste valor dentro da coluna
                    float totalCasos = valoresAtributoCalculo.RetornaProporcaoCasos(valor.ToString());

                    //Retorna os diferentes valores contidos dentro da classeMeta para esse valor
                    var casosClasseMeta = valoresAtributoCalculo.RetornaCasosOutroExemplo(valor.ToString(), valoresClasseMeta.valores);

                    double casosSomados = 0;

                    foreach (var caso in casosClasseMeta)
                    {
                        double divisao = caso.Value / totalCasos;
                        casosSomados += divisao * (Math.Log(divisao, 2));
                    }

                    double calculoD = (totalCasos / valoresAtributoCalculo.valores.Count) * casosSomados;
                    listaCalculoD.Add(calculoD < 0 ? calculoD *= -1 : calculoD);
                }
                #endregion
            }


            //Entropia - (Soma da lista do cálculo do D)
            ganho = entropia - (listaCalculoD.Sum());

            return(ganho);
        }