forked from gatapia/py_ml_utils
-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathTransformYClassifier.py
53 lines (42 loc) · 1.93 KB
/
TransformYClassifier.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
from sklearn.base import BaseEstimator, ClassifierMixin
from sklearn import preprocessing
import numpy as np
import pandas as pd
import math
class TransformYClassifier(BaseEstimator, ClassifierMixin):
def __init__(self, base_classifier, transformation, transform_on_fit=True, anti_transform_on_predict=True):
self.base_classifier = base_classifier
self.transformation = transformation
self.shift_val = 0
self.transform_on_fit = transform_on_fit
def _do_transformation_impl(self, y):
if hasattr(self.transformation, '__call__'):
return self.transformation(y)
elif self.transformation == 'log':
ymin = y.min()
if ymin < 0:
self.shift_val = ymin * -1.01
return np.log(y + self.shift_val)
elif self.transformation == 'arcsinh':
return np.arcsinh(y)
else: raise Exception('Not Supported: ' + `self.transformation`)
def _on_fit_transform(self, y):
if not self.transform_on_fit: return y
return self._do_transformation_impl(y)
def _post_predict_transform(self, y):
if not self.transform_on_fit: return self._do_transformation_impl(y)
if not anti_transform_on_predict: return y
elif self.transformation == 'log': return np.power(math.e, y) - self.shift_val
elif self.transformation == 'arcsinh': return np.sinh(y)
else: raise Exception('Not Supported: ' + self.transformation)
def fit(self, X, y):
self.base_classifier.fit(X, self._on_fit_transform(y))
return self
def predict(self, X):
return self._post_predict_transform(self.base_classifier.predict(X))
def predict_proba(self, X):
return self._post_predict_transform(self.base_classifier.predict_proba(X))
def get_sigmoid_transform(beta):
return lambda y: 0.5 * ((2 * abs(y - 0.5)) ** beta) * np.sign(y - 0.5) + 0.5
def get_logistic_transform(k):
return lambda y: 1.0 / (1.0 + np.exp(-k * preprocessing.scale(y)))