Как выполнить обратное преобразование прогнозов регрессии после конвейера?

Я пытаюсь выяснить, как масштабировать мои данные (предположительно, используя inverse_transform) для прогнозов, когда я использую конвейер. Приведенные ниже данные являются лишь примером. Мои фактические данные намного больше и сложнее, но я хочу использовать RobustScaler (так как мои данные имеют выбросы) и Lasso (поскольку мои данные имеют множество бесполезных функций). Я новичок в трубопроводах в целом.

По сути, если я пытаюсь использовать эту модель для предсказания чего-либо, я хочу, чтобы этот прогноз был в немасштабированном виде. Возможно ли это с трубопроводом? Как я могу сделать это с помощью inverse_transform?

import pandas as pd
from sklearn.linear_model import Lasso
from sklearn.model_selection import train_test_split
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import RobustScaler

data = [[100, 1, 50],[500 , 3, 25],[1000 , 10, 100]]
df = pd.DataFrame(data,columns=['Cost','People', 'Supplies'])

X = df[['People', 'Supplies']]
y = df[['Cost']]

#Split
X_train,X_test,y_train,y_test = train_test_split(X,y)

#Pipeline
pipeline = Pipeline([('scale', RobustScaler()),
            ('alg', Lasso())])

clf = pipeline.fit(X_train,y_train)

train_score = clf.score(X_train,y_train)
test_score = clf.score(X_test,y_test)

print ("training score:", train_score)
print ("test score:", test_score)

#Predict example 
example = [[10,100]]
clf.predict(example)

person Kelsey    schedule 14.05.2019    source источник
comment
Масштабируются ли данные на выходе? Я не вижу в коде, где вы вызывали .transform() на входах, чтобы использовать robustscaler, ни для вашего поезда, ни для теста   -  person G. Anderson    schedule 14.05.2019
comment
Возможно, тогда это одна из моих проблем. Опять же, очень новичок в конвейерах. Должен ли я вызывать fit_transform () где-нибудь в конвейере?   -  person Kelsey    schedule 14.05.2019
comment
Типичный рабочий процесс - pipeline.fit(train), pipeline.transform(train), pipeline.transform(test), тогда вы сможете использовать встроенный inverse_transform, чтобы отменить преобразование после прогнозирования.   -  person G. Anderson    schedule 14.05.2019
comment
Поэтому, когда я пытаюсь выполнить pipeline.transform (X_train, y_train), я получаю сообщение об ошибке: AttributeError: объект «Lasso» не имеет атрибута «transform».   -  person Kelsey    schedule 14.05.2019
comment
Похоже на проблему, при которой конвейер не может преобразоваться, если трансформатор не является последним шагом. Обходные пути обсуждаются в этом вопросе   -  person G. Anderson    schedule 14.05.2019
comment
Понятно. Если я попытаюсь сделать это без конвейера, то на самом деле у меня возникнет другая проблема с inverse_transform. Я просто не могу здесь выиграть. Я получаю сообщение об ошибке: ValueError: не транслируемый выходной операнд с формой (1,1) не соответствует форме трансляции (1,2). По сути, это не позволяет мне масштабировать только одно предсказание?   -  person Kelsey    schedule 14.05.2019


Ответы (1)


Простое объяснение

Ваш конвейер преобразует только значения в X, а не y. Различия, которые вы видите в y для прогнозов, связаны с различиями в значениях коэффициентов между двумя моделями, подобранными с использованием масштабированных и немасштабированных данных.

Итак, если вы хотите получить этот прогноз в немасштабированном выражении, исключите средство масштабирования из своего конвейера. Если вы хотите, чтобы этот прогноз был в масштабированном выражении, вам необходимо масштабировать новые данные прогноза перед их передачей в функцию .predict (). На самом деле конвейер делает это за вас автоматически, если вы включили в него шаг масштабирования.

Масштабирование и регрессия

