Cette fois, nous allons implémenter l'estimation la plus probable de la distribution t de Student. La distribution t de Student est bien connue comme une distribution plus robuste aux valeurs aberrantes que la distribution gaussienne, mais si vous vous souvenez bien, cette distribution n'a jamais été utilisée, c'est donc une bonne opportunité et sa robustesse. Je vais vérifier. Au moment de la Première implémentation PRML, j'ai défini une règle selon laquelle seul numpy est possible sauf pour la bibliothèque standard, mais cette fois, il s'agit d'une fonction inconnue appelée fonction digamma. J'ai aussi utilisé scipy parce qu'il est sorti. Pour la deuxième fois de ce projet, j'utiliserai un package tiers autre que numpy dès que possible, et je me rappellerai de l'avenir.
La distribution t de Student est la distribution gaussienne
Il s'agit de l'étape E (Attente) de l'algorithme EM. Dans cette étape, fixez les paramètres que vous souhaitez estimer ($ \ mu, a, b $) et calculez à partir de quelle variance (ou précision $ \ tau $) la distribution gaussienne à partir de laquelle chaque point d'échantillonnage $ x_i $ est échantillonné. Je vais.
Il s'agit de l'étape M (Maximisation) de l'algorithme EM. Calculez la fonction de vraisemblance du journal pour les données complètes $ \ {x_i, \ tau_i \} $ et maximisez-la pour les paramètres $ \ mu, a, b $. Pour le paramètre de précision $ \ tau_i $ à ce moment, utilisez celui obtenu à l'étape E.
Si vous regardez les solutions de $ a et b $ en premier lieu, elles sont mélangées l'une avec l'autre, donc les trois équations ci-dessus ne maximisent probablement pas la fonction de vraisemblance logarithmique. De cette manière, l'algorithme EM lorsque la fonction de vraisemblance logarithmique n'est pas complètement maximisée est appelé l'algorithme EM généralisé. Il semble que la raison pour laquelle le paramètre de degré de liberté $ \ nu (= 2a) $ est fixé à une certaine valeur lors de l'exécution de l'estimation la plus probable de la distribution t de l'étudiant est que l'étape M est exécutée exactement. Si le paramètre de degré de liberté est fixe, la cible d'estimation restante sera $ \ mu, \ lambda $, et je pense que la fonction de vraisemblance logarithmique peut être facilement maximisée.
Je ferai quelques corrections et suppléments en fonction des commentaires ci-dessous. S'il s'agit de l'étape E d'origine, le paramètre de précision
\tau_i Distribution postérieure dep(\tau_i|x_i,\mu,a,b) = {\rm Gam}(\tau_i|a+{1\over2},b+{1\over2}(x_i-\mu)^2) Se termine par la partie calculée, et à l'étape M suivante, la fonction de vraisemblance logarithmique parfaite\ln p(x_i,\tau_i|\mu,a,b) のそDistribution postérieure deについての期待値\mathbb{E}[\sum_i\ln p(x_i,\tau_i|\mu,a,b)] Calculer. Si le résultat du calcul est extrait uniquement là où il est lié au paramètre,-{1\over2}\sum_i\mathbb{E}\[\tau_i\](x_i-\mu)^2+a\sum_i\mathbb{E}\[\ln\tau_i\]+aN\lnb-b\sum_i\mathbb{E}[\tau_i]-N\ln\Gamma(a) ,Etlaformedelafonctionàmaximiserestpartiellementdifférente.L'algorithmeEMdel'articleoriginalestunexempled'approximationducalculdelavaleurattendue\mathbb{E}[\sum_i\lnp(x_i,\tau_i|\mu,a,b)]=\sum_i\lnp(x_i,\tau_i^{(sample)}|\mu,a,b) Cependant,iln'yatoujoursqu'uneseuletailled'échantillonchacun\tau_i^{(sample)}=\mathbb{E}[\tau_i] J'apprécieraissivouspouviezinterprétercelaenutilisantl'échantillon.Danslafigureci-dessous,celasemblefonctionnerdansunecertainemesure,donccetexempled'approximationpeutnepasaffecterautantlaprécision(jesuisvraimentheureuxsicelaseproduit).
Pour résumer ce qui précède,
Utilisez cet algorithme EM généralisé pour trouver les paramètres de la distribution t de Student.
import Importez les fonctions gamma et digamma de matplotlib et numpy pour illustrer les résultats, et en plus scipy.
import matplotlib.pyplot as plt
import numpy as np
from scipy.special import gamma, digamma
Estimation la plus probable par distribution gaussienne uniquement pour comparaison avec la distribution t de Student
class Gaussian(object):
def fit(self, x):
self.mean = np.mean(x)
self.var = np.var(x)
def predict_proba(self, x):
return (np.exp(-0.5 * (x - self.mean) ** 2 / self.var)
/ np.sqrt(2 * np.pi * self.var))
C'est le code pour estimer le plus probable par la distribution t de l'étudiant. L'estimation la plus probable est effectuée par la méthode d'ajustement. Répétez les étapes E et M et terminez lorsque les paramètres ne sont plus mis à jour.
class StudentsT(object):
def __init__(self, mean=0, a=1, b=1, learning_rate=0.01):
self.mean = mean
self.a = a
self.b = b
self.learning_rate = learning_rate
def fit(self, x):
while True:
params = [self.mean, self.a, self.b]
self._expectation(x)
self._maximization(x)
if np.allclose(params, [self.mean, self.a, self.b]):
break
def _expectation(self, x):
self.precisions = (self.a + 0.5) / (self.b + 0.5 * (x - self.mean) ** 2)
def _maximization(self, x):
self.mean = np.sum(self.precisions * x) / np.sum(self.precisions)
a = self.a
b = self.b
self.a = a + self.learning_rate * (
len(x) * np.log(b)
+ np.log(np.prod(self.precisions))
- len(x) * digamma(a))
self.b = a * len(x) / np.sum(self.precisions)
def predict_proba(self, x):
return ((1 + (x - self.mean) ** 2/(2 * self.b)) ** (-self.a - 0.5)
* gamma(self.a + 0.5)
/ (gamma(self.a) * np.sqrt(2 * np.pi * self.b)))
students_t_mle.py
import matplotlib.pyplot as plt
import numpy as np
from scipy.special import gamma, digamma
class Gaussian(object):
def fit(self, x):
self.mean = np.mean(x)
self.var = np.var(x)
def predict_proba(self, x):
return (np.exp(-0.5 * (x - self.mean) ** 2 / self.var)
/ np.sqrt(2 * np.pi * self.var))
class StudentsT(object):
def __init__(self, mean=0, a=1, b=1, learning_rate=0.01):
self.mean = mean
self.a = a
self.b = b
self.learning_rate = learning_rate
def fit(self, x):
while True:
params = [self.mean, self.a, self.b]
self._expectation(x)
self._maximization(x)
if np.allclose(params, [self.mean, self.a, self.b]):
break
def _expectation(self, x):
self.precisions = (self.a + 0.5) / (self.b + 0.5 * (x - self.mean) ** 2)
def _maximization(self, x):
self.mean = np.sum(self.precisions * x) / np.sum(self.precisions)
a = self.a
b = self.b
self.a = a + self.learning_rate * (
len(x) * np.log(b)
+ np.log(np.prod(self.precisions))
- len(x) * digamma(a))
self.b = a * len(x) / np.sum(self.precisions)
def predict_proba(self, x):
return ((1 + (x - self.mean) ** 2/(2 * self.b)) ** (-self.a - 0.5)
* gamma(self.a + 0.5)
/ (gamma(self.a) * np.sqrt(2 * np.pi * self.b)))
def main():
# create toy data including outliers and plot histogram
x = np.random.normal(size=20)
x = np.concatenate([x, np.random.normal(loc=20., size=3)])
plt.hist(x, bins=50, normed=1., label="samples")
# prepare model
students_t = StudentsT()
gaussian = Gaussian()
# maximum likelihood estimate
students_t.fit(x)
gaussian.fit(x)
# plot results
x = np.linspace(-5, 25, 1000)
plt.plot(x, students_t.predict_proba(x), label="student's t", linewidth=2)
plt.plot(x, gaussian.predict_proba(x), label="gaussian", linewidth=2)
plt.legend()
plt.show()
if __name__ == '__main__':
main()
Si vous exécutez le code ci-dessus, vous obtiendrez le résultat suivant. Comme le montre la figure 2.16 de PRML, l'ajustement par la distribution t de Student est certainement robuste même s'il existe une valeur aberrante. La moyenne de la distribution t de Student est d'environ 0, mais la moyenne de la distribution gaussienne est d'environ 2,5, tirée par les valeurs aberrantes.
Il a été confirmé que l'estimation la plus probable avec la distribution t de Student est plus robuste que la distribution gaussienne comme modèle. Si j'ai une chance, j'essaierai de résoudre le problème de régression de courbe en utilisant la distribution t de Student.
Recommended Posts