class Scorer(_RefuseDataInConstructor, Reprable): feature_type = None class_type = None supports_sparse_data = None preprocessors = [RemoveNaNClasses()] def __call__(self, data, feature=None): if not data.domain.class_var: raise ValueError("Data with class labels required.") if not isinstance(data.domain.class_var, self.class_type): raise ValueError( "Scoring method %s requires a class variable of type %s." % (type(self).__name__, self.class_type.__name__)) if feature is not None: f = data.domain[feature] data = data.from_table(Domain([f], data.domain.class_vars), data) for pp in self.preprocessors: data = pp(data) if any(not isinstance(a, self.feature_type) for a in data.domain.attributes): raise ValueError('Only %ss are supported' % self.feature_type) return self.score_data(data, feature) def score_data(self, data, feature): raise NotImplementedError
class Scorer(_RefuseDataInConstructor, Reprable): feature_type = None class_type = None supports_sparse_data = None preprocessors = [ RemoveNaNClasses() ] @property def friendly_name(self): """Return type name with camel-case separated into words. Derived classes can provide a better property or a class attribute. """ return re.sub("([a-z])([A-Z])", lambda mo: mo.group(1) + " " + mo.group(2).lower(), type(self).__name__) @staticmethod def _friendly_vartype_name(vartype): if vartype == DiscreteVariable: return "categorical" if vartype == ContinuousVariable: return "numeric" # Fallbacks name = vartype.__name__ if name.endswith("Variable"): return name.lower()[:-8] return name def __call__(self, data, feature=None): if not data.domain.class_var: raise ValueError( "{} requires data with a target variable." .format(self.friendly_name)) if not isinstance(data.domain.class_var, self.class_type): raise ValueError( "{} requires a {} target variable." .format(self.friendly_name, self._friendly_vartype_name(self.class_type))) if feature is not None: f = data.domain[feature] data = data.transform(Domain([f], data.domain.class_vars)) for pp in self.preprocessors: data = pp(data) for var in data.domain.attributes: if not isinstance(var, self.feature_type): raise ValueError( "{} cannot score {} variables." .format(self.friendly_name, self._friendly_vartype_name(type(var)))) return self.score_data(data, feature) def score_data(self, data, feature): raise NotImplementedError
class Scorer: feature_type = None class_type = None preprocessors = [ RemoveNaNClasses() ] def __new__(cls, *args, **kwargs): self = super().__new__(cls) self.preprocessors = list(self.preprocessors) if args: self.__init__(**kwargs) return self(*args) else: return self def __call__(self, data, feature=None): if not data.domain.class_var: raise ValueError("Data with class labels required.") if not isinstance(data.domain.class_var, self.class_type): raise ValueError("Scoring method %s requires a class variable of type %s." % (type(self).__name__, self.class_type.__name__)) if feature is not None: f = data.domain[feature] data = data.from_table(Domain([f], data.domain.class_vars), data) for pp in self.preprocessors: data = pp(data) if any(not isinstance(a, self.feature_type) for a in data.domain.attributes): raise ValueError('Only %ss are supported' % self.feature_type) return self.score_data(data, feature) def score_data(self, data, feature): raise NotImplementedError