Конвейеры трансформаторных каскадов в IBEX, проблемы с доступом к колонкам в Scikit-Learn и Pandas - PullRequest
0 голосов
/ 14 мая 2018

Я пытаюсь создать конвейер, основанный на scikit-learn, для конвейера через фрейм данных pandas. На каждом этапе следует затрагивать только подмножество функций, остальные должны пройти без изменений. Я использую IBEX для этого, поскольку DataFrameMapper, кажется, не выполняет эту работу за меня, поскольку нетронутые поля не сохраняются, для полноты, здесь код DataFrameMapper (который НЕ работает для меня, но, возможно, для кого-то еще) :

from sklearn_pandas import DataFrameMapper
from sklearn.preprocessing import StandardScaler


mapper = DataFrameMapper([
    (['x','y','z'], StandardScaler())
])

df_scaled = mapper.fit_transform(df)

Фрейм данных имеет следующие поля

x y z исходный класс

Используя IBEX, я запускаю следующий код:

from ibex.sklearn.preprocessing import StandardScaler
from ibex.sklearn.preprocessing import LabelEncoder
from ibex import trans

pipeline = (trans(LabelEncoder(), in_cols=['class']) + trans(None, ['source', 'x','y','z'])) | (trans(StandardScaler(), in_cols=['x','y','z']) + trans(None, ['source', 'class']))
df_scaled = pipeline.fit_transform(df)

Теперь я получаю следующую ошибку, поскольку кажется, что поля не сохраняются на втором этапе конвейера:

KeyError: "['x' 'y' 'z'] отсутствует в индексе"

См. GIST полной ошибки

1 Ответ

0 голосов
/ 15 мая 2018

ibex (который я написал в соавторстве) широко использует многоуровневые индексы Pandas.

Предположим, что мы начинаем с

import pandas as pd

df = pd.DataFrame({'source': [2, 44], 'class': [0, 1], 'x': [0, 5], 'y': [0, 6], 'z': [0, 8], 'w': 10})
>>> df
    class   source  w   x   y   z
0   0   2   10  0   0   0
1   1   44  10  5   6

Тогда начало вашего конвейера дает

>>> (trans(LabelEncoder(), in_cols=['class']) + trans(None, ['source', 'x','y','z'])).fit_transform(df)
    functiontransformer_0   functiontransformer_1
    0                       source  x   y   z
0   0                       2       0   0   0
1   1                       44      5   6   8

Это по замыслу.

Вы можете достичь того, чтовы хотите, написав конвейер как:

p = (trans(LabelEncoder(), in_cols='class') + 
    trans(StandardScaler(), in_cols=['x', 'y', 'z']) + 
    trans(None, in_cols='source')
)
>>> p.fit_transform(df)
    functiontransformer_0   functiontransformer_1   functiontransformer_2
    0                       x        y         z    source
0   0                       -1.0    -1.0    -1.0    2
1   1                       1.0     1.0     1.0     44
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...