2017-02-23 2 views
2

Dies ist ein bisschen ein Neuling Frage.Make RandomForestClassifier wählen Sie eine Variable für die Sicherheit während des Trainings

Ich würde gerne eine Random Forest mit einem RandomForestClassifier von sklearn trainieren. Ich habe ein paar Variablen, aber von diesen Variablen möchte ich, dass der Algorithmus eine Variable (nennen wir sie SourceID) in jedem Baum, den er trainiert, sicher auswählt.

Wie mache ich das? Ich sehe keine Parameter im Klassifikator, die in diesem Fall helfen würden.

Jede Hilfe wäre willkommen! TIA.

EDIT

Also hier ist das Szenario, das ich habe ..

Wenn ein Lehrer auf Concept A einen Auftrag vergibt, ich habe das nächste mögliche Zuordnung Konzept prognostizieren. Das nächste zugewiesene Konzept wäre stark abhängig von Concept A, die bereits zugewiesen wurde. Zum Beispiel - nachdem "Newtons erstes Bewegungsgesetz" zugewiesen wurde, gibt es eine große Möglichkeit, dass "Newtons zweites Bewegungsgesetz" zugewiesen werden kann. Ziemlich oft ist die Auswahl von Konzepten, die nach beispielsweise Concept A zugewiesen werden sollen, begrenzt. Ich würde gerne die bestmögliche Option vorhersagen, nachdem Concept A zugewiesen wurde, basierend auf vergangenen Daten.

Wenn ich lasse die random forest seine Arbeit tun Variablen zufällig Kommissionierung, dann wird es ein paar Bäume sein, die die Variable nicht für Concept A haben wird, wobei in diesem Fall die Vorhersage nicht viel Sinn machen, weshalb ich ist Ich möchte diese Variable zur Auswahl zwingen. Besser noch, es wäre toll, wenn diese Variable als erste Variable in jedem zu teilenden Baum gewählt wird.

Macht dies die Dinge klar? Ist random forest kein Kandidat für diesen Job?

+3

Die Natur von Random Forest, und Machine Learning als Ganzes in der Tat, ist, dass das Modell auf den Werten in Daten im Gegensatz zu harten Eingabe/Kontrolle basiert. Erzählen Sie uns mehr über den Hintergrund Ihrer Frage - warum versuchen Sie, hier eine Variable zu erzwingen? – Michal

+0

@Michal: habe die Frage bearbeitet, um weitere Details hinzuzufügen. – Patthebug

Antwort

1

Ich glaube nicht, dass es jetzt einen Weg in Scikit gibt. Sie könnten max_features = None verwenden, wodurch alle Zufälligkeiten von Feature-Auswahlen entfernt werden.

Wenn Sie Pakete, R Ranger (https://cran.r-project.org/web/packages/ranger/ranger.pdf) hat Optionen split.select.weights und always.split.variables, die sein kann, was Sie suchen wechseln. Definieren Sie die Wahrscheinlichkeit für die zufälligen Auswahlen oder fügen Sie diese zusätzlich zu den zufälligen Auswahlen immer ein.

Dies wirkt dem allgemeinen Design von Random Forest entgegen und reduziert die Zufälligkeit, was wiederum die Varianzreduktion des Algorithmus schwächen kann. Sie sollten eine Menge über Ihre Daten und das Problem wissen, diese Option zu wählen. Wie @Michal schon angedeutet hat, gehen Sie hier vorsichtig vor.

3

Es gibt keine Option dafür in der RandomForestClassifier, aber der Random Forest-Algorithmus ist nur ein Ensemble von Entscheidungsbäumen, wobei jeder Baum nur eine Teilmenge aller möglichen Features berücksichtigt und auf einer Bootstrap-Teilstichprobe der Trainingsdaten trainiert wird.

So ist es nicht zu schwierig, dies selbst manuell für Bäume zu erstellen, die gezwungen sind, bestimmte Funktionen zu verwenden. Ich habe eine Klasse geschrieben, um das unten zu tun. Dies tut nicht führen robuste Eingabe Validierung oder ähnliches, aber Sie können die Quelle von sklearn Random Forest fit Funktion dafür konsultieren.Damit ist gemeint, um Ihnen einen Eindruck davon, wie es selbst zu bauen:

FixedFeatureRFC.py

import numpy as np 
from sklearn.tree import DecisionTreeClassifier 

class FixedFeatureRFC: 
    def __init__(self, n_estimators=10, random_state=None): 
     self.n_estimators = n_estimators 

     if random_state is None: 
      self.random_state = np.random.RandomState() 

    def fit(self, X, y, feats_fixed=None, max_features=None, bootstrap_frac=0.8): 
     """ 
     feats_fixed: indices of features (columns of X) to be 
        always used to train each estimator 

     max_features: number of features that each estimator will use, 
         including the fixed features. 

     bootstrap_frac: size of bootstrap sample that each estimator will use. 
     """ 
     self.estimators = [] 
     self.feats_used = [] 
     self.n_classes = np.unique(y).shape[0] 

     if feats_fixed is None: 
      feats_fixed = [] 
     if max_features is None: 
      max_features = X.shape[1] 

     n_samples = X.shape[0] 
     n_bs = int(bootstrap_frac*n_samples) 

     feats_fixed = list(feats_fixed) 
     feats_all = range(X.shape[1]) 

     random_choice_size = max_features - len(feats_fixed) 

     feats_choosable = set(feats_all).difference(set(feats_fixed)) 
     feats_choosable = np.array(list(feats_choosable)) 

     for i in range(self.n_estimators): 
      chosen = self.random_state.choice(feats_choosable, 
               size=random_choice_size, 
               replace=False) 
      feats = feats_fixed + list(chosen) 
      self.feats_used.append(feats) 

      bs_sample = self.random_state.choice(n_samples, 
               size=n_bs, 
               replace=True) 

      dtc = DecisionTreeClassifier(random_state=self.random_state) 
      dtc.fit(X[bs_sample][:,feats], y[bs_sample]) 
      self.estimators.append(dtc) 

    def predict_proba(self, X): 
     out = np.zeros((X.shape[0], self.n_classes)) 
     for i in range(self.n_estimators): 
      out += self.estimators[i].predict_proba(X[:,self.feats_used[i]]) 
     return out/self.n_estimators 

    def predict(self, X): 
     return self.predict_proba(X).argmax(axis=1) 

    def score(self, X, y): 
     return (self.predict(X) == y).mean() 

Hier ist ein Testskript, um zu sehen, ob die Klasse oben genannten Arbeiten wie vorgesehen:

test.py

import numpy as np 
from sklearn.datasets import load_breast_cancer 
from FixedFeatureRFC import FixedFeatureRFC 

rs = np.random.RandomState(1234) 
BC = load_breast_cancer() 
X,y = BC.data, BC.target 
train = rs.rand(X.shape[0]) < 0.8 

print "n_features =", X.shape[1] 

fixed = [0,4,21] 
maxf = 10 

ffrfc = FixedFeatureRFC(n_estimators=1000) 
ffrfc.fit(X[train], y[train], feats_fixed=fixed, max_features=maxf) 

for feats in ffrfc.feats_used: 
    assert len(feats) == maxf 
    for f in fixed: 
     assert f in feats 

print ffrfc.score(X[~train], y[~train]) 

Der Ausgang ist:

n_features = 30 
0.983739837398 

Keine der Behauptungen fehlgeschlagen, was darauf hinweist, dass die Funktionen, die wir festgelegt in jeder Zufalls Merkmal Unterabtast wurden verwendet, um zu entschieden haben und dass die Größe von jedem Merkmal Unterabtast die erforderlich war max_features Größe . Die hohe Genauigkeit bei den gehaltenen Daten zeigt an, dass der Klassifikator ordnungsgemäß funktioniert.

Verwandte Themen