Esempio n. 1
0
    def test_tcp_classification_svm(self):
        # -----------------------------------------------------------------------------
        # Setup training, calibration and test indices
        # -----------------------------------------------------------------------------
        data = load_iris()

        idx = np.random.permutation(data.target.size)
        train = idx[:int(idx.size / 2)]
        test = idx[int(idx.size / 2):]

        # -----------------------------------------------------------------------------
        # Train and calibrate
        # -----------------------------------------------------------------------------
        tcp = TcpClassifier(
            ClassifierNc(ClassifierAdapter(SVC(probability=True)),
                         MarginErrFunc()))
        tcp.fit(data.data[train, :], data.target[train])

        # -----------------------------------------------------------------------------
        # Predict
        # -----------------------------------------------------------------------------
        prediction = tcp.predict(data.data[test, :], significance=0.1)
        header = np.array(["c0", "c1", "c2", "Truth"])
        table = np.vstack([prediction.T, data.target[test]]).T
        df = pd.DataFrame(np.vstack([header, table]))
        print(df)
Esempio n. 2
0
from sklearn.datasets import load_iris

from nonconformist.base import ClassifierAdapter
from nonconformist.cp import TcpClassifier
from nonconformist.nc import ClassifierNc, MarginErrFunc

# -----------------------------------------------------------------------------
# Setup training, calibration and test indices
# -----------------------------------------------------------------------------
data = load_iris()

idx = np.random.permutation(data.target.size)
train = idx[:int(idx.size / 2)]
test = idx[int(idx.size / 2):]

# -----------------------------------------------------------------------------
# Train and calibrate
# -----------------------------------------------------------------------------
tcp = TcpClassifier(ClassifierNc(ClassifierAdapter(SVC(probability=True)),
                                 MarginErrFunc()))
tcp.fit(data.data[train, :], data.target[train])

# -----------------------------------------------------------------------------
# Predict
# -----------------------------------------------------------------------------
prediction = tcp.predict(data.data[test, :], significance=0.1)
header = np.array(['c0','c1','c2','Truth'])
table = np.vstack([prediction.T, data.target[test]]).T
df = pd.DataFrame(np.vstack([header, table]))
print(df)
Esempio n. 3
0
import sys
sys.path.append('/Users/staffan/git/peptid_studie/experiments/src') # Nonconformist

from nonconformist.cp import TcpClassifier
from nonconformist.nc import NcFactory


iris = load_iris()

idx = np.random.permutation(iris.target.size)

# Divide the data into training set and test set
idx_train, idx_test = idx[:100], idx[100:]

model = SVC(probability=True)	# Create the underlying model
nc = NcFactory.create_nc(model)	# Create a default nonconformity function
tcp = TcpClassifier(nc)			# Create a transductive conformal classifier

# Fit the TCP using the proper training set
tcp.fit(iris.data[idx_train, :], iris.target[idx_train])

# Produce predictions for the test set
predictions = tcp.predict(iris.data[idx_test, :])

# 
targets = np.array(iris.target[idx_test], copy=True)
targets.shape = (len(targets),1)
output = np.hstack((targets, predictions))

np.savetxt('resources/multiclass.csv', output, delimiter=',')
Esempio n. 4
0
train = idx[:int(idx.size / 2)]
test = idx[int(idx.size / 2):]

# -----------------------------------------------------------------------------
# Train and calibrate TCP
# -----------------------------------------------------------------------------
tcp = TcpClassifier(
    ClassifierNc(ClassifierAdapter(SVC(probability=True, gamma='scale')),
                 MarginErrFunc()))

tcp.fit(data.data[train, :], data.target[train])

# -----------------------------------------------------------------------------
# Predict
# -----------------------------------------------------------------------------
prediction = tcp.predict(data.data[test, :], significance=0.1)
header = np.array(['c0', 'c1', 'c2', 'Truth'])
table = np.vstack([prediction.T, data.target[test]]).T
df = pd.DataFrame(np.vstack([header, table]))
print('TCP')
print('---')
print(df)

error_rate = class_mean_errors(tcp.predict(data.data[test, :]),
                               data.target[test],
                               significance=0.1)
print('Error rate: {}'.format(error_rate))

