[PYTHON] Ich habe versucht, lightGBM, xg Boost mit Boruta zu verwenden

Da lightGBM und xgboost in Boruta nicht funktionierten, habe ich ein Teil neu geschrieben, damit es funktioniert.

Im Folgenden erfahren Sie, wie Sie dies normalerweise mit dem sklearn-Schätzer tun https://qiita.com/studio_haneya/items/bdb25b19baaf43d867d7

Testumgebung

Windows10 python 3.6.7 scikit-learn 0.21.3 lightgbm 2.3.0 xgboost 0.90

Wo ich mich verändert habe

Boruta arbeitet mit dem sklearn-Schätzer, der feature_importance_ erhalten kann, sodass Sie RandomForest und GradientBoosting verwenden können. Der sklearn-Wrapper von lightGBM und xgboost sieht jedoch wie sklearn aus, funktioniert jedoch nicht so, wie er ist, da er etwas anders ist. ist. Also habe ich die BorutaPy-Klasse geerbt und sie teilweise neu geschrieben, damit sie funktioniert.
Es gibt zwei Unterschiede, die problematisch sein können, wenn Sie versuchen, lightGBM mit Boruta zu verwenden:

boruta lgb/xgb
random_state np.random.RandomState int
max_Keine Tiefenbegrenzung None -1

In sklearn kann Startwert von np.random.RandomState () übergeben werden, aber lightGBM / xgboost kann ihn nicht als numerischen Wert vom Typ int übergeben und wird Parametern zugewiesen, wenn das Limit max_depth entfernt wird. Da der Wert None für sklearn und -1 für lightGBM ist, können n_estimators, die basierend auf max_depth berechnet wurden, nicht normal berechnet werden. Wenn Sie also die Teile reparieren, die diesen beiden entsprechen, funktioniert es.

Verwenden Sie lightGBM mit Boruta

Unten finden Sie den Beispielcode, mit dem lightGBM ausgeführt wird. Ich habe BorutaPy geerbt und einen Teil neu geschrieben, aber da _fit () eine Spezifikation ist, die random_state durch np.random.RandomState () und dann self.estimator.fit () ersetzt, wird es nicht neu geschrieben. Ich kann mir keinen Weg vorstellen, es zu tun, und es ist ein sehr langer Code. Bitte lassen Sie mich wissen, ob es einen besseren Weg gibt. (Behoben 20191102: Behoben, weil der Code nicht den Wert des Zufallszustands widerspiegelte) </ font>

python


