Нелинейное преобразование объекта в python - PullRequest
4 голосов
/ 08 марта 2020

Чтобы приспособить модель линейной регрессии к некоторым данным обучения X и меткам y, я хочу дополнить свои данные тренировки X нелинейными преобразованиями данных характеристик. Допустим, у нас есть функция x 1 , x 2 и x 3 . И мы хотим использовать дополнительные преобразованные функции:

x 4 = x 1 2 , x 5 = x 2 2 и x 6 = x 3 2

x 7 = exp (x 1 ), x 8 = exp (x 2 ) и x 9 = exp (x 3 )

x 10 = cos (x 1 ), x 11 = cos (x 2 ) и x 12 = cos (x 3 )

Я попробовал следующий подход, который, однако, привел к модели, которая работала очень плохо с точки зрения из Root Среднее квадратичное отклонение как критерий оценки:

import pandas as pd
import numpy as np
from sklearn import linear_model
#import the training data and extract the features and labels from it
DATAPATH = 'train.csv'
data = pd.read_csv(DATAPATH)
features = data.drop(['Id', 'y'], axis=1)
labels = data[['y']]

features['x6'] = features['x1']**2
features['x7'] = features['x2']**2
features['x8'] = features['x3']**2


features['x9'] = np.exp(features['x1'])
features['x10'] = np.exp(features['x2'])
features['x11'] = np.exp(features['x3'])


features['x12'] = np.cos(features['x1'])
features['x13'] = np.cos(features['x2'])
features['x14'] = np.cos(features['x3'])

regr = linear_model.LinearRegression()

regr.fit(features, labels)

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

Приветствия Лукас

1 Ответ

5 голосов
/ 08 марта 2020

В качестве начального замечания я думаю, что есть лучший способ преобразовать все столбцы. Один из вариантов будет выглядеть примерно так:

# Define list of transformation
trans = [lambda a: a, np.square, np.exp, np.cos]

# Apply and concatenate transformations
features = pd.concat([t(features) for t in trans], axis=1)

# Rename column names
features.columns = [f'x{i}' for i in range(1, len(list(features))+1)]

Что касается характеристик модели, как сказал @warped в комментарии, это обычная практика для масштабирования всех ваших данных. В зависимости от вашего распределения данных вы можете использовать различные типы скейлера (обсуждение по этому поводу Стандартный против Minmax Scaler ).

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

from sklearn.preprocessing import MinMaxScaler

scaler = MinMaxScaler()
scaler.fit(features.to_numpy())
scaled_features = scaler.transform(features.to_numpy())

Теперь каждый столбец scaled_features будет в диапазоне от 0 до 1.

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

...