feat(Models): added StaticAverageModel for average ensembling & StaticNaiveModel (#64)

* feat(Models): added StaticAverageModel for average ensembling

* feat(Models): made sure we only pipe in predictions to StaticAverageModel, added StaticNaiveModel as potential baseline

* chore(Models): removed unnecessary commented out code
This commit is contained in:
Mark Aron Szulyovszky
2021-12-21 15:57:08 +01:00
committed by GitHub
parent 79d84cf0a3
commit d3d7184ea4
6 changed files with 64 additions and 9 deletions
+24
View File
@@ -0,0 +1,24 @@
from models.base import Model
import numpy as np
class StaticAverageModel(Model):
'''
Model that averages .
'''
# data_format = 'dataframe'
data_scaling = 'unscaled'
only_column = 'model_'
def fit(self, X, y):
# This is a static model, it can' learn anything
pass
def predict(self, X):
# Make sure there's data to average
assert X.shape[1] > 0
prediction = np.average(X[0])
return np.array([prediction])
def clone(self):
return self
+5 -1
View File
@@ -1,20 +1,24 @@
from typing import Literal, Optional
from sklearn.base import clone
from abc import ABC, abstractmethod, abstractproperty
class Model:
class Model(ABC):
# data_format: Literal['dataframe', 'numpy']
data_scaling: Literal["scaled", "unscaled"]
# data_format: Literal["wide", "narrow"]
only_column: Optional[str]
@abstractmethod
def fit(self, X, y):
pass
@abstractmethod
def predict(self, X):
pass
@abstractmethod
def clone(self):
pass
+1 -1
View File
@@ -6,7 +6,7 @@ class StaticMomentumModel(Model):
Model that uses only one feature: momentum. It's positive if momentum is greater than 0, otherwise it's negative.
'''
data_format = 'dataframe'
# data_format = 'dataframe'
data_scaling = 'unscaled'
only_column = 'mom'
+21
View File
@@ -0,0 +1,21 @@
from models.base import Model
import numpy as np
class StaticNaiveModel(Model):
'''
Model that carries the last observation (from returns) to the next one, naively.
'''
# data_format = 'dataframe'
data_scaling = 'unscaled'
only_column = None
def fit(self, X, y):
# This is a static model, it can' learn anything
pass
def predict(self, X):
return np.array([X[-1][0]])
def clone(self):
return self
+11 -6
View File
@@ -15,6 +15,8 @@ from sklearn.neural_network import MLPRegressor, MLPClassifier
from sklearn.ensemble import AdaBoostRegressor, RandomForestRegressor, ExtraTreesRegressor, AdaBoostClassifier, GradientBoostingClassifier, RandomForestClassifier, ExtraTreesClassifier
from models.base import SKLearnModel
from models.momentum import StaticMomentumModel
from models.average import StaticAverageModel
from models.naive import StaticNaiveModel
import feature_extractors.feature_extractor_presets as feature_extractor_presets
from training.pipeline import run_single_asset_trainig_pipeline
@@ -53,19 +55,22 @@ def get_config() -> tuple[dict, dict, dict]:
# ('RF', SKLearnModel(RandomForestRegressor(n_jobs=-1))),
# ('SVR', SKLearnModel(SVR(kernel='rbf', C=1e3, gamma=0.1)))
]
regression_ensemble_model = [('Ensemble - Ridge', SKLearnModel(Ridge(alpha=0.1)))]
regression_ensemble_model = [('Ensemble - Average', StaticAverageModel())]
# regression_ensemble_model = [('Ensemble - Ridge', SKLearnModel(Ridge(alpha=0.1)))]
classification_models = [
('LR', SKLearnModel(LogisticRegression(n_jobs=-1))),
# ('LDA', SKLearnModel(LinearDiscriminantAnalysis())),
# ('KNN', SKLearnModel(KNeighborsClassifier())),
# ('CART', SKLearnModel(DecisionTreeClassifier())),
('StaticMomentum', StaticMomentumModel(allow_short=True))
('LDA', SKLearnModel(LinearDiscriminantAnalysis())),
('KNN', SKLearnModel(KNeighborsClassifier())),
('CART', SKLearnModel(DecisionTreeClassifier())),
('StaticMomentum', StaticMomentumModel(allow_short=True)),
# ('StaticNaive', StaticNaiveModel()),
# ('NB', SKLearnModel(GaussianNB())),
# ('AB', SKLearnModel(AdaBoostClassifier())),
# ('RF', SKLearnModel(RandomForestClassifier(n_jobs=-1)))
]
classification_ensemble_model = [('Ensemble - CART', SKLearnModel(DecisionTreeClassifier()))]
classification_ensemble_model = [('Ensemble - Average', StaticAverageModel())]
# classification_ensemble_model = [('Ensemble - CART', SKLearnModel(DecisionTreeClassifier()))]
model_config = dict(
level_1_models = regression_models if data_config['method'] == 'regression' else classification_models,
+2 -1
View File
@@ -56,7 +56,8 @@ def run_single_asset_trainig_pipeline(
)
column_name = ticker_to_predict + "_" + model_name
results[column_name] = result
predictions[column_name] = preds
# column names for model outputs should be different, so we can differentiate between original data and model predictions later, where necessary
predictions["model_" + column_name] = preds
if wandb_active:
run = wandb.init(project="price-forecasting", config={"model_type": model_name, "ticker": ticker_to_predict}, reinit=True)