#! /usr/bin/env python
# -*- coding: utf-8 -*-
#
# This file is part of pandas-learn
# https://github.com/RichLewis42/pandas-learn
#
# Licensed under the MIT license:
# http://www.opensource.org/licenses/MIT
# Copyright (c) 2015, <NAME> <<EMAIL>>

"""
tests.test_adaptor.classifier
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Tests for the classifier adaptor module of pdlearn.
"""

import pytest

from ..test_utils import DATA_FRAME, SERIES, ONE_D_ARRAY, TWO_D_ARRAY
from pdlearn.utils import is_frame, is_series, CompatabilityWarning

import pdlearn.adaptor.classifier
import pdlearn.adaptor.model
import numpy as np
import pandas as pd

TARGETS = pd.DataFrame(TWO_D_ARRAY, columns=['T', 'G'])

class MockClassifier(object):

    def __init__(self, multitask=False):
        if multitask:
            self.classes_ = [np.array([0, 1]), np.array([0, 1])]
        else:
            self.classes_ = np.array([0, 1])

        self._num_tasks = 2 if multitask else 1

    def fit(self, X, y=None):
        pass

    def predict(self, X):
        if self._num_tasks == 1:
            return np.array([1] * len(X))
        else:
            return [np.array([1] * len(X))] * self._num_tasks

    def predict_proba(self, X):

        if self._num_tasks == 1:
            return np.array([[0.1, 0.9]] * len(X))
        else:
            return [np.array([[0.1, 0.9]] * len(X))] * self._num_tasks

    def predict_log_proba(self, X):
        if self._num_tasks == 1:
            return np.array([[-1, -0.04]] * len(X))
        else:
            return [np.array([[-1, -0.04]] * len(X))] * self._num_tasks


@pdlearn.adaptor.classifier
class ChildClassifier(MockClassifier):

    def __init__(self, features=None, targets=None, multitask=False):

        if targets:
            self.target_names_ = pd.Index(targets)
            multitask = multitask or len(self.target_names_) > 1
        if features:
            self.feature_names_ = pd.Index(features)

        super(ChildClassifier, self).__init__(multitask)

class TestClassifier(object):

    """ Tests for pdlearn.adaptor.classifier """

    def test_not_multitask(self):

        assert not ChildClassifier(targets=['a']).multitask_

    def test_multitask(self):

        assert ChildClassifier(targets=['a', 'b']).multitask_


    def test_fit_with_arr(self):

        child = ChildClassifier().fit(TWO_D_ARRAY)
        assert not child.pandas_mode_

        child.fit(TWO_D_ARRAY, ONE_D_ARRAY)
        assert not child.pandas_mode_

    def test_with_hybrid(self):

        child = ChildClassifier().fit(TWO_D_ARRAY, SERIES)
        assert child.pandas_mode_
        assert np.array_equal(child.target_names_, ['T'])

        child.fit(DATA_FRAME, ONE_D_ARRAY)
        assert child.pandas_mode_
        assert np.array_equal(child.feature_names_, ['x', 'y'])

    def test_fit_with_df(self):

        child = ChildClassifier().fit(DATA_FRAME)
        assert child.pandas_mode_
        assert np.array_equal(child.feature_names_, ['x', 'y'])

    def test_fit_with_df_ser(self):

        child = ChildClassifier().fit(DATA_FRAME, SERIES)
        assert child.pandas_mode_
        assert np.array_equal(child.feature_names_, ['x', 'y'])
        assert np.array_equal(child.target_names_, ['T'])

    def test_fit_multitarget(self):

        child = ChildClassifier().fit(DATA_FRAME, TARGETS)
        assert child.pandas_mode_
        assert np.array_equal(child.feature_names_, ['x', 'y'])
        assert np.array_equal(child.target_names_, ['T', 'G'])

    def test_predict(self):

        res = ChildClassifier().predict(TWO_D_ARRAY)
        assert isinstance(res, np.ndarray)
        assert np.array_equal(res, [1, 1])

    def test_predict_arr_pdmode(self):

        c = ChildClassifier(features=['x', 'y'], targets=['a'])

        with pytest.warns(CompatabilityWarning):
            res = c.predict(TWO_D_ARRAY)

        assert is_series(res)
        assert np.array_equal(res.index, range(len(TWO_D_ARRAY)))
        assert res.name == 'a'

    def test_predict_df(self):

        c = ChildClassifier(features=['x', 'y'], targets=['c'])

        res = c.predict(DATA_FRAME)
        assert is_series(res)
        assert np.array_equal(res.index, DATA_FRAME.index)
        assert res.name == 'c'

    def test_predict_df_multitask(self):

        c = ChildClassifier(features=['x', 'y'], targets=['c', 'd'])

        res = c.predict(DATA_FRAME)
        assert is_frame(res)
        assert np.array_equal(res.columns, ['c', 'd'])
        assert np.array_equal(res.index, DATA_FRAME.index)

    def test_predict_proba_arr(self):

        c = ChildClassifier()
        res = c.predict(TWO_D_ARRAY)
        assert isinstance(res, np.ndarray)

    def test_predict_proba_arr_pdmode(self):

        c = ChildClassifier(features=['x', 'y'], targets=['c'])

        with pytest.warns(CompatabilityWarning):
            res = c.predict_proba(TWO_D_ARRAY)
        assert is_frame(res)
        assert np.array_equal(res.index, range(len(TWO_D_ARRAY)))
        assert isinstance(res.columns, pd.MultiIndex)
        assert np.array_equal(res.columns.get_level_values(0), ['c', 'c'])
        assert np.array_equal(res.columns.get_level_values(1), [0, 1])

    def test_predict_proba_df(self):

        c = ChildClassifier(features=['x', 'y'], targets=['c'])
        res = c.predict_proba(DATA_FRAME)
        assert is_frame(res)
        assert np.array_equal(res.index, DATA_FRAME.index)
        assert isinstance(res.columns, pd.MultiIndex)
        assert np.array_equal(res.columns.get_level_values(0), ['c', 'c'])
        assert np.array_equal(res.columns.get_level_values(1), [0, 1])

    def test_predict_proba_multitask(self):

        c = ChildClassifier(features=['x', 'y'], targets=['c', 'd'])
        res = c.predict_proba(DATA_FRAME)
        assert np.array_equal(res.index, DATA_FRAME.index)
        assert isinstance(res.columns, pd.MultiIndex)
        assert np.array_equal(res.columns.get_level_values(0), ['c', 'c', 'd', 'd'])
        assert np.array_equal(res.columns.get_level_values(1), [0, 1, 0, 1])

    def test_predict_log_proba_arr(self):

        res = ChildClassifier().predict_log_proba(TWO_D_ARRAY)
        assert isinstance(res, np.ndarray)

    def test_predict_log_proba_arr_pdmode(self):

        c = ChildClassifier(features=['x', 'y'], targets=['c'])
        with pytest.warns(CompatabilityWarning):
            res = c.predict_log_proba(TWO_D_ARRAY)
        assert is_frame(res)
        assert np.array_equal(res.index, range(len(TWO_D_ARRAY)))
        assert isinstance(res.columns, pd.MultiIndex)
        assert np.array_equal(res.columns.get_level_values(0), ['c', 'c'])
        assert np.array_equal(res.columns.get_level_values(1), [0, 1])

    def test_predict_log_proba_df(self):

        c = ChildClassifier(features=['x', 'y'], targets=['c'])
        res = c.predict_log_proba(DATA_FRAME)
        assert is_frame(res)
        assert np.array_equal(res.index, DATA_FRAME.index)
        assert isinstance(res.columns, pd.MultiIndex)
        assert np.array_equal(res.columns.get_level_values(0), ['c', 'c'])
        assert np.array_equal(res.columns.get_level_values(1), [0, 1])

    def test_predict_log_proba_multitask(self):

        c = ChildClassifier(features=['x', 'y'], targets=['c', 'd'])
        res = c.predict_log_proba(DATA_FRAME)
        assert np.array_equal(res.index, DATA_FRAME.index)
        assert isinstance(res.columns, pd.MultiIndex)
        assert np.array_equal(res.columns.get_level_values(0), ['c', 'c', 'd', 'd'])
        assert np.array_equal(res.columns.get_level_values(1), [0, 1, 0, 1])

#! /usr/bin/env python
# -*- coding: utf-8 -*-
#
# This file is part of pandas-learn
# https://github.com/RichLewis42/pandas-learn
#
# Licensed under the MIT license:
# http://www.opensource.org/licenses/MIT
# Copyright (c) 2015, <NAME> <<EMAIL>>

