Dans le précédent post <Introduction à la régression linéaire simple>, j’avais introduit la régression linéaire simple en utilisant Python. Nous avons vu que la régression linéaire peut être appliquée à de nombreux problèmes linéaires.
Cependant, un avantage important de la régression linéaire est qu’elle peut également s’appliquer aux problèmes qui ne semblent pas linéaires au début. Dans ce post, nous allons cibler les problèmes exponentiels.
Il y a beaucoup de croissance exponentielle dans la vie réelle:
La loi de Moore stipule que les transistors sur une puce doublent tous les deux ans environ. Doubler tous les deux ans indique que nous avons une courbe exponentielle.
La question est: qu'est-ce que cela a à voir avec la régression linéaire?
Le truc ici est que nous ne mesurerons pas les comptes de transistors directement, mais nous allons mesurer le logarithme naturel des comptes de transistors. Simulons ce problème en python. Importons d'abord les bibliothèques nécessaires.
import numpy as np
import matplotlib.pyplot as plt
import math
import random
#08/06/2019
#Version python → 3.7.3
#version numpy → 1.16.2
#version matplotlib → 3.0.3
Le premier microprocesseur (Intel 4004) a été inventé en 1971. Il s’agissait d’une unité de calcul de 4 bits, cadencée à 740 kHz et intégrant 2300 transistors. Nous allons maintenant simuler la loi de Moore en générant des données représentant l'évolution du nombre de transistors sur 70 ans. Nous allons commencer par 2300 transistors et doubler ce nombre de deux tous les deux ans. Notez que les données générées ici ne représentent pas les données dans la réalité et ceci est juste à des fins de démonstration.
#Générer nos données
X=[]
Y=[]
#Nous commençons par 2300 transistors et
#doublons ce nombre tous les deux ans
start=2300
for i in range(1,70,2):
X.append(i)
Y.append(start)
start *= 2
Nous allons transformer X et Y en tableaux numpy et imprimer le nombre de transistors pour la 5ème année
X=np.array(X)
Y=np.array(Y)
#le troisième élément de X (indice = 2) représente la cinquième année.
#Dans la boucle ci-dessus, nous avons commencé par un
#et nous incrémentons de deux.
#Les éléments dans X seront comme ceci [1,3,5,7, ..., 69].
print(X[2])
# → 5
print(Y[2])
# → 9200
Maintenant, tracé les données.
plt.scatter(X,Y)
plt.show()
On peut remarquer que les données de Y ont la forme d’une courbe exponentielle.
L'astuce ici est que nous ne voulons pas appliquer la régression linéaire à ces données, mais nous allons calculer le logarithme naturel de Y qui semble linéaire.
Y=np.log(Y)
plt.scatter(X,Y)
plt.show()
Nous avons maintenant des données qui semblent linéaires. Nous pouvons appliquer ce que nous avons fait dans le post précédent <Introduction à la régression linéaire simple> et calculer a et b.
denominator=X.dot(X) - X.mean() * X.sum()
a=(X.dot(Y)-Y.mean()*X.sum())/denominator
b=(Y.mean()* X.dot(X)-X.mean()*X.dot(Y))/denominator
Yhat=a*X + b
plt.scatter(X,Y)
plt.plot(X,Yhat,'r')
plt.show()
Nous avons maintenant une ligne droite qui ajuste parfaitement le logarithme des données.
Nous allons maintenant calculer le R-carré pour montrer à quel point notre ligne est bonne pour ajuster les données.
d1=Y-Yhat
d2=Y-Y.mean()
r2=1-(d1.dot(d1)/d2.dot(d2))
print("a:",a,"b:",b)
print("R-carre est :",r2)
# → R-carre est : 1.0
Nous avons une valeur de 1, ce qui signifie que nous avons une ligne parfaite. Notez que les données ici sont simulées et que dans les problèmes réels, vous n’obtiendrez pas la valeur 1, car les données contiennent du bruit.
Faisons maintenant notre prédiction. Rappelez-vous que nous avons 9200 transistors pour la cinquième année. Maintenant que nous avons a et b, nous allons calculer le nombre de transistors pour x = 5.
pred=a*X[2]+b
#Notez que nous devrions calculer l’exponentielle
#de la prédiction pour obtenir le nombre de transistors.
print(math.exp(pred))
# → 9200.000
Nous pouvons voir que nous avons parfaitement obtenu le nombre de transistors.
Nous allons maintenant répéter le même exemple mais en ajoutant du bruit aux données.
import numpy as np
import matplotlib.pyplot as plt
import math
import random
X=[]
Y=[]
start=2300
for i in range(1,70,2):
X.append(i)
Y.append(start)
#Bruit ajouté ici
start *= (2 + 2*random.uniform(0, 1))
X=np.array(X)
Y=np.array(Y)
print(X[2])
# → 5
print(Y[2])
# → 19412.444
#Notez que vous aurez un numéro différent du mien.
#Tracer les données exponentielles
plt.scatter(X,Y)
plt.show()
#Calcul du log des données
Y=np.log(Y)
#Tracer le log des données (il devrait être linéaire)
plt.scatter(X,Y)
plt.show()
#Calculer a et b
denominator=X.dot(X) - X.mean() * X.sum()
a=(X.dot(Y)-Y.mean()*X.sum())/denominator
b=(Y.mean()* X.dot(X)-X.mean()*X.dot(Y))/denominator
Yhat=a*X + b
#Tracer la ligne de meilleur ajustement
plt.scatter(X,Y)
plt.plot(X,Yhat,'r')
plt.show()
#Calculer le R-carré
d1=Y-Yhat
d2=Y-Y.mean()
r2=1-(d1.dot(d1)/d2.dot(d2))
print("a:",a,"b:",b)
print("R-carre est :",r2)
# → 0.99
#Vous n'obtiendrez pas 1 maintenant
#Faire la prédiction
pred=a*X[2]+b
print(math.exp(pred))
# → 14362.320
#Notez que vous aurez un numéro différent du mien.
#Vous pouvez remarquer ici que lorsque nous avons
#ajouté du bruit aux données, nous n’avions
#pas le nombre exact de transistors.
Article précédent:
Article suivant: