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 **
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()
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. ..
J'ai fait référence à ce document.
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 ** 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