[PYTHON] Unterstützung der Vektorregression und Merkmalsauswahl

Unterstützung der Vektorregression

Die Support-Vektor-Regression ist eine der Methoden des maschinellen Lernens und eignet sich für multivariate nichtlineare Regressionsprobleme, da sie die Regressionskurve schätzt, ohne eine funktionale Form anzunehmen. Darüber hinaus weist es eine starke Co-Linearität auf und hat das Merkmal, dass es schwierig ist, instabil zu werden, selbst wenn es ungefähr so oft wie möglich für die erklärenden Variablen verwendet wird.

** Beispiel für eine Support-Vektor-Regression ** figure_1-1.png

test_svr.py


import numpy as np
import random
import matplotlib.pyplot as plt
from sklearn import svm

PI = 3.14

#Machen Sie einen Punkt, indem Sie 0 bis 2π in 120 gleiche Teile teilen
X = np.array(range(120))
X = X * 6 * PI / 360
# y=Berechnen Sie sinX und fügen Sie einen Fehler hinzu, der der Gaußschen Verteilung folgt
y = np.sin(X)
e = [random.gauss(0, 0.2) for i in range(len(y))]
y += e
#In Spaltenvektor konvertieren
X = X[:, np.newaxis]

#Lerne
svr = svm.SVR(kernel='rbf')
svr.fit(X, y)

#Zeichnen Sie eine Regressionskurve
X_plot = np.linspace(0, 2*PI, 10000)
y_plot = svr.predict(X_plot[:, np.newaxis])

#Zeichnen Sie in der Grafik.
plt.scatter(X, y)
plt.plot(X_plot, y_plot)
plt.show()

Problem bei der Funktionsauswahl

Im Allgemeinen ist die Regressionskurve der Unterstützungsvektorregression eine nichtlineare Abbildung auf einen hochdimensionalen Merkmalsraum. Daher ist es nicht möglich, den Beitrag jeder erklärenden Variablen zur Erklärungskraft einfach aus dem absoluten Wert des Koeffizienten wie bei der multiplen Regressionsanalyse abzuleiten. (Das kannst du doch nicht, oder?) Daher wird es als effektiv angesehen, eine Sensitivitätsanalyse durchzuführen, den Übergang des Entscheidungskoeffizienten beim Löschen in der Reihenfolge aus der Variablen mit der niedrigsten Sensitivität aufzuzeichnen und die unmittelbar vor dem signifikanten Abfall des Entscheidungskoeffizienten festgelegte Variable als effektives Merkmal zu verwenden. ..

Methode und Implementierung

