簡體   English   中英

如何讓我的管道執行插補階段?

[英]How can I make my pipeline execute the imputation stage?

我正在嘗試運行一個基本模型,但似乎我的管道的插補階段失敗了,我真的不明白為什么。

這是最小的可復制代碼

如果您願意,可以找到xy的數據。 最初它們位於一個公共文件中,我可以輕松地將您鏈接到該文件,但我對它們進行了一些轉換,因此我將使用編輯后的輸出來減少您必須閱讀的代碼。 但是,如果需要,我可以輕松鏈接到原始代碼和數據集。

import pandas as pd
import numpy as np
from sklearn.ensemble import RandomForestClassifier,AdaBoostRegressor,AdaBoostClassifier,RandomForestRegressor
from category_encoders import CatBoostEncoder,CountEncoder,TargetEncoder,SumEncoder
from sklearn.preprocessing import OneHotEncoder, StandardScaler
from sklearn.compose import make_column_transformer
from sklearn.pipeline import make_pipeline
from sklearn.impute import SimpleImputer
import datetime as dt

x = pd.read_csv("/home/user/Python Practice/Working/Playstore/x.csv",index_col=("Unnamed: 0"))
y = pd.read_csv("/home/user/Python Practice/Working/Playstore/y.csv",index_col=("Unnamed: 0"))

# Set up Imputers
strat = ["mean","median","most_frequent","constant"]
num_imp = SimpleImputer(strategy=strat[0])
obj_imp = SimpleImputer(strategy=strat[2])

# Set up the scaler
sc = StandardScaler()

# Set up Encoders
cb = CatBoostEncoder()
oh = OneHotEncoder()

# Set up columns
obj = list(x.select_dtypes(include="object"))
num = list(x.select_dtypes(exclude="object"))
cb_col = [i for i in obj if len(x[i].unique())>30]
oh_col = [i for i in obj if len(x[i].unique())<10]

# Col Transformation
col = make_column_transformer((cb,cb_col),
                              (obj_imp,cb_col),
                              (oh,oh_col),
                              (obj_imp,oh_col),
                              (num_imp,num),
                              (sc,num))

model = AdaBoostRegressor(random_state=(0))

#Second Pipeline
run = make_pipeline((col),(model))
run.fit(x,y)
print("The score is",run.score(x,y))

模型在.fit階段崩潰並顯示錯誤消息: ValueError: Input contains NaN 為什么在我估算后它會這樣做? 我該如何解決?

我正在使用 Pandas v1.1.3 和 sklearn v0.23.2。

我想主要問題是由CatBoostEncoder引起的。 需要列 y 作為 input ,因此它可能無法與make_column_transformer() ,至少不能根據手冊描述的內容。 它的輸出格式也不同於其他轉換器,如固定代碼所示。

使固定

首先,你的索引搞砸了,加載后必須修復。

x.index[10470:10475]
Out[34]: Int64Index([10470, 10471, 10473, 10474, 10475], dtype='int64')

# fix
x.reset_index(drop=True, inplace=True)
y.reset_index(drop=True, inplace=True)

其次,使 OneHotEncoder 輸出一個密集數組。

oh = OneHotEncoder(sparse=False)

三是打通管道。

# 1. Impute
x[num] = num_imp.fit_transform(x[num])
x[obj] = obj_imp.fit_transform(x[obj])
assert x.isnull().sum().sum() == 0  # make sure no missing value exists

# 2. Transform
x = pd.concat([pd.DataFrame(sc.fit_transform(x[num])),
               cb.fit_transform(x[cb_col], y),
               pd.DataFrame(oh.fit_transform(x[oh_col]))
               ], axis=1)

最后,直接訓練和評估模型。 形狀轉換抑制警告。

model = AdaBoostRegressor(random_state=0)
model.fit(x.values, y.values.reshape(-1))
print("The score is", model.score(x, y.values.reshape(-1)))

結果:

The score is 0.6329093797171869

附加信息

我試圖忽略第三方CatBoostEncoder ,只在所有對象列上使用OneHotEncoder

col = make_column_transformer(
    (num_imp, num),
    (obj_imp, obj),
    (sc, num),
    (oh, obj),
)

但是,嘗試以許多我不明白的奇怪方式失敗了。

  • ohValueError: Input contains NaN失敗ValueError: Input contains NaN
  • scValueError: Input contains NaN, infinity or a value too large for dtype('float64').失敗ValueError: Input contains NaN, infinity or a value too large for dtype('float64'). 當只有x[num]被傳遞到管道時會發生這種情況,而且obj_impoh被關閉。

這是我決定放棄管道的主要原因,因為管道中轉換器的行為與我在固定代碼中觀察到的有很大不同。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM