Source code for skmultilearn.base.problem_transformation

import copy
import numpy as np
from .base import MLClassifierBase
from ..utils import get_matrix_in_format, matrix_creation_function_for_format
from scipy.sparse import issparse, csr_matrix
from sklearn.base import BaseEstimator, ClassifierMixin


[docs]class ProblemTransformationBase(MLClassifierBase): """Base class providing common functions for multi-label classifiers that follow the problem transformation approach. Problem transformation is the approach in which the original multi-label classification problem is transformed into one or more single-label problems, which are then solved by single-class or multi-class classifiers. Scikit-multilearn provides a number of such methods: - :class:`BinaryRelevance` - which performs a single-label single-class classification for each label and sums the results :class:`BinaryRelevance` - :class:`ClassifierChains` - which performs a single-label single-class classification for each label and sums the results :class:`ClassifierChain` - :class:`LabelPowerset` - which performs a single-label single-class classification for each label and sums the results :class:`LabelPowerset` Parameters ---------- classifier : scikit classifier type The base classifier that will be used in a class, will be automagically put under self.classifier for future access. require_dense : boolean Whether the base classifier requires input as dense arrays, False by default """ def __init__(self, classifier=None, require_dense=None): super(ProblemTransformationBase, self).__init__() self.copyable_attrs = ["classifier", "require_dense"] self.classifier = classifier if require_dense is not None: if isinstance(require_dense, bool): self.require_dense = [require_dense, require_dense] else: assert len(require_dense) == 2 and isinstance( require_dense[0], bool) and isinstance(require_dense[1], bool) self.require_dense = require_dense else: if isinstance(self.classifier, MLClassifierBase): self.require_dense = [False, False] else: self.require_dense = [True, True]
[docs] def ensure_multi_label_from_single_class(self, matrix, matrix_format='csr'): """Transform single class outputs to a 2D sparse matrix""" is_2d = None dim_1 = None dim_2 = None # check if array like of array likes if isinstance(matrix, (list, tuple, np.ndarray)): if isinstance(matrix[0], (list, tuple, np.ndarray)): is_2d = True dim_1 = len(matrix) dim_2 = len(matrix[0]) # 1d list or array else: is_2d = False # shape is n_samples of 1 class assignment dim_1 = len(matrix) dim_2 = 1 # not an array but 2D, probably a matrix elif matrix.ndim == 2: is_2d = True dim_1=matrix.shape[0] dim_2=matrix.shape[1] # what is it? else: raise ValueError("Matrix dimensions too large (>2) or other value error") new_matrix = None if is_2d: if issparse(matrix): new_matrix = matrix else: new_matrix = matrix_creation_function_for_format(matrix_format)(matrix, shape=(dim_1, dim_2)) else: new_matrix = matrix_creation_function_for_format(matrix_format)(matrix).T assert new_matrix.shape == (dim_1, dim_2) return new_matrix