Ich habe auf [dieses Dokument] verwiesen (http://www.ipss.go.jp/syoushika/bunken/data/pdf/20011206.pdf).

Bewertung des Entscheidungskoeffizienten

  1. Finden Sie die Regressionskurve unter Verwendung aller Merkmale und berechnen Sie den Entscheidungskoeffizienten (es wird empfohlen, eine Rastersuche + Kreuzvalidierung durchzuführen).

Sensitivitätsanalyse

  1. Teilen Sie in Trainingsdaten und Testdaten auf. Ersetzen Sie für Testdaten die Werte anderer Variablen als der Variablen, für die Sie die Empfindlichkeit erhalten möchten, durch den Durchschnittswert dieser Variablen.
  2. Lernen Sie die Verwendung der Trainingsdaten und erhalten Sie den Ausgabewert aus den in 2 erstellten Testdaten.
  3. Führen Sie eine einfache Regressionsanalyse mit der Variablen durch, für die Sie die Empfindlichkeit als erklärende Variable und den Ausgabewert als Zielvariable erhalten möchten, und verwenden Sie den absoluten Wert des Gradienten als Empfindlichkeit.

Merkmalsauswahl

  1. Entfernen Sie nach Auswertung der Determinanten und der Sensitivitätsanalyse für alle Merkmale das Merkmal mit der niedrigsten Empfindlichkeit.
  2. Machen Sie diese eine Runde und wiederholen Sie den obigen Vorgang.
  3. Überprüfen Sie den Übergang des Entscheidungskoeffizienten beim Reduzieren der Features und schneiden Sie die Variablen so weit ab, wie Sie möchten.

Prüfung

Lassen Sie uns anhand der in scikit-learn bereitgestellten Bostoner Hauspreisdaten überprüfen.

** Anzahl der Feature-Reduktionsrunden und Entscheidungsfaktor ** image Es ist ersichtlich, dass der Bestimmungskoeffizient selbst dann nicht stark abfällt, wenn einige Merkmalsgrößen entfernt werden. Die Tabelle ist wie folgt.

Anzahl der Runden Ausgeschlossene Funktionen Entscheidungskoeffizient
0 - 0.644
1 ZN 0.649
2 INDUS 0.663
3 CHAS 0.613
4 CRIM 0.629
5 RAD 0.637
6 NOX 0.597
7 PTRATIO 0.492
8 B 0.533
9 TAX 0.445
10 DIS 0.472
11 AGE 0.493
12 RM 0.311

Die letzte verbleibende Funktion ist LSTAT.

Die Bedeutung jedes Merkmals ist ungefähr wie folgt. Weitere Informationen finden Sie unter hier. ** KRIMINALITÄT **: Pro-Kopf-Kriminalitätsrate ** ZN **: Prozentsatz des Wohngrundstücks über 25.000 Quadratfuß ** INDUS **: Prozentsatz der Nichteinzelhandelsbranche ** CHAS **: Ob es den Charles River berührt ** NOX **: Stickoxidkonzentration ** RM **: Anzahl der Zimmer ** ALTER **: Prozentsatz der Häuser, die vor 1940 gebaut wurden ** DIS **: Entfernung zu den Bostoner Beschäftigungszentren ** RAD **: Einfacher Zugang zu radialen Autobahnen ** STEUER **: Anlagesteuersatz bei Fälligkeit ** PTRATIO **: Anzahl der Schüler pro Lehrer ** B **: Verhältnis von Schwarzen zur Bevölkerung ** LSTAT **: Prozentsatz der Menschen der unteren Klasse

Aus diesem Ergebnis können wir Folgendes sehen.

――LSTAT und RM sind wichtiger als ZN und INDUS, um den Immobilienpreis in Boston vorherzusagen.

Durch die Kombination der Sensitivitätsanalyse auf diese Weise kann der Beitrag von Merkmalsgrößen auch dann eingestuft werden, wenn eine Unterstützungsvektorregression verwendet wird. Abschließend wird der für die Merkmalsauswahl verwendete Code beschrieben.

select_features.py


def standardize(data_table):
    for column in data_table.columns:
        if column in ["target"]:
            continue
        if data_table[column].std() == 0:
            data_table.loc[:, column] = 0
        else:
            data_table.loc[:, column] = ((data_table.loc[:,column] - data_table[column].mean()) 
                                         / data_table[column].std())

    return data_table

#Es ist eine Methode zur Berechnung der Empfindlichkeit
def calculate_sensitivity(data_frame, feature_name, k=10):
    import numpy as np
    import pandas as pd
    from sklearn import svm
    from sklearn import linear_model
    from sklearn import grid_search
    
    #Legen Sie die Parameter für die Rastersuche fest
    tuned_parameters = [{'kernel': ['rbf'], 'gamma': [10**i for i in range(-4, 0)],
                         'C': [10**i for i in range(1,4)]}]
    
    #Eine Liste, in der die Neigungswerte gespeichert sind.
    slope_list = []
    
    #Stichprobengröße
    sample_size = len(data_frame.index)
    
    features = list(data_frame.columns)
    features.remove("target")
    
    for number_set in range(k):
        
        #Teilen Sie die Daten für Training und Test.
        if number_set < k - 1:
            test_data = data_frame.iloc[number_set*sample_size//k:(number_set+1)*sample_size//k,:]
            learn_data = pd.concat([data_frame.iloc[0:number_set*sample_size//k, :],data_frame.loc[(number_set+1)*sample_size//k:, :]])
        else:
            test_data = data_frame[(k-1)*sample_size//k:]
            learn_data = data_frame[:(k-1)*sample_size//k]
        #Teilen Sie jedes in Beschriftungen und Merkmale ein
        learn_label_data = learn_data["target"]
        learn_feature_data = learn_data.loc[:,features]
        test_label_data = test_data["target"]
        test_feature_data = test_data.loc[:, features]
        
        #Ersetzen Sie die anderen Spalten als die, für die Sie die Empfindlichkeit der Testdaten analysieren möchten, durch den Spaltenmittelwert.
        for column in test_feature_data.columns:
            if column == feature_name:
                continue
            test_feature_data.loc[:, column] = test_feature_data[column].mean()
        
        #Numpy jede Daten für SVR.In Array-Format konvertieren.
        X_test = np.array(test_feature_data)
        X_linear_test = np.array(test_feature_data[feature_name])
        X_linear_test = X_linear_test[:, np.newaxis]
        y_test = np.array(test_label_data)
        X_learn = np.array(learn_feature_data)
        y_learn = np.array(learn_label_data)
        
        #Führen Sie eine Regressionsanalyse durch und erhalten Sie eine Ausgabe
        gsvr = grid_search.GridSearchCV(svm.SVR(), tuned_parameters, cv=5, scoring="mean_squared_error") 
        gsvr.fit(X_learn, y_learn)
        y_predicted = gsvr.predict(X_test)
        
        #Führt eine lineare Regression für die Ausgabe durch.
        lm = linear_model.LinearRegression()
        lm.fit(X_linear_test, y_predicted)
        
        #Holen Sie sich die Neigung
        slope_list.append(lm.coef_[0])
    
    return np.array(slope_list).mean()

#Diese Methode berechnet den Bestimmungskoeffizienten.
def calculate_R2(data_frame,k=10):
    import numpy as np
    import pandas as pd
    from sklearn import svm
    from sklearn import grid_search
    
    #Legen Sie die Parameter für die Rastersuche fest
    tuned_parameters = [{'kernel': ['rbf'], 'gamma': [10**i for i in range(-4, 0)],
                         'C': [10**i for i in range(1,4)]}]
    svr = svm.SVR()
    
    #Definieren Sie eine Liste, um den Wert jedes Entscheidungsfaktors zu speichern.
    R2_list = []
    
    features = list(data_frame.columns)
    features.remove("target")
    
    #Stichprobengröße
    sample_size = len(data_frame.index)
    
    for number_set in range(k):
        
        #Teilen Sie die Daten für Training und Test.
        if number_set < k - 1:
            test_data = data_frame[number_set*sample_size//k:(number_set+1)*sample_size//k]
            learn_data = pd.concat([data_frame[0:number_set*sample_size//k],data_frame[(number_set+1)*sample_size//k:]])
        else:
            test_data = data_frame[(k-1)*sample_size//k:]
            learn_data = data_frame[:(k-1)*sample_size//k]
        #Teilen Sie jedes in Beschriftungen und Merkmale ein
        learn_label_data = learn_data["target"]
        learn_feature_data = learn_data.loc[:, features]
        test_label_data = test_data["target"]
        test_feature_data = test_data.loc[:, features]

        #Numpy jede Daten für SVR.In Array-Format konvertieren.
        X_test = np.array(test_feature_data)
        y_test = np.array(test_label_data)
        X_learn = np.array(learn_feature_data)
        y_learn = np.array(learn_label_data)
        
        #Führen Sie eine Regressionsanalyse und R für Testdaten durch^Berechnen Sie 2.
        gsvr = grid_search.GridSearchCV(svr, tuned_parameters, cv=5, scoring="mean_squared_error") 
        gsvr.fit(X_learn, y_learn)
        score = gsvr.best_estimator_.score(X_test, y_test)
        R2_list.append(score)
    
    # R^Gibt den Durchschnittswert von 2 zurück.
    return np.array(R2_list).mean()

if __name__ == "__main__":
    from sklearn.datasets import load_boston
    from sklearn import svm
    import pandas as pd
    import random
    import numpy as np

    #Lesen Sie die Mietdaten für Boston.
    boston = load_boston()
    X_data, y_data = boston.data, boston.target
    df = pd.DataFrame(X_data, columns=boston["feature_names"])
    df['target'] = y_data
    count = 0
    temp_data = standardize(df)
    #Sortieren Sie die Daten nach dem Zufallsprinzip für die Kreuzvalidierung.
    temp_data.reindex(np.random.permutation(temp_data.index)).reset_index(drop=True)
    #Erstellen Sie einen Datenrahmen, um die Empfindlichkeit und den Bestimmungskoeffizienten der Merkmalsmenge in jeder Schleife zu speichern.
    result_data_frame = pd.DataFrame(np.zeros((len(df.columns), len(df.columns))), columns=df.columns)
    result_data_frame["Entscheidungskoeffizient"] = np.zeros(len(df.columns))
    #Führen Sie die folgende Schleife aus, bis der Feature-Betrag vollständig entfernt ist.
    while(len(temp_data.columns)>1):
        #Dies ist der Bestimmungsfaktor, wenn alle verbleibenden Funktionen in dieser Runde verwendet werden.
        result_data_frame.loc[count, "Entscheidungskoeffizient"] = calculate_R2(temp_data,k=10)
        #Ein Datenrahmen, in dem die Empfindlichkeit jedes Features in dieser Runde gespeichert wird
        temp_features = list(temp_data.columns)
        temp_features.remove('target')
        temp_result = pd.DataFrame(np.zeros(len(temp_features)),
                                   columns=["abs_Sensitivity"], index=temp_features)

        #Das Folgende wird für jede Merkmalsmenge wiederholt.
        for i, feature in enumerate(temp_data.columns):
            if feature == "target":
                continue
            #Sensitivitätsanalyse durchführen.
            sensitivity = calculate_sensitivity(temp_data, feature)

            result_data_frame.loc[count, feature] = sensitivity
            temp_result.loc[feature, "abs_Sensitivity"] = abs(sensitivity)
            print(feature, sensitivity)

        print(count, result_data_frame.loc[count, "Entscheidungskoeffizient"])
        #Erstellen Sie eine Kopie der Daten mit den Funktionen, bei denen die kleinste absolute Empfindlichkeit entfernt wurde.
        ineffective_feature = temp_result["abs_Sensitivity"].argmin()
        print(ineffective_feature)
        temp_data = temp_data.drop(ineffective_feature, axis=1)


    #Daten und Empfindlichkeit und R.^Gibt den Übergang von 2 zurück.
        result_data_frame.to_csv("result.csv")

        count += 1

Recommended Posts

Unterstützung der Vektorregression und Merkmalsauswahl
Maschinelles Lernen unterstützt Vektormaschine
Funktionsauswahl durch sklearn.feature_selection
Merkmalsauswahl durch genetischen Algorithmus
Unterschied zwischen Regression und Klassifikation
Funktionsauswahl durch Null-Wichtigkeiten
Maschinelles Lernen: Überwacht - Support Vector Machine
Algorithmus für maschinelles Lernen (Support Vector Machine)