mirror of
https://github.com/microsoft/qlib.git
synced 2026-07-11 14:56:55 +08:00
online_serving V3
This commit is contained in:
@@ -8,7 +8,7 @@ from qlib import get_module_logger
|
||||
|
||||
class TaskCollector:
|
||||
"""
|
||||
Collect the record results of the finished tasks with key and filter
|
||||
Collect the record (or its results) of the tasks
|
||||
"""
|
||||
|
||||
def __init__(self, experiment_name: str) -> None:
|
||||
@@ -17,7 +17,7 @@ class TaskCollector:
|
||||
self.logger = get_module_logger("TaskCollector")
|
||||
|
||||
def list_recorders(self, rec_filter_func=None):
|
||||
""""""
|
||||
|
||||
recs = self.exp.list_recorders()
|
||||
recs_flt = {}
|
||||
for rid, rec in recs.items():
|
||||
@@ -26,57 +26,77 @@ class TaskCollector:
|
||||
|
||||
return recs_flt
|
||||
|
||||
def list_recorders_by_task(self, task_filter_func=None):
|
||||
def rec_filter(recorder):
|
||||
return task_filter_func(self.get_task(recorder))
|
||||
|
||||
return self.list_recorders(rec_filter)
|
||||
|
||||
def list_latest_recorders(self, rec_filter_func=None):
|
||||
recs_flt = self.list_recorders(rec_filter_func)
|
||||
max_test = self.latest_time(recs_flt)
|
||||
latest_rec = {}
|
||||
for rid, rec in recs_flt.items():
|
||||
if self.get_task(rec)["dataset"]["kwargs"]["segments"]["test"] == max_test:
|
||||
latest_rec[rid] = rec
|
||||
return latest_rec
|
||||
|
||||
def get_recorder_by_id(self, recorder_id):
|
||||
return self.exp.get_recorder(recorder_id, create=False)
|
||||
|
||||
def list_recorders_by_task(self, task_filter_func):
|
||||
"""[summary]
|
||||
def get_task(self, recorder):
|
||||
if isinstance(recorder, str):
|
||||
recorder = self.get_recorder_by_id(recorder_id=recorder)
|
||||
try:
|
||||
task = recorder.load_object("task")
|
||||
except OSError:
|
||||
raise OSError(f"Can't find task in {recorder.info['id']}, have you trained with model.trainer.task_train?")
|
||||
return task
|
||||
|
||||
Parameters
|
||||
----------
|
||||
task_filter_func : [type], optional
|
||||
[description], by default None
|
||||
"""
|
||||
def latest_time(self, recorders):
|
||||
if len(recorders) == 0:
|
||||
raise Exception(f"Can't find any recorder in {self.exp_name}")
|
||||
max_test = max(self.get_task(rec)["dataset"]["kwargs"]["segments"]["test"] for rec in recorders.values())
|
||||
return max_test
|
||||
|
||||
def rec_filter_func(recorder):
|
||||
try:
|
||||
task = recorder.load_object("task")
|
||||
except OSError:
|
||||
raise OSError(
|
||||
f"Can't find task in {recorder.info['id']}, have you trained with model.trainer.task_train?"
|
||||
)
|
||||
return task_filter_func(task)
|
||||
|
||||
return self.list_recorders(rec_filter_func)
|
||||
class RollingCollector(TaskCollector):
|
||||
"""
|
||||
Collect the record results of the rolling tasks
|
||||
"""
|
||||
|
||||
def collect_predictions(
|
||||
def __init__(
|
||||
self,
|
||||
get_key_func,
|
||||
task_filter_func=None,
|
||||
):
|
||||
"""
|
||||
Collect predictions using a filter and a key function.
|
||||
experiment_name: str,
|
||||
) -> None:
|
||||
super().__init__(experiment_name)
|
||||
self.logger = get_module_logger("RollingCollector")
|
||||
|
||||
def collect_rolling_predictions(self, get_key_func, rec_filter_func=None):
|
||||
"""For rolling tasks, the predictions will be in the diffierent recorder.
|
||||
To collect and concat the predictions of one rolling task, get_key_func will help this method see which group a recorder will be.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
experiment_name : str
|
||||
get_key_func : Callable[[dict], bool] -> Union[Number, str, tuple]
|
||||
get the key of a task when collect it
|
||||
filter_func : Callable[[dict], bool] -> bool
|
||||
to judge a task will be collected or not
|
||||
get_key_func : Callable[dict,str]
|
||||
a function that get task config and return its group str
|
||||
rec_filter_func : Callable[Recorder,bool], optional
|
||||
a function that decide whether filter a recorder, by default None
|
||||
|
||||
Returns
|
||||
-------
|
||||
dict
|
||||
the dict of predictions
|
||||
a dict of {group: predictions}
|
||||
"""
|
||||
recs_flt = self.list_recorders(task_filter_func=task_filter_func, only_have_task=True)
|
||||
|
||||
# filter records
|
||||
recs_flt = self.list_recorders(rec_filter_func)
|
||||
|
||||
# group
|
||||
recs_group = {}
|
||||
for _, rec in recs_flt.items():
|
||||
params = rec.task
|
||||
group_key = get_key_func(params)
|
||||
task = self.get_task(rec)
|
||||
group_key = get_key_func(task)
|
||||
recs_group.setdefault(group_key, []).append(rec)
|
||||
|
||||
# reduce group
|
||||
@@ -85,39 +105,12 @@ class TaskCollector:
|
||||
pred_l = []
|
||||
for rec in rec_l:
|
||||
pred_l.append(rec.load_object("pred.pkl").iloc[:, 0])
|
||||
pred = pd.concat(pred_l).sort_index()
|
||||
# Make sure the pred are sorted according to the rolling start time
|
||||
pred_l.sort(key=lambda pred: pred.index.get_level_values("datetime").min())
|
||||
pred = pd.concat(pred_l)
|
||||
# If there are duplicated predition, we use the latest perdiction
|
||||
pred = pred[~pred.index.duplicated(keep="last")]
|
||||
pred = pred.sort_index()
|
||||
reduce_group[k] = pred
|
||||
|
||||
self.logger.info(f"Collect {len(reduce_group)} predictions in {self.exp_name}")
|
||||
return reduce_group
|
||||
|
||||
def collect_latest_records(
|
||||
self,
|
||||
task_filter_func=None,
|
||||
):
|
||||
"""Collect latest recorders using a filter.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
task_filter_func : Callable[[dict], bool], optional
|
||||
to judge a task will be collected or not, by default None
|
||||
|
||||
Returns
|
||||
-------
|
||||
dict, tuple
|
||||
a dict of recorders and a tuple of test segments
|
||||
"""
|
||||
recs_flt = self.list_recorders(task_filter_func=task_filter_func, only_have_task=True)
|
||||
|
||||
if len(recs_flt) == 0:
|
||||
self.logger.warning("Can not collect any recorders...")
|
||||
return None, None
|
||||
max_test = max(rec.task["dataset"]["kwargs"]["segments"]["test"] for rec in recs_flt.values())
|
||||
|
||||
latest_record = {}
|
||||
for rid, rec in recs_flt.items():
|
||||
if rec.task["dataset"]["kwargs"]["segments"]["test"] == max_test:
|
||||
latest_record[rid] = rec
|
||||
|
||||
self.logger.info(f"Collect {len(latest_record)} latest records in {self.exp_name}")
|
||||
return latest_record, max_test
|
||||
return reduce_group
|
||||
Reference in New Issue
Block a user