PineBioML 1.2.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- PineBioML/IO/__init__.py +158 -0
- PineBioML/__init__.py +0 -0
- PineBioML/model/__init__.py +0 -0
- PineBioML/model/supervised/Classification.py +989 -0
- PineBioML/model/supervised/Regression.py +783 -0
- PineBioML/model/supervised/Survival.py +1 -0
- PineBioML/model/supervised/__init__.py +414 -0
- PineBioML/model/utils.py +393 -0
- PineBioML/preprocessing/__init__.py +168 -0
- PineBioML/preprocessing/bagging.py +221 -0
- PineBioML/preprocessing/impute.py +143 -0
- PineBioML/preprocessing/utils.py +161 -0
- PineBioML/report/__init__.py +0 -0
- PineBioML/report/utils.py +763 -0
- PineBioML/selection/Volcano.py +201 -0
- PineBioML/selection/__init__.py +145 -0
- PineBioML/selection/classification.py +836 -0
- PineBioML/selection/regression.py +737 -0
- PineBioML-1.2.0.dist-info/LICENSE +21 -0
- PineBioML-1.2.0.dist-info/METADATA +148 -0
- PineBioML-1.2.0.dist-info/RECORD +23 -0
- PineBioML-1.2.0.dist-info/WHEEL +5 -0
- PineBioML-1.2.0.dist-info/top_level.txt +1 -0
PineBioML/model/utils.py
ADDED
|
@@ -0,0 +1,393 @@
|
|
|
1
|
+
from sklearn import metrics
|
|
2
|
+
from sklearn.model_selection import StratifiedKFold
|
|
3
|
+
from sklearn.pipeline import Pipeline
|
|
4
|
+
from pandas import DataFrame, Series, concat
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class sklearn_esitimator_wrapper():
|
|
8
|
+
"""
|
|
9
|
+
A basic wrapper for sklearn_esitimator. It transfer the data pipeline of sklearn from numpy.array to pandas.DataFrame.
|
|
10
|
+
If you want to pass any model with api in sklearn style into Pine, you should wrap it in wrapper.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
def __init__(self, kernel: object):
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
Args:
|
|
17
|
+
kernel (object): a sklearn esitimator. for example: sklearn.ensemble.RandomForestClassifier or sklearn.ensemble.RandomForestRegressor
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
self.kernel = kernel
|
|
21
|
+
|
|
22
|
+
def fit(self, x: DataFrame, y: Series, retune=True) -> object:
|
|
23
|
+
"""
|
|
24
|
+
sklearn esitimator api: fit
|
|
25
|
+
|
|
26
|
+
Args:
|
|
27
|
+
x (DataFrame): feature
|
|
28
|
+
y (Series): label
|
|
29
|
+
retune (bool, optional): To retune the model or not. For sklearn_esitimator_wrapper, it is just a placeholder without acutual facility. Defaults to True.
|
|
30
|
+
|
|
31
|
+
Returns:
|
|
32
|
+
object: A sklearn_esitimator within pandas data flow.
|
|
33
|
+
"""
|
|
34
|
+
self.label_name = y.name
|
|
35
|
+
self.kernel.fit(x, y)
|
|
36
|
+
return self
|
|
37
|
+
|
|
38
|
+
def predict(self, x: DataFrame) -> Series:
|
|
39
|
+
"""
|
|
40
|
+
sklearn esitimator api: predict
|
|
41
|
+
|
|
42
|
+
Args:
|
|
43
|
+
x (DataFrame): feature
|
|
44
|
+
|
|
45
|
+
Returns:
|
|
46
|
+
Series: kernel prediction
|
|
47
|
+
"""
|
|
48
|
+
|
|
49
|
+
return Series(self.kernel.predict(x),
|
|
50
|
+
index=x.index,
|
|
51
|
+
name=self.label_name)
|
|
52
|
+
|
|
53
|
+
def predict_proba(self, x: DataFrame) -> DataFrame:
|
|
54
|
+
"""
|
|
55
|
+
sklearn esitimator api: predict_proba for classification
|
|
56
|
+
|
|
57
|
+
Args:
|
|
58
|
+
x (DataFrame): feature
|
|
59
|
+
|
|
60
|
+
Raises:
|
|
61
|
+
NotImplementedError: Regression has no attribute 'predict_proba'
|
|
62
|
+
|
|
63
|
+
Returns:
|
|
64
|
+
DataFrame: predicted probability with shape (n_sample, n_class)
|
|
65
|
+
"""
|
|
66
|
+
if "predict_proba" in dir(self.kernel):
|
|
67
|
+
return DataFrame(self.kernel.predict_proba(x),
|
|
68
|
+
index=x.index,
|
|
69
|
+
columns=self.kernel.classes_)
|
|
70
|
+
else:
|
|
71
|
+
raise NotImplementedError(
|
|
72
|
+
"{} do not have attribute 'predict_proba'.".format(
|
|
73
|
+
self.kernel.__str__()))
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
class classification_scorer():
|
|
77
|
+
"""
|
|
78
|
+
A utility to calculate classification scores.
|
|
79
|
+
The result will contain mcc(matthews corrcoef), acc(accuracy) and support(the number of samples), furthermore:
|
|
80
|
+
if target_label was given(not None), then sensitivity, specificity and coresponding roc-auc score will be added to result.
|
|
81
|
+
if multi_class_extra is True, then one vs rest macro_auc, cross_entropy and cohen_kappa will be added to result.
|
|
82
|
+
"""
|
|
83
|
+
|
|
84
|
+
def __init__(self,
|
|
85
|
+
target_label: str = None,
|
|
86
|
+
prefix: str = "",
|
|
87
|
+
multi_class_extra: bool = False):
|
|
88
|
+
"""
|
|
89
|
+
|
|
90
|
+
Args:
|
|
91
|
+
target_label (str, optional): the name of target_label. For example, the label in a binary classification task might be {'pos', 'neg'}. Then you can assign 'neg' to target_label, and the result will contain sensitivity, specificity and roc-auc score of label 'neg'. Defaults to None.
|
|
92
|
+
prefix (str, optional): prefix before score names. For example suppose prefix="Train_", then all the scores in result will be like "Train_mcc". Defaults to "".
|
|
93
|
+
multi_class_extra (bool, optional): _description_. Defaults to False.
|
|
94
|
+
"""
|
|
95
|
+
|
|
96
|
+
self.prefix = prefix
|
|
97
|
+
self.target_label = target_label
|
|
98
|
+
self.multi_class_extra = multi_class_extra
|
|
99
|
+
|
|
100
|
+
def score(self, y_true: Series,
|
|
101
|
+
y_pred_prob: DataFrame) -> dict[str, float]:
|
|
102
|
+
"""
|
|
103
|
+
Scoring y_true and y_pred_prob.
|
|
104
|
+
|
|
105
|
+
Args:
|
|
106
|
+
y_true (Series): The ground True.
|
|
107
|
+
y_pred_prob (DataFrame): The prediction from an estimator. Shape should be (n_sample, n_classes)
|
|
108
|
+
|
|
109
|
+
Returns:
|
|
110
|
+
dict[str, float]: The result stored in a dict, be like {'score_name': score}.
|
|
111
|
+
"""
|
|
112
|
+
y_pred = y_pred_prob.idxmax(axis=1)
|
|
113
|
+
|
|
114
|
+
result = {}
|
|
115
|
+
if not self.target_label is None:
|
|
116
|
+
(_, result["sensitivity"], result["f1"],
|
|
117
|
+
_) = metrics.precision_recall_fscore_support(
|
|
118
|
+
y_true=(y_true == self.target_label),
|
|
119
|
+
y_pred=(y_pred == self.target_label),
|
|
120
|
+
average="binary",
|
|
121
|
+
pos_label=True)
|
|
122
|
+
|
|
123
|
+
(_, result["specificity"], _,
|
|
124
|
+
_) = metrics.precision_recall_fscore_support(
|
|
125
|
+
y_true=(y_true == self.target_label),
|
|
126
|
+
y_pred=(y_pred == self.target_label),
|
|
127
|
+
average="binary",
|
|
128
|
+
pos_label=False)
|
|
129
|
+
|
|
130
|
+
# binary
|
|
131
|
+
result["auc"] = metrics.roc_auc_score(
|
|
132
|
+
y_true == self.target_label, y_pred_prob[self.target_label])
|
|
133
|
+
|
|
134
|
+
if self.multi_class_extra:
|
|
135
|
+
result["macro_auc"] = metrics.roc_auc_score(
|
|
136
|
+
y_true,
|
|
137
|
+
y_pred_prob,
|
|
138
|
+
multi_class="ovr",
|
|
139
|
+
labels=y_pred_prob.columns)
|
|
140
|
+
result["macro_f1"] = metrics.f1_score(y_true,
|
|
141
|
+
y_pred,
|
|
142
|
+
average="macro")
|
|
143
|
+
result["cross_entropy"] = metrics.log_loss(y_true, y_pred_prob)
|
|
144
|
+
result["cohen_kappa"] = metrics.cohen_kappa_score(y_true, y_pred)
|
|
145
|
+
|
|
146
|
+
result["mcc"] = metrics.matthews_corrcoef(y_true, y_pred)
|
|
147
|
+
result["accuracy"] = metrics.accuracy_score(y_true, y_pred)
|
|
148
|
+
result["support"] = len(y_true)
|
|
149
|
+
|
|
150
|
+
prefix_result = {}
|
|
151
|
+
for score in result:
|
|
152
|
+
prefix_result[self.prefix + score] = result[score]
|
|
153
|
+
|
|
154
|
+
return prefix_result
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
class regression_scorer():
|
|
158
|
+
"""
|
|
159
|
+
A utility to calculate regression scores. rmse(rooted mean squared error), r2(R squared) and support(the number of samples) are included.
|
|
160
|
+
if y_true and y_pred are all positive, then mape(mean absolute percentage error) will be added.
|
|
161
|
+
"""
|
|
162
|
+
|
|
163
|
+
def __init__(self, prefix: str = "", target_label: str = None):
|
|
164
|
+
"""
|
|
165
|
+
|
|
166
|
+
Args:
|
|
167
|
+
prefix (str, optional): prefix before score names. For example suppose prefix="Train_", then all the scores in result will be like "Train_mse". Defaults to "".
|
|
168
|
+
target_label (str, optional): A placehold without any facility. Defaults to None.
|
|
169
|
+
"""
|
|
170
|
+
|
|
171
|
+
self.prefix = prefix
|
|
172
|
+
|
|
173
|
+
def score(self, y_true: Series, y_pred: Series) -> dict[str, float]:
|
|
174
|
+
"""
|
|
175
|
+
calculate the scores
|
|
176
|
+
|
|
177
|
+
Args:
|
|
178
|
+
y_true (Series): Ground true
|
|
179
|
+
y_pred (Series): predicted values
|
|
180
|
+
|
|
181
|
+
Returns:
|
|
182
|
+
dict[str, float]: The result stored in a dict, be like {'score_name': score}.
|
|
183
|
+
"""
|
|
184
|
+
|
|
185
|
+
result = {}
|
|
186
|
+
result["rmse"] = metrics.root_mean_squared_error(y_true, y_pred)
|
|
187
|
+
result["r2"] = metrics.r2_score(y_true, y_pred)
|
|
188
|
+
if (y_true > 0).all() and (y_pred > 0).all():
|
|
189
|
+
result["mape"] = metrics.mean_absolute_percentage_error(
|
|
190
|
+
y_true, y_pred)
|
|
191
|
+
result["support"] = len(y_true)
|
|
192
|
+
|
|
193
|
+
prefix_result = {}
|
|
194
|
+
for score in result:
|
|
195
|
+
prefix_result[self.prefix + score] = result[score]
|
|
196
|
+
|
|
197
|
+
return prefix_result
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
# ToDo: the Integration of .predict and .transform
|
|
201
|
+
class Pine():
|
|
202
|
+
"""
|
|
203
|
+
Deep first traversal the given experiment setting.
|
|
204
|
+
the last step of experiment sould be model.
|
|
205
|
+
Please refer to example_Pine.ipynb for usage.
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
note: experiment step and experiment stage is the same thing.
|
|
209
|
+
"""
|
|
210
|
+
|
|
211
|
+
def __init__(self,
|
|
212
|
+
experiment: list[tuple[str, dict[str, object]]],
|
|
213
|
+
target_label: str = None,
|
|
214
|
+
cv_result: bool = False):
|
|
215
|
+
"""
|
|
216
|
+
Args:
|
|
217
|
+
experiment (list[tuple[str, dict[str, object]]]): list of experiment steps. step should be in the form: ('step_name', {'method_name': method}). it could be several method in one step and they will fork in deep first traversal. Each method should be either sklearn estimator or transformer.
|
|
218
|
+
target_label (str, optional): the name of target_label. For example, the label in a binary classification task might be {'pos', 'neg'}. Then you can assign 'neg' to target_label, and the result will contain sensitivity, specificity and roc-auc score of label 'neg'. Defaults to None.
|
|
219
|
+
cv_result (bool, optional): Rcording the scores and prediction of cross validation. Defaults to False.
|
|
220
|
+
"""
|
|
221
|
+
|
|
222
|
+
self.experiment = experiment
|
|
223
|
+
self.total_stage = len(experiment)
|
|
224
|
+
self.target_label = target_label
|
|
225
|
+
self.cv_result = cv_result
|
|
226
|
+
|
|
227
|
+
self.result = []
|
|
228
|
+
|
|
229
|
+
self.train_pred = []
|
|
230
|
+
self.cv_pred = []
|
|
231
|
+
self.test_pred = []
|
|
232
|
+
|
|
233
|
+
def do_stage(self, train_x: DataFrame, train_y: Series, test_x: DataFrame,
|
|
234
|
+
test_y: Series, stage: int, record: dict) -> None:
|
|
235
|
+
"""
|
|
236
|
+
the recursive function to traversal the experiment.
|
|
237
|
+
the socres and path will be stored in self.result amd self.____pred, so there is no return in recursive function.
|
|
238
|
+
|
|
239
|
+
Args:
|
|
240
|
+
train_x (pd.DataFrame): training x
|
|
241
|
+
train_y (pd.Series): training y
|
|
242
|
+
test_x (pd.DataFrame): training x
|
|
243
|
+
test_y (pd.Series): training y
|
|
244
|
+
stage (int): the order of current stage in the experiment setting
|
|
245
|
+
record (dict): record the traversal path in a dict of str
|
|
246
|
+
"""
|
|
247
|
+
|
|
248
|
+
# unzip the stage, stage = (stage_name, {operator_name: operator})
|
|
249
|
+
stage_name, operators = self.experiment[stage]
|
|
250
|
+
|
|
251
|
+
# fork to next stage according to the diffirent operator (opt)
|
|
252
|
+
for opt_name in operators:
|
|
253
|
+
record[stage_name] = opt_name
|
|
254
|
+
opt = operators[opt_name]
|
|
255
|
+
|
|
256
|
+
# if not the last stage
|
|
257
|
+
if stage < self.total_stage - 1:
|
|
258
|
+
# transform by operators
|
|
259
|
+
processed_train_x = opt.fit_transform(train_x, train_y)
|
|
260
|
+
if test_x is not None:
|
|
261
|
+
processed_test_x = opt.transform(test_x)
|
|
262
|
+
|
|
263
|
+
# reccursivly call
|
|
264
|
+
self.do_stage(processed_train_x, train_y, processed_test_x,
|
|
265
|
+
test_y, stage + 1, record)
|
|
266
|
+
|
|
267
|
+
# the last layer, it should be models
|
|
268
|
+
else:
|
|
269
|
+
model = opt
|
|
270
|
+
if "predict_proba" in dir(model):
|
|
271
|
+
# is not regression
|
|
272
|
+
f = model.predict_proba
|
|
273
|
+
scorer = classification_scorer
|
|
274
|
+
else:
|
|
275
|
+
# is regression
|
|
276
|
+
f = model.predict
|
|
277
|
+
scorer = regression_scorer
|
|
278
|
+
|
|
279
|
+
# tune/fit the model on training data
|
|
280
|
+
model.fit(train_x, train_y)
|
|
281
|
+
|
|
282
|
+
# compute the training score
|
|
283
|
+
train_pred = f(train_x)
|
|
284
|
+
self.train_pred.append(train_pred)
|
|
285
|
+
train_scores = scorer(prefix="train_",
|
|
286
|
+
target_label=self.target_label).score(
|
|
287
|
+
train_y, train_pred)
|
|
288
|
+
|
|
289
|
+
if test_x is not None:
|
|
290
|
+
# if there is testing data, compute the testing score.
|
|
291
|
+
test_pred = f(test_x)
|
|
292
|
+
self.test_pred.append(test_pred)
|
|
293
|
+
test_scores = scorer(prefix="test_",
|
|
294
|
+
target_label=self.target_label).score(
|
|
295
|
+
test_y, test_pred)
|
|
296
|
+
else:
|
|
297
|
+
test_scores = {}
|
|
298
|
+
|
|
299
|
+
if self.cv_result:
|
|
300
|
+
# compute the cross validation score on training set
|
|
301
|
+
fold_scores = []
|
|
302
|
+
cv_pred = []
|
|
303
|
+
cross_validation = StratifiedKFold(n_splits=5,
|
|
304
|
+
shuffle=True,
|
|
305
|
+
random_state=133)
|
|
306
|
+
for (train_idx, valid_idx) in cross_validation.split(
|
|
307
|
+
train_x, train_y):
|
|
308
|
+
|
|
309
|
+
# fit on training fold
|
|
310
|
+
model.fit(train_x.iloc[train_idx],
|
|
311
|
+
train_y.iloc[train_idx],
|
|
312
|
+
retune=False)
|
|
313
|
+
|
|
314
|
+
# score on testing fold
|
|
315
|
+
fold_pred = f(train_x.iloc[valid_idx])
|
|
316
|
+
cv_pred.append(fold_pred)
|
|
317
|
+
fold_scores.append(
|
|
318
|
+
scorer(prefix="cv_",
|
|
319
|
+
target_label=self.target_label).score(
|
|
320
|
+
train_y.iloc[valid_idx], fold_pred))
|
|
321
|
+
# average the fold scores
|
|
322
|
+
"""
|
|
323
|
+
valid_scores = {}
|
|
324
|
+
for metric_name in fold_scores[0].keys():
|
|
325
|
+
valid_scores[metric_name] = np.array([
|
|
326
|
+
fold_scores[cv][metric_name] for cv in range(5)
|
|
327
|
+
]).mean()
|
|
328
|
+
"""
|
|
329
|
+
self.cv_pred.append(concat(cv_pred, axis=0))
|
|
330
|
+
valid_scores = DataFrame(fold_scores).mean().to_dict()
|
|
331
|
+
else:
|
|
332
|
+
valid_scores = {}
|
|
333
|
+
|
|
334
|
+
# concatenate the score dicts
|
|
335
|
+
all_scores = dict(**record, **train_scores, **valid_scores,
|
|
336
|
+
**test_scores)
|
|
337
|
+
self.result.append(all_scores)
|
|
338
|
+
|
|
339
|
+
def do_experiment(self, train_x, train_y, test_x=None, test_y=None):
|
|
340
|
+
"""
|
|
341
|
+
the first call of recurssive fuction.
|
|
342
|
+
|
|
343
|
+
Args:
|
|
344
|
+
train_x (pd.DataFrame): training x
|
|
345
|
+
train_y (pd.Series): training y
|
|
346
|
+
test_x (pd.DataFrame): training x
|
|
347
|
+
test_y (pd.Series): training y
|
|
348
|
+
|
|
349
|
+
Returns:
|
|
350
|
+
pd.DataFrame: the result
|
|
351
|
+
"""
|
|
352
|
+
# clear the results.
|
|
353
|
+
self.result = []
|
|
354
|
+
|
|
355
|
+
self.do_stage(train_x, train_y, test_x, test_y, 0, {})
|
|
356
|
+
return self.experiment_results()
|
|
357
|
+
|
|
358
|
+
def experiment_results(self) -> DataFrame:
|
|
359
|
+
"""
|
|
360
|
+
|
|
361
|
+
Returns:
|
|
362
|
+
DataFrame: The experiment results.
|
|
363
|
+
"""
|
|
364
|
+
return DataFrame(self.result)
|
|
365
|
+
|
|
366
|
+
def experiment_predictions(self):
|
|
367
|
+
"""
|
|
368
|
+
cv_pred will be empty if cv_result was False in initialization.
|
|
369
|
+
|
|
370
|
+
Returns:
|
|
371
|
+
train_pred, cv_pred, test_pred: the prediction of training set, cross validation and testing set
|
|
372
|
+
"""
|
|
373
|
+
return self.train_pred, self.cv_pred, self.test_pred
|
|
374
|
+
|
|
375
|
+
def recall_model(self, id):
|
|
376
|
+
"""
|
|
377
|
+
query the last experiment result by id and build the pipeline object.
|
|
378
|
+
|
|
379
|
+
Todo: A proper way to fit the pipeline object.
|
|
380
|
+
|
|
381
|
+
Args:
|
|
382
|
+
id (int): the order of experiment path.
|
|
383
|
+
|
|
384
|
+
Returns:
|
|
385
|
+
sklearn.pipeline.Pipeline: ready to use object.
|
|
386
|
+
"""
|
|
387
|
+
|
|
388
|
+
model_spec = self.result[id]
|
|
389
|
+
model_pipeline = []
|
|
390
|
+
for (step_name, methods) in self.experiment:
|
|
391
|
+
using_method = model_spec[step_name]
|
|
392
|
+
model_pipeline.append((step_name, methods[using_method]))
|
|
393
|
+
return Pipeline(model_pipeline)
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import sklearn.preprocessing as skprpr
|
|
2
|
+
from pandas import DataFrame
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class Normalizer():
|
|
6
|
+
"""
|
|
7
|
+
A wrapper of sklearn normalizers. This will conserve pandas features.
|
|
8
|
+
method be one of ["StandardScaler", "RobustScaler", "MinMaxScaler", "Normalizer", "PowerTransformer"]
|
|
9
|
+
let x with shape [n, d] where n is the sample size, d is the number of features.
|
|
10
|
+
StandardScaler(x) = (x - x.mean(n)) / x.std(n)
|
|
11
|
+
RobustScaler(x) = (x - x.median(n)) / (x.quartile3(n) - x.quartile1(n))
|
|
12
|
+
MinMaxScaler(x) = (x - x.min(n)) / (x.max(n) - x.min(n))
|
|
13
|
+
Normalizer(x) = x / x.norm(d)
|
|
14
|
+
PowerTransformer(x) = yeo-johnson transform(x)
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
def __init__(self, center=True, scale=True, method="RobustScaler"):
|
|
18
|
+
"""
|
|
19
|
+
Args:
|
|
20
|
+
center (bool, optional): Whether to centralize data. Default to True.
|
|
21
|
+
scale (bool, optional): Whether to scaling data after centralized. Default to True.
|
|
22
|
+
method (str, optional): the way to normalize data. Be one of ["StandardScaler", "RobustScaler", "MinMaxScaler", "Normalizer", "PowerTransformer"]
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
kernels = {
|
|
26
|
+
"StandardScaler":
|
|
27
|
+
skprpr.StandardScaler(with_mean=center, with_std=scale),
|
|
28
|
+
"RobustScaler":
|
|
29
|
+
skprpr.RobustScaler(with_centering=center, with_scaling=scale),
|
|
30
|
+
"MinMaxScaler":
|
|
31
|
+
skprpr.MinMaxScaler(),
|
|
32
|
+
"Normalizer":
|
|
33
|
+
skprpr.Normalizer(),
|
|
34
|
+
"PowerTransformer":
|
|
35
|
+
skprpr.PowerTransformer()
|
|
36
|
+
}
|
|
37
|
+
self.kernel = kernels[method]
|
|
38
|
+
|
|
39
|
+
def fit(self, x, y=None):
|
|
40
|
+
"""
|
|
41
|
+
Computing and Recording the mean and std of X for prediction.
|
|
42
|
+
|
|
43
|
+
Args:
|
|
44
|
+
x (pandas.DataFrame or a 2D array): The data to normalize.
|
|
45
|
+
y (pandas.Series or a 1D array): A placeholder only. Normalizer do nothing to y.
|
|
46
|
+
|
|
47
|
+
Returns:
|
|
48
|
+
Normalizer: self after fitting.
|
|
49
|
+
"""
|
|
50
|
+
|
|
51
|
+
self.kernel.fit(x, y)
|
|
52
|
+
|
|
53
|
+
return self
|
|
54
|
+
|
|
55
|
+
def transform(self, x):
|
|
56
|
+
"""
|
|
57
|
+
Transform input x. Only activates after "fit" was called.
|
|
58
|
+
|
|
59
|
+
Args:
|
|
60
|
+
x (pandas.DataFrame or a 2D array): The data to normalize.
|
|
61
|
+
y (pandas.Series or a 1D array): A placeholder only. Normalizer do nothing to y.
|
|
62
|
+
|
|
63
|
+
Returns:
|
|
64
|
+
pandas.DataFrame or a 2D array: Normalized x.
|
|
65
|
+
pandas.Series or a 1D array: Same as input y.
|
|
66
|
+
"""
|
|
67
|
+
x_normalized = DataFrame(self.kernel.transform(x),
|
|
68
|
+
index=x.index,
|
|
69
|
+
columns=x.columns)
|
|
70
|
+
|
|
71
|
+
return x_normalized
|
|
72
|
+
|
|
73
|
+
def fit_transform(self, x, y=None):
|
|
74
|
+
"""
|
|
75
|
+
A functional stack of "fit" and "transform".
|
|
76
|
+
|
|
77
|
+
Args:
|
|
78
|
+
x (pandas.DataFrame or a 2D array): The data to normalize.
|
|
79
|
+
y (pandas.Series or a 1D array): A placeholder only. Normalizer do nothing to y.
|
|
80
|
+
|
|
81
|
+
Returns:
|
|
82
|
+
pandas.DataFrame or a 2D array: Normalized x.
|
|
83
|
+
"""
|
|
84
|
+
self.fit(x, y)
|
|
85
|
+
x_normalized = self.transform(x)
|
|
86
|
+
return x_normalized
|
|
87
|
+
|
|
88
|
+
def inverse_transform(self, x):
|
|
89
|
+
"""
|
|
90
|
+
The inverse transform of normalize.
|
|
91
|
+
|
|
92
|
+
Args:
|
|
93
|
+
x (pandas.DataFrame or a 2D array): The data to revert original scale.
|
|
94
|
+
y (pandas.Series or a 1D array): A placeholder only. Normalizer do nothing to y.
|
|
95
|
+
|
|
96
|
+
Returns:
|
|
97
|
+
pandas.DataFrame or a 2D array: x in original scale.
|
|
98
|
+
"""
|
|
99
|
+
|
|
100
|
+
x_original = DataFrame(self.kernel.inverse_transform(x),
|
|
101
|
+
index=x.index,
|
|
102
|
+
columns=x.columns)
|
|
103
|
+
|
|
104
|
+
return x_original
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
class Pass():
|
|
108
|
+
"""
|
|
109
|
+
Do nothing.
|
|
110
|
+
"""
|
|
111
|
+
|
|
112
|
+
def __init__(self):
|
|
113
|
+
pass
|
|
114
|
+
|
|
115
|
+
def fit(self, x, y=None):
|
|
116
|
+
"""
|
|
117
|
+
Do nothing.
|
|
118
|
+
|
|
119
|
+
Args:
|
|
120
|
+
x (pandas.DataFrame or a 2D array): The data to normalize.
|
|
121
|
+
y (pandas.Series or a 1D array): A placeholder only. Normalizer do nothing to y.
|
|
122
|
+
|
|
123
|
+
Returns:
|
|
124
|
+
Pass: No, do nothing.
|
|
125
|
+
"""
|
|
126
|
+
|
|
127
|
+
return self
|
|
128
|
+
|
|
129
|
+
def transform(self, x):
|
|
130
|
+
"""
|
|
131
|
+
Do nothing.
|
|
132
|
+
|
|
133
|
+
Args:
|
|
134
|
+
x (pandas.DataFrame or a 2D array): The data to normalize.
|
|
135
|
+
|
|
136
|
+
Returns:
|
|
137
|
+
pandas.DataFrame or a 2D array: Normalized x.
|
|
138
|
+
"""
|
|
139
|
+
|
|
140
|
+
return x
|
|
141
|
+
|
|
142
|
+
def fit_transform(self, x, y=None):
|
|
143
|
+
"""
|
|
144
|
+
Do nothing.
|
|
145
|
+
|
|
146
|
+
Args:
|
|
147
|
+
x (pandas.DataFrame or a 2D array): The data to normalize.
|
|
148
|
+
y (pandas.Series or a 1D array): A placeholder only. Normalizer do nothing to y.
|
|
149
|
+
|
|
150
|
+
Returns:
|
|
151
|
+
pandas.DataFrame or a 2D array: x.
|
|
152
|
+
"""
|
|
153
|
+
self.fit(x, y)
|
|
154
|
+
x_normalized = self.transform(x)
|
|
155
|
+
return x_normalized
|
|
156
|
+
|
|
157
|
+
def inverse_transform(self, x):
|
|
158
|
+
"""
|
|
159
|
+
Do nothing.
|
|
160
|
+
|
|
161
|
+
Args:
|
|
162
|
+
x (pandas.DataFrame or a 2D array): The data to revert original scale.
|
|
163
|
+
|
|
164
|
+
Returns:
|
|
165
|
+
pandas.DataFrame or a 2D array: x.
|
|
166
|
+
"""
|
|
167
|
+
|
|
168
|
+
return x
|