Я хочу запустить все задачи предварительной обработки и оптимизации модели в одном конвейере, выполнив следующие шаги:
- однотонное кодирование
- уменьшение размера SVD
- агрегация (pandas groupby)
- Моделирование случайного леса
мои входные переменные:
- X_train с 349 строками, которые после шага 3 (агрегация) станут 338 строками
- y_train с 338 строками
Я получаю ошибку «Найдены входные переменные с непоследовательным количеством образцов».
Это потому, что sklearn не допускает разницыномер строки между X_train и y_train.
Знаете ли вы другой способ, если возможно, для агрегации в конвейере?
вот мой код:
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import OneHotEncoder
from sklearn.decomposition import TruncatedSVD
from sklearn.base import BaseEstimator, TransformerMixin
from sklearn.compose import ColumnTransformer
# does nothing, but is here to collect numerical columns
class nothing(BaseEstimator, TransformerMixin):
def fit(self, X, y=None):
return self
def transform(self, X):
return X
class Aggregator(BaseEstimator, TransformerMixin):
def fit(self, X, y=None):
return self
def transform(self, X):
X = pd.DataFrame(X)
X = X.rename(columns = {0 :'InvoiceNo', 1 : 'amount', 2:'Quantity',
3:'UnitPrice',4:'CustomerID' })
X['InvoiceNo'] = X['InvoiceNo'].astype('int')
X['Quantity'] = X['Quantity'].astype('float64')
X['UnitPrice'] = X['UnitPrice'].astype('float64')
aggregations = dict()
for col in range(5, X.shape[1]-1) :
aggregations[col] = 'max'
aggregations.update({ 'CustomerID' : 'first',
'amount' : "sum",'Quantity' : 'mean', 'UnitPrice' : 'mean'})
# aggregating all basket lines
result = X.groupby('InvoiceNo').agg(aggregations)
# add number of lines in the basket
result['lines_nb'] = X.groupby('InvoiceNo').size()
return result
numeric_features = ['InvoiceNo','amount', 'Quantity', 'UnitPrice',
'CustomerID']
numeric_transformer = Pipeline(steps=[('nothing', nothing())])
categorical_features = ['StockCode', 'Country']
preprocessor = ColumnTransformer(
[
# 'num' transformer does nothing, but is here to
# collect numerical columns
('num', numeric_transformer ,numeric_features ),
('cat', Pipeline([
('onehot', OneHotEncoder(handle_unknown='ignore')),
('best', TruncatedSVD(n_components=100)),
]), categorical_features)
]
)
pipe = Pipeline(steps=[
('preprocessor', preprocessor),
('aggregator', Aggregator()),
('rf', RandomForestClassifier(n_estimators=400,
max_features='auto',
class_weight=class_weights)),
])
X_train_transformed = pipe.fit_transform(X_train)
ValueError: Found input variables with inconsistent numbers of samples: [349, 338]
более подробно, чтобы ответить на комментарий @desertnaut:
пример:
X_train содержит 4 строки: customer_num: 1 article_ref: 1 money: 10 $customer_num: 1 article_ref: 2 money:15 $ customer_num: 2 article_ref: 5 money: 5 $ customer_num: 3 article_ref: 4 money: 11 $
Я объединяю 4 строки с pandas groupby = cucstomer_num, результирующий кадр данных, X_train_transformed , имеет 3 строки, по одной на клиента
y_train имеет 3 строки, содержащие группу (метка для прогнозирования) для customer_num 1, customer_num 2 и customer_num 3.
Стандартный метод:
конвейер 1: преобразовать X_train (4 строки) в X_train_transformed (3 строки)
конвейер 2: подогнать модель к (X_train_transformed (3 строки), y_train (3 строки))
Я хочу иметь один конвейер для обработки трубопровода 1 и трубопровода 2