Exemplo n.º 1
0
    def test_predict_distance_weighted_knn(self):
        ds = DataSet()
        ds.load_from_arff('./../../datasets/simple_distance_example.arff')
        target_attribute = 'PlayTennis'
        X = ds.pandas_df.drop(columns=target_attribute)
        y = ds.pandas_df[target_attribute]

        instance = pd.Series({
            'humidity': 75,
            'age': 30,
            'temperature': 30,
        })

        classifier = KNNClassifier(1, distance_weighted=True)
        classifier.fit(X, y)
        assert classifier.predict(instance) == 'YES'

        # por mas de que se tienen 2 NO y 1 YES, el YES es mas cercano
        classifier = KNNClassifier(3, distance_weighted=True)
        classifier.fit(X, y)
        assert classifier.predict(instance) == 'YES'

        # por mas de que se tienen 4 YES y 3 NO, los NO son mas cercanos y por tanto pesan mas
        classifier = KNNClassifier(7, distance_weighted=True)
        classifier.fit(X, y)
        assert classifier.predict(instance) == 'NO'
Exemplo n.º 2
0
    def test_predictions(self):
        """
        Para todos los ejemplos de entrenamiento se debe cumplir que el valor predecido coincida con el valor dado
        """
        ds = DataSet()
        ds.load_from_arff('../../datasets/tom_mitchell_example.arff')

        target_attribute = 'PlayTennis'

        # noinspection PyTypeChecker
        classifier = Classifier(select_attribute, target_attribute)
        classifier.fit(ds)

        for i in range(ds.pandas_df.shape[0]):
            instance = ds.pandas_df.loc[i]
            v = classifier.predict(instance)
            if instance[target_attribute] == 'YES':
                self.assertTrue(
                    v,
                    f'Para la instancia {i+1}, el valor predecido no coincide con el valor conocido'
                )
            else:
                self.assertFalse(
                    v,
                    f'Para la instancia {i+1}, el valor predecido no coincide con el valor conocido'
                )
Exemplo n.º 3
0
    def test_id3_structure(self):
        ds = DataSet()
        ds.load_from_arff('../../datasets/tom_mitchell_example.arff')

        expected_tree_structure = load_expected_tree_structure()
        built_tree = id3(examples=ds, select_attribute=select_attribute, target_attribute='PlayTennis')

        assert equal_tree_structure(built_tree, expected_tree_structure)
Exemplo n.º 4
0
def k_fold_cross_validation(ds: DataSet, target_attribute: str, k: int,
                            fn_on_empty_value: callable,
                            fn_on_continues_values: callable):

    # Se parte al conjunto original en k subconjuntos Ti
    # Se entrena k veces, utilizando a un Ti para validar y a la unión del resto para entrenar
    # Se toma el promedio de los errores de las k iteraciones.

    # Validación cruzada de tamaño k.
    #     Partimos el conjunto de datos D en T1,...,Tk de igual tamaño
    #     Para i=1 hasta k
    #       Ei = D - Ti
    #       hi = L(Ei)
    #       δi = error(hi, Ti)
    # δ = (1/k)Σδi

    union_ti = pd.DataFrame()
    n = round(ds.pandas_df.__len__() / k)
    errors = [0 for i in range(k)]

    for i in range(k):

        diff_df_union_ti = ds.pandas_df.loc[
            ~ds.pandas_df.index.isin(union_ti.index), :]

        test_df = diff_df_union_ti.sample(n=min(n, len(diff_df_union_ti)))
        union_ti = pd.concat([union_ti, test_df])

        train_df = ds.pandas_df.loc[~ds.pandas_df.index.isin(test_df.index), :]

        train = DataSet()
        train.load_from_pandas_df(train_df, ds.attribute_info,
                                  ds.attribute_list)

        # noinspection PyTypeChecker
        classifier = Classifier(fn_on_continues_values, target_attribute,
                                fn_on_empty_value)
        classifier.fit(train)

        logging.info(f'Arbol iteracion k = {i}')
        logging.info(RenderTree(classifier._decision_tree))

        errors[i] = get_error(test_df, classifier, target_attribute, k)

        Error = 0
        for i in range(k):
            Error = Error + errors[i]

    logging.info(f'Errores obtenidoes en iteracion k = {i}, Errores: {errors}')

    Error = (1 / k) * Error
    logging.info(f'Error total (1/k)*Error : {Error}')
    return Error
