#python #numpy #scikit-learn #converter #pipeline
#python #numpy #scikit-learn #конвертеры #конвейер
Вопрос:
У меня есть преобразователь, который вычисляет процент значений для каждой группы. Изначально использовался pandas, потому что я начал с pandas, а с именами столбцов удобнее обращаться. Однако теперь мне нужно интегрироваться в sklearn-pipeline.
Как я могу преобразовать свой Transformer для поддержки массивов numpy из конвейера sklearn вместо фреймов данных pandas? Дело в том, что self.colname
это нельзя использовать для массивов numpy, и я думаю, что группировку нужно выполнять по-другому.
Как реализовать постоянство такого преобразователя, поскольку эти веса должны быть загружены с диска, чтобы развернуть такой преобразователь в конвейере.
class PercentageTransformer(TransformerMixin):
def __init__(self, colname,typePercentage='totalTarget', _target='TARGET', _dropOriginal=True):
self.colname = colname
self._target = _target
self._dropOriginal = _dropOriginal
self.typePercentage = typePercentage
def fit(self, X, y, *_):
original = pd.concat([y,X], axis=1)
grouped = original.groupby([self.colname, self._target]).size()
if self.typePercentage == 'totalTarget':
df = grouped / original[self._target].sum()
else:
df = (grouped / grouped.groupby(level=0).sum())
if self.typePercentage == 'totalTarget':
nameCol = "pre_" self.colname
else:
nameCol = "pre2_" self.colname
self.nameCol = nameCol
grouped = df.reset_index(name=nameCol)
groupedOnly = grouped[grouped[self._target] == 1]
groupedOnly = groupedOnly.drop(self._target, 1)
self.result = groupedOnly
return self
def transform(self, dataF):
mergedThing = pd.merge(dataF, self.result, on=self.colname, how='left')
mergedThing.loc[(mergedThing[self.nameCol].isnull()), self.nameCol] = 0
if self._dropOriginal:
mergedThing = mergedThing.drop(self.colname, 1)
return mergedThing
Он будет использоваться в конвейере, подобном этому:
pipeline = Pipeline([
('features', FeatureUnion([
('continuous', Pipeline([
('extract', ColumnExtractor(CONTINUOUS_FIELDS)),
])),
('factors', Pipeline([
('extract', ColumnExtractor(FACTOR_FIELDS)),
# using labelencoding and all bias
('bias', PercentageAllTransformer(FACTOR_FIELDS, _dropOriginal=True, typePercentage='totalTarget')),
]))
], n_jobs=-1)),
('estimator', estimator)
])
pipeline
Будет оснащен X
и y
, где оба являются фреймами данных. Я не уверен, что X.as_matrix
помогло бы.
Комментарии:
1.
pandas
объекты являются оболочками вокругnumpy
объектов. Я полагаю, вы имеете в виду, чтоpandas
массива нетSeries
? В любом случае, возможно, ваша проблема была бы решена простым возвратомself.values
вместоself
.2. Что касается постоянства, есть несколько способов добиться этого. Как правило, для сериализации объектов в Python будет использоваться
pickle
модуль.3. Действительно, я имел в виду фреймы данных pandas. Дело в том, что, если я правильно понимаю: orignal
original.groupby([self.colname, self._target]
больше не является фреймом данных, а массивом numpy, например, имена столбцов больше не работают. таким образом, self.values, похоже, недостаточно.4. Нет,
groupby
возвращаетgroupby
объект, который обычно используется для генерации новогоDataFrame
. Вы не можете получить доступself.colname, self._target
, как обычно, потому что по умолчанию они используются какindex
к новомуDataFrame
. Передайтеas_index=False
вgroupby
, чтобы сохранить столбцы вашей группировки в качестве столбцов.
Ответ №1:
- Преобразование туда и обратно
В Pandas есть метод .to_records() и, как вы упомянули, метод .as_matrix(). Метод .to_records () фактически сохранит имена ваших столбцов для вас. Numpy поддерживает именованные столбцы в массивах. Смотрите здесь.
- Постоянство
В Pandas есть метод pandas.to_pickle(obj, filename), который принимает объект pandas и обрабатывает его. Существует соответствующий метод pandas.read_pickle(filename).
В Numpy также есть функции сохранения и загрузки.