[PYTHON] Prise en charge de la régression vectorielle et de la sélection des fonctionnalités

Régression vectorielle de soutien

La régression vectorielle de support est l'une des méthodes d'apprentissage automatique et convient aux problèmes de régression non linéaire multivariée car elle estime la courbe de régression sans prendre une forme fonctionnelle. De plus, il a une forte colinéarité, et il a la particularité qu'il est difficile de devenir instable même s'il est utilisé à peu près autant que possible pour les variables explicatives.

** Exemple de régression vectorielle de support ** 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

#Faites un point en divisant 0 à 2π en 120 parties égales
X = np.array(range(120))
X = X * 6 * PI / 360
# y=Calculez sinX et ajoutez une erreur qui suit la distribution gaussienne
y = np.sin(X)
e = [random.gauss(0, 0.2) for i in range(len(y))]
y += e
#Convertir en vecteur de colonne
X = X[:, np.newaxis]

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

#Dessinez une courbe de régression
X_plot = np.linspace(0, 2*PI, 10000)
y_plot = svr.predict(X_plot[:, np.newaxis])

#Tracez sur le graphique.
plt.scatter(X, y)
plt.plot(X_plot, y_plot)
plt.show()

Problème de sélection des fonctionnalités

En général, la courbe de régression de la régression vectorielle de support est un mappage non linéaire vers un espace de caractéristiques de grande dimension. Par conséquent, il n'est pas possible de déduire simplement la contribution de chaque variable explicative au pouvoir explicatif à partir de la valeur absolue du coefficient comme dans l'analyse de régression multiple. (Vous ne pouvez pas faire ça, non?) Par conséquent, il est considéré comme efficace d'effectuer une analyse de sensibilité, d'enregistrer la transition du coefficient de décision tout en supprimant dans l'ordre de la variable avec la sensibilité la plus faible et d'utiliser l'ensemble de variables immédiatement avant que le coefficient de décision ne diminue de manière significative comme une caractéristique efficace. ..

Méthode et mise en œuvre

J'ai fait référence à ce document.

Évaluation du coefficient de décision

  1. Trouvez la courbe de régression en utilisant toutes les fonctionnalités et calculez le coefficient de décision (il est recommandé de faire une recherche de grille + validation croisée)

Analyse de sensibilité

  1. Divisez en données d'entraînement et données de test. Pour les données de test, remplacez les valeurs des variables autres que la variable pour laquelle vous souhaitez obtenir la sensibilité par la valeur moyenne de cette variable.
  2. Apprenez à utiliser les données d'entraînement et obtenez la valeur de sortie à partir des données de test créées en 2.
  3. Effectuez une analyse de régression simple avec la variable pour laquelle vous souhaitez obtenir la sensibilité comme variable explicative et la valeur de sortie comme variable objectif, et utilisez la valeur absolue du gradient comme sensibilité.

Sélection de fonctionnalité

  1. Après avoir évalué les déterminants et l'analyse de sensibilité pour toutes les fonctions, supprimez la fonction avec la sensibilité la plus faible.
  2. Faites un tour et répétez le processus ci-dessus.
  3. Vérifiez la transition du coefficient de décision dans le processus de réduction des caractéristiques et coupez les variables autant que vous le souhaitez.

tester

Vérifions en utilisant les données sur les prix des maisons à Boston fournies dans scikit-learn.

** Nombre de cycles de réduction des fonctionnalités et facteur de décision ** image On peut voir que le coefficient de détermination ne baisse pas brusquement même si certaines quantités de caractéristiques sont supprimées. Le tableau est le suivant.

Nombre de tours Fonctionnalités exclues Coefficient de décision
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

La dernière fonctionnalité restante est LSTAT.

La signification de chaque caractéristique est à peu près la suivante. Voir ici pour plus de détails. ** CRIM **: Taux de criminalité par habitant ** ZN **: Pourcentage de terrains résidentiels de plus de 25000 pieds carrés ** INDUS **: Pourcentage d'industries non commerciales ** CHAS **: s'il touche la rivière Charles ** NOX **: concentration d'oxyde d'azote ** RM **: Nombre de chambres ** AGE **: Pourcentage de maisons construites avant 1940 ** DIS **: Distance des centres d'emploi de Boston ** RAD **: accès facile aux autoroutes radiales ** TAX **: Taux d'imposition des immobilisations à l'échéance ** PTRATIO **: Nombre d'élèves par enseignant ** B **: Rapport des Noirs à la population ** LSTAT **: Pourcentage de personnes de classe inférieure

De ce résultat, nous pouvons voir ce qui suit.

――LSTAT et RM sont plus importants que ZN et INDUS pour prédire le prix de l'immobilier à Boston.

En combinant l'analyse de sensibilité de cette manière, il est possible de classer la contribution des caractéristiques même en utilisant la régression vectorielle de support. Enfin, le code utilisé pour la sélection des fonctionnalités est décrit.

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

#C'est une méthode pour calculer la sensibilité
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
    
    #Définir les paramètres de la recherche de grille
    tuned_parameters = [{'kernel': ['rbf'], 'gamma': [10**i for i in range(-4, 0)],
                         'C': [10**i for i in range(1,4)]}]
    
    #Une liste qui stocke les valeurs d'inclinaison.
    slope_list = []
    
    #taille de l'échantillon
    sample_size = len(data_frame.index)
    
    features = list(data_frame.columns)
    features.remove("target")
    
    for number_set in range(k):
        
        #Divisez les données pour la formation et les tests.
        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]
        #Divisez chacun en libellés et fonctionnalités
        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]
        
        #Remplacez les colonnes autres que celle pour laquelle vous souhaitez analyser la sensibilité des données de test par la moyenne de la colonne.
        for column in test_feature_data.columns:
            if column == feature_name:
                continue
            test_feature_data.loc[:, column] = test_feature_data[column].mean()
        
        #Numpy chaque données pour SVR.Convertir au format tableau.
        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)
        
        #Effectuer une analyse de régression et obtenir une sortie
        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)
        
        #Effectue une régression linéaire sur la sortie.
        lm = linear_model.LinearRegression()
        lm.fit(X_linear_test, y_predicted)
        
        #Obtenez l'inclinaison
        slope_list.append(lm.coef_[0])
    
    return np.array(slope_list).mean()

#Cette méthode calcule le coefficient de détermination.
def calculate_R2(data_frame,k=10):
    import numpy as np
    import pandas as pd
    from sklearn import svm
    from sklearn import grid_search
    
    #Définir les paramètres de la recherche de grille
    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()
    
    #Définissez une liste qui stocke la valeur de chaque facteur de décision.
    R2_list = []
    
    features = list(data_frame.columns)
    features.remove("target")
    
    #taille de l'échantillon
    sample_size = len(data_frame.index)
    
    for number_set in range(k):
        
        #Divisez les données pour la formation et les tests.
        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]
        #Divisez chacun en libellés et fonctionnalités
        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 chaque données pour SVR.Convertir au format tableau.
        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)
        
        #Effectuer une analyse de régression et R pour les données de test^Calculez 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^Renvoie la valeur moyenne de 2.
    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

    #Lisez les données de location de 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)
    #Triez les données de manière aléatoire pour une validation croisée.
    temp_data.reindex(np.random.permutation(temp_data.index)).reset_index(drop=True)
    #Créez une trame de données pour stocker la sensibilité et le coefficient de détermination de la quantité d'entités dans chaque boucle.
    result_data_frame = pd.DataFrame(np.zeros((len(df.columns), len(df.columns))), columns=df.columns)
    result_data_frame["Coefficient de décision"] = np.zeros(len(df.columns))
    #Exécutez la boucle suivante jusqu'à ce que la quantité de fonctionnalités soit complètement supprimée.
    while(len(temp_data.columns)>1):
        #C'est le facteur de détermination lors de l'utilisation de toutes les fonctionnalités restantes dans ce tour.
        result_data_frame.loc[count, "Coefficient de décision"] = calculate_R2(temp_data,k=10)
        #Une trame de données qui stocke la sensibilité de chaque fonctionnalité dans ce tour
        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)

        #Ce qui suit est mis en boucle pour chaque quantité de caractéristiques.
        for i, feature in enumerate(temp_data.columns):
            if feature == "target":
                continue
            #Effectuer une analyse de sensibilité.
            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, "Coefficient de décision"])
        #Faites une copie des données en supprimant les fonctionnalités avec la plus petite sensibilité absolue.
        ineffective_feature = temp_result["abs_Sensitivity"].argmin()
        print(ineffective_feature)
        temp_data = temp_data.drop(ineffective_feature, axis=1)


    #Données et sensibilité et R^Renvoie la transition de 2.
        result_data_frame.to_csv("result.csv")

        count += 1

Recommended Posts

Prise en charge de la régression vectorielle et de la sélection des fonctionnalités
Machine de vecteur de support d'apprentissage automatique
Sélection des fonctionnalités par sklearn.feature_selection
Sélection des caractéristiques par algorithme génétique
Différence entre régression et classification
Sélection de fonctionnalités par importances nulles
Machine Learning: Supervisé - Support Vector Machine
Algorithme d'apprentissage automatique (machine vectorielle de support)