Exemplo n.º 5
0
    def predict(self, X: Union[DataFrame, Series]) -> Union[Series, Any]:
        """
        Predict y value for a set of instances

        :param X: set of instances which y value wants to be predicted (use pandas Series for individual instances)
        :return: returns the list of predicted values for each instance in X (if X is just an individual instance it just
         returns its predicted value)
        """
        try:
            getattr(self, "X_")
            (X_train_aux, target_attribute) = _generate_train_set(self.X_, self.y_, self.target_attribute)
            # noinspection PyPep8Naming
            X_train: DataSet = DataSet()
            X_train.load_from_pandas_df(X_train_aux, self.attribute_info, self.attribute_list)
        except AttributeError:
            raise RuntimeError("You must train classifier before predicting data!")

        # X is a set
        if X.__class__ == DataFrame:
            y = X.apply(lambda row: naive_bayes_classifier(X_train, row, self.target_attribute), axis=1)

        # X is an instance
        else:
            y = naive_bayes_classifier(X_train, X, self.target_attribute)

        return y
Exemplo n.º 6
0
def select_attribute(examples: DataSet, target_attribute: str,
                     node: Node) -> StrategyResult:
    """
    Implementa una estrategia de seleccion de atributos basada en el calculo de ganancia segun entropia.
    No soporta atributos que tomen valores nulos.

    :param node: es el nodo para el cual se quiere seleccionar el atributo
    :param examples: conjunto de ejemplos de entrenamiento que se tienen al momento
    :param target_attribute: el atributo que se quiere predecir
    :return: devuelve el atributo seleccionado
    """

    gain_max = -1
    for a in [a for a in examples.attribute_list if a != target_attribute]:
        if examples.is_continuous_attribute(a):
            partitions = _split_continuous_values(examples, a,
                                                  target_attribute)
        else:
            partitions = _split_discrete_values(examples, a)
        g = _gain(examples.pandas_df,
                  [p.filter(examples).pandas_df for p in partitions],
                  target_attribute)
        if g > gain_max:
            gain_max = g
            result = StrategyResult(a, partitions)

    # noinspection PyUnboundLocalVariable
    return result
Exemplo n.º 7
0
def get_train_test():

    #Separa 1/5 , 4/5

    ds = DataSet()
    ds.load_from_arff('../../datasets/Autism-Adult-Data.arff')
    # Fixed by https: // eva.fing.edu.uy / mod / forum / discuss.php?d = 117656
    ds.remove_attribute('result')

    train_pandas_df = ds.pandas_df.sample(frac=0.8)
    test_pandas_df = ds.pandas_df.loc[~ds.pandas_df.index.isin(train_pandas_df.index), :]

    train = DataSet()
    train.load_from_pandas_df(train_pandas_df, ds.attribute_info, ds.attribute_list)

    return (train, test_pandas_df)
Exemplo n.º 8
0
 def filter(self, ds: DataSet):
     ds_new = ds.copy()
     ds_new.pandas_df = ds_new.pandas_df[operator.and_(
         self._op1(self._lower_bound, ds_new.pandas_df[self.attribute]),
         self._op2(ds_new.pandas_df[self.attribute], self._upper_bound)
     )]
     return ds_new
Exemplo n.º 9
0
def m_estimate(ds: DataSet, a:str, a_value, target_attribute: str, target_attribute_value: str):

    attributes_info = ds.attribute_info
    df = ds.pandas_df

    if ds.is_continuous_attribute(a):
        # Cuando se trabaja con valores continuos el algoritmo supone que los valores de los atributos estan normalmente
        # distribuidos y a partir del set de entrenamiento simplemente se calcula la media y la desviacion estandar de los valores
        # condicionados de los atributos para obtener la probablidiad
        df_a = df[df[target_attribute] == target_attribute_value]
        mu = np.mean(df_a[a])
        sigma = np.std(df_a[a])
        n = norm(mu, sigma)
        return n.pdf(a_value)

    # m-estimador:
    #   (e + m.p)/(n + m)
    # p es la estimación a priori de la probabilidad buscada y m es el “tamaño equivalente de muestra”.
    # Un método típico para elegir p en ausencia de otra información es asumir prioridades uniformes;
    # es decir, si un atributo tiene k valores posibles, establecemos p = i/k.

    n = df[df[target_attribute] == target_attribute_value].shape[0]
    df_a = df[df[a] == a_value]
    e = df_a[df_a[target_attribute] == target_attribute_value].shape[0]
    p = 1 / len (attributes_info[a].domain)

    if n == 0 or e == 0:
        m = 3
    else:
        m = 0

    return (e + m * p) / (n + m)
Exemplo n.º 10
0
    def test_data_clase(self):

        target_attribute = 'Juega'

        ds: DataSet = DataSet()
        ds.load_from_arff('../../datasets/dataset_clase.arff')
        # noinspection PyPep8Naming
        X: DataFrame = ds.pandas_df.drop(columns=target_attribute)
        y = ds.pandas_df[target_attribute]

        classifier = NBClassifier(target_attribute, ds.attribute_info,
                                  ds.attribute_list)
        classifier.fit(X, y)
        predict_df(ds.pandas_df, target_attribute, classifier)

        preprocessor = DataSetPreprocessor(ds, target_attribute)
        df = preprocessor.transform_to_rn()
        # noinspection PyPep8Naming
        X: DataFrame = df.drop(columns=target_attribute)
        y = df[target_attribute]

        classifier = KNNClassifier(1)
        classifier.fit(X, y)
        predict_df(df, target_attribute, classifier)

        classifier = KNNClassifier(3)
        classifier.fit(X, y)
        predict_df(df, target_attribute, classifier)

        classifier = KNNClassifier(7)
        classifier.fit(X, y)
        predict_df(df, target_attribute, classifier)
Exemplo n.º 11
0
    def test_data_clase(self):
        ej1 = {
            "Ded": "Media",
            "Dif": "Alta",
            "Hor": "Nocturno",
            "Hum": "Alta",
            "Hdoc": "Malo"
        }
        ej2 = {
            "Ded": "Baja",
            "Dif": "Alta",
            "Hor": "Matutino",
            "Hum": "Alta",
            "Hdoc": "Bueno"
        }

        target_attribute = 'Salva'

        ds = DataSet()
        ds.load_from_arff('../../datasets/dataset_clase.arff')
        classifier = Classifier(select_attribute, target_attribute)
        classifier.fit(ds)

        print(RenderTree(classifier._decision_tree))

        print(f'Predict {ej1}: {classifier.predict(ej1)}')
        print(f'Predict {ej2}: {classifier.predict(ej2)}')

        for i in range(ds.pandas_df.shape[0]):
            instance = ds.pandas_df.loc[i]
            v = classifier.predict(instance)
            if instance[target_attribute] == 'YES':
                self.assertTrue(
                    v,
                    f'Para la instancia {i+1}, el valor predecido no coincide con el valor conocido'
                )
            else:
                self.assertFalse(
                    v,
                    f'Para la instancia {i+1}, el valor predecido no coincide con el valor conocido'
                )
Exemplo n.º 12
0
    def test_data_Autism_Adult(self):
        ds = DataSet()
        ds.load_from_arff('../../datasets/Autism-Adult-Data.arff')
        # Fixed by https: // eva.fing.edu.uy / mod / forum / discuss.php?d = 117656
        ds.remove_attribute('result')
        target_attribute = 'Class/ASD'

        classifier = Classifier(select_attribute, target_attribute,
                                get_value_attribute_1)
        classifier.fit(ds)

        print(RenderTree(classifier._decision_tree))

        for i in range(ds.pandas_df.shape[0]):
            instance = ds.pandas_df.loc[i]
            v = classifier.predict(instance)
            if instance[target_attribute] == 'YES':
                self.assertTrue(
                    v,
                    f'Para la instancia {i+1}, el valor predecido no coincide con el valor conocido'
                )
            else:
                self.assertFalse(
                    v,
                    f'Para la instancia {i+1}, el valor predecido no coincide con el valor conocido'
                )
Exemplo n.º 13
0
def select_attribute(examples: DataSet, target_attribute: str, node: Node) -> StrategyResult:
    """
    Implementa una estrategia de seleccion de atributos basada en el calculo de ganancia segun entropia.
    No soporta atributos que tomen valores nulos.

    :param node: es el nodo para el cual se quiere seleccionar el atributo
    :param examples: conjunto de ejemplos de entrenamiento que se tienen al momento
    :param target_attribute: el atributo que se quiere predecir
    :return: devuelve el atributo seleccionado
    """

    # si no es el nodo raiz obtengo la entropia del conjunto actual guardada en el nodo padre (al final de
    # este metodo en donde se guardan las entropias) (parte de codigo inutilizada)
    #if hasattr(node, 'parent') and hasattr(node.parent, 'entropies'):
        # noinspection PyUnresolvedReferences
    #    branch_value = node.root_value.decode('utf-8')
    #    s_entropy = node.parent.entropies[branch_value]
    #else:
    #    s_entropy = None

    # busco el atributo que de mayor ganancia
    gain_max = -1
    for a in [a for a in examples.attribute_list if a != target_attribute]:
        if examples.is_continuous_attribute(a):
            (c, g, e_s_under_c, e_s_above_c) = get_discrete_values_from_continuous_values(examples, a, target_attribute)
            if g > gain_max:
                gain_max = g
                best_attribute = a
                best_attribute_is_continuous = True
                entropies = {
                    f'< {c}': e_s_under_c,
                    f'>= {c}': e_s_above_c
                }
        else:
            (g, entropies_aux) = gain(examples, a, target_attribute)
            if g > gain_max:
                gain_max = g
                best_attribute = a
                best_attribute_is_continuous = False
                entropies = entropies_aux

    # guardo las entropias obtenidas para las ramas futuras en el nodo actual
    # noinspection PyUnboundLocalVariable
    node.entropies = entropies

    # noinspection PyUnboundLocalVariable
    if best_attribute_is_continuous:
        # noinspection PyUnboundLocalVariable
        return result_for_continuos_attribute(best_attribute, c)
    else:
        # noinspection PyUnboundLocalVariable
        return result_for_discrete_attribute(examples, best_attribute)
Exemplo n.º 14
0
    def test_predict_knn(self):
        ds = DataSet()
        ds.load_from_arff('./../../datasets/simple_distance_example.arff')
        target_attribute = 'PlayTennis'
        X = ds.pandas_df.drop(columns=target_attribute)
        y = ds.pandas_df[target_attribute]

        instance = pd.Series({
            'humidity': 75,
            'age': 30,
            'temperature': 30,
        })

        classifier = KNNClassifier(1)
        classifier.fit(X, y)
        assert classifier.predict(instance) == 'YES'

        classifier = KNNClassifier(3)
        classifier.fit(X, y)
        assert classifier.predict(instance) == 'NO'

        classifier = KNNClassifier(7)
        classifier.fit(X, y)
        assert classifier.predict(instance) == 'YES'
Exemplo n.º 15
0
    def test_basic(self):
        """
        En el conjunto de entrenamiento la clasificacion debe ser perfecta (para una instancias x,
        la instancia  que mas se acerca es si misma)
        """
        ds: DataSet = DataSet()
        ds.load_from_arff('./../../datasets/Autism-Adult-Training-Subset.arff')
        target_attribute = 'Class/ASD'
        preprocessor = DataSetPreprocessor(ds, target_attribute)
        df = preprocessor.transform_to_rn()
        X: DataFrame = df.drop(columns=target_attribute)
        y = df[target_attribute]

        classifier = KNNClassifier(1)
        classifier.fit(X, y)

        for i in range(len(df)):
            self.assertEqual(classifier.predict(X.loc[i]),
                             y.loc[i],
                             f'El valor predecido para la instancia {i} no coincide su valor en el dataset')
Exemplo n.º 16
0
    def __init__(self, ds: DataSet, target_attribute: str):
        """
        Constructor

        :param ds: DataSet que se quiere transformar
        :param target_attribute: atributo objetivo
        """
        self._ds = ds
        self._target_attribute = target_attribute
        self._attribute_info = {}

        for a in ds.attribute_list:

            if ds.is_continuous_attribute(a):

                self._attribute_info[a] = {}

                # se calcula una aproximacion a la esperanza (mu) de los valores tomados por las instancias en 'a'
                self._attribute_info[a]['mu'] = np.mean(ds.pandas_df[a])

                # se calcula una aproximacion a la varianza (sigma) de los valores tomados por las instancias en 'a'
                self._attribute_info[a]['sigma'] = np.std(ds.pandas_df[a])
Exemplo n.º 17
0
 def filter(self, ds: DataSet):
     ds_new = ds.copy()
     ds_new.pandas_df = ds_new.pandas_df[ds_new.pandas_df[self.attribute] == self._value]
     return ds_new
Exemplo n.º 18
0
 def filter(self, ds: DataSet):
     ds_new = ds.copy()
     ds_new.pandas_df = ds_new.pandas_df[self._operator(ds_new.pandas_df[self.attribute], self._value)]
     return ds_new
Exemplo n.º 19
0
    def test2(self):

        training_ds = DataSet ()
        training_ds.load_from_arff ('../../datasets/Autism-Adult-Training-Subset.arff')

        test_ds = DataSet ()
        test_ds.load_from_arff ('../../datasets/Autism-Adult-Test-Subset.arff')

        training_df = training_ds.pandas_df
        test_pandas_df = test_ds.pandas_df

        n = 2
        k_for_k_fold = 10
        target_attribute = 'Class/ASD'
        accuracies = []
        recall = []
        classifier = Classifier(entropy.select_attribute, target_attribute, get_value_attribute_1)

        table_kfold = []
        table = []
        for i in range (n):

            kf = KFold (n_splits=k_for_k_fold, do_shuffle=True)
            indexes = kf.split (training_df)

            for test_indexes, training_indexes in indexes:
                df_test = training_df.iloc[test_indexes]
                df_train = training_df.iloc[training_indexes]

                ds_df_train = DataSet()
                ds_df_train.load_from_pandas_df(df_train, training_ds.attribute_info, training_ds.attribute_list)

                classifier.fit(ds_df_train)
                y_predicted = df_test.apply (lambda row: classifier.predict (row), axis=1)
                y_true = df_test[target_attribute]

                accuracies.append (accuracy_score (y_predicted, y_true))
                recall.append(recall_score(y_predicted, y_true))

            # Presentacion de resultados
            x = [i + 1 for i in range (k_for_k_fold)]
            for i in range (k_for_k_fold):
                table_kfold.append ([x[i], accuracies[i], recall[i]])

            classifier.fit(training_ds)
            y_predicted = test_pandas_df.apply (lambda row: classifier.predict (row), axis=1)
            y_true = test_pandas_df[target_attribute]

            table.append([i, accuracy_score (y_predicted, y_true), recall_score(y_predicted, y_true)])


        print ("K fold validation :\n")
        print (tabulate (table_kfold, headers=["#", "Accuracy", "Recall"]))
        print ()
        print ("T=1/5 S=4/5 :\n")
        print (tabulate (table, headers=["#", "Accuracy", "Recall"]))

        plt.figure (figsize=(10, 10))
        plt.ylabel ('Accuracy/Recall')
        plt.axis ([0, (n * k_for_k_fold) - 1, 0, 1])
        plt.grid (True)

        plt.plot (accuracies, color='r', label='NB Accuracies')
        plt.plot (recall, color='g', label='NB Recall')

        plt.legend (loc=0)
        plt.show ()