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在场。但当MyLEncodertransform()被调用时,这在预测期间不会出现。
3)当前您的线路:
pipeline.predict(X)
是靠运气工作的,因为您的X是相同的,当调用MyLEncodertransform()时,您已经定义了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
基础教程推荐
- Kivy 使用 opencv.调整图像大小 2022-01-01
- Python,确定字符串是否应转换为 Int 或 Float 2022-01-01
- 究竟什么是“容器"?在蟒蛇?(以及所有的 python 容器类型是什么?) 2022-01-01
- kivy 应用程序中的一个简单网页作为小部件 2022-01-01
- 比较两个文本文件以找出差异并将它们输出到新的文本文件 2022-01-01
- 在 Django Admin 中使用内联 OneToOneField 2022-01-01
- 在 Python 中将货币解析为数字 2022-01-01
- Python 中是否有任何支持将长字符串转储为块文字或折叠块的 yaml 库? 2022-01-01
- matplotlib 设置 yaxis 标签大小 2022-01-01
- 对多索引数据帧的列进行排序 2022-01-01
