2014-08-28 22 views
6

Tôi muốn tạo biến áp của riêng mình để sử dụng với đường ống sklearn. Do đó tôi đang tạo ra một lớp thực hiện cả hai phương thức phù hợp và biến đổi. Mục đích của máy biến áp sẽ là loại bỏ các hàng khỏi ma trận có nhiều hơn một số lượng NaN được chỉ định. Vì vậy, vấn đề tôi đang phải đối mặt là làm thế nào tôi có thể thay đổi cả hai ma trận X và y được truyền cho máy biến áp? Tôi tin rằng điều này phải được thực hiện theo phương pháp phù hợp vì nó có quyền truy cập cả X và y. Kể từ khi python vượt qua các đối số bằng cách gán một khi tôi gán lại X cho một ma trận mới với ít hàng hơn, tham chiếu đến X ban đầu bị mất (và tất nhiên điều này cũng đúng với y). Có thể duy trì tham chiếu này không?Biến áp tùy chỉnh cho sklearn Đường ống làm thay đổi cả X và y

Tôi đang sử dụng gấu trúc DataFrame để dễ dàng xóa các hàng có quá nhiều NaN, đây có thể không phải là cách phù hợp để thực hiện việc này cho trường hợp sử dụng của tôi. mã hiện trông như thế này:

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 

Trả lời

6

Sửa đổi trục mẫu, ví dụ loại bỏ các mẫu, không (chưa?) tuân thủ API biến áp scikit-learn. Vì vậy, nếu bạn cần phải làm điều này, bạn nên làm điều đó bên ngoài bất kỳ cuộc gọi để scikit tìm hiểu, như tiền xử lý.

Hiện tại, API biến áp được sử dụng để chuyển đổi các tính năng của một mẫu nhất định thành mẫu mới. Điều này hoàn toàn có thể chứa thông tin từ các mẫu khác, nhưng các mẫu không bao giờ bị xóa.

Một tùy chọn khác là cố gắng ám chỉ các giá trị bị thiếu. Nhưng một lần nữa, nếu bạn cần xóa các mẫu, hãy coi nó như là tiền xử lý trước khi sử dụng scikit.

+4

Đây là trên todo. –

+1

A [liên kết có liên quan] (https://github.com/scikit-learn/scikit-learn/issues/3855) với todo được đề cập bởi @AndreasMueller. – zaxliu

1

Sử dụng "sâu bản" thêm vào, xuống các đường ống dẫn và X, y vẫn bảo vệ

.fit() thể đầu tiên gán trên mỗi cuộc gọi bản sao sâu cho các biến lớp học mới

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

và sau đó giảm/chuyển đổi những không có nhiều NaN -s hơn lệnh của self.treshold

+2

Nhưng các máy biến áp khác trong cùng một đường ống giả sử như thế nào để truy cập các bản sao này? – MarkAWard

3

Bạn có thể giải quyết việc này một cách dễ dàng bằng cách sử dụng phương pháp sklearn.preprocessing.FunctionTransformer (http://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.FunctionTransformer.html)

Bạn chỉ cần đặt alternations của bạn để X trong một chức năng

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 

sau đó bạn sẽ có được biến áp của bạn bằng cách gọi số

transformer = FunctionTransformer(drop_nans, validate=False) 

mà bạn có thể sử dụng trong đường ống. Ngưỡng này có thể được đặt bên ngoài hàm drop_nans.

+0

Thay vì thiết lập đập bên ngoài chức năng tôi sẽ đề nghị sử dụng một đối số bổ sung và sau đó vượt qua một chức năng đánh giá một phần với ngưỡng mong muốn thiết lập để FunctionTransformer https://docs.python.org/2/library/functools.html#functools.partial – MarkAWard

+1

Ý tưởng hay. Tôi đã ấn tượng rằng bạn không thể chọn một phần chức năng nhưng đó là sai.Vì vậy, bạn có thể sử dụng functools.partial và vẫn chọn toàn bộ sklearn.pipeline.Pipeline. – MaxBenChrist

+3

Tôi không chắc chắn cách điều này sẽ sửa đổi Y theo cách mà các máy biến áp/ước tính khác ở hạ lưu trong đường ống có thể truy cập vào tập hợp con tương ứng Y. –

Các vấn đề liên quan