[Apprentissage automatique] "Détection d'anomalies et détection de changement" Dessinons la figure du chapitre 1 en Python.

Livre rouge de Rumor's, Série Machine Learning Professional "Détection des anomalies et détection des changements" (http://ide-research.net/book/support.html#kodansha) Il s'agit d'un article sur l'écriture des graphiques du chapitre 1 en Python. ..

Comme ça, je dessine la précision de l'échantillon et la courbe ROC avec animation.

ROC_curve2.gif

Le code complet est ici

Seules des explications simples sont données ici, donc si vous souhaitez en savoir plus, achetez le livre!

Figure 1.1 Exemples de diverses anomalies dans les données de séries chronologiques

J'ai généré des données similaires en Python, pas exactement les mêmes données, ou j'ai recherché et tracé les données. (Surtout, il était difficile de trouver les données d'électrocardiogramme [^ 1] ...: sweat_smile :)

[^ 1]: Veuillez noter que la partie rouge anormale est traitée et que les données ECG ne sont pas correctes. L'URL pour obtenir les données est décrite sur GitHub.

anomaly_detection_1.1-compressor.png Le code entier qui rend ceci est ici

Figure 1.2 Description du jugement d'anomalie pour les données étiquetées

À partir de la figure 1.2, j'ai essayé de visualiser la pertinence en reliant le degré d'anomalie et la fonction d'indicateur et le dessin.

  1. Générez des données à partir de nombres aléatoires qui suivent deux distributions normales, tracez en bleu comme données normales et en rouge comme données anormales
  2. Calculez la moyenne et l'écart type à partir de l'histogramme en 1. et dessinez la fonction de densité de la distribution normale. (La densité de noyau estimée à partir de la distribution est également dessinée avec une ligne pointillée)
  3. \ln p({\bf x}'|y=0,\mathcal{D})-\ln p({\bf x}'|y=1,\mathcal{D})Est dessiné séparément. 4.Anomalie$a(x') \ln{ p({\bf x}'|y=1,\mathcal{D})\over p({\bf x}'|y=0,\mathcal{D})} $Dessiner
  4. Dessinez la fonction d'indicateur $ I [a (x) \ ge \ tau] $

De plus, le seuil du point de branchement est calculé comme le point où les valeurs de la fonction de densité sont les mêmes, et $ \ tau $ dans ce cas est représenté par la barre horizontale dans le quatrième graphique.

anomaly_detection_1.2.png Le code entier qui rend ceci est ici

Code Python

#Génération aléatoire
rd.seed()
n = 1000
d_0 = rd.normal(135, 18, n)  #Données normales
d_1 = rd.normal(80, 30, n)   #Données anormales

#Calcul de la moyenne et de l'écart type
m_0  = np.mean(d_0)
sd_0 = np.sqrt(np.var(d_0))
m_1  = np.mean(d_1)
sd_1 = np.sqrt(np.var(d_1))

#Génération de données sur l'axe X
xx = np.linspace(0,300, 5000)

#Fonction de densité de distribution normale
density_0 = st.norm.pdf(xx, m_0, sd_0)
density_1 = st.norm.pdf(xx, m_1, sd_1)

#Calcul des anomalies
abnormaly_score = np.log(density_1) - np.log(density_0)

def balance_position(x_min, x_max, f1, f2, EPS=0.00001):
    if abs(f1(x_max) - f2(x_max)) > EPS:
        center = (x_min + x_max)/2.
        if np.sign(f1(x_max) - f2(x_max)) * np.sign(f1(center) - f2(center)) < 0:
            x_min = center
        else:
            x_max = center
        x_max = balance_position(x_min, x_max, f1, f2)
    else:
        return x_max
    return x_max
    
mark = balance_position(0, 200, lambda x:st.norm.pdf(x, m_0, sd_0), lambda x: st.norm.pdf(x, m_1, sd_1)) 
print "mark:", mark

tau_pos = np.argsort(np.abs(xx - mark))[0]
print "tau pos:", tau_pos

tau = abnormaly_score[tau_pos]
print "tau:", tau

tau2_pos = np.max(np.argsort(np.abs(abnormaly_score - tau))[0:2])
print "tau2_pos:",tau2_pos

tau2 = abnormaly_score[tau2_pos]
print "tau2:",tau2

mark2 = xx[tau2_pos]
print "mark2:",mark2

#----------------Processus de dessin-----------------#
n_row = 5                         #Nombre de lignes dans le graphique

plt.subplots(n_row, 1, sharex=True,figsize=(12,12)) 
gs = gridspec.GridSpec(n_row, 1, height_ratios=[3,3,3,3,3])

axs = [plt.subplot(gs[i]) for i in range(n_row) ]
#Dessin de la première zone
axs[0].hist(d_1, bins=40, color="r", alpha=0.6, range=(0,300), label="data 1")
axs[0].hist(d_0, bins=40, color="b", alpha=0.6, range=(0,300), label="data 0")
axs[0].legend(loc='best')

#Dessin de la deuxième zone
axs[1].plot(xx, get_density(d_1, xx), "r--", alpha=.4 , lw=2, label=r"density of data 1")
axs[1].plot(xx, get_density(d_0, xx), "b--", alpha=.4 , lw=2, label=r"density of data 0")
axs[1].legend(loc='best')
axs[1].plot([0,300],[0,0],"k")
axs[1].plot(xx, density_1, c="r", alpha=.5 )
axs[1].plot(xx, density_0, c="b", alpha=.5 )
axs[1].fill_between(xx[0:tau_pos], density_0[0:tau_pos], color="lightblue", zorder = 500, alpha=.6)
axs[1].set_ylim(0,np.max(density_0)*1.1)
axs[1].plot([mark ,mark],[-100,200], "k--", lw=.5)
axs[1].plot([mark2 ,mark2],[-100,200], "k--", lw=.5)

#Dessin de la troisième zone
axs[2].plot(xx, -np.log(density_0), c="b", alpha=.5,  label=r"$\ln p({\bf x}'|y=0,\mathcal{D})$")
axs[2].plot(xx,  np.log(density_1), c="r", alpha=.5, label=r"$-\ln p({\bf x}'|y=1,\mathcal{D})$")
axs[2].plot([mark ,mark],[-110,200], "k--", lw=.5)
axs[2].plot([mark2 ,mark2],[-110,200], "k--", lw=.5)
axs[2].set_ylim(-25,40)
axs[2].legend(loc='best')
    
#4ème dessin de zone
axs[3].plot(xx, abnormaly_score, c="purple", alpha=.6, label=r"$$ \ln{ p({\bf x}'|y=1,\mathcal{D})\over  p({\bf x}'|y=0,\mathcal{D})} $$")
axs[3].set_ylim(-5,5)
axs[3].plot([mark ,mark],[-100,200], "k--", lw=.5)
axs[3].plot([mark2 ,mark2],[-100,200], "k--", lw=.5)
axs[3].plot([0 ,300],[tau, tau], "k", lw=.5)
axs[3].legend(loc='best')

#Dessin de la cinquième zone
axs[4].fill_between(xx[0:tau_pos], np.ones_like(xx[0:tau_pos]), color="blue", zorder = 500, alpha=.6)
axs[4].fill_between(xx[tau2_pos:], np.ones_like(xx[tau2_pos:]), color="blue", zorder = 500, alpha=.6)
axs[4].plot([mark, mark],[-110,200], "k--", lw=.5)
axs[4].plot([mark2, mark2],[-110,200], "k--", lw=.5)
axs[4].text(10, 1.3, r"$I[a(x) \ge \tau]$")
axs[4].set_ylim(0,5)

#Plage fixe de x dans tous les domaines
for ax in axs:
    ax.set_xlim(0,300)

plt.subplots_adjust(hspace=0)

Figure 1.3 Définition des anomalies pour les données non étiquetées

De manière similaire à la figure 1.2, la fonction de densité de la distribution normale estimée à partir de l'histogramme, la densité du noyau, la moyenne / dispersion est dessinée, et la "quantité d'informations" est tracée. Le degré d'anomalie augmente simplement à mesure que la distance par rapport à la moyenne des données augmente.

anomaly_detection_002.png Le code entier qui rend ceci est ici

Code Python

#Pour les données non étiquetées
#Génération aléatoire
n = 1000
data = rd.normal(80, 15, n)

#Calcul de la moyenne et de l'écart type
m  = np.mean(data)
sd = np.sqrt(np.var(data))

#Génération de données sur l'axe X
xx = np.linspace(0,300, 5000)

#Fonction de densité de distribution normale
density = st.norm.pdf(xx, m, sd)

#----------------Processus de dessin-----------------#
n_row = 3                         #Nombre de lignes dans le graphique
xx = np.linspace(0,300, 5000)     #Génération de données sur l'axe X

plt.subplots(n_row, 1, sharex=True,figsize=(12,10)) 
gs = gridspec.GridSpec(n_row, 1, height_ratios=[3,3,3])

axs = [plt.subplot(gs[i]) for i in range(n_row) ]

#Dessin de la première zone
axs[0].hist(data, bins=50, range=(0,300), label="data: a", color="b", alpha=0.5)
axs[0].set_ylim(0,200)
axs[0].legend(loc='best')

#Dessin de la deuxième zone
axs[1].plot(xx, get_density(data, xx), lw=2, linestyle="--", label="density of the data", color="b", alpha=0.4)
axs[1].plot(xx, density, lw=1, label=r"estimated density of norm dist: $p({\bf x}'|\mathcal{D})$", color="b", alpha=0.5)
axs[1].legend(loc='best')

#Dessin de la troisième zone
axs[2].plot(xx, -np.log(density), lw=1, label=r"information:$-\ln p({\bf x}'|\mathcal{D})$", color="b", alpha=0.5)
axs[2].legend(loc='best')


#Plage fixe de x dans tous les domaines
for ax in axs:
    ax.set_xlim(0,300)

plt.subplots_adjust( hspace=0)

Figure 1.4, Figure 1.5 Précision normale de l'échantillon, précision anormale de l'échantillon et courbe ROC

J'ai essayé d'animer la relation entre la précision normale de l'échantillon, la précision anormale de l'échantillon et la courbe ROC. De plus, les détails de la courbe ROC ont déjà été expliqués dans "[Statistiques] Qu'est-ce que la courbe ROC? ](Http://qiita.com/kenmatsu4/items/550b38f4fa31e9af6f4f) "est également écrit, veuillez donc vous y référer.

Dans cette figure, la précision de l'échantillon est dessinée comme indiqué ci-dessous.

r_0 = \log(1 + x) \\
r_1 = \log(e -x)

Le graphique de la deuxième ligne représente la valeur F et la définition est la suivante.

f  \equiv { 2r_0 r_1 \over r_0 + r_1 }

Puisque la courbe ROC est $ (X, Y) = (1 --r_0 (\ tau), \ r_1 (\ tau)) $, la valeur de coordonnée y du point qui trace la ligne rouge utilise $ 1-y $. Les coordonnées sont affichées sur l'animation, et le nombre sur le côté droit des deux correspond à cela.

ROC_curve2.gif Le code entier qui rend ceci est ici

Code Python

def animate(nframe):
    global num_frame
    sys.stdout.write(str(int(float(nframe)/num_frame*100)) + "%, ") 
    
    plt.clf()
    
    #Valeurs minimum et maximum de x
    xmin = 0
    xmax = np.e -1

    #Nombre de divisions de x
    sx = num_frame * 2

    #emplacement actuel
    pos = nframe * 2

    #génération de l'axe des x
    xx = np.linspace(xmin, xmax, sx)

    #Précision de l'échantillon
    cx1 = np.log(1+xx)
    cx2 = np.log(np.e -xx)

    #Premier dessin graphique-----------------------
    plt.subplot(311)
    plt.title("Sample accuracy. x={0:.2f}".format(xx[pos]))
    plt.xlim(xmin, xmax)
    plt.ylim(0,1)
    
    #Tracez une courbe
    plt.plot(xx,cx1,linewidth=2)
    plt.plot(xx,cx2,linewidth=2)
    
    #Dessiner des points et des valeurs de coordonnées
    plt.scatter(xx[pos],cx1[pos], c="g", s=40, zorder=100)
    plt.text(xx[pos]+.01,cx1[pos]-.05,"{0:.3f}, {1:.3f}".format(cx1[pos], 1-cx1[pos]), size=16)
    plt.scatter(xx[pos],cx2[pos], c="b", s=40, zorder=100)
    plt.text(xx[pos]-.20,cx2[pos]-.05,"{0:.3f}".format(cx2[pos]), size=16)

    #Dessin au trait en pointillé
    plt.plot([xx[pos], xx[pos]], [0,1], "k--", alpha=.5, lw=2 )
    plt.plot([0, xx[pos]], [cx1[pos],cx1[pos]], "k--", alpha=.5, lw=2 )
    plt.plot([0, xx[pos]], [cx2[pos],cx2[pos]], "k--", alpha=.5, lw=2 )

    plt.text(.08, .42, r"normal:$r_0$", color="r", size=16)
    plt.text(1.2, .42, r"anomalous:$r_1$", color="#2F79B0", size=16)
    
    #Deuxième dessin graphique-----------------------
    plt.subplot(312)
    plt.title("F-value")
    plt.xlim(xmin, xmax)
    plt.ylim(0,1)
    F = 2*cx1*cx2/(cx1+cx2)
    F_pos = 2*cx1[pos]*cx2[pos]/(cx1[pos]+cx2[pos])
    plt.scatter(xx[pos], F_pos, c="g", alpha=1, s=50)
    plt.plot(xx, F)
    plt.plot([xx[pos], xx[pos]], [0,1], "k--", alpha=.5, lw=2 )
    plt.tight_layout()
    
    #Troisième dessin graphique-----------------------
    plt.subplot(313)
    
    plt.title("ROC Curve.")
    plt.xlim(0,1)
    plt.ylim(0,1)
    
    #Dessiner des courbes et des points
    plt.plot(1-cx1, cx2, linewidth=2, color="b", alpha=.4)
    plt.scatter(1-cx1[pos],cx2[pos], c="b", s=40, zorder=100)
    plt.text(1-cx1[pos]+.01,cx2[pos]-.05, "{0:.3f}, {1:.3f}".format(1-cx1[pos], cx2[pos]), size=16)

    plt.xlabel(r"$1-r_0$", size=16)
    plt.ylabel(r"$r_1$", size=16)
    plt.tight_layout()
    
num_frame = 50
fig = plt.figure(figsize=(5,10))
anim = ani.FuncAnimation(fig, animate, frames=num_frame, blit=True)
anim.save('ROC_curve2.gif', writer='imagemagick', fps=3, dpi=60)

Livres de référence

"Détection d'anomalies et détection de changement" par Tsuyoshi Ide et Masaru Sugiyama (série professionnelle d'apprentissage automatique)   http://ide-research.net/book/support.html

Recommended Posts

[Apprentissage automatique] "Détection d'anomalies et détection de changement" Dessinons la figure du chapitre 1 en Python.
Le résultat de l'apprentissage automatique des ingénieurs Java avec Python www
Changer la saturation et la clarté des spécifications de couleur comme # ff000 dans python 2.5
Mémo d'apprentissage Python pour l'apprentissage automatique par Chainer jusqu'à la fin du chapitre 2
Python: prétraitement en machine learning: gestion des données manquantes / aberrantes / déséquilibrées
Touchons une partie de l'apprentissage automatique avec Python
traitement (python) Diagramme les coordonnées de la liste Spécifiez le nombre de fois dans draw ()
Deep Learning from scratch La théorie et la mise en œuvre de l'apprentissage profond appris avec Python Chapitre 3
Liste des principales distributions de probabilité utilisées en apprentissage automatique et statistiques et code en python
Comprenez attentivement la distribution exponentielle et dessinez en Python
À propos des tests dans la mise en œuvre de modèles d'apprentissage automatique
Comprendre attentivement la distribution de Poisson et dessiner en Python
Reproduire l'exemple d'exécution du chapitre 4 de Hajipata en Python
Utilisons les données ouvertes de "Mamebus" en Python
Résumé du flux de base de l'apprentissage automatique avec Python
Reproduire l'exemple d'exécution du chapitre 5 de Hajipata en Python
[Python] Changeons l'URL du site administrateur de Django
[Python] Changer la couleur du texte et la couleur d'arrière-plan d'un mot clé spécifique dans la sortie d'impression
Enquête sur l'utilisation du machine learning dans les services réels
[Astuces] Problèmes et solutions dans le développement de python + kivy
Vérifions et formons statiquement le code du test automatique E2E écrit en Python [VS Code]
[Apprentissage automatique] Ecrivez vous-même la méthode k-plus proche voisin en python et reconnaissez les nombres manuscrits.
L'histoire de Python et l'histoire de NaN
Comptez bien le nombre de caractères thaïlandais et arabes en Python
Importance de l'apprentissage automatique et de l'apprentissage par mini-lots
Défis de Coursera Machine Learning en Python: ex5 (ajustement des paramètres de régularisation)
[Python] Réduisons le nombre d'éléments dans le résultat dans le fonctionnement de l'ensemble
N'hésitez pas à changer l'étiquette de légende avec Seaborn en python
Classification et régression dans l'apprentissage automatique
Dessinez une illusion d'aquarelle avec détection des contours en Python3 et openCV3
Python: prétraitement dans l'apprentissage automatique: présentation
Mémorandum of scraping & machine learning [technique de développement] par Python (chapitre 4)
Mémorandum of scraping & machine learning [technique de développement] par Python (chapitre 5)
Obtenez le titre et la date de livraison de Yahoo! News en Python
Comparer la grammaire de base de Python et Go d'une manière facile à comprendre
Ouvrez un fichier Excel en Python et coloriez la carte du Japon
Mémo d'apprentissage Python pour l'apprentissage automatique par Chainer Chapitre 13 Bases du réseau neuronal
Procédure d'apprentissage automatique de base: ③ Comparez et examinez la méthode de sélection de la quantité de caractéristiques
Changer la longueur des chaînes csv Python
Vérifiez le comportement du destroyer en Python
Notes d'apprentissage depuis le début de Python 1
[python] Techniques souvent utilisées dans l'apprentissage automatique
Le résultat de l'installation de python sur Anaconda
Python: prétraitement en machine learning: acquisition de données
Principes de base pour exécuter NoxPlayer en Python
Créer un environnement pour Python et l'apprentissage automatique (macOS)
[Python] Enregistrement des résultats d'apprentissage (modèles) dans l'apprentissage automatique
À la recherche du FizzBuzz le plus rapide en Python
Python: prétraitement dans l'apprentissage automatique: conversion de données
Notes d'apprentissage depuis le début de Python 2
Projet Euler # 1 "Multiple de 3 et 5" en Python
J'ai comparé la vitesse des expressions régulières en Ruby, Python et Perl (version 2013)
Affiche automatiquement les paroles de la chanson en cours de lecture sur iTunes en Python
Jouons avec Python Receive et enregistrez / affichez le texte du formulaire de saisie
Divise la chaîne de caractères par le nombre de caractères spécifié. En Ruby et Python.
En Python, changez le comportement de la méthode en fonction de la façon dont elle est appelée
Créez un environnement python pour apprendre la théorie et la mise en œuvre de l'apprentissage profond
[Python] J'ai expliqué en détail la théorie et l'implémentation de la machine à vecteurs de support (SVM).
J'ai essayé de prédire l'évolution de la quantité de neige pendant 2 ans par apprentissage automatique