import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.metrics import confusion_matrix, accuracy_score
from boruta import BorutaPy
import lightgbm as lgb
import xgboost as xgb
from sklearn.utils import check_random_state
class BorutaPyForLGB(BorutaPy):
    def __init__(self, estimator, n_estimators=1000, perc=100, alpha=0.05,
                 two_step=True, max_iter=100, random_state=None, verbose=0):
        super().__init__(estimator, n_estimators, perc, alpha,
                         two_step, max_iter, random_state, verbose)
        if random_state is None:
            self.random_state_input = np.random.randint(0, 2**64-1)
        elif isinstance(random_state, int):
            self.random_state_input = random_state
        else:
            raise TypeError('random_state must be int or None')

    def _get_tree_num(self, n_feat):
        depth = self.estimator.get_params()['max_depth']
        if (depth == None) or (depth <= 0):
            depth = 10
        f_repr = 100
        multi = ((n_feat * 2) / (np.sqrt(n_feat * 2) * depth))
        n_estimators = int(multi * f_repr)
        return n_estimators

    def _fit(self, X, y):
        # check input params
        self._check_params(X, y)
        self.random_state = check_random_state(self.random_state)
        # setup variables for Boruta
        n_sample, n_feat = X.shape
        _iter = 1
        # holds the decision about each feature:
        # 0  - default state = tentative in original code
        # 1  - accepted in original code
        # -1 - rejected in original code
        dec_reg = np.zeros(n_feat, dtype=np.int)
        # counts how many times a given feature was more important than
        # the best of the shadow features
        hit_reg = np.zeros(n_feat, dtype=np.int)
        # these record the history of the iterations
        imp_history = np.zeros(n_feat, dtype=np.float)
        sha_max_history = []

        # set n_estimators
        if self.n_estimators != 'auto':
            self.estimator.set_params(n_estimators=self.n_estimators)

        # main feature selection loop
        while np.any(dec_reg == 0) and _iter < self.max_iter:
            # find optimal number of trees and depth
            if self.n_estimators == 'auto':
                # number of features that aren't rejected
                not_rejected = np.where(dec_reg >= 0)[0].shape[0]
                n_tree = self._get_tree_num(not_rejected)
                self.estimator.set_params(n_estimators=n_tree)

            # make sure we start with a new tree in each iteration
            self.estimator.set_params(random_state=self.random_state_input)

            # add shadow attributes, shuffle them and train estimator, get imps
            cur_imp = self._add_shadows_get_imps(X, y, dec_reg)

            # get the threshold of shadow importances we will use for rejection
            imp_sha_max = np.percentile(cur_imp[1], self.perc)

            # record importance history
            sha_max_history.append(imp_sha_max)
            imp_history = np.vstack((imp_history, cur_imp[0]))

            # register which feature is more imp than the max of shadows
            hit_reg = self._assign_hits(hit_reg, cur_imp, imp_sha_max)

            # based on hit_reg we check if a feature is doing better than
            # expected by chance
            dec_reg = self._do_tests(dec_reg, hit_reg, _iter)

            # print out confirmed features
            if self.verbose > 0 and _iter < self.max_iter:
                self._print_results(dec_reg, _iter, 0)
            if _iter < self.max_iter:
                _iter += 1

        # we automatically apply R package's rough fix for tentative ones
        confirmed = np.where(dec_reg == 1)[0]
        tentative = np.where(dec_reg == 0)[0]
        # ignore the first row of zeros
        tentative_median = np.median(imp_history[1:, tentative], axis=0)
        # which tentative to keep
        tentative_confirmed = np.where(tentative_median
                                       > np.median(sha_max_history))[0]
        tentative = tentative[tentative_confirmed]

        # basic result variables
        self.n_features_ = confirmed.shape[0]
        self.support_ = np.zeros(n_feat, dtype=np.bool)
        self.support_[confirmed] = 1
        self.support_weak_ = np.zeros(n_feat, dtype=np.bool)
        self.support_weak_[tentative] = 1

        # ranking, confirmed variables are rank 1
        self.ranking_ = np.ones(n_feat, dtype=np.int)
        # tentative variables are rank 2
        self.ranking_[tentative] = 2
        # selected = confirmed and tentative
        selected = np.hstack((confirmed, tentative))
        # all rejected features are sorted by importance history
        not_selected = np.setdiff1d(np.arange(n_feat), selected)
        # large importance values should rank higher = lower ranks -> *(-1)
        imp_history_rejected = imp_history[1:, not_selected] * -1

        # update rank for not_selected features
        if not_selected.shape[0] > 0:
                # calculate ranks in each iteration, then median of ranks across feats
                iter_ranks = self._nanrankdata(imp_history_rejected, axis=1)
                rank_medians = np.nanmedian(iter_ranks, axis=0)
                ranks = self._nanrankdata(rank_medians, axis=0)

                # set smallest rank to 3 if there are tentative feats
                if tentative.shape[0] > 0:
                    ranks = ranks - np.min(ranks) + 3
                else:
                    # and 2 otherwise
                    ranks = ranks - np.min(ranks) + 2
                self.ranking_[not_selected] = ranks
        else:
            # all are selected, thus we set feature supports to True
            self.support_ = np.ones(n_feat, dtype=np.bool)

        # notify user
        if self.verbose > 0:
            self._print_results(dec_reg, _iter, 1)
        return self

Jetzt, da wir fertig sind, lassen Sie es uns unten laufen. Der Code basiert auf Folgendem. https://github.com/masakiaota/blog/blob/master/boruta/Madalon_Data_Set.ipynb

