为分类变量 sklearn 创建我的自定义 Imputer
Create my custom Imputer for categorical variables sklearn
我有一个缺少很多分类值的数据集,我想制作一个自定义输入器,它将用等于 "no-variable_name"
.
的值填充空值
例如,如果列 "Workclass"
具有 Nan
值,请将其替换为 "No Workclass"
。
我是这样做的
X_train['workclass'].fillna("No workclass", inplace = True)
但我想做一个Imputer
,这样我就可以在管道中传递它。
您可以使用 TransformerMixin
定义自定义转换器。这是一个简单的例子,如何定义一个简单的转换器并将其包含在管道中:
df = pd.DataFrame({'workclass':['class1', np.nan, 'Some other class', 'class1',
np.nan, 'class12', 'class2', 'class121'],
'color':['red', 'blue', np.nan, 'pink',
'green', 'magenta', np.nan, 'yellow']})
# train test split of X
df_train = df[:3]
df_test = df[3:]
print(df_test)
workclass color
3 class1 pink
4 NaN green
5 class12 magenta
6 class2 NaN
7 class121 yellow
我们的想法是使用 df_train
数据框进行拟合,并在 df_test
上复制转换。我们可以定义自定义转换 class 继承自 TransformerMixin
:
from sklearn.pipeline import Pipeline
from sklearn.base import TransformerMixin
class InputColName(TransformerMixin):
def fit(self, X, y):
self.fill_with = X.columns
return self
def transform(self, X):
return np.where(X.isna(), 'No ' + self.fill_with, X)
然后将其包含在您的管道中(此处仅使用 InputColName
以保持示例简单)并使其与训练数据相匹配:
pipeline = Pipeline(steps=[
('inputter', InputColName())
])
pipeline.fit(df_train)
现在,如果我们尝试使用看不见的数据进行转换:
print(pd.DataFrame(pipeline.transform(df_test), columns=df.columns))
workclass color
0 class1 pink
1 No workclass green
2 class12 magenta
3 class2 No color
4 class121 yellow
您可以定义自定义函数并使用 FunctionTransformer
:
调用它
from sklearn.preprocessing import FunctionTransformer
def custom_fillna(X):
return X.fillna('NONE')
custom_imputer = FunctionTransformer(custom_fillna)
custom_imputer.transform(X)
您可以像这样自定义 simpleImputer
!
from sklearn.impute import SimpleImputer
class customImputer(SimpleImputer):
def fit(self, X, y=None):
self.fill_value = ['No '+c for c in X.columns]
return super().fit(X, y)
df = pd.DataFrame({'workclass': ['classA', 'classB', np.NaN],
'fruit': ['apple',np.NaN,'orange']})
df
# workclass fruit
#0 classA apple
#1 classB NaN
#2 NaN orange
customImputer(strategy='constant').fit_transform(df)
#array([['classA', 'apple'],
# ['classB', 'No fruit'],
# ['No workclass', 'orange']], dtype=object)
我有一个缺少很多分类值的数据集,我想制作一个自定义输入器,它将用等于 "no-variable_name"
.
例如,如果列 "Workclass"
具有 Nan
值,请将其替换为 "No Workclass"
。
我是这样做的
X_train['workclass'].fillna("No workclass", inplace = True)
但我想做一个Imputer
,这样我就可以在管道中传递它。
您可以使用 TransformerMixin
定义自定义转换器。这是一个简单的例子,如何定义一个简单的转换器并将其包含在管道中:
df = pd.DataFrame({'workclass':['class1', np.nan, 'Some other class', 'class1',
np.nan, 'class12', 'class2', 'class121'],
'color':['red', 'blue', np.nan, 'pink',
'green', 'magenta', np.nan, 'yellow']})
# train test split of X
df_train = df[:3]
df_test = df[3:]
print(df_test)
workclass color
3 class1 pink
4 NaN green
5 class12 magenta
6 class2 NaN
7 class121 yellow
我们的想法是使用 df_train
数据框进行拟合,并在 df_test
上复制转换。我们可以定义自定义转换 class 继承自 TransformerMixin
:
from sklearn.pipeline import Pipeline
from sklearn.base import TransformerMixin
class InputColName(TransformerMixin):
def fit(self, X, y):
self.fill_with = X.columns
return self
def transform(self, X):
return np.where(X.isna(), 'No ' + self.fill_with, X)
然后将其包含在您的管道中(此处仅使用 InputColName
以保持示例简单)并使其与训练数据相匹配:
pipeline = Pipeline(steps=[
('inputter', InputColName())
])
pipeline.fit(df_train)
现在,如果我们尝试使用看不见的数据进行转换:
print(pd.DataFrame(pipeline.transform(df_test), columns=df.columns))
workclass color
0 class1 pink
1 No workclass green
2 class12 magenta
3 class2 No color
4 class121 yellow
您可以定义自定义函数并使用 FunctionTransformer
:
from sklearn.preprocessing import FunctionTransformer
def custom_fillna(X):
return X.fillna('NONE')
custom_imputer = FunctionTransformer(custom_fillna)
custom_imputer.transform(X)
您可以像这样自定义 simpleImputer
!
from sklearn.impute import SimpleImputer
class customImputer(SimpleImputer):
def fit(self, X, y=None):
self.fill_value = ['No '+c for c in X.columns]
return super().fit(X, y)
df = pd.DataFrame({'workclass': ['classA', 'classB', np.NaN],
'fruit': ['apple',np.NaN,'orange']})
df
# workclass fruit
#0 classA apple
#1 classB NaN
#2 NaN orange
customImputer(strategy='constant').fit_transform(df)
#array([['classA', 'apple'],
# ['classB', 'No fruit'],
# ['No workclass', 'orange']], dtype=object)