【发布时间】:2020-01-05 19:17:32
【问题描述】:
我正在构建一个自定义转换器,它执行几个步骤来预处理数据。首先是它应用了我编写的一组功能,这些功能将采用现有功能并设计新功能。从那里,分类变量将被一次性编码。最后一步是从 DataFrame 中删除不再需要的特征或列。
我使用的数据集是 Kaggle House Prices 数据集。
这里的问题是确保测试集中的分类虚拟变量与训练集中相同,因为训练集中某个特征的某些类别可能不在测试集中,因此测试集不会” t 有该类别的虚拟变量。我已经完成了研究,遇到了这个solution,我正在尝试在我的自定义转换器类中实现第一个答案。首先,我不确定这是否是最好的方法。其次,我收到了一个下面提到的错误。
我已经包含了我应用于数据的函数的完整列表,但仅在下面显示了几个实际函数。
class HouseFeatureTransformer(BaseEstimator, TransformerMixin):
def __init__(self, funcs, func_cols, drop_cols, drop_first=True):
self.funcs = funcs
self.func_cols = func_cols
self.train_cols = None
self.drop_cols = drop_cols
self.drop_first = drop_first
def fit(self, X, y=None):
X_trans = self.apply_funcs(X)
X_trans.drop(columns=self.drop_cols, inplace=True)
#save training_columns to compare to columns of any later seen dataset
self.train_cols = X_trans.columns
return self
def transform(self, X, y=None):
X_test = self.apply_funcs(X)
X_test.drop(columns=self.drop_cols, inplace=True)
test_cols = X_test.columns
#ensure that all columns in the training set are present in the test set
#set should be empty for first fit_transform
missing_cols = set(self.train_cols) - set(test_cols)
for col in missing_cols:
X_test[col] = 0
#reduce columns in test set to only what was in the training set
X_test = X_test[self.train_cols]
return X_test.values
def apply_funcs(self, X):
#apply each function to respective column
for func, func_col in zip(self.funcs, self.func_cols):
X[func_col] = X.apply(func, axis=1)
#one hot encode categorical variables
X = pd.get_dummies(X, drop_first=self.drop_first)
return X
#functions to apply
funcs = [sold_age, yrs_remod, lot_shape, land_slope, rfmat, bsmt_bath, baths,
other_rooms, fence_qual, newer_garage]
#feature names
func_cols = ['sold_age', 'yr_since_remod', 'LotShape', 'LandSlope', 'RoofMatl', 'BsmtBaths', 'Baths', \
'OtherRmsAbvGr', 'Fence', 'newer_garage']
#features to drop
to_drop = ['Alley', 'Utilities', 'Condition2', 'HouseStyle', 'LowQualFinSF', 'EnclosedPorch', \
'3SsnPorch', 'ScreenPorch', 'PoolArea', 'PoolQC', 'MiscFeature', 'MiscVal', \
'YearBuilt', 'YrSold', 'YearRemodAdd', 'BsmtFullBath', 'BsmtHalfBath', 'FullBath', 'HalfBath', \
'TotRmsAbvGrd', 'GarageYrBlt', '1stFlrSF', '2ndFlrSF', 'BsmtFinSF1', 'BsmtFinSF2', 'BsmtUnfSF', 'ExterQual', \
'ExterCond', 'BsmtQual', 'BsmtCond', 'KitchenQual', 'FireplaceQu', 'GarageQual', 'GarageCond', 'BsmtFinType2', \
'Exterior1st', 'Exterior2nd', 'GarageCars', 'Functional', 'SaleType', 'SaleCondition']
#functions to transform data
def sold_age(row):
'''calculates the age of the house when it was sold'''
return row['YrSold'] - row['YearBuilt']
def yrs_remod(row):
'''calculates the years since house was remodeled'''
yr_blt = row['YearBuilt']
yr_remodeled = row['YearRemodAdd']
yr_sold = row['YrSold']
if yr_blt == yr_remodeled:
return 0
else:
return yr_sold - yr_remodeled
def lot_shape(row):
'''consolidates all irregular categories into one'''
if row['LotShape'] == 'Reg':
return 'Reg'
else:
return 'Irreg'
在拟合期间,我应用函数,虚拟化分类,删除不需要的列,然后将列保存到 self.train_cols。当我进行转换时,除了将转换后的列保存到 test_cols 之外,我执行相同的步骤。我将这些列与拟合中获得的列进行比较,并从训练中的测试集中添加任何缺失的列,如我链接的答案所示。我得到的错误如下:
KeyError: "['Alley' 'Utilities' 'Condition2' 'HouseStyle' 'PoolQC' 'MiscFeature'\n 'ExterQual' 'ExterCond' 'BsmtQual' 'BsmtCond' 'KitchenQual' 'FireplaceQu'\n 'GarageQual' 'GarageCond' 'BsmtFinType2' 'Exterior1st' 'Exterior2nd'\n 'Functional' 'SaleType' 'SaleCondition'] not found in axis"
我正在尝试了解为什么会出现此错误,以及是否有比我执行此过程更好的方法来实现此过程。
【问题讨论】:
-
你能不能也展示一个数据和函数的最小例子,func_cols,drop_cols?没有这些信息,您的问题是不完整的
-
谢谢。我已经编辑了帖子并包含了其他信息。
标签: python scikit-learn pipeline imputation