Python中的非线性特征转换

4
为了将线性回归模型拟合给定的训练数据X和标签y,我想通过给定特征的非线性变换来增强我的训练数据X。假设我们有特征x1、x2和x3,我们想使用以下额外的转换特征:
x4 = x12,x5 = x22和x6 = x32 x7 = exp(x1),x8 = exp(x2)和x9 = exp(x3)
x10 = cos(x1),x11 = cos(x2)和x12 = cos(x3)
我尝试了以下方法,但导致模型在均方根误差作为评估标准时表现非常差:
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)

我对机器学习还很陌生,肯定有更好的方法来进行这些非线性特征转换。非常感谢您的帮助。
祝好,Lukas

我的直觉是你的数据集中np.exp项比其他所有项都要大得多,因此你的回归只适合它们。在训练分类器之前,你可以通过对数据进行归一化来避免这种情况。查看这篇文章 - warped
1个回答

6
作为初始备注,我认为有更好的方法来转换所有列。 一种选择是类似于以下内容:
# 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在评论中所说,将所有数据进行缩放是一种常见做法。根据您的数据分布,可以使用不同类型的缩放器(有关此问题的讨论请参见标准缩放器与最小-最大值缩放器)。

由于您使用非线性变换,即使您的原始数据可能是正态分布的,在转换之后,它们将失去这种属性。因此,最好使用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这样的方法之前应用缩放器,则可能会发生数据泄漏,并且这对模型也不利。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接