3
votes

Comment estimer les distributions gaussiennes derrière une couche de bruit?

J'ai donc cet histogramme de mes données 1-D qui contient quelques temps de transition en secondes. Les données contiennent beaucoup de bruit mais derrière le bruit se trouvent des pics / gaussiens qui décrivent les valeurs de temps correctes. (Voir les images)

Les données sont extraites du temps de transition des personnes marchant entre deux endroits avec des vitesses différentes prises à partir d'une distribution de vitesse de marche normale (moyenne sur 1,4 m / s). Parfois, il peut y avoir plusieurs chemins entre deux emplacements qui peuvent générer plusieurs gaussiens.

Je veux extraire les gaussiens sous-jacents qui sont affichés au-dessus du bruit. Cependant, étant donné que les données peuvent provenir de différents scénarios mais avec un nombre arbitraire (disons environ 0-3) de chemins corrects / `` gaussiens '', je ne peux pas vraiment utiliser un GMM (Gaussian Mixture Model) car cela me demanderait de connaître le nombre de composants gaussiens?.

Je suppose / sais que les distributions de temps de transition correctes sont gaussiennes tandis que le bruit provient d'une autre distribution (Chi-carré?). Je suis assez nouveau sur le sujet, donc je me trompe peut-être totalement.

Puisque je connais à l'avance la distance de vérité terrain entre les deux points, je sais où les moyens doivent être situés.

Cette image a deux gaussiens corrects avec les moyennes sur 250s et 640s . (La variance devient plus élevée sur des temps plus longs)

 entrez la description de l'image ici

Cette image a un gaussien correct avec la moyenne sur 428s . entrez la description de l'image ici

Question: Existe-t-il une bonne approche pour récupérer les gaussiens ou au moins réduire considérablement le bruit étant donné quelque chose comme les données ci-dessus? Je ne m'attends pas à attraper les gaussiens qui se noient dans le bruit.


1 commentaires

Quelques commentaires. (1) D'après la description du problème et les données disponibles, il ne semble pas que les composants gaussiens correspondent bien. Je pense que vous avez besoin de quelque chose qui est biaisé et peut-être tronqué aux deux extrémités. (2) Je suis presque sûr que les gens ont travaillé sur des modèles de mélange dans lesquels le nombre de composants est déduit avec les paramètres de chaque composant. Je pense qu'une recherche sur le Web devrait trouver des ressources pour cela.


3 Réponses :


3
votes

J'aborderais cela en utilisant Estimation de la densité du noyau . I vous permet d'estimer la densité de probabilité directement à partir des données, sans trop d'hypothèses sur la distribution sous-jacente. En modifiant la bande passante du noyau, vous pouvez contrôler le niveau de lissage que vous appliquez, ce qui, je suppose, pourrait être réglé manuellement par une inspection visuelle jusqu'à ce que vous obteniez quelque chose qui réponde à vos attentes. Un exemple d'implémentation de KDE en python utilisant scikit-learn peut être trouvé ici .

Exemple:

from scipy.signal import find_peaks

# You can tweak with the other arguments of the 'find_peaks' function
# in order to fine-tune the extracted peaks according to your PDF
peaks = find_peaks(density)

Une fois le filtrage la distribution est estimée, vous pouvez analyser cela et identifier les pics en utilisant quelque chose comme this .

import numpy as np
from sklearn.neighbors import KernelDensity

# x is your original data
x = ...
# Adjust bandwidth to get the smoothness to your liking
bandwidth = ...

kde = KernelDensity(kernel='gaussian', bandwidth=bandwidth).fit(x)
support = np.linspace(min(x), max(x), 1000)
density = kde.score_samples(support)

Clause de non-responsabilité : Il s'agit d'une réponse de plus ou moins haut niveau, car votre question était également de haut niveau . Je suppose que vous savez ce que vous faites au niveau du code et que vous cherchez juste des idées. Mais si vous avez besoin d'aide pour quelque chose de spécifique, veuillez nous montrer du code et ce que vous avez essayé jusqu'à présent afin que nous puissions être plus précis.


2 commentaires

Génial! Mais je ne sais pas vraiment comment récupérer les pics de la fonction pdf. J'ai mis à jour la question avec un exemple de code, pourriez-vous suggérer un moyen de le faire?


Pas besoin de rééchantillonner les données du PDF généré. Tout ce que vous avez à faire est de trouver les sommets du PDF lui-même. La fonction scipy.signal.find_peaks peut être utilisée à cette fin. Je mettrai à jour ma réponse pour la rendre plus claire.



2
votes

Je vous conseille de jeter un œil à l'estimation du mélange gaussien

https://scikit-learn.org/stable/modules/mixture .html # gmm

"Un modèle de mélange gaussien est un modèle probabiliste qui suppose que tous les points de données sont générés à partir d'un mélange d'un nombre fini de distributions gaussiennes avec des paramètres inconnus."


1 commentaires

J'ai déjà regardé et expérimenté des GMM, mais cela me demande de savoir avec combien de composants gaussiens je travaille. Dans mon cas, cela pourrait différer. Il ne supportera pas très bien le bruit non plus car ce n'est pas vraiment gaussien (je pense). Savez-vous s'il existe un moyen de surmonter cela?



3
votes

Vous pouvez le faire en utilisant Kernel Density Estimation comme indiqué par @Pasa. scipy.stats.gaussian_kde peut le faire facilement. La syntaxe est illustrée dans l'exemple ci-dessous, qui génère 3 distributions gaussiennes, les superpose et ajoute du bruit puis utilise gaussian_kde pour estimer la courbe gaussienne, puis trace tout pour la démonstration.

import matplotlib.pyplot as plt
import numpy as np
from scipy.stats.kde import gaussian_kde

# Create three Gaussian curves and add some noise behind them
norm1 = np.random.normal(loc=10.0, size=5000, scale=1.1)
norm2 = np.random.normal(loc=5.0, size=3000)
norm3 = np.random.normal(loc=14.0, size=1000)
noise = np.random.rand(8000)*18
norm = np.concatenate((norm1, norm2, norm3, noise))

# The plotting is purely for demonstration
fig = plt.figure(dpi=300, figsize=(10,6))
plt.hist(norm, facecolor=(0, 0.4, 0.8), bins=200, rwidth=0.8, normed=True, alpha=0.3)
plt.xlim([0.0, 18.0])

# This is the relevant part, modifier modifies the estimation,
# lower values follow the data more closesly, higher more loosely
modifier= 0.03
kde = gaussian_kde(norm, modifier)

# Plots the KDE output for demonstration
kde_x = np.linspace(0, 18, 10000)
plt.plot(kde_x, kde(kde_x), 'k--', linewidth = 1.0)
plt.title("KDE example", fontsize=17)
plt.show()


1 commentaires

Excellente réponse avec l'exemple de code en complément! Cependant, je ne sais pas trop comment récupérer les pics à partir du pdf (?) Généré. Existe-t-il un moyen sophistiqué de le faire?