def main():
    #Lesen Sie die Daten
    data_url='https://archive.ics.uci.edu/ml/machine-learning-databases/madelon/MADELON/madelon_train.data'
    label_url='https://archive.ics.uci.edu/ml/machine-learning-databases/madelon/MADELON/madelon_train.labels'
    X_data = pd.read_csv(data_url, sep=" ", header=None)
    y_data = pd.read_csv(label_url, sep=" ", header=None)
    data = X_data.iloc[:,0:500]
    data['target'] = y_data[0]

    y=data['target']
    X=data.drop(columns='target')
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state=42)


    #Lernen Sie mit ganzen Daten
    model = lgb.LGBMClassifier(objective='binary',
                                num_leaves = 23,
                                learning_rate=0.1,
                                n_estimators=100,)
    model.fit(X_train.values, y_train.values)

    y_test_pred = model.predict(X_test.values)
    print(confusion_matrix(y_test.values, y_test_pred, labels=model.classes_), '\n')
    print('SCORE with ALL Features: %1.2f\n' % accuracy_score(y_test, y_test_pred))


    #Funktionsauswahl mit Boruta(Verwenden Sie das teilweise umgeschriebene Boruta Py)
    model = lgb.LGBMClassifier(objective='binary',
                                num_leaves = 23,
                                learning_rate=0.1,
                                n_estimators=100,)
    feat_selector = BorutaPyForLGB(model, n_estimators='auto', two_step=False,verbose=2, random_state=42)
    feat_selector.fit(X_train.values, y_train.values)
    print(X_train.columns[feat_selector.support_])

    #Extrahieren Sie das ausgewählte Feature
    X_train_selected = X_train.iloc[:,feat_selector.support_]
    X_test_selected = X_test.iloc[:,feat_selector.support_]
    print(X_test_selected.head())


    #Lernen Sie mit der ausgewählten Funktion
    model = lgb.LGBMClassifier(objective='binary',
                                num_leaves = 23,
                                learning_rate=0.1,
                                n_estimators=100,)
    model.fit(X_train_selected.values, y_train.values)

    y_test_pred = model.predict(X_test_selected.values)
    print(confusion_matrix(y_test.values, y_test_pred, labels=model.classes_), '\n')
    print('SCORE with selected Features: %1.2f\n' % accuracy_score(y_test, y_test_pred))


if __name__=='__main__':
    main()

Das Ergebnis der Ausführung ist wie folgt. Es scheint, dass Sie es richtig auswählen können.

Ergebnis


[[192  57]
 [ 49 202]] 
SCORE with ALL Features: 0.79


Index([48, 105, 153, 241, 318, 336, 338, 378, 442, 453, 472, 475], dtype='object')

[[212  37]
 [ 34 217]] 
SCORE with selected Features: 0.86

Verwenden Sie xgboost mit Boruta

Das oben erstellte BorutaPyForLGB () kann auch mit xgboost verwendet werden.

python


def main():
    #Lesen Sie die Daten
    data_url='https://archive.ics.uci.edu/ml/machine-learning-databases/madelon/MADELON/madelon_train.data'
    label_url='https://archive.ics.uci.edu/ml/machine-learning-databases/madelon/MADELON/madelon_train.labels'
    X_data = pd.read_csv(data_url, sep=" ", header=None)
    y_data = pd.read_csv(label_url, sep=" ", header=None)
    data = X_data.iloc[:,0:500]
    data['target'] = y_data[0]

    y=data['target']
    X=data.drop(columns='target')
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state=42)


    #Lernen Sie mit ganzen Daten
    model = lgb.LGBMClassifier(objective='binary',
                                num_leaves = 23,
                                learning_rate=0.1,
                                n_estimators=100,)
    model.fit(X_train.values, y_train.values)

    y_test_pred = model.predict(X_test.values)
    print(confusion_matrix(y_test.values, y_test_pred, labels=model.classes_), '\n')
    print('SCORE with ALL Features: %1.2f\n' % accuracy_score(y_test, y_test_pred))


    #Funktionsauswahl mit Boruta(Verwenden Sie das teilweise umgeschriebene Boruta Py)
    model = lgb.LGBMClassifier(objective='binary',
                                num_leaves = 23,
                                learning_rate=0.1,
                                n_estimators=100,)
    feat_selector = BorutaPyForLGB(model, n_estimators='auto', two_step=False,verbose=2, random_state=42)
    feat_selector.fit(X_train.values, y_train.values)
    print(X_train.columns[feat_selector.support_])

    #Extrahieren Sie das ausgewählte Feature
    X_train_selected = X_train.iloc[:,feat_selector.support_]
    X_test_selected = X_test.iloc[:,feat_selector.support_]
    print(X_test_selected.head())


    #Lernen Sie mit der ausgewählten Funktion
    model = lgb.LGBMClassifier(objective='binary',
                                num_leaves = 23,
                                learning_rate=0.1,
                                n_estimators=100,)
    model.fit(X_train_selected.values, y_train.values)

    y_test_pred = model.predict(X_test_selected.values)
    print(confusion_matrix(y_test.values, y_test_pred, labels=model.classes_), '\n')
    print('SCORE with selected Features: %1.2f\n' % accuracy_score(y_test, y_test_pred))


if __name__=='__main__':
    main()

Es funktioniert, aber es funktioniert nicht gut und die Genauigkeit ist gesunken. Es scheint, dass die Anzahl der Funktionen zu stark reduziert wurde, aber warum?

Ergebnis


[[182  67]
 [ 75 176]] 
SCORE with ALL Features: 0.72


Index([28, 378, 451, 475], dtype='object')

