In [351]:
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
In [352]:
#Le polynome que l'on souhaite découvir, il est utilisé pour générer des données
#mais sera supposé inconnu par la suite
def poly(x):
#1x³-3x²+3x-5
return 1*x*x*x - 3*x*x + 3*x - 5
In [353]:
#On génère un ensemble de points (x,y) à partir du polynome pour le training
xTrain = [val for val in xrange(-4,6)]
xTrain = np.array(xTrain)
yTrain = map(poly, xTrain)
#On génère un ensemble de points (x,y) à partir du polynome pour la validation
xTest = [-3.4,-1.9, -0.5, 1.1, 1.5, 3.6, 4.8]
xTest = np.array(xTest)
yTest = map(poly, xTest)
#################################################
#Etant donné que dans la réalité les données ne sont pas parfaites mais contiennent toujours du bruit
#nous allons le simuler en ajoutant un bruit aléatoire aux valeurs de y
rs = np.random.RandomState(1) #fixe l'état aléatoire pour pouvoir reproduire le meme bruit à chaque exécution du code
noise = 10*rs.randn(len(xTrain)) #on genere autant de bruit que de données (x,y)
yTrainNoisy = yTrain + noise #on ajoute le bruit aux valeurs y
noise = 10*rs.randn(len(xTest))
yTestNoisy = yTest + noise
In [354]:
plt.plot(xTrain,yTrain, c='blue') #on dessine la courbe représentant les données non bruités en bleu
plt.scatter(xTrain,yTrain, c='blue') #on place les points non bruités en bleu
plt.scatter(xTrain, yTrainNoisy, c='red') #on place les points bruités en rouge
Out[354]:
In [363]:
#Prediction avec les données NON BRUITEES
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error
#Puisqu'on souhaite découvrir le modèle (le polynome que l'on ne connait pas) à partir des donnés (x,y)
#le polynome peut être écrit sous la forme : w0*x0 + w1*x1 + w2*x2 + w3*x3 + w4*x4+.....+wn*xn
#où chaque attribut xn correspond à x^n
#on doit donc trouver les paramètres W de manière à ce que le modèle trouvé soit :
# -5*x0 + 3*x1 -3*x2 + 1*x3
#Nous allons créer en nous basant sur les valeur de x, une matrice ou chaque colonne correspond à un attribut x^d
#la première colonne est la colonne des 1 puisque x0=1
trainPoly = np.array( [xTrain**d for d in xrange(1,10) ] ).transpose()
testPoly = np.array( [xTest**d for d in xrange(1,10) ] ).transpose()
#puisque on ne connait pas le dégré du polynome que l'on cherche, nous allons tester différents modèles
# de degrés différents et choisir celui qui donne le meilleur score
for d in [1,2,3,4,5,6,7,8,9,10]:
train = trainPoly[:,:d] #on choisit les d premières colonnes, ce qui correspons à un polynome de degré d-1
test = testPoly[:,:d]
LR = LinearRegression()
LR.fit(train, yTrain) #on applique la régression linéaire
predTrain = LR.predict(train) # on prédit pour train
predTest = LR.predict(test) # on prédit pour les données de validation
#on affiche l'erreur RMSE ainsi que les coefficients du modèle calculés
print 'degre=', d, ' train :' , np.sqrt(mean_squared_error(predTrain, yTrain)),
print ' test : ', np.sqrt(mean_squared_error(predTest, yTest))
print LR.coef_[::-1], LR.intercept_
print
#le meilleur modèle touvé est de degré 3 avec les coefficients [ 1. -3. 3.] -5.0 ce qui correspond
#exactement aux coefficients du polynome que l'on cherchait.
In [357]:
#Prediction avec les données BRUITEES
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error
trainPoly = np.array( [xTrain**d for d in xrange(1,10) ] ).transpose()
testPoly = np.array( [xTest**d for d in xrange(1,10) ] ).transpose()
for d in xrange(1,10):
train = trainPoly[:,:d]
test = testPoly[:,:d]
LR = LinearRegression(normalize=True)
LR.fit(train, yTrainNoisy)
predTrain = LR.predict(train)
predTest = LR.predict(test)
print 'degre=', d, ' train :' , np.sqrt(mean_squared_error(predTrain, yTrainNoisy)),
print ' test : ', np.sqrt(mean_squared_error(predTest, yTestNoisy))
print LR.coef_[::-1], LR.intercept_
print
#avec les donnée bruitées, on voit que le meilleur score obtenu pour les données de training est celui correspondant
#au modèle de degré 9
#En effet, puisque nous avons 10 points d'apprentissage (bruités), la meilleure courbe passant par ces points
#est un polynome de degré 9 ( voir courbe ci-dessous)
#Le modèle de degré 9 est un modèle qui n'a pas appris le pattern qui se cache dans les données mais a appris
#le bruit qui se trouve dans les données, il est donc incapable de généraliser pour de nouvelles données.
#Et on voit que le score pour la validation est énorme
In [358]:
#On va tracer les courbes correspondant au modèle de degré 9
#On construit le modèle avec toutes les colonnes (d=10)
for d in [10]:
train = trainPoly[:,:d]
test = testPoly[:,:d]
LR = LinearRegression(normalize=True)
LR.fit(train, yTrainNoisy)
predTrain = LR.predict(train)
predTest = LR.predict(test)
print 'degre=', d, ' train :' , np.sqrt(mean_squared_error(predTrain, yTrainNoisy)),
print ' test : ', np.sqrt(mean_squared_error(predTest, yTestNoisy))
print LR.coef_[::-1], LR.intercept_
print
#plt.figure(figsize=(20,10))
plt.plot(xTrain, predTrain)
plt.plot(xTrain, yTrain, c='red')
plt.scatter(xTrain, yTrainNoisy, c='red')
#plt.scatter(xTest, yTestNoisy, c='green')
Out[358]:
In [359]:
#RIDGE REGULARIZATION
from sklearn.linear_model import LinearRegression, Ridge
from sklearn.metrics import mean_squared_error
trainPoly = np.array( [xTrain**d for d in xrange(0,11) ] ).transpose()
testPoly = np.array( [xTest**d for d in xrange(0,11) ] ).transpose()
for d in xrange(1,10):
train = trainPoly[:,:d]
test = testPoly[:,:d]
LR = Ridge(alpha=1, normalize=True)
LR.fit(train, yTrainNoisy)
predTrain = LR.predict(train)
predTest = LR.predict(test)
print 'degre=', d, ' train :' , np.sqrt(mean_squared_error(predTrain, yTrainNoisy)),
print ' test : ', np.sqrt(mean_squared_error(predTest, yTestNoisy))
print LR.coef_[1:][::-1], LR.intercept_
print
In [360]:
#On choisit un modèle de degré 9, alpha=0.05 est la meilleur valeur de régularization pour ce modèle
#On voit que l'erreur de validation est très petite comparée à la regression Lineaire
#On remarque aussi que les coefficients de degré élevé tendent vers 0
for d in [10]:
train = trainPoly[:,:d]
test = testPoly[:,:d]
LR = Ridge(alpha=0.05, normalize=True)
LR.fit(train, yTrainNoisy)
predTrain = LR.predict(train)
predTest = LR.predict(test)
print 'degre=', d, ' train :' , np.sqrt(mean_squared_error(predTrain, yTrainNoisy)),
print ' test : ', np.sqrt(mean_squared_error(predTest, yTestNoisy))
print LR.coef_[1:][::-1], LR.intercept_
print
plt.plot(xTrain, predTrain)
plt.plot(xTrain, yTrain, c='red')
Out[360]:
In [361]:
#L'avantage de Lasso par rapport à Ridge est que les degrés non important possèdent un coefficient EGAL à 0
from sklearn.linear_model import LinearRegression, Lasso
from sklearn.metrics import mean_squared_error
trainPoly = np.array( [xTrain**d for d in xrange(0,11) ] ).transpose()
testPoly = np.array( [xTest**d for d in xrange(0,11) ] ).transpose()
for d in [10]:
train = trainPoly[:,:d]
test = testPoly[:,:d]
LR = Lasso(alpha=0.03, normalize=True)
LR.fit(train, yTrainNoisy)
predTrain = LR.predict(train)
predTest = LR.predict(test)
print 'degre=', d, ' train :' , np.sqrt(mean_squared_error(predTrain, yTrainNoisy)),
print ' test : ', np.sqrt(mean_squared_error(predTest, yTestNoisy))
print LR.coef_[1:][::-1], LR.intercept_
print
In [362]:
plt.plot(xTrain, predTrain)
plt.plot(xTrain, yTrain, c='red')
Out[362]:
In [249]:
Out[249]:
In [ ]: