2017-05-04 19 views
9

में वर्गीकरण के बाद एक मीट्रिक का उपयोग करें, मैं पाइपलाइन के बारे में जांच करना जारी रखता हूं। मेरा उद्देश्य केवल पाइपलाइन के साथ मशीन सीखने के प्रत्येक चरण को निष्पादित करना है। यह एक अन्य उपयोग के मामले के साथ मेरी पाइपलाइन अनुकूलित करने के लिए और अधिक लचीला और आसान हो जाएगा। तो मैं क्या कर:पाइपलाइन

  • चरण 1: भरें NaN मान
  • चरण 2: नंबर में स्पष्ट मूल्यों को बदलने
  • चरण 3: वर्गीकरणकर्ता
  • चरण 4: GridSearch
  • चरण 5: एक जोड़े मैट्रिक्स (असफल)

यहाँ मेरी कोड है:

import pandas as pd 
from sklearn.base import BaseEstimator, TransformerMixin 
from sklearn.feature_selection import SelectKBest 
from sklearn.preprocessing import LabelEncoder 
from sklearn.model_selection import GridSearchCV 
from sklearn.model_selection import train_test_split 
from sklearn.ensemble import RandomForestClassifier 
from sklearn.pipeline import Pipeline 
from sklearn.metrics import roc_curve, auc 
import matplotlib.pyplot as plt 
from sklearn.metrics import confusion_matrix 
from sklearn.metrics import f1_score 


class FillNa(BaseEstimator, TransformerMixin): 

    def transform(self, x, y=None): 
      non_numerics_columns = x.columns.difference(
       x._get_numeric_data().columns) 
      for column in x.columns: 
       if column in non_numerics_columns: 
        x.loc[:, column] = x.loc[:, column].fillna(
         df[column].value_counts().idxmax()) 
       else: 
        x.loc[:, column] = x.loc[:, column].fillna(
         x.loc[:, column].mean()) 
      return x 

    def fit(self, x, y=None): 
     return self 


class CategoricalToNumerical(BaseEstimator, TransformerMixin): 

    def transform(self, x, y=None): 
     non_numerics_columns = x.columns.difference(
      x._get_numeric_data().columns) 
     le = LabelEncoder() 
     for column in non_numerics_columns: 
      x.loc[:, column] = x.loc[:, column].fillna(
       x.loc[:, column].value_counts().idxmax()) 
      le.fit(x.loc[:, column]) 
      x.loc[:, column] = le.transform(x.loc[:, column]).astype(int) 
     return x 

    def fit(self, x, y=None): 
     return self 


class Perf(BaseEstimator, TransformerMixin): 

    def fit(self, clf, x, y, perf="all"): 
     """Only for classifier model. 

     Return AUC, ROC, Confusion Matrix and F1 score from a classifier and df 
     You can put a list of eval instead a string for eval paramater. 
     Example: eval=['all', 'auc', 'roc', 'cm', 'f1'] will return these 4 
     evals. 
     """ 
     evals = {} 
     y_pred_proba = clf.predict_proba(x)[:, 1] 
     y_pred = clf.predict(x) 
     perf_list = perf.split(',') 
     if ("all" or "roc") in perf.split(','): 
      fpr, tpr, _ = roc_curve(y, y_pred_proba) 
      roc_auc = round(auc(fpr, tpr), 3) 
      plt.style.use('bmh') 
      plt.figure(figsize=(12, 9)) 
      plt.title('ROC Curve') 
      plt.plot(fpr, tpr, 'b', 
        label='AUC = {}'.format(roc_auc)) 
      plt.legend(loc='lower right', borderpad=1, labelspacing=1, 
         prop={"size": 12}, facecolor='white') 
      plt.plot([0, 1], [0, 1], 'r--') 
      plt.xlim([-0.1, 1.]) 
      plt.ylim([-0.1, 1.]) 
      plt.ylabel('True Positive Rate') 
      plt.xlabel('False Positive Rate') 
      plt.show() 

     if "all" in perf_list or "auc" in perf_list: 
      fpr, tpr, _ = roc_curve(y, y_pred_proba) 
      evals['auc'] = auc(fpr, tpr) 

     if "all" in perf_list or "cm" in perf_list: 
      evals['cm'] = confusion_matrix(y, y_pred) 

     if "all" in perf_list or "f1" in perf_list: 
      evals['f1'] = f1_score(y, y_pred) 

     return evals 