# -----------------------------------------------------------------------------
# Train and calibrate Mondrian (class-conditional) TCP
# -----------------------------------------------------------------------------
Esempio n. 5
0
class CPHMM(BaseEstimator):
    def __init__(self, ncm, n_states, smooth=True):
        """Initialise a CP-HMM model.

        Parameters
        ----------
        ncm : nonconformist.BaseScorer
            Nonconformity measure to use.
        n_states : int
            Number of hidden states.
        smooth : bool
            If True, smooth CP is used, which achieves exact validity.
            Otherwise, standard CP is used, guaranteeing error smaller or
            equal to the significance level.
        """
        self.ncm = ncm
        self.n_states = n_states
        self.smooth = smooth

    def fit(self, X, Y, lengths=None, init_prob=None, tran_prob=None):
        """Fits the model on observables X and respective hidden sequences Y.

        Parameters
        ----------
        X : numpy array (n_samples, n_features)
            Individual observations.
        Y : numpy array (n_samples,)
            Individual observations of hidden states.
        lengths : list of integer
            Lengths of sequences in X and Y. If None, X and Y are assumed to
            be a single sequence. The sum of lengths should be n_samples.
        init_prob : dict (Default: None)
            The item corresponding to the i-th key is the
            probability of the hidden process to start in the
            i-th state.
            If default (=None), it is estimated from data.
        tran_prob : dict (Default: None)
            The item corresponding to the i-th key of the dictionary
            is a dictionary itself, which, for the j-th key,
            indicates the probability of transitioning from the
            i-th to the j-th state.
            If default (=None), it is estimated from data.
        """
        self.train_x = X
        self.train_y = Y
        if lengths is None:
            lengths = [len(Y)]

        # CP model
        self.cp = TcpClassifier(self.ncm, smoothing=self.smooth)

        # Initial and transition probabilities.
        if not init_prob:
            init_prob = self._estimate_initial_prob(Y, lengths)

        if not tran_prob:
            tran_prob = self._estimate_transition_prob(Y, lengths)

        self.init_prob = init_prob
        self.tran_prob = tran_prob

    def predict(self, x, e):
        """Return a CP-HMM prediction region.

        Uses CP-HMM to output a prediction region (i.e.: a set of candidate
        hidden sequences) for the observed sequence x.
        NOTE: If any of the elements of the sequence has an empty
        prediction set, then no predictions are returned.

        Parameters
        ----------
        x : list
            Observed sequence.
        e : float in [0,1]
            Significance level.
        """
        # Reduce significance level as required.
        e /= float(len(x))
        # Find candidates.
        candidates = self._hidden_candidates(x, e)

        # Generate paths.
        paths = self._generate_paths(candidates, self.tran_prob,
                                     self.init_prob)

        return paths

    def _generate_paths(self, candidates, trans_prob, init_prob):
        """Generate and score paths.

        Accepts a list of list of candidate. Each list of
        candidate contains potential true hidden states to
        compose a path.
        The function produces all possible paths, and scores them
        w.r.t. the transition and initial probabilities.
        It returns the paths in a list, sorted by scores:
        from the most likely to the least likely.

        Parameters
        ----------
        candidates : list of list
            The i-th list it contains represents a set of state
            candidates for the i-th element of the sequence.
        trans_prob : dictionary
            The keys of this dictionary are tuples in the form
            (i, j). The element (i, j) is associated with the
            transition  probability from state i to state j.
        init_prob : dictionary
            The keys are numbers i (as many as the states).
            init_prob[i] contains the probability of a sequence
            starting in state i.
        """
        paths = list(itertools.product(*candidates))
        scores = []
        for p in paths:
            p = list(map(int, p))  # So we can use them as indexes
            s = init_prob[p[0]]
            for i in range(len(p) - 1):
                s *= trans_prob[(p[i], p[i + 1])]
            scores.append(s)

        paths_sorted = [x[1] for x in sorted(zip(scores, paths), reverse=True)]

        return paths_sorted

    def _hidden_candidates(self, x, e):
        """Uses CP-HMM to predict, for each element of the observed sequence, a
        list of candidate states.  Thanks to CP's validity guarantee, the true
        hidden states is within the list of candidates with probability 1-e.

        Parameters
        ----------
        x : list
            Observed sequence.
        e : float in [0,1]
            Significance level.
        """
        # Flatten sequences, "train" CP
        X = self.train_x.flatten().reshape(-1, 1)
        Y = self.train_y.flatten()
        self.cp.fit(X, Y)
        # For each element of the observed sequence x
        # determine a set of candidate states.
        y_candidates = []
        for i in range(len(x)):
            candidates_bool = self.cp.predict(x[i].reshape(-1, 1), e)[0]
            candidates = self.cp.classes[candidates_bool]
            y_candidates.append(candidates)

        return y_candidates

    def _estimate_initial_prob(self, Y, lengths):
        """Returns an frequentist estimate of the initial probabilities over
        the observed hidden states.  Assumes that the hidden states are
        specified by sequential numbers 0, 1, ...  numbers).

        Parameters
        ----------
        Y : numpy array (n_samples,)
            Individual observations of hidden states.
        lengths : list of integer
            Lengths of sequences in X and Y. If None, X and Y are assumed to
            be a single sequence. The sum of lengths should be n_samples.
        """
        if not len(Y):
            return []

        ip = np.array([.0] * self.n_states)
        for i, j in iter_from_X_lengths(Y, lengths):
            ip[Y[i]] += 1

        ip /= sum(ip)
        # To dictionary
        ip = dict(list(zip(list(range(len(ip))), ip)))

        return ip

    def _estimate_transition_prob(self, Y, lengths):
        """Returns an frequentist estimate of the transition probabilities over
        the observed hidden states.  Assumes that the hidden states are
        specified by sequential numbers 0, 1, ... .

        Parameters
        ----------
        Y : numpy array (n_samples,)
            Individual observations of hidden states.
        lengths : list of integer
            Lengths of sequences in X and Y. If None, X and Y are assumed to
            be a single sequence. The sum of lengths should be n_samples.
        """
        if not len(Y):
            return np.empty()

        tp = np.zeros((self.n_states, self.n_states))
        for i, j in iter_from_X_lengths(Y, lengths):
            for k in range(i, j - 1):
                tp[Y[k], Y[k + 1]] += 1

        # Missing values, normalise
        # NOTE: here is made the assumption that states are integers
        # 0, 1, ..., self.n_states-1.
        for y in range(self.n_states):
            if sum(tp[y, :]) == 0:
                tp[y, :] = 1.0
            tp[y, :] /= sum(tp[y, :])

        # To dictionary
        tran_prob = {}
        for i in range(len(tp)):
            for j in range(len(tp[0])):
                tran_prob[(i, j)] = tp[i][j]

        return tran_prob