[PYTHON] [Baies non paramétriques] Estimation du nombre de clusters à l'aide du processus Diricle

Aperçu

Bonjour, c'est kwashi. Parallèlement à la popularité de l'apprentissage automatique, le domaine de l'apprentissage non supervisé augmente également. En parlant d'apprentissage non supervisé, le modèle thématique est célèbre. Le modèle thématique est une technique d'estimation de la signification potentielle. L'un des objectifs est d'obtenir des significations potentielles, telles que les catégories d'articles de presse. Dans ce modèle de rubrique, la distribution des rubriques (nombre de catégories) de chaque document est acquise à l'aide du processus Diricle.

De plus, je présenterai un article sur la séparation des sources sonores, mais Bayesian Nonparametrics for Microphone Array Processing est de l'entrée à plusieurs microphones (microphone array) par plusieurs sources sonores. , Explique la méthode d'estimation de la direction de la source sonore + son séparé. Comme mentionné dans le sujet de cet article, le nombre de sources sonores est calculé dans le processus Dirikure en utilisant des baies non paramétriques. Le nombre de sources sonores est très important. En effet, cela donne un indice sur le nombre de sons séparés à générer.

Dans cet article, nous expliquerons en utilisant un exemple d'estimation simultanée de la moyenne et de la variance du nombre de clusters et de la distribution normale en utilisant le processus Diricle comme baies non paramétriques.

Objectif

Dans cet article, la moyenne et la variance de chaque distribution normale sont calculées à partir des données d'entraînement générées à partir de la distribution normale mixte suivante. Tout d'abord, nous expliquerons comment estimer chaque distribution normale avec le nombre de grappes spécifié, puis expliquerons comment estimer le nombre de grappes en même temps.

Les valeurs de chaque distribution normale sont la moyenne (-8, 0, 4), la variance (1,8, 1,5, 1,3) et le mélange de distribution normale (0,2, 0,5, 0,3). La figure ci-dessous montre la distribution de densité de probabilité (ligne verte) générée et la fréquence des données générées. Il décrit également un programme mixte de distribution normale et de génération de données.

img001.png


import pymc3 as pm
import numpy as np
import theano.tensor as tt
import scipy.stats as stats
from scipy import optimize
import matplotlib.pyplot as plt

np.random.seed(53536)

xmin = -15.
xmax = 10.
xsize = 200
x = np.linspace(xmin, xmax, xsize)
pi_k = np.array([0.2, 0.5, 0.3])
loc_x = np.array([-8, 0, 4])

norm1 = stats.norm.pdf(x, loc=loc_x[0], scale=1.8) * pi_k[0]
norm2 = stats.norm.pdf(x, loc=loc_x[1], scale=1.5) * pi_k[1]
norm3 = stats.norm.pdf(x, loc=loc_x[2], scale=1.3) * pi_k[2]

npdf = norm1 + norm2 + norm3
npdf /= npdf.sum()

#Valeur en fonction de la probabilité de la distribution de probabilité(x)Avoir
y = np.random.choice(x, size=4000, p=npdf)

Nombre fixe de grappes Estimation de la distribution normale

Dans ce chapitre, nous expliquerons comment estimer la moyenne et la variance des trois distributions normales avec le nombre de grappes fixé à trois à l'avance. Il existe de nombreuses méthodes pour estimer les paramètres de la distribution normale avec le nombre de clusters déterminé, telles que l'algorithme EM, Variant Bayes et les méthodes de Monte Carlo par chaîne de Markov (MCMC). Dans ce chapitre, MCMC est utilisé.

Le modèle de génération de distribution normale est illustré dans le programme suivant. La distribution catégorielle génère un ID (z) indiquant à quel groupe appartient chaque donnée, en utilisant le rapport de mélange de chaque distribution normale générée à partir de la distribution de Diricre comme paramètre. Après cela, pour chaque distribution normale, nous définissons des distributions qui méritent la moyenne et la variance.

with pm.Model() as model:
  p = pm.Dirichlet('p', a=np.ones(cluster))
  z = pm.Categorical('z', p=p, shape=y.shape[0])

  mu = pm.Normal('mu', mu=y.mean(), sd=10, shape=cluster)
  sd = pm.HalfNormal('sd', sd=10, shape=cluster)

  y = pm.Normal('y', mu=mu[z], sd=sd[z], observed=y)

  trace = pm.sample(1000)

