mirror of
https://github.com/microsoft/qlib.git
synced 2026-07-15 00:36:55 +08:00
@@ -8,6 +8,33 @@ data_handler_config: &data_handler_config
|
|||||||
fit_start_time: 2008-01-01
|
fit_start_time: 2008-01-01
|
||||||
fit_end_time: 2014-12-31
|
fit_end_time: 2014-12-31
|
||||||
instruments: *market
|
instruments: *market
|
||||||
|
infer_processors: [
|
||||||
|
{
|
||||||
|
"class" : "DropCol",
|
||||||
|
"kwargs":{"col_list": ["VWAP0"]}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"class" : "CSZFillna",
|
||||||
|
"kwargs":{"fields_group": "feature"}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
learn_processors: [
|
||||||
|
{
|
||||||
|
"class" : "DropCol",
|
||||||
|
"kwargs":{"col_list": ["VWAP0"]}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"class" : "DropnaProcessor",
|
||||||
|
"kwargs":{"fields_group": "feature"}
|
||||||
|
},
|
||||||
|
"DropnaLabel",
|
||||||
|
{
|
||||||
|
"class": "CSZScoreNorm",
|
||||||
|
"kwargs": {"fields_group": "label"}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
process_type: "independent"
|
||||||
|
|
||||||
port_analysis_config: &port_analysis_config
|
port_analysis_config: &port_analysis_config
|
||||||
strategy:
|
strategy:
|
||||||
class: TopkDropoutStrategy
|
class: TopkDropoutStrategy
|
||||||
@@ -30,7 +57,7 @@ task:
|
|||||||
module_path: qlib.contrib.model.pytorch_nn
|
module_path: qlib.contrib.model.pytorch_nn
|
||||||
kwargs:
|
kwargs:
|
||||||
loss: mse
|
loss: mse
|
||||||
input_dim: 158
|
input_dim: 157
|
||||||
output_dim: 1
|
output_dim: 1
|
||||||
lr: 0.002
|
lr: 0.002
|
||||||
lr_decay: 0.96
|
lr_decay: 0.96
|
||||||
|
|||||||
@@ -207,6 +207,7 @@ class Alpha158(DataHandlerLP):
|
|||||||
learn_processors=_DEFAULT_LEARN_PROCESSORS,
|
learn_processors=_DEFAULT_LEARN_PROCESSORS,
|
||||||
fit_start_time=None,
|
fit_start_time=None,
|
||||||
fit_end_time=None,
|
fit_end_time=None,
|
||||||
|
process_type=DataHandlerLP.PTYPE_A,
|
||||||
**kwargs,
|
**kwargs,
|
||||||
):
|
):
|
||||||
infer_processors = check_transform_proc(infer_processors, fit_start_time, fit_end_time)
|
infer_processors = check_transform_proc(infer_processors, fit_start_time, fit_end_time)
|
||||||
@@ -225,6 +226,7 @@ class Alpha158(DataHandlerLP):
|
|||||||
data_loader=data_loader,
|
data_loader=data_loader,
|
||||||
infer_processors=infer_processors,
|
infer_processors=infer_processors,
|
||||||
learn_processors=learn_processors,
|
learn_processors=learn_processors,
|
||||||
|
process_type=process_type,
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_feature_config(self):
|
def get_feature_config(self):
|
||||||
|
|||||||
@@ -146,7 +146,6 @@ class ALSTM(Model):
|
|||||||
|
|
||||||
raise ValueError("unknown metric `%s`" % self.metric)
|
raise ValueError("unknown metric `%s`" % self.metric)
|
||||||
|
|
||||||
|
|
||||||
def train_epoch(self, x_train, y_train):
|
def train_epoch(self, x_train, y_train):
|
||||||
|
|
||||||
x_train_values = x_train.values
|
x_train_values = x_train.values
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ from ...data.dataset import DatasetH
|
|||||||
from ...data.dataset.handler import DataHandlerLP
|
from ...data.dataset.handler import DataHandlerLP
|
||||||
from ...utils import unpack_archive_with_buffer, save_multiple_parts_file, create_save_path, drop_nan_by_y_index
|
from ...utils import unpack_archive_with_buffer, save_multiple_parts_file, create_save_path, drop_nan_by_y_index
|
||||||
from ...log import get_module_logger, TimeInspector
|
from ...log import get_module_logger, TimeInspector
|
||||||
|
from ...workflow import R
|
||||||
|
|
||||||
|
|
||||||
class DNNModelPytorch(Model):
|
class DNNModelPytorch(Model):
|
||||||
@@ -49,7 +50,7 @@ class DNNModelPytorch(Model):
|
|||||||
self,
|
self,
|
||||||
input_dim,
|
input_dim,
|
||||||
output_dim,
|
output_dim,
|
||||||
layers=(256, 512, 768, 1024, 768, 512, 256, 128, 64),
|
layers=(256, 512, 768, 512, 256, 128, 64),
|
||||||
lr=0.001,
|
lr=0.001,
|
||||||
max_steps=300,
|
max_steps=300,
|
||||||
batch_size=2000,
|
batch_size=2000,
|
||||||
@@ -78,7 +79,7 @@ class DNNModelPytorch(Model):
|
|||||||
self.optimizer = optimizer.lower()
|
self.optimizer = optimizer.lower()
|
||||||
self.loss_type = loss
|
self.loss_type = loss
|
||||||
self.visible_GPU = GPU
|
self.visible_GPU = GPU
|
||||||
self.use_gpu = torch.cuda.is_available()
|
self.use_GPU = torch.cuda.is_available()
|
||||||
|
|
||||||
self.logger.info(
|
self.logger.info(
|
||||||
"DNN parameters setting:"
|
"DNN parameters setting:"
|
||||||
@@ -107,7 +108,7 @@ class DNNModelPytorch(Model):
|
|||||||
loss,
|
loss,
|
||||||
eval_steps,
|
eval_steps,
|
||||||
GPU,
|
GPU,
|
||||||
self.use_gpu,
|
self.use_GPU,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -138,7 +139,7 @@ class DNNModelPytorch(Model):
|
|||||||
)
|
)
|
||||||
|
|
||||||
self._fitted = False
|
self._fitted = False
|
||||||
if self.use_gpu:
|
if self.use_GPU:
|
||||||
self.dnn_model.cuda()
|
self.dnn_model.cuda()
|
||||||
# set the visible GPU
|
# set the visible GPU
|
||||||
if self.visible_GPU:
|
if self.visible_GPU:
|
||||||
@@ -151,13 +152,11 @@ class DNNModelPytorch(Model):
|
|||||||
verbose=True,
|
verbose=True,
|
||||||
save_path=None,
|
save_path=None,
|
||||||
):
|
):
|
||||||
|
|
||||||
df_train, df_valid = dataset.prepare(
|
df_train, df_valid = dataset.prepare(
|
||||||
["train", "valid"], col_set=["feature", "label"], data_key=DataHandlerLP.DK_L
|
["train", "valid"], col_set=["feature", "label"], data_key=DataHandlerLP.DK_L
|
||||||
)
|
)
|
||||||
x_train, y_train = df_train["feature"], df_train["label"]
|
x_train, y_train = df_train["feature"], df_train["label"]
|
||||||
x_valid, y_valid = df_valid["feature"], df_valid["label"]
|
x_valid, y_valid = df_valid["feature"], df_valid["label"]
|
||||||
|
|
||||||
try:
|
try:
|
||||||
wdf_train, wdf_valid = dataset.prepare(["train", "valid"], col_set=["weight"], data_key=DataHandlerLP.DK_L)
|
wdf_train, wdf_valid = dataset.prepare(["train", "valid"], col_set=["weight"], data_key=DataHandlerLP.DK_L)
|
||||||
w_train, w_valid = wdf_train["weight"], wdf_valid["weight"]
|
w_train, w_valid = wdf_train["weight"], wdf_valid["weight"]
|
||||||
@@ -171,7 +170,6 @@ class DNNModelPytorch(Model):
|
|||||||
best_loss = np.inf
|
best_loss = np.inf
|
||||||
evals_result["train"] = []
|
evals_result["train"] = []
|
||||||
evals_result["valid"] = []
|
evals_result["valid"] = []
|
||||||
|
|
||||||
# train
|
# train
|
||||||
self.logger.info("training...")
|
self.logger.info("training...")
|
||||||
self._fitted = True
|
self._fitted = True
|
||||||
@@ -181,13 +179,11 @@ class DNNModelPytorch(Model):
|
|||||||
y_train_values = torch.from_numpy(y_train.values).float()
|
y_train_values = torch.from_numpy(y_train.values).float()
|
||||||
w_train_values = torch.from_numpy(w_train.values).float()
|
w_train_values = torch.from_numpy(w_train.values).float()
|
||||||
train_num = y_train_values.shape[0]
|
train_num = y_train_values.shape[0]
|
||||||
|
|
||||||
# prepare validation data
|
# prepare validation data
|
||||||
x_val_auto = torch.from_numpy(x_valid.values).float()
|
x_val_auto = torch.from_numpy(x_valid.values).float()
|
||||||
y_val_auto = torch.from_numpy(y_valid.values).float()
|
y_val_auto = torch.from_numpy(y_valid.values).float()
|
||||||
w_val_auto = torch.from_numpy(w_valid.values).float()
|
w_val_auto = torch.from_numpy(w_valid.values).float()
|
||||||
|
if self.use_GPU:
|
||||||
if self.use_gpu:
|
|
||||||
x_val_auto = x_val_auto.cuda()
|
x_val_auto = x_val_auto.cuda()
|
||||||
y_val_auto = y_val_auto.cuda()
|
y_val_auto = y_val_auto.cuda()
|
||||||
w_val_auto = w_val_auto.cuda()
|
w_val_auto = w_val_auto.cuda()
|
||||||
@@ -200,16 +196,15 @@ class DNNModelPytorch(Model):
|
|||||||
loss = AverageMeter()
|
loss = AverageMeter()
|
||||||
self.dnn_model.train()
|
self.dnn_model.train()
|
||||||
self.train_optimizer.zero_grad()
|
self.train_optimizer.zero_grad()
|
||||||
|
|
||||||
choice = np.random.choice(train_num, self.batch_size)
|
choice = np.random.choice(train_num, self.batch_size)
|
||||||
x_batch_auto = x_train_values[choice]
|
x_batch_auto = x_train_values[choice]
|
||||||
y_batch_auto = y_train_values[choice]
|
y_batch_auto = y_train_values[choice]
|
||||||
w_batch_auto = w_train_values[choice]
|
w_batch_auto = w_train_values[choice]
|
||||||
|
|
||||||
if self.use_gpu:
|
if self.use_GPU:
|
||||||
x_batch_auto = x_batch_auto.float().cuda()
|
x_batch_auto = x_batch_auto.cuda()
|
||||||
y_batch_auto = y_batch_auto.float().cuda()
|
y_batch_auto = y_batch_auto.cuda()
|
||||||
w_batch_auto = w_batch_auto.float().cuda()
|
w_batch_auto = w_batch_auto.cuda()
|
||||||
|
|
||||||
# forward
|
# forward
|
||||||
preds = self.dnn_model(x_batch_auto)
|
preds = self.dnn_model(x_batch_auto)
|
||||||
@@ -217,10 +212,10 @@ class DNNModelPytorch(Model):
|
|||||||
cur_loss.backward()
|
cur_loss.backward()
|
||||||
self.train_optimizer.step()
|
self.train_optimizer.step()
|
||||||
loss.update(cur_loss.item())
|
loss.update(cur_loss.item())
|
||||||
|
R.log_metrics(train_loss=loss.avg, step=step)
|
||||||
|
|
||||||
# validation
|
# validation
|
||||||
train_loss += loss.val
|
train_loss += loss.val
|
||||||
# print(loss.val)
|
|
||||||
if step and step % self.eval_steps == 0:
|
if step and step % self.eval_steps == 0:
|
||||||
stop_steps += 1
|
stop_steps += 1
|
||||||
train_loss /= self.eval_steps
|
train_loss /= self.eval_steps
|
||||||
@@ -233,6 +228,7 @@ class DNNModelPytorch(Model):
|
|||||||
preds = self.dnn_model(x_val_auto)
|
preds = self.dnn_model(x_val_auto)
|
||||||
cur_loss_val = self.get_loss(preds, w_val_auto, y_val_auto, self.loss_type)
|
cur_loss_val = self.get_loss(preds, w_val_auto, y_val_auto, self.loss_type)
|
||||||
loss_val.update(cur_loss_val.item())
|
loss_val.update(cur_loss_val.item())
|
||||||
|
R.log_metrics(val_loss=loss_val.val, step=step)
|
||||||
if verbose:
|
if verbose:
|
||||||
self.logger.info(
|
self.logger.info(
|
||||||
"[Epoch {}]: train_loss {:.6f}, valid_loss {:.6f}".format(step, train_loss, loss_val.val)
|
"[Epoch {}]: train_loss {:.6f}, valid_loss {:.6f}".format(step, train_loss, loss_val.val)
|
||||||
@@ -255,7 +251,7 @@ class DNNModelPytorch(Model):
|
|||||||
|
|
||||||
# restore the optimal parameters after training ??
|
# restore the optimal parameters after training ??
|
||||||
self.dnn_model.load_state_dict(torch.load(save_path))
|
self.dnn_model.load_state_dict(torch.load(save_path))
|
||||||
if self.use_gpu:
|
if self.use_GPU:
|
||||||
torch.cuda.empty_cache()
|
torch.cuda.empty_cache()
|
||||||
|
|
||||||
def get_loss(self, pred, w, target, loss_type):
|
def get_loss(self, pred, w, target, loss_type):
|
||||||
@@ -274,12 +270,12 @@ class DNNModelPytorch(Model):
|
|||||||
raise ValueError("model is not fitted yet!")
|
raise ValueError("model is not fitted yet!")
|
||||||
x_test_pd = dataset.prepare("test", col_set="feature")
|
x_test_pd = dataset.prepare("test", col_set="feature")
|
||||||
x_test = torch.from_numpy(x_test_pd.values).float()
|
x_test = torch.from_numpy(x_test_pd.values).float()
|
||||||
if self.use_gpu:
|
if self.use_GPU:
|
||||||
x_test = x_test.cuda()
|
x_test = x_test.cuda()
|
||||||
self.dnn_model.eval()
|
self.dnn_model.eval()
|
||||||
|
|
||||||
with torch.no_grad():
|
with torch.no_grad():
|
||||||
if self.use_gpu:
|
if self.use_GPU:
|
||||||
preds = self.dnn_model(x_test).detach().cpu().numpy()
|
preds = self.dnn_model(x_test).detach().cpu().numpy()
|
||||||
else:
|
else:
|
||||||
preds = self.dnn_model(x_test).detach().numpy()
|
preds = self.dnn_model(x_test).detach().numpy()
|
||||||
@@ -331,7 +327,7 @@ class Net(nn.Module):
|
|||||||
dnn_layers.append(drop_input)
|
dnn_layers.append(drop_input)
|
||||||
for i, (input_dim, hidden_units) in enumerate(zip(layers[:-1], layers[1:])):
|
for i, (input_dim, hidden_units) in enumerate(zip(layers[:-1], layers[1:])):
|
||||||
fc = nn.Linear(input_dim, hidden_units)
|
fc = nn.Linear(input_dim, hidden_units)
|
||||||
activation = nn.ReLU()
|
activation = nn.LeakyReLU(negative_slope=0.1, inplace=False)
|
||||||
bn = nn.BatchNorm1d(hidden_units)
|
bn = nn.BatchNorm1d(hidden_units)
|
||||||
seq = nn.Sequential(fc, bn, activation)
|
seq = nn.Sequential(fc, bn, activation)
|
||||||
dnn_layers.append(seq)
|
dnn_layers.append(seq)
|
||||||
@@ -354,7 +350,7 @@ class Net(nn.Module):
|
|||||||
def _weight_init(self):
|
def _weight_init(self):
|
||||||
for m in self.modules():
|
for m in self.modules():
|
||||||
if isinstance(m, nn.Linear):
|
if isinstance(m, nn.Linear):
|
||||||
nn.init.xavier_normal_(m.weight, gain=1)
|
nn.init.kaiming_normal_(m.weight, a=0.1, mode="fan_in", nonlinearity="leaky_relu")
|
||||||
|
|
||||||
def forward(self, x):
|
def forward(self, x):
|
||||||
cur_output = x
|
cur_output = x
|
||||||
|
|||||||
@@ -90,6 +90,18 @@ class DropnaLabel(DropnaProcessor):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
class DropCol(Processor):
|
||||||
|
def __init__(self, col_list=[]):
|
||||||
|
self.col_list = col_list
|
||||||
|
|
||||||
|
def __call__(self, df):
|
||||||
|
if isinstance(df.columns, pd.MultiIndex):
|
||||||
|
mask = df.columns.get_level_values(-1).isin(self.col_list)
|
||||||
|
else:
|
||||||
|
mask = df.columns.isin(self.col_list)
|
||||||
|
return df.loc[:, ~mask]
|
||||||
|
|
||||||
|
|
||||||
class TanhProcess(Processor):
|
class TanhProcess(Processor):
|
||||||
""" Use tanh to process noise data"""
|
""" Use tanh to process noise data"""
|
||||||
|
|
||||||
@@ -240,7 +252,8 @@ class CSZScoreNorm(Processor):
|
|||||||
def __call__(self, df):
|
def __call__(self, df):
|
||||||
# try not modify original dataframe
|
# try not modify original dataframe
|
||||||
cols = get_group_columns(df, self.fields_group)
|
cols = get_group_columns(df, self.fields_group)
|
||||||
df[cols] = df[cols].groupby("datetime").apply(lambda df: (df - df.mean()).div(df.std()))
|
df[cols] = df[cols].groupby("datetime").apply(lambda x: (x - x.mean()).div(x.std()))
|
||||||
|
|
||||||
return df
|
return df
|
||||||
|
|
||||||
|
|
||||||
@@ -258,3 +271,15 @@ class CSRankNorm(Processor):
|
|||||||
t *= 3.46 # NOTE: towards unit std
|
t *= 3.46 # NOTE: towards unit std
|
||||||
df[cols] = t
|
df[cols] = t
|
||||||
return df
|
return df
|
||||||
|
|
||||||
|
|
||||||
|
class CSZFillna(Processor):
|
||||||
|
"""Cross Sectional Fill Nan"""
|
||||||
|
|
||||||
|
def __init__(self, fields_group=None):
|
||||||
|
self.fields_group = fields_group
|
||||||
|
|
||||||
|
def __call__(self, df):
|
||||||
|
cols = get_group_columns(df, self.fields_group)
|
||||||
|
df[cols] = df[cols].groupby("datetime").apply(lambda x: x.fillna(x.mean()))
|
||||||
|
return df
|
||||||
|
|||||||
Reference in New Issue
Block a user