Introduction à la Recherche OpérationelleM2 Statistique Science des Données (SSD) |
Anatoli Juditsky Franck Iutzeler |
Nous considérons le modèle suivant de classification (prédiction de 0 et 1) $$ y=\mathrm{sign}(X\theta+\sigma\xi),\;\;\xi\sim \mathcal{N}(0, I_m),$$ où $X\in \mathbb{R}^{m\times n}$ et $y\in \{-1,1\}^m$ sont les observables, et $\theta\in \mathbb{R}^n$ est le paramètre inconnu. $\mathrm{sign}(x) = -1 $ si $x<0$ et $+1$ si $x\geq 0$.
Nous allons voir plusieurs méthodes pour prédire $y$ et les comparer. Les fonctions utilisées sont toutes des combinaisons des fonctions CVXPY disponibles ici: https://www.cvxpy.org/tutorial/functions/index.html#scalar-functions
import cvxpy as cp
import numpy as np
# Exemple jouet
n = 4
m = 6
sigma = 0.1
X = np.random.randn(m,n) # matrice de mélange -- connue
theta0 = np.random.randn(n)
non_null_coordinates = np.random.choice(n, int(0.8*n), replace=False)
theta_true = np.zeros(n)
theta_true[non_null_coordinates] = theta0[non_null_coordinates] # vrai theta -- inconnu: à estimer
xi = np.random.randn(m) # bruit
y = np.sign(np.dot(X,theta_true) + sigma*xi) # observations -- connue
X
theta_true
y
Le premier estimateur que nous allons implémenter est le lasso:
\begin{equation} \tag{A} \theta_A \in \arg\min_\theta \left\{ \frac{1}{2} \| X\theta - y \|_2^2 + \lambda \|\theta\|_1 \right\}, \end{equation}où $\lambda>0$ est le paramètre de régularisation qui controle le degré de parcimonie de la solution.
Question 1: Écrivez une fonction
EstimateurA
qui retourne ${\theta}_{A}$.
- Cette fonction qui prend en entrée:
X
y
lambda
- et sort les elements
coef
, vecteur des coefficients de regressionstatus
, le champstatus
de la solution du problème d'optimisation.Testez cette fonction sur l'exemple du début.
Prenons un estimateur proche du sélecteur de Dantzig (TP2)
\begin{equation} \tag{B} \theta_B \in \arg\min_\theta \left\{ \|\theta\|_1 \text{ sous contrainte } \| X\theta - y \|_2^2 \leq \lambda \right\}, \end{equation}où $\lambda>0$ est l'erreur autorisée qui restreint les solutions à être optimale à $\lambda$ près.
Question 2: Écrivez une fonction
EstimateurB
qui retourne ${\theta}_{B}$.
- Cette fonction qui prend en entrée:
X
y
lambda
- et sort les elements
coef
, vecteur des coefficients de regressionstatus
, le champstatus
de la solution du problème d'optimisation.Testez cette fonction sur l'exemple du début.
Question 3: Testez l'estimateur B pour différentes valeurs de lambda. Le problème d'optimisation a-t-il toujours une solution? Expliquez.
Au lieu de contraindre l'erreur, contraignons les valeurs du paramètre.
\begin{equation} \tag{C} \theta_C \in \arg\min_\theta \left\{ \| X\theta - y \|_2^2 \text{ sous contrainte } |\theta_i| \leq \lambda \text{ pour tout } i \right\}, \end{equation}où $\lambda>0$ est la norme maximale.
Question 4: Écrivez une fonction
EstimateurC
qui retourne ${\theta}_{C}$.
- Cette fonction qui prend en entrée:
X
y
lambda
- et sort les elements
coef
, vecteur des coefficients de regressionstatus
, le champstatus
de la solution du problème d'optimisation.dual
, la variable duale optimaleTestez cette fonction sur l'exemple du début.
Question 5: Faites varier lambda et utilisez la valeur de la variable duale pour déterminer si la contrainte est active ou inactive.
Question 6: La solution $\theta_C$ est-elle toujours différente de la solution du problème des moindres carrés $\theta_{MoindresCarrés} \in \arg\min_\theta \left\{ \| X\theta - y \|_2^2 \right\}$ ?
Comparons maintenant les estimateurs ci-dessus à partir de l'exemple suivant:
# Exemple plus grand
n = 60
m = 200
sigma = 0.1
X = np.random.randn(m,n) # matrice de mélange -- connue
theta0 = np.random.randn(n)
non_null_coordinates = np.random.choice(n, int(0.8*n), replace=False)
theta_true = np.zeros(n)
theta_true[non_null_coordinates] = theta0[non_null_coordinates] # vrai theta -- inconnu: à estimer
xi = np.random.randn(m) # bruit
y = np.sign(np.dot(X,theta_true) + sigma*xi) # observations -- connue
Divisons les données à moitié en jeu d'entrainement et moitié en jeu de test.
X_train = X[:int(m/2),:]
y_train = y[:int(m/2)]
X_test = X[int(m/2):,:]
y_test = y[int(m/2):]
Question 7: Pour chacun des estimateurs, trouvez la valeur de $\lambda$ pour laquelle l'estimateur (calculé sur les données d'entrainement) minimise l'erreur de classification (sur les données de test).
Ex: Pour l'estimateur A, on calcule theta_A, = EstimateurA(X_train, y_train, lam = 1e-5 )
puis la prédiction
$$ y_{A,pred} = \text{sign}(X_{test}\theta_A). $$
Puis l'erreur de classification s'écrit comme le pourcentage de coordonnées $i$ pour lesquelles $ y_{A,pred}(i) \neq y_{test}(i)$.
Question 8: Comparez les quatre estimateurs. (Cette question est volontairement ouverte, plusieurs critères peuvent être utilisés, des propositions d'améliorations peuvent etre formulées.)