[[148 101]
 [109 142]] 
SCORE with selected Features: 0.58

Es ist wie es ist. Bitte lassen Sie mich wissen, ob es eine Möglichkeit gibt, es kürzer zu schreiben. Lass es uns versuchen!

Recommended Posts

Ich habe versucht, lightGBM, xg Boost mit Boruta zu verwenden
Ich habe versucht, LightGBM mit Yellowbrick zu lernen
Ich habe versucht, Autoencoder mit TensorFlow zu implementieren
Ich habe versucht, AutoEncoder mit TensorFlow zu visualisieren
Ich habe versucht, mit Hy anzufangen
Ich habe versucht, CVAE mit PyTorch zu implementieren
Ich habe versucht, TSP mit QAOA zu lösen
Ich habe versucht, nächstes Jahr mit AI vorherzusagen
Ich habe versucht, das Lesen von Dataset mit PyTorch zu implementieren
Ich möchte MATLAB feval mit Python verwenden
Ich habe versucht, mit TF Learn die logische Operation zu lernen
Ich habe versucht, GAN (mnist) mit Keras zu bewegen
Ich habe versucht, die Daten mit Zwietracht zu speichern
Ich habe versucht, mit OpenCV Bewegungen schnell zu erkennen
Ich habe versucht, Keras in TFv1.1 zu integrieren
Ich habe versucht, CloudWatch-Daten mit Python abzurufen
[AWS] [GCP] Ich habe versucht, die Verwendung von Cloud-Diensten mit Python zu vereinfachen
Ich habe versucht, LLVM IR mit Python auszugeben
Ich habe versucht zu debuggen.
Ich möchte Temporäres Verzeichnis mit Python2 verwenden
Ich habe versucht, ein Objekt mit M2Det zu erkennen!
Ich habe versucht, die Herstellung von Sushi mit Python zu automatisieren
Ich möchte -inf nicht mit np.log verwenden
Ich habe versucht, das Überleben der Titanic mit PyCaret vorherzusagen
Ich möchte ip vrf mit SONiC verwenden
Ich habe versucht, Linux mit Discord Bot zu betreiben
Ich habe versucht, DP mit Fibonacci-Sequenz zu studieren
Ich habe versucht, Jupyter mit allen Amazon-Lichtern zu starten
Ich habe versucht, Tundele mit Naive Bays zu beurteilen
Ich habe versucht, Java mit Termux unter Verwendung von Termux Arch zu verwenden, aber es hat nicht funktioniert
Ich habe versucht, die Pferde vorherzusagen, die mit LightGBM unter den Top 3 sein werden
Ich habe versucht, die Sündenfunktion mit Chainer zu trainieren
Ich habe versucht, maschinelles Lernen (Objekterkennung) mit TouchDesigner zu verschieben
Verwendung von xgboost: Mehrklassenklassifizierung mit Irisdaten
Ich habe versucht, Funktionen mit SIFT von OpenCV zu extrahieren
Ich habe versucht, Faster R-CNN mit Pytorch auszuführen
Ich habe versucht, mit VOICEROID2 2 automatisch zu lesen und zu speichern
Ich habe versucht zusammenzufassen, wie man Matplotlib von Python verwendet
Ich habe versucht, DCGAN mit PyTorch zu implementieren und zu lernen
Ich habe versucht, Mine Sweeper auf dem Terminal mit Python zu implementieren
Ich habe versucht, mit Blenders Python script_Part 01 zu beginnen
Ich habe versucht, eine CSV-Datei mit Python zu berühren
Ich habe versucht, Soma Cube mit Python zu lösen
Ich habe versucht, mit VOICEROID2 automatisch zu lesen und zu speichern
Ich habe versucht, mit Blenders Python script_Part 02 zu beginnen
Ich habe versucht, ObjectId (Primärschlüssel) mit Pymongo zu generieren
Ich habe versucht, künstliches Perzeptron mit Python zu implementieren
Ich habe versucht, eine ML-Pipeline mit Cloud Composer zu erstellen
Ich habe versucht, unsere Dunkelheit mit der Chatwork-API aufzudecken
[Einführung in Pytorch] Ich habe versucht, Cifar10 mit VGG16 ♬ zu kategorisieren
Ich habe versucht zusammenzufassen, wie man Pandas von Python benutzt
Ich habe versucht, das Problem mit Python Vol.1 zu lösen
Ich habe versucht, Grad-CAM mit Keras und Tensorflow zu implementieren
Ich habe versucht, eine OCR-App mit PySimpleGUI zu erstellen