path = '~/proj/akd-doc/notebooks/data/' 
df = pd.read_csv(path + 'titanic_tuto.csv', sep=';') 
y = df.pop('Survival-Status').replace(to_replace=['dead', 'alive'], 
             value=[0., 1.]) 
X = df.copy() 
X_train, X_test, y_train, y_test = train_test_split(
    X.copy(), y.copy(), test_size=0.2, random_state=42) 

percent = 0.50 
nb_features = round(percent * df.shape[1]) + 1 
clf = RandomForestClassifier() 
pipeline = Pipeline([('fillna', FillNa()), 
        ('categorical_to_numerical', CategoricalToNumerical()), 
        ('features_selection', SelectKBest(k=nb_features)), 
        ('random_forest', clf), 
        ('perf', Perf())]) 

params = dict(random_forest__max_depth=list(range(8, 12)), 
       random_forest__n_estimators=list(range(30, 110, 10))) 
cv = GridSearchCV(pipeline, param_grid=params) 
cv.fit(X_train, y_train) 

मुझे पता है कि एक रॉक वक्र मुद्रित करना आदर्श नहीं है लेकिन यह अभी समस्या नहीं है।

तो, जब मैं इस कोड निष्पादित मेरे पास है:

TypeError: If no scoring is specified, the estimator passed should have a 'score' method. The estimator Pipeline(steps=[('fillna', FillNa()), ('categorical_to_numerical', CategoricalToNumerical()), ('features_selection', SelectKBest(k=10, score_func=<function f_classif at 0x7f4ed4c3eae8>)), ('random_forest', RandomForestClassifier(bootstrap=True, class_weight=None, criterion='gini', 
      max_depth=None,...=1, oob_score=False, random_state=None, 
      verbose=0, warm_start=False)), ('perf', Perf())]) does not. 

मैं सभी विचारों में रुचि हूँ ...

उत्तर

5

त्रुटि राज्यों के रूप में, आप GridSearchCV में स्कोरिंग पैरामीटर निर्दिष्ट की जरूरत है।

उपयोग

GridSearchCV(pipeline, param_grid=params, scoring = 'accuracy')

संपादित (टिप्पणी में सवाल के आधार पर):

आप आरओसी, एयूसी वक्र और f1 पूरे X_train के लिए और y_train (और नहीं सभी के लिए की जरूरत है ग्रिडशर्चसीवी के विभाजन), पाइपलाइन से पेर्फ क्लास को बाहर रखना बेहतर है।

pipeline = Pipeline([('fillna', FillNa()), 
        ('categorical_to_numerical', CategoricalToNumerical()), 
        ('features_selection', SelectKBest(k=nb_features)), 
        ('random_forest', clf)]) 

#Fit the data in the pipeline 
pipeline.fit(X_train, y_train) 

performance_meas = Perf() 
performance_meas.fit(pipeline, X_train, y_train) 
+0

बढ़िया! लेकिन इस तरह से मेरे रॉक वक्र को साजिश करना संभव नहीं है? और एक ही पाइपलाइन में सटीकता और एफ 1 स्कोर प्राप्त करना संभव होगा? –

+0

हां यह संभव है। क्या आपको परिणाम नहीं मिल रहे हैं? आपके कोड के आगे निरीक्षण के बाद, ऐसा लगता है कि यह इसे हल करने के बाद भी एक और त्रुटि देगा। –

+0

यदि मैं अपना 'क्लास पेर्फ' हटा देता हूं और 'सीवी = ग्रिडशर्चसीवी (पाइपलाइन, param_grid = पैरा, स्कोरिंग =' सटीकता ') cv.fit (X_train, y_train)' को कॉल करता हूं, मुझे कोई त्रुटि नहीं है। मैं उसी दौड़ –

संबंधित मुद्दे