Практическая цель масштабирования здесь может заключаться в том, что люди и расходные материалы имеют разные динамические диапазоны. Использование RobustScaler () удаляет медианное значение и масштабирует данные в соответствии с диапазоном квантилей. Обычно вы делаете это только в том случае, если считаете, что у ваших сотрудников или поставщиков есть выбросы, которые могут отрицательно повлиять на выборочное среднее / дисперсию. Если это не так, вы, вероятно, использовали бы StandardScaler () для удаления среднего и масштабирования до единичной дисперсии.

После масштабирования данных вы можете сравнить коэффициенты регрессии, чтобы лучше понять, как модель делает свои прогнозы. Это важно, поскольку коэффициенты для немасштабированных данных могут вводить в заблуждение.

Пример использования вашего кода

В следующем примере показано:

  1. Прогнозы с использованием масштабированных и немасштабированных данных с конвейером и без него.

  2. Прогнозы совпадают в обоих случаях.

  3. Вы можете увидеть, что делает конвейер в фоновом режиме, посмотрев на примеры, не относящиеся к конвейеру.

  4. Я также включил коэффициенты модели в обоих случаях. Обратите внимание, что коэффициенты или веса для масштабированных и немасштабированных подобранных моделей сильно различаются.

  5. # P13 #
    import pandas as pd
    from sklearn.linear_model import Lasso
    from sklearn.model_selection import train_test_split
    from sklearn.pipeline import Pipeline
    from sklearn.preprocessing import RobustScaler
    
    data = [[100, 1, 50],[500 , 3, 25],[1000 , 10, 100]]
    df = pd.DataFrame(data,columns=['Cost','People', 'Supplies'])
    
    X = df[['People', 'Supplies']]
    y = df[['Cost']]
    
    #Split
    X_train,X_test,y_train,y_test = train_test_split(X,y,random_state=0)
    
    #Pipeline
    pipeline_scaled = Pipeline([('scale', RobustScaler()),
                         ('alg', Lasso(random_state=0))])
    
    pipeline_unscaled = Pipeline([('alg', Lasso(random_state=0))])
    
    clf1 = pipeline_scaled.fit(X_train,y_train)
    clf2 = pipeline_unscaled.fit(X_train,y_train)
    
    
    #Pipeline predict example 
    example = [[10,100]]
    print('Pipe Scaled: ', clf1.predict(example))
    print('Pipe Unscaled: ',clf2.predict(example))
    
    #------------------------------------------------
    
    rs = RobustScaler()
    reg = Lasso(random_state=0)
    # Scale the taining data 
    X_train_scaled = rs.fit_transform(X_train)
    reg.fit(X_train_scaled, y_train)
    # Scale the example
    example_scaled = rs.transform(example)
    # Predict using the scaled data
    print('----------------------')
    print('Reg Scaled: ', reg.predict(example_scaled))
    print('Scaled Coefficents:',reg.coef_)
    
    #------------------------------------------------
    reg.fit(X_train, y_train)
    print('Reg Unscaled: ', reg.predict(example))
    print('Unscaled Coefficents:',reg.coef_)
    

Выходы:

Pipe Scaled:  [1892.]
Pipe Unscaled:  [-699.6]
----------------------
Reg Scaled:  [1892.]
Scaled Coefficents: [199.  -0.]
Reg Unscaled:  [-699.6]
Unscaled Coefficents: [  0.     -15.9936]

Для полноты

В исходном вопросе вы спрашиваете о масштабировании ваших данных. Я не думаю, что это то, что вам действительно нужно, поскольку X_train - это ваши немасштабированные данные. Однако в следующем примере показано, как это можно сделать, используя объект масштабирования из вашего конвейера.

#------------------------------------------------
pipeline_scaled['scale'].inverse_transform(X_train_scaled)

Вывод

array([[ 3., 25.],
       [ 1., 50.]])
person Jake Drew    schedule 18.12.2020