Сравнить агрегированные показатели по условиям работы с отсеченным фреймом данных на основе нескольких столбцов с различным порогом - PullRequest
0 голосов
/ 23 мая 2019

У меня есть степень безопасности юниверса (скажем, S & P500) с фундаментальными ценностями (например, Price_to_earnings, Price_to_book, Return_on_equity и т. Д.)
Я должен сравнить влияние различных комбинаций фундаментальных порогов ((PE<x , PB <y, ROE >z), где x, y, z - все комбинации ((10,15,20), (2,5,8) и т. Д.) На различные показатели портфеля (например, коэффициент Шарпа, mean_rtn и т. д.)

Я пробовал эти решения:

1) Запуск нескольких циклов for на основных пороговых значениях и отсечение df каждый раз и сохранение результата метрики. Но он становится чрезвычайно масштабируемым по нескольким условиям и сохраняет результаты для некоторого разумного

2) Я попытался создать фреймворк, используя sklearn.Pipeline и GridSearch, чтобы упростить этот процесс

### custom transformer to clip df
class row_clipper(BaseEstimator,TransformerMixin):

    def __init__(self,col_name,threshold,symbol):
        self.conditional_symbol = symbol
        self.col_name = col_name
        self.threshold = threshold

    def fit(self,df):
        pass ## do nothing

    def transform(self):
        pass ## again do nothing

    def fit_transform(self, df, y=None, **fit_params):
        return eval('df[df[self.col_name] %s self.threshold]' %self.conditional_symbol)


pipe = Pipeline(
    [
        ('clip_pe', row_clipper(col_name='pe', symbol = '<='))
        ,('clip_pb', row_clipper(col_name='pb', symbol = '<='))
        ,('clip_roe', row_clipper(col_name='roe', symbol = '>=')
    ]
)

def mean_rtn(clipped_df, nothing_else, rtn_column = 'rtn_1'):
    return (nothing_else.groupby('Date')[rtn_column].mean()).mean()

mean_rtn_scorer = sklearn.metrics.make_scorer(mean_rtn , greater_is_better=True)

param_grid = {
    'clip_pe__threshold' : [10,15,20,25],
    'clip_pb__threshold' : [1.5,2.5,5,7.5,10],
    'clip_roe__threshold' : np.arange(5,25),
}

grid = GridSearchCV(pipe,param_grid, cv = [(slice(None), slice(None))], scoring=mean_rtn_scorer)
grid.fit(df,df)

## and grid.cv_results_ gives me this result
grid.cv_results_

2-е решение, безусловно, является улучшением, но оно все же требует от меня, чтобы многие из моих требований были адаптированы к фреймворку sklearn, который, как мне кажется, не предназначен для этой работы (я могу ошибаться). Я ищу лучшее решение для реализации этой структуры.

...