Régression linéaire en ligne en Python (estimation robuste)

introduction

Vous trouverez ci-dessous la version estimée de Robust.

Formule

J'utiliserai la méthode d'estimation Biweight avec quelques arrangements. Voir ci-dessus pour l'estimation en ligne des coefficients.

Estimation en ligne de la valeur moyenne

\bar{x}_n = (1-\alpha) \bar{x}_{n-1} + \alpha x_n

Méthode d'estimation bi-pondérée

d = y-(ax+b)\\
w(d) = \left\{\begin{array}{l}
\left[ 1 - \left( \frac{d}{W} \right)^2 \right]^2 & \left(|d| \le W \right) \\
0 & \left(W < |d| \right)
\end{array}\right.

Explicatif

Entrez une valeur d'écart de 10 fois l'écart environ une fois toutes les 10 fois

outliers = [0,0,0,0,0,0,0,0,0,1]

...

y = x + 0.05 * sp.random.normal() + outliers[sp.random.randint(10)] * 0.5 * sp.random.normal()

Commencez 30 fois comme d'habitude, puis appliquez du poids

W = 0.1
def biweight(d):
    return ( 1 - (d/W) ** 2 ) ** 2 if abs(d/W) < 1 else 0

...

if count[0] < 30:
    alpha = 0.1
else:
    d = y - (a * x + b)
    alpha = weight(d) * 0.1

Code source

(C'est un gâchis parce que c'est une défaite)

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import matplotlib.pyplot as plt
import matplotlib.animation as animation
import scipy as sp
sp.seterr(divide='ignore', invalid='ignore')

def mean(old, new, alpha):
    return new if sp.isnan(old) else ( 1.0 - alpha ) * old + alpha * new

W = 0.1
def weight(d):
    return ( 1 - (d/W) ** 2 ) ** 2 if abs(d/W) < 1 else 0

def plot(fig):
    a = sp.array([sp.nan])
    b = sp.array([sp.nan])

    xyhist = sp.ones([100, 2]) * sp.nan
    mean_x0  = sp.array([sp.nan])
    mean_y0  = sp.array([sp.nan])
    mean_x20 = sp.array([sp.nan])
    mean_xy0 = sp.array([sp.nan])

    mean_x  = sp.array([sp.nan])
    mean_y  = sp.array([sp.nan])
    mean_x2 = sp.array([sp.nan])
    mean_xy = sp.array([sp.nan])

    ax = fig.gca()
    ax.hold(True)
    ax.grid(True)
    ax.set_xlim([0, 1.0])
    ax.set_ylim([0, 1.0])

    xyscat = ax.scatter([],[], c='black', s=10, alpha=0.4)
    approx0 = ax.add_line(plt.Line2D([], [], color='r'))
    approx = ax.add_line(plt.Line2D([], [], color='b'))

    outliers = [0,0,0,0,0,0,0,0,0,1]

    count = [0]

    def inner(i):
        x = sp.random.rand()
        y = x + 0.05 * sp.random.normal() + outliers[sp.random.randint(10)] * 0.5 * sp.random.normal()

        count[0] += 1
        if count[0] < 30:
            alpha = 0.1
        else:
            d = y - (a * x + b)
            alpha = biweight(d) * 0.1

        xyhist[:-1, :] = xyhist[1:, :]
        xyhist[-1, 0] = x
        xyhist[-1, 1] = y

        mean_x0[:]  = mean( mean_x0,  x,      0.1 )
        mean_y0[:]  = mean( mean_y0,  y,      0.1 )
        mean_xy0[:] = mean( mean_xy0, x *  y, 0.1 )
        mean_x20[:] = mean( mean_x20, x ** 2, 0.1 )

        mean_x[:]  = mean( mean_x,  x,      alpha )
        mean_y[:]  = mean( mean_y,  y,      alpha )
        mean_xy[:] = mean( mean_xy, x *  y, alpha )
        mean_x2[:] = mean( mean_x2, x ** 2, alpha )

        a0 = ( mean_xy0 - mean_x0 * mean_y0 ) / ( mean_x20 - mean_x0 ** 2 )
        b0 = mean_y0 - a0 * mean_x0

        a[:] = ( mean_xy - mean_x * mean_y ) / ( mean_x2 - mean_x ** 2 )
        b[:] = mean_y - a * mean_x

        ax.title.set_text('y = %.3fx %+.3f' % (a, b))
        xyscat.set_offsets(xyhist)
        approx.set_data([0, 1], [b, a*1+b])
        approx0.set_data([0, 1], [b0, a0*1+b0])
        plt.draw()

    return inner


fig = plt.figure()
ani = animation.FuncAnimation(fig, plot(fig), interval=100, frames=300)
ani.save('result2.gif', writer='imagemagick')

résultat

Il semble que le bipoids (bleu) soit plus stable dans une certaine mesure.

result2.gif

Recommended Posts

Régression linéaire en ligne en Python (estimation robuste)
Régression linéaire en ligne en Python
Régression linéaire en Python (statmodels, scikit-learn, PyMC3)
Recherche linéaire en Python
Analyse de régression avec Python
Implémenté en Python PRML Chapitre 3 Régression linéaire bayésienne
"Régression linéaire" et "Version probabiliste de la régression linéaire" en Python "Régression linéaire de Bayes"
Coursera Machine Learning Challenge en Python: ex1 (régression linéaire)
Analyse de régression simple avec Python
[Python] Régression linéaire avec scicit-learn
Régression linéaire robuste avec scikit-learn
Première analyse de régression simple en Python
Régression linéaire
Valeurs authentiques et vecteurs propres: Algèbre linéaire en Python <7>
J'ai essayé d'implémenter la régression logistique de Cousera en Python
Indépendance et base linéaires: Algèbre linéaire en Python <6>
Introduction aux vecteurs: Algèbre linéaire en Python <1>
J'ai essayé d'implémenter la régression linéaire bayésienne par échantillonnage de Gibbs en python
Quadtree en Python --2
CURL en Python
Métaprogrammation avec Python
Python 3.3 avec Anaconda
Géocodage en python
SendKeys en Python
Méta-analyse en Python
Unittest en Python
Époque en Python
Discord en Python
Allemand en Python
DCI en Python
tri rapide en python
EV3 x Python Machine Learning Partie 2 Régression linéaire
nCr en python
N-Gram en Python
Programmation avec Python
Plink en Python
Constante en Python
FizzBuzz en Python
Sqlite en Python
Étape AIC en Python
LINE-Bot [0] en Python
CSV en Python
Assemblage inversé avec Python
Réflexion en Python
Matrice unitaire et matrice inverse: Algèbre linéaire en Python <4>
Constante en Python
nCr en Python.
format en python
Scons en Python 3
Puyopuyo en python
python dans virtualenv
PPAP en Python
Produit intérieur et vecteur: Algèbre linéaire en Python <2>
Quad-tree en Python
Calcul matriciel et équations linéaires: Algèbre linéaire en Python <3>
Réflexion en Python
Chimie avec Python
Hashable en Python