"""
tests.test_adaptor.classifier
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Tests for the classifier adaptor module of pdlearn.
"""

import pytest

from ..test_utils import DATA_FRAME, SERIES, ONE_D_ARRAY, TWO_D_ARRAY
from pdlearn.utils import is_frame, is_series, CompatabilityWarning

import pdlearn.adaptor.classifier
import pdlearn.adaptor.model
import numpy as np
import pandas as pd

TARGETS = pd.DataFrame(TWO_D_ARRAY, columns=['T', 'G'])

class MockClassifier(object):

    def __init__(self, multitask=False):
        if multitask:
            self.classes_ = [np.array([0, 1]), np.array([0, 1])]
        else:
            self.classes_ = np.array([0, 1])

        self._num_tasks = 2 if multitask else 1

    def fit(self, X, y=None):
        pass

    def predict(self, X):
        if self._num_tasks == 1:
            return np.array([1] * len(X))
        else:
            return [np.array([1] * len(X))] * self._num_tasks

    def predict_proba(self, X):

        if self._num_tasks == 1:
            return np.array([[0.1, 0.9]] * len(X))
        else:
            return [np.array([[0.1, 0.9]] * len(X))] * self._num_tasks

    def predict_log_proba(self, X):
        if self._num_tasks == 1:
            return np.array([[-1, -0.04]] * len(X))
        else:
            return [np.array([[-1, -0.04]] * len(X))] * self._num_tasks


@pdlearn.adaptor.classifier
class ChildClassifier(MockClassifier):

    def __init__(self, features=None, targets=None, multitask=False):

        if targets:
            self.target_names_ = pd.Index(targets)
            multitask = multitask or len(self.target_names_) > 1
        if features:
            self.feature_names_ = pd.Index(features)

        super(ChildClassifier, self).__init__(multitask)

class TestClassifier(object):

    """ Tests for pdlearn.adaptor.classifier """

    def test_not_multitask(self):

        assert not ChildClassifier(targets=['a']).multitask_

    def test_multitask(self):

        assert ChildClassifier(targets=['a', 'b']).multitask_


    def test_fit_with_arr(self):

        child = ChildClassifier().fit(TWO_D_ARRAY)
        assert not child.pandas_mode_

        child.fit(TWO_D_ARRAY, ONE_D_ARRAY)
        assert not child.pandas_mode_

    def test_with_hybrid(self):

        child = ChildClassifier().fit(TWO_D_ARRAY, SERIES)
        assert child.pandas_mode_
        assert np.array_equal(child.target_names_, ['T'])

        child.fit(DATA_FRAME, ONE_D_ARRAY)
        assert child.pandas_mode_
        assert np.array_equal(child.feature_names_, ['x', 'y'])

    def test_fit_with_df(self):

        child = ChildClassifier().fit(DATA_FRAME)
        assert child.pandas_mode_
        assert np.array_equal(child.feature_names_, ['x', 'y'])

    def test_fit_with_df_ser(self):

        child = ChildClassifier().fit(DATA_FRAME, SERIES)
        assert child.pandas_mode_
        assert np.array_equal(child.feature_names_, ['x', 'y'])
        assert np.array_equal(child.target_names_, ['T'])

    def test_fit_multitarget(self):

        child = ChildClassifier().fit(DATA_FRAME, TARGETS)
        assert child.pandas_mode_
        assert np.array_equal(child.feature_names_, ['x', 'y'])
        assert np.array_equal(child.target_names_, ['T', 'G'])

    def test_predict(self):

        res = ChildClassifier().predict(TWO_D_ARRAY)
        assert isinstance(res, np.ndarray)
        assert np.array_equal(res, [1, 1])

    def test_predict_arr_pdmode(self):

        c = ChildClassifier(features=['x', 'y'], targets=['a'])

        with pytest.warns(CompatabilityWarning):
            res = c.predict(TWO_D_ARRAY)

        assert is_series(res)
        assert np.array_equal(res.index, range(len(TWO_D_ARRAY)))
        assert res.name == 'a'

    def test_predict_df(self):

        c = ChildClassifier(features=['x', 'y'], targets=['c'])

        res = c.predict(DATA_FRAME)
        assert is_series(res)
        assert np.array_equal(res.index, DATA_FRAME.index)
        assert res.name == 'c'

    def test_predict_df_multitask(self):

        c = ChildClassifier(features=['x', 'y'], targets=['c', 'd'])

        res = c.predict(DATA_FRAME)
        assert is_frame(res)
        assert np.array_equal(res.columns, ['c', 'd'])
        assert np.array_equal(res.index, DATA_FRAME.index)

    def test_predict_proba_arr(self):

        c = ChildClassifier()
        res = c.predict(TWO_D_ARRAY)
        assert isinstance(res, np.ndarray)

    def test_predict_proba_arr_pdmode(self):

        c = ChildClassifier(features=['x', 'y'], targets=['c'])

        with pytest.warns(CompatabilityWarning):
            res = c.predict_proba(TWO_D_ARRAY)
        assert is_frame(res)
        assert np.array_equal(res.index, range(len(TWO_D_ARRAY)))
        assert isinstance(res.columns, pd.MultiIndex)
        assert np.array_equal(res.columns.get_level_values(0), ['c', 'c'])
        assert np.array_equal(res.columns.get_level_values(1), [0, 1])

    def test_predict_proba_df(self):

        c = ChildClassifier(features=['x', 'y'], targets=['c'])
        res = c.predict_proba(DATA_FRAME)
        assert is_frame(res)
        assert np.array_equal(res.index, DATA_FRAME.index)
        assert isinstance(res.columns, pd.MultiIndex)
        assert np.array_equal(res.columns.get_level_values(0), ['c', 'c'])
        assert np.array_equal(res.columns.get_level_values(1), [0, 1])

    def test_predict_proba_multitask(self):

        c = ChildClassifier(features=['x', 'y'], targets=['c', 'd'])
        res = c.predict_proba(DATA_FRAME)
        assert np.array_equal(res.index, DATA_FRAME.index)
        assert isinstance(res.columns, pd.MultiIndex)
        assert np.array_equal(res.columns.get_level_values(0), ['c', 'c', 'd', 'd'])
        assert np.array_equal(res.columns.get_level_values(1), [0, 1, 0, 1])

    def test_predict_log_proba_arr(self):

        res = ChildClassifier().predict_log_proba(TWO_D_ARRAY)
        assert isinstance(res, np.ndarray)

    def test_predict_log_proba_arr_pdmode(self):

        c = ChildClassifier(features=['x', 'y'], targets=['c'])
        with pytest.warns(CompatabilityWarning):
            res = c.predict_log_proba(TWO_D_ARRAY)
        assert is_frame(res)
        assert np.array_equal(res.index, range(len(TWO_D_ARRAY)))
        assert isinstance(res.columns, pd.MultiIndex)
        assert np.array_equal(res.columns.get_level_values(0), ['c', 'c'])
        assert np.array_equal(res.columns.get_level_values(1), [0, 1])

    def test_predict_log_proba_df(self):

        c = ChildClassifier(features=['x', 'y'], targets=['c'])
        res = c.predict_log_proba(DATA_FRAME)
        assert is_frame(res)
        assert np.array_equal(res.index, DATA_FRAME.index)
        assert isinstance(res.columns, pd.MultiIndex)
        assert np.array_equal(res.columns.get_level_values(0), ['c', 'c'])
        assert np.array_equal(res.columns.get_level_values(1), [0, 1])

    def test_predict_log_proba_multitask(self):

        c = ChildClassifier(features=['x', 'y'], targets=['c', 'd'])
        res = c.predict_log_proba(DATA_FRAME)
        assert np.array_equal(res.index, DATA_FRAME.index)
        assert isinstance(res.columns, pd.MultiIndex)
        assert np.array_equal(res.columns.get_level_values(0), ['c', 'c', 'd', 'd'])
        assert np.array_equal(res.columns.get_level_values(1), [0, 1, 0, 1])

#! /usr/bin/env python # -*- coding: utf-8 -*- # # This file is part of pandas-learn # https://github.com/RichLewis42/pandas-learn # # Licensed under the MIT license: # http://www.opensource.org/licenses/MIT # Copyright (c) 2015, <NAME> <<EMAIL>> tests.test_adaptor.classifier ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~  Tests for the classifier adaptor module of pdlearn. Tests for pdlearn.adaptor.classifier