Cependant, ce modèle est lent à calculer en raison de la variable cachée z. Par conséquent, la périphérisation(∫p(y|z,θ)dz -> p(y|θ))Et modifiez le programme comme suit.

with pm.Model() as model:
  p = pm.Dirichlet('p', a=np.ones(cluster))
  mu = pm.Normal('mu', mu=y.mean(), sd=10, shape=cluster)
  sd = pm.HalfNormal('sd', sd=10, shape=cluster)

  y = pm.NormalMixture('y', w=p, mu=mu, sd=sd, observed=y)

  trace = pm.sample(3000, chains=1)

Le résultat de l'inférence est présenté dans la figure ci-dessous. La moyenne (-8, 0, 4) (mu), la variance (1,8, 1,5, 1,3) (sd) de chaque distribution normale et le rapport de mélange (0,2, 0,5, 0,3) (p) de la distribution normale sont bien estimés. Peut être vu.

img002.png

Nombre de grappes inconnu Estimation de la distribution normale

Dans le chapitre précédent, nous avons estimé les paramètres de la distribution normale en supposant que le nombre de clusters est connu. Dans ce chapitre, nous expliquerons l'estimation des paramètres de distribution normale lorsque le nombre de clusters est inconnu en introduisant le processus Diricle. Dans ce chapitre, la priorité est donnée à l'explication de l'image du processus Dirikure. Pour plus de détails sur le processus Dirikure, voir [Suite / Reconnaissance de formes facile à comprendre - Introduction à l'apprentissage sans enseignant](https://www.amazon.co.jp/%E7%B6%9A%E3%83%BB%E3%82%8F%] E3% 81% 8B% E3% 82% 8A% E3% 82% 84% E3% 81% 99% E3% 81% 84% E3% 83% 91% E3% 82% BF% E3% 83% BC% E3% 83% B3% E8% AA% 8D% E8% AD% 98% E2% 80% 95% E6% 95% 99% E5% B8% AB% E3% 81% AA% E3% 81% 97% E5% AD% A6% E7% BF% 92% E5% 85% A5% E9% 96% 80% E2% 80% 95-% E7% 9F% B3% E4% BA% 95-% E5% 81% A5% E4% B8% 80% E9% 83% 8E / dp / 427421530X) est très utile, veuillez donc le lire.

Pour expliquer brièvement le processus Diricle (DP), H ~ DP (a, H '), a sont représentés par le degré de concentration (image comme dispersion) et H (distribution de base; image comme moyenne), et par DP. La distribution H est générée. Pour cette raison, on l'appelle parfois la distribution par rapport à la distribution. Dans mon image personnelle, comme indiqué dans Retour en utilisant le processus gaussien, la fonction de régression elle-même est déduite par le processus gaussien. L'image est que le processus Diricle déduit également la distribution elle-même.

À propos, il existe un processus de cuisson chinois (CRP) et un processus de rupture de bâton (SBP) comme méthode pour réaliser ce processus Dirikure. Dans ce chapitre, nous expliquerons la méthode utilisant ce SBP. SBP est exprimé par la formule suivante. K est le nombre de distributions. Lorsque K est infini, la distribution de Diricre de dimension infinie peut être affichée dans SBP. (En utilisation réelle, définissez K sur une constante finie.)

{\pi_k = b_k \prod_{j=1}^{K-1} (1-b_j),\,b_k \sim {\rm Beta}(b;1,\alpha) } 

Le résultat π de cette équation est le rapport de mélange de la grappe k. Le programme et les résultats de ce SBP sont présentés ci-dessous. Cependant, ce SPB seul ne peut pas calculer la moyenne de la distribution. Par conséquent, la valeur est générée à partir de la distribution de base comme indiqué dans la formule suivante et est définie sur l'axe horizontal.

{  \theta _ { k } \sim H _ { 0 } , \text { for } k = 1 , \ldots , K } 

La figure ci-dessous montre quel rapport de mélange a été généré à chaque position. Si a est petit, il est concentré au centre, mais si a est grand, vous pouvez voir qu'il est dispersé à l'extérieur. img007.png

def stick_breaking(a, h, k):
  '''
  a:Concentration
  h:Distribution de base(scipy dist)
  K:Nombre de composants

  Return
  locs :position(array)
  w:probabilité(array)
  '''
  s = stats.beta.rvs(1, a, size=K)
 #ex : [0.02760315 0.1358357  0.02517414 0.11310199 0.21462781]
  w = np.empty(K)
  w = s * np.concatenate(([1.], np.cumprod(1 - s[:-1])))
  #ex: 0.02760315 0.13208621 0.0211541  0.09264824 0.15592888]
  # if i == 1, s , elif i > 1, s∑(1-sj) (j 1 -> i-1)

  locs = H.rvs(size=K)
  return locs, w

Ensuite, la distribution normale exprimée par le rapport de mélange généré par SPB lorsque K = 5 et la moyenne générée à partir de la distribution de base (distribution normale) sont montrées. La distribution est constante. Comme le montre cette figure, on peut voir que toute distribution normale mixte peut être exprimée en modifiant le paramètre SPB a et la distribution de base. imga_1.png

Maintenant, sur la base du fait que le rapport de mélange est généré par SPB de cette manière, l'estimation des paramètres de distribution normale est effectuée lorsque le nombre de grappes est inconnu. J'ai écrit le programme suivant selon le format de pymc. Seul le rapport de mélange est émis par SPB. De plus, l'hyper paramètre a de SPB est généré à partir de la distribution gamma. Et la moyenne et la variance sont générées à partir de la distribution normale. K est fixé à un nombre fini (20).

def stick_breaking_DP(a, K):
  b = pm.Beta('B', 1., a, shape=K)
  w = b * pm.math.concatenate([[1.], tt.extra_ops.cumprod(1. - b)[:-1]])
  return w

K = 20

with pm.Model() as model:
  a = pm.Gamma('a', 1., 1.)
  w = pm.Deterministic('w', stick_breaking_DP(a, K))
  mu = pm.Normal('mu', mu=y.mean(), sd=10, shape=K)
  sd = pm.HalfNormal('sd', sd=10, shape=K)

  y = pm.NormalMixture('y', w=w, mu=mu, sd=sd, observed=y)

  trace = pm.sample(1000, chains=1)

Les nombres de mélange estimés sont indiqués ci-dessous. De cette manière, on peut estimer qu'il y a 3 clusters car le rapport de mélange avec une grande valeur est 3. (Les valeurs réelles sont 0,2, 0,5, 0,3) De plus, les autres moyennes et distributions étaient presque les mêmes que pour les grappes. L'important ici est que nous pouvons estimer les deux clusters.

img006.png

Résumé

Dans cet article, en tant que baies non paramétriques, nous avons expliqué une méthode d'estimation du nombre de clusters en utilisant le processus Diricle en même temps que l'estimation de la distribution normale. Comme l'explication a été donnée en priorité sur l'image, certaines personnes peuvent se sentir mal à l'aise, mais dans ce cas, merci pour vos conseils.

Recommended Posts

[Baies non paramétriques] Estimation du nombre de clusters à l'aide du processus Diricle
Estimation de l'effet des mesures à l'aide des scores de propension
Déterminez le nombre de classes à l'aide de la formule Starges
Clustering G-means qui détermine automatiquement le nombre de clusters
Comment trouver le nombre optimal de clusters pour les k-moyennes
10. Compter le nombre de lignes
Obtenez le nombre de chiffres
Calculez le nombre de changements
J'ai étudié la méthode X-means qui estime automatiquement le nombre de clusters
Obtenez le nombre de vues de Qiita
Calcul du nombre d'associations de Klamer
Obtenez le nombre d'abonnés Youtube
Comment connaître le nombre de processeurs sans utiliser la commande sar
Représentez graphiquement l'évolution du nombre d'apparitions de mots clés par mois à l'aide de pandas
Compter / vérifier le nombre d'appels de méthode.
Implémenter une partie du processus en C ++
Utilisation de gensim avec R (processus de Dirichlet hiérarchique)
Définissez le nom du processus du programme Python
Compter le nombre de caractères avec écho
[Python] Totale automatiquement le nombre total d'articles publiés par Qiita à l'aide de l'API
Une introduction à l'analyse de données à l'aide de Python - Pour augmenter le nombre de vues vidéo -