2014-08-28 33 views
6

我想創建我自己的變壓器以與sklearn管道一起使用。因此,我創建了一個實現擬合和變換方法的類。變壓器的目的是從矩陣中移除具有超過指定數量的NaN的行。所以我面臨的問題是如何改變傳遞給變換器的X和Y矩陣?我相信這必須以適合的方法來完成,因爲它可以訪問X和Y.由於python通過賦值傳遞參數,所以我將X重新分配給一個具有較少行的新矩陣,原始X的引用將丟失(當然對於y也是如此)。是否有可能保持這一參考?用於sklearn的定製變壓器改變X和y的管道

我正在使用熊貓DataFrame輕鬆刪除具有太多NaN的行,這可能不是正確的方式來做我的用例。當前的代碼如下所示:

class Dropna(): 

    # thresh is max number of NaNs allowed in a row 
    def __init__(self, thresh=0): 
     self.thresh = thresh 

    def fit(self, X, y): 
     total = X.shape[1] 
     # +1 to account for 'y' being added to the dframe                                
     new_thresh = total + 1 - self.thresh 
     df = pd.DataFrame(X) 
     df['y'] = y 
     df.dropna(thresh=new_thresh, inplace=True) 
     X = df.drop('y', axis=1).values 
     y = df['y'].values 
     return self 

    def transform(self, X): 
     return X 

回答

6

修改樣本軸線,例如有序去除樣品,不(但?)符合scikit-learn變壓器API。所以如果你需要這樣做,你應該在任何調用scikit的電話以外進行預處理。

現在,變壓器API用於將給定樣本的特徵轉換爲新的特徵。這可以隱含地包含來自其他樣本的信息,但樣本不會被刪除。

另一種選擇是試圖歸納缺失值。但是,如果您需要刪除樣本,請在使用scikit學習之前將其視爲預處理。

+4

這是待辦事項。 – 2014-08-28 18:09:02

+1

A [相關鏈接](https://github.com/scikit-learn/scikit-learn/issues/3855)到@AndreasMueller提到的待辦事項。 – zaxliu 2015-11-18 00:26:50

1

使用 「深拷貝」 進一步上,下管道和Xy受到保護

.fit()可以先在每個呼叫分配深拷貝到新類變量

self.X_without_NaNs = X.copy() 
self.y_without_NaNs = y.copy() 

然後減少/轉換這些不具有更多NaN -s比self.treshold

+2

但是同一管道中的其他變換器如何設想訪問這些副本? – MarkAWard 2014-08-28 02:44:25

3

您可以通過使用sklearn.preprocessing.FunctionTransformer法(http://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.FunctionTransformer.html

輕鬆解決這個

你只需把你的交替,以X在功能

def drop_nans(X, y=None): 
    total = X.shape[1]           
    new_thresh = total - thresh 
    df = pd.DataFrame(X) 
    df.dropna(thresh=new_thresh, inplace=True) 
    return df.values 

那麼您得到您的變壓器呼叫

transformer = FunctionTransformer(drop_nans, validate=False) 

你可以在管道中使用。閾值可以在drop_nans函數之外設置。

+0

除了在函數外部設置thresh外,我還會建議使用額外的參數,然後將所需的閾值設置爲FunctionTransformer的部分評估函數https://docs.python.org/2/library/functools.html#functools.partial – MarkAWard 2016-01-05 18:34:13

+1

好主意。我的印象是,你不能醃製部分功能,但那是錯誤的。所以你可以使用functools.partial,然後繼續使用完整的sklearn.pipeline.Pipeline。 – MaxBenChrist 2016-01-15 08:14:37

+3

我不知道這將如何修改Y,使得管道中下游的其他變換器/估計器可以訪問相應的子集Y. – 2016-04-22 19:58:02

相關問題