Während dieser Zeit erhielt ich Stufe 2 des statistischen Tests und im Rahmen der Testvorbereitung studierte ich eine statistische Methode namens "Chi-Quadrat-Test". Ich habe mich gefragt, ob dieser "Chi-Quadrat-Test" für die Auswahl von Feature-Mengen beim maschinellen Lernen nützlich ist, und festgestellt, dass er bereits in Select KBest von scicit-learn implementiert ist. Daher möchte ich eine Notiz zur Verwendung machen.
Auch als "Test der Unabhängigkeit" bekannt, dient es zum Testen, dass Ereignis A und Ereignis B "unabhängig" sind.
Unter der Annahme, dass Ereignis A und Ereignis B unabhängig sind, prüfen Sie, wie "unmöglich" der gemessene Wert ist, und "unmöglich" = "Ereignis A und Ereignis B sind nicht unabhängig und haben eine Beziehung". Mein Verständnis ist, dass es ein Test dafür ist.
Die folgenden Seiten sind sehr hilfreich für eine etwas detailliertere Erklärung.
Unabhängigkeitstest - Beliebtester Chi-Quadrat-Test (Statistik-WEB)
Verwenden Sie die folgenden Daten, einschließlich kategorialer Daten in den erklärenden Variablen. Diese Daten erfassen zusammen mit Informationen wie Alter, Beruf und Geschlecht der Person, ob das Jahreseinkommen einer Person 50.000 übersteigt.
Datenname | Adult Data Set |
URL | https://archive.ics.uci.edu/ml/datasets/adult |
Die Anzahl der Daten | 32561 |
Notieren Sie den Code, um die obigen Daten zu lesen. Da der Chi-Quadrat-Test zum Testen dient, wie stark die Häufigkeit einer bestimmten Merkmalsgröße vom erwarteten Wert abweicht, werden außerdem numerische Daten (quantitative Daten) ausgeschlossen und das Lernen wird nur unter Verwendung von Kategoriedaten durchgeführt.
from sklearn.model_selection import train_test_split
import pandas as pd
import numpy as np
#Datenlesen und Angabe des Spaltennamens
#Datenlesen und Datenverarbeitung
columns=['age','workclass','fnlwgt','education','education-num',
'marital-status','occupation','relationship','race','sex','capital-gain',
'capital-loss','hours-per-week','native-country','Income']
data = pd.read_csv('adult.data.csv', header=None).sample(frac=1).dropna()
data.columns=columns
print(data.shape)
data = data.replace({' <=50K':0,' >50K':1})
data.head()
#Erklärende Variable(Kategoriedaten)Und durch objektive Variable getrennt
data_x = data[['workclass','education','marital-status','occupation','relationship','race','sex','native-country']]
data_y = data['Income']
#Kategoriedaten sind eine Dummy-Variable
data_dm = pd.get_dummies(data_x)
#Unterteilt in Trainingsdaten und Testdaten
X_train, X_test, Y_train, Y_test = train_test_split(data_dm, data_y, train_size=0.7)
Lassen Sie uns zunächst das Ergebnis überprüfen, wenn die Feature-Menge nicht ausgewählt ist, dh wenn das Modell mit allen Feature-Mengen trainiert wird.
Das diesmal verwendete Modell ist eine Gradientenverstärkung und wird standardmäßig ohne Parametereinstellung trainiert.
from sklearn.preprocessing import StandardScaler
from sklearn.ensemble import GradientBoostingClassifier
from imblearn.pipeline import Pipeline
scaler = StandardScaler()
clf = GradientBoostingClassifier()
#Eine Reihe von Verarbeitung(Pipeline)Definieren
#Standardisierung → Diskriminatorentraining
estimator = [
('scaler',scaler),
('clf',clf)
]
pipe = Pipeline(estimator)
pipe.fit(X_train, Y_train)
print('Richtige Antwortrate: ' + str(pipe.score(X_test, Y_test)))
Richtige Antwortrate: 0,828743986078
Ich habe keine Parametereinstellung vorgenommen, daher ist es genau. Schauen wir uns als nächstes die Ergebnisse an, wenn die Auswahl der Merkmalsmenge mithilfe des Chi-Quadrat-Tests durchgeführt wird.
Die Auswahl von Funktionen durch Chi-Quadrat-Test kann mithilfe von "SelectKBest" von scikit-learn einfach implementiert werden. Ich werde.
Diese Klasse schränkt die Anzahl der Features basierend auf dem durch den Parameter score_func angegebenen Bewertungsindex ein. Die verwendete Methode ist die übliche Anpassung / Transformation. Die Anzahl der Merkmale nach dem Eingrenzen kann durch den Parameter k angegeben werden.
Es können mehrere Bewertungsindizes ausgewählt werden, aber da hier der Chi-Quadrat-Test verwendet wird, wird "Chi2" angegeben.
Wir trainieren zuerst alle Features, reduzieren dann die Features nacheinander und beenden die Iteration, wenn die richtige Antwortrate des Modells zu sinken beginnt. (Es scheint sich um eine Methode namens "Backward Feature Elimination" zu handeln.)
from sklearn.feature_selection import SelectKBest, chi2
max_score = 0
for k in range(len(data_dm.columns)):
print(len(data_dm.columns)-k)
select = SelectKBest(score_func=chi2, k=len(data_dm.columns)-k)
scaler = StandardScaler()
clf = GradientBoostingClassifier()
#Eine Reihe von Verarbeitung(Pipeline)Definieren
#Merkmalsextraktion → Standardisierung → Klassifizierertraining
estimator = [
('select',select),
('scaler',scaler),
('clf',clf)
]
pipe_select = Pipeline(estimator)
pipe_select.fit(X_train, Y_train)
score = pipe_select.score(X_test, Y_test)
if score < max_score:
break
else:
max_score = score
pipe_fix = pipe_select
print('Richtige Antwortrate: ' + str(pipe_fix.score(X_test, Y_test)))
Richtige Antwortrate: 0,828948715324
Die richtige Antwortrate hat sich etwas erhöht. Es scheint, dass die Originaldaten unnötige Merkmale enthielten, und es scheint, dass die Merkmale durch Auswahl der Merkmale durch den Chi-Quadrat-Test ausgeschlossen werden könnten.
Übrigens können die ausgeschlossenen Funktionen unten bestätigt werden.
mask = -pipe_fix.steps[0][1].get_support()
data_dm.iloc[:,mask].columns
Index(['native-country_ Greece', 'native-country_ Holand-Netherlands','native-country_ Thailand'],dtype='object')
Zum Vergleich werde ich auch eine andere Methode zur Auswahl von Merkmalsmengen vorstellen. Einige beim maschinellen Lernen verwendete Modelle behalten bei, welche Funktionen erheblich zur Genauigkeit beitragen. Zum Beispiel Lasso-Regression, Ridge-Regression. Schauen wir uns hier ein Implementierungsbeispiel für die Auswahl von Features durch Random Forest und das Ergebnis an.
from sklearn.feature_selection import SelectFromModel
from sklearn.ensemble import RandomForestClassifier
select = SelectFromModel(RandomForestClassifier(n_estimators=100, n_jobs=-1))
scaler = StandardScaler()
clf = GradientBoostingClassifier()
#Eine Reihe von Verarbeitung(Pipeline)Definieren
#Merkmalsextraktion → Standardisierung → Klassifizierertraining
estimator = [
('select',select),
('scaler',scaler),
('clf',clf)
]
pipe_rf = Pipeline(estimator)
pipe_rf.fit(X_train, Y_train)
print('Richtige Antwortrate: ' + str(pipe_rf.score(X_test, Y_test)))
Richtige Antwortrate: 0,826287235132
Die Genauigkeitsrate ist niedriger als bei Verwendung aller Funktionen.
Ich denke, dass die Genauigkeit nicht gut ist, da die Parameter des Modells, das für die Merkmalsauswahl verwendet wird, nicht abgestimmt sind. Es ist nicht das Hauptthema, daher werde ich in diesem Artikel nicht näher darauf eingehen.
In diesem Artikel habe ich eine kurze Erläuterung des Chi-Quadrat-Tests und ein Implementierungsbeispiel mit Select KBest vorgestellt. Mein derzeitiges Verständnis ist, dass die Auswahl der Merkmalsmenge durch den Chi-Quadrat-Test nur für Klassifizierungsprobleme gültig ist, da es sich bei der Merkmalsmenge um kategoriale Daten handelt. Verwenden Sie für Merkmalsgrößen, die numerische Daten enthalten, oder für Regressionsprobleme die Merkmalsmengenauswahl basierend auf Bewertungsindikatoren wie dem Pearson-Korrelationskoeffizienten und der ANOVA. (Übrigens verwende ich häufig die Auswahl der Merkmalsmenge nach zufälliger Gesamtstruktur, die unabhängig von Kategoriedaten oder numerischen Daten einfach zu verwenden ist.)
Wenn Sie Fragen oder Bedenken bezüglich der Beschreibung haben, kommentieren Sie bitte.
Dokument von chi2, angegeben durch score_func von SelectKBest (sklearn.feature_selection.chi2 ), Finden Sie die folgende Beschreibung.
X : {array-like, sparse matrix}, shape = (n_samples, n_features_in)
Die als Parameter übergebenen Daten werden als spärliches Array geschrieben, dh als Array mit den meisten Elementen 0.
Wenn Sie die Quelle lesen, sehen Sie, dass es einen Code wie den folgenden gibt, der den Gesamtwert für jede Spalte berechnet, dh die Häufigkeit ihrer Merkmalsmenge. Um diese Berechnung durchzuführen, können Sie sehen, dass ein Fehler auftritt, wenn Sie die Daten einschließlich der Zeichenfolge übergeben, bevor Sie sie als Parameter in eine Dummy-Variable umwandeln.
feature_count = X.sum(axis=0).reshape(1, -1)
Auch wenn die Merkmalsmenge numerische Daten (quantitative Daten) enthält, tritt kein Fehler auf, sondern es wird eine mysteriöse Berechnung durchgeführt. (Wenn beispielsweise eine charakteristische Altersgröße vorhanden ist, wird das Gesamtalter aller Linien berechnet und als Häufigkeit erkannt.)
Nach dem Anpassen verfügt die SelectKBest-Instanz über eine Liste der Features, die mit der Methode get_support () ausgewählt wurden. Wenn die Transformationsmethode ausgeführt wird, scheint der Merkmalsbetrag, dessen Maske True ist, ausgewählt und aus den Merkmalsbeträgen der Eingabedaten zurückgegeben zu werden.
Die folgende Quelle ist ein Implementierungsbeispiel, wenn die Anzahl der Features auf 10 eingegrenzt wird.
from sklearn.feature_selection import SelectKBest, chi2
select = SelectKBest(score_func=chi2, k=10)
select.fit(X_train, Y_train)
mask = select.get_support()
mask
array([ True, True, True, True, True, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False], dtype=bool)
Sie können beispielsweise anhand des folgenden Codes überprüfen, welchen Funktionsbetrag Sie ausgewählt haben.
data_dm.iloc[:,mask].columns
Index(['age', 'fnlwgt', 'education-num', 'capital-gain', 'capital-loss','hours-per-week', 'marital-status_ Married-civ-spouse','marital-status_ Never-married', 'relationship_ Husband','relationship_ Own-child'],dtype='object')
Recommended Posts