LeaveOneOutEncoder in sklearn.pipeline(Sklearn.eline中的LeaveOneOutEncode)
问题描述
我使用LeaveOneOutEncode创建了一个管道。当然,我用了一个玩具的例子。Leave One Out用于转换类别变量
import pandas as pd
import numpy as np
from sklearn import preprocessing
import sklearn
from sklearn.pipeline import Pipeline
from sklearn.pipeline import FeatureUnion
from category_encoders import LeaveOneOutEncoder
from sklearn import linear_model
from sklearn.base import BaseEstimator, TransformerMixin
df= pd.DataFrame({ 'y': [1,2,3,4,5,6,7,8], 'a': ['a', 'b','a', 'b','a', 'b','a', 'b' ], 'b': [5,5,3,4,8,6,7,3],})
class ItemSelector(BaseEstimator, TransformerMixin):
def __init__(self, key):
self.key = key
def fit(self, x, y=None):
return self
def transform(self, data_dict):
return data_dict[self.key]
class MyLEncoder(BaseEstimator, TransformerMixin):
def transform(self, X, **fit_params):
enc = LeaveOneOutEncoder()
encc = enc.fit(np.asarray(X), y)
enc_data = encc.transform(np.asarray(X))
return enc_data
def fit_transform(self, X,y=None, **fit_params):
self.fit(X,y, **fit_params)
return self.transform(X)
def fit(self, X, y, **fit_params):
return self
X = df[['a', 'b']]
y = df['y']
regressor = linear_model.SGDRegressor()
pipeline = Pipeline([
# Use FeatureUnion to combine the features
('union', FeatureUnion(
transformer_list=[
# categorical
('categorical', Pipeline([
('selector', ItemSelector(key='a')),
('one_hot', MyLEncoder())
])),
# year
])),
# Use a regression
('model_fitting', linear_model.SGDRegressor()),
])
pipeline.fit(X, y)
pipeline.predict(X)
我在列车和测试数据上使用它时,这些都是正确的!但当我尝试预测新数据时,出现错误
pipeline.predict(pd.DataFrame({ 'y': [3, 8], 'a': ['a', 'b' ], 'b': [3, 6],}))
帮助查找错误!这个错误肯定很简单,但我的眼睛湿透了。问题一定出在MyLEncoder类中。我必须更改什么?
推荐答案
您正在呼叫
encc = enc.fit(np.asarray(X), y)
在MyLEncoder
的transform()
方法中。
所以这里有几个问题:
1)您的LeaveOneOutEncoder
只记住传递给MyLEncoder
的transform
的最后数据,而忘记了以前的数据。
LeaveOneOutEncoder
要求y
在场。但当MyLEncoder
transform()
被调用时,这在预测期间不会出现。
3)当前您的线路:
pipeline.predict(X)
是靠运气工作的,因为您的X
是相同的,当调用MyLEncoder
transform()
时,您已经定义了y
,所以使用它。但这是错误的。
4)不相关的事情(可能不会称其为错误)。执行此操作时:
pipeline.predict(pd.DataFrame({ 'y': [3, 8], 'a': ['a', 'b' ], 'b': [3, 6],}))
pipeline.predict()
只需要X
,不需要y
。但您也在其中发送了y
。目前这不是问题,因为在管道中,您只使用a
列并丢弃所有信息,但可能在复杂的设置中,这可能会漏掉,并且y
列中的数据将被用作功能(X
数据),这将给您错误的结果。
若要解决此问题,请将MyLEncoder
更改为:
class MyLEncoder(BaseEstimator, TransformerMixin):
# Save the enc during fitting
def fit(self, X, y, **fit_params):
enc = LeaveOneOutEncoder()
self.enc = enc.fit(np.asarray(X), y)
return self
# Here, no new learning should be done, so never call fit() inside this
# Only use the already saved enc here
def transform(self, X, **fit_params):
enc_data = self.enc.transform(np.asarray(X))
return enc_data
# No need to define this function, if you are not doing any optimisation in it.
# It will be automatically inherited from TransformerMixin
# I have only kept it here, because you kept it.
def fit_transform(self, X,y=None, **fit_params):
self.fit(X, y, **fit_params)
return self.transform(X)
现在执行此操作时:
pipeline.predict(pd.DataFrame({ 'y': [3, 8], 'a': ['a', 'b' ], 'b': [3, 6],}))
您不会收到任何错误,但仍如第4点所述,我希望您这样做:
new_df = pd.DataFrame({ 'y': [3, 8], 'a': ['a', 'b' ], 'b': [3, 6],})
new_X = new_df[['a', 'b']]
new_y = new_df['y']
pipeline.predict(new_X)
使训练时间中使用的X和预测时间中使用的new_X看起来相同。
这篇关于Sklearn.eline中的LeaveOneOutEncode的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:Sklearn.eline中的LeaveOneOutEncode


基础教程推荐
- 修改列表中的数据帧不起作用 2022-01-01
- 求两个直方图的卷积 2022-01-01
- 无法导入 Pytorch [WinError 126] 找不到指定的模块 2022-01-01
- 在Python中从Azure BLOB存储中读取文件 2022-01-01
- 使用大型矩阵时禁止 Pycharm 输出中的自动换行符 2022-01-01
- Plotly:如何设置绘图图形的样式,使其不显示缺失日期的间隙? 2022-01-01
- 包装空间模型 2022-01-01
- 在同一图形上绘制Bokeh的烛台和音量条 2022-01-01
- PermissionError: pip 从 8.1.1 升级到 8.1.2 2022-01-01
- PANDA VALUE_COUNTS包含GROUP BY之前的所有值 2022-01-01