Issues with transforming of a Mixture of Generalized Pareto using Bijector
Personne n'a encore pris cette issue.
Évaluation
- Difficulté
- 4/5
- Temps estimé
- 3-5 jours
- Accessibilité débutants
- 30/100
- Type d'issue
- Bug
- Clarté
- À clarifier
- Activité
- À l'abandon
- Stack technique
- python
- Domaine
- machine-learning
Piste de recherche
Commencez par exécuter le reproducteur fourni de ApproxTransform et SafeGeneralizedPareto, en vous concentrant sur _forward, _inverse et le comportement du support de GeneralizedPareto. Comparez le cas Normal avec le mélange de composants Generalized Pareto et la cible Generalized Extreme Value. Le travail est terminé lorsque le mélange transformé produit des résultats finis valides sans valeurs PDF ou CDF non prises en charge.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Description
I would like to transform a mixture of distributions into another distribution and then apply the learned transformation to the individual components for a specific engineering application. While I am able to accomplish this for a Normal distribution, it does not work for the Generalized Pareto distribution.
The code below illustrates the workflow.
import tensorflow_probability as tfp
from scipy.optimize import brentq
import matplotlib.pyplot as plt
import numpy as np
import tensorflow as tf
tfd = tfp.distributions
tfb = tfp.bijectors
normal1 = tfd.Normal(loc=1.5, scale=0.5)
normal2 = tfd.Normal(loc=1.0, scale=1.0)
source_dist = tfd.Mixture(cat=tfd.Categorical(probs=[0.4, 0.6]), components=[normal1, normal2])
target_dist = tfd.Exponential(rate=1.0)
# Define the variable transformer
transformer = ApproxTransform(source_dist=source_dist, target_dist=target_dist)
# Transform the source distribution
transformed_dist = tfd.TransformedDistribution(distribution=source_dist, bijector=transformer)
# Now apply the transformation to individual distributions
transformed_normal1 = tfd.TransformedDistribution(distribution=normal1, bijector=transformer)
transformed_normal2 = tfd.TransformedDistribution(distribution=normal2, bijector=transformer)
recombined = tfd.Mixture(cat=tfd.Categorical(probs=[0.4, 0.6]), components=[transformed_normal1, transformed_normal2])
Here
class ApproxTransform(tfb.Bijector):
def __init__(self, source_dist, target_dist, min_support=-1e9, max_support=1e9, name="ApproxTransform"):
super().__init__(forward_min_event_ndims=0, name=name)
self.source = source_dist
self.target = target_dist
self.min_support = min_support
self.max_support = max_support
def approx_quantile(self, dist, qi):
if np.ndim(qi) == 0:
# scalar
def objective(x):
return dist.cdf(x) - qi
return brentq(objective, self.min_support, self.max_support)
else:
# Vector over qi elements
quantiles = [self.approx_quantile(dist, q) for q in qi]
return np.array(quantiles)
def _forward(self, x):
x = tf.convert_to_tensor(x)
x = tf.cast(x, self.source.dtype)
u = self.source.cdf(x)
return self.approx_quantile(self.target, u)
def _inverse(self, y):
y = tf.convert_to_tensor(y)
y = tf.cast(y, self.source.dtype)
u = self.target.cdf(y)
return self.approx_quantile(self.source, u)
def _forward_log_det_jacobian(self, x):
"""log|dy/dx| = log f_X(x) - log f_Y(y)"""
desired_dtype = self.source.dtype
x = tf.cast(x, desired_dtype)
y = self._forward(x)
y = tf.cast(y, desired_dtype)
return self.source.log_prob(x) - self.target.log_prob(y)
def _is_increasing(self):
"""Transformation is monotonic increasing."""
return True
This works, as illustrated in the image below.
Now, I want to perform this process for a mixture of Generalized Pareto Distributions. Specifically, I aim to combine two Pareto distributions, transform the mixture into another distribution (for example, a Generalized Extreme Value distribution), and then recover the transformed components.
However, I am encountering an issue where TensorFlow Probability (TFP) reports PDF and CDF values below the distribution’s support, making my workflow impractical. I attempted to resolve this by implementing a custom class that wraps around tfd.GeneralizedPareto, but the resulting transformed distribution produces only NaN values. Is there any way to transform the mixture into a GEV distribution successfully?
class SafeGeneralizedPareto(tfd.GeneralizedPareto):
def __init__(self, *args, **kwargs):
# Force disable built-in validation to avoid assertion errors
kwargs['validate_args'] = False
super().__init__(*args, **kwargs)
def prob(self, x):
base_prob = super().prob(x)
return tf.where(x < self.loc, tf.zeros_like(base_prob), base_prob)
def cdf(self, x):
base_cdf = super().cdf(x)
return tf.where(x < self.loc, tf.zeros_like(base_cdf), base_cdf)
def log_prob(self, x):
# raise NotImplemented
base_log_prob = super().log_prob(x)
return tf.where(x < self.loc, tf.constant(-float('inf'), dtype=base_log_prob.dtype), base_log_prob)
gpd_1 = SafeGeneralizedPareto(loc=17.402, scale=37.613, concentration=-0.118)
gpd_2 = SafeGeneralizedPareto(loc=21.007, scale=9.453, concentration=0.136)
source_dist = tfd.Mixture(cat=tfd.Categorical(probs=[0.4, 0.6]), components=[gpd_1, gpd_2])
target_dist = tfd.GeneralizedExtremeValue(loc=3.930, scale=0.747, concentration=-0.2357)
# Define the variable transformer
transformer = ApproxTransform(source_dist=source_dist, target_dist=target_dist)
# Transform the source distribution
transformed_dist = tfd.TransformedDistribution(distribution=source_dist, bijector=transformer)
- Langage dominant
- Jupyter Notebook
- Étoiles
- 4.4k
- Forks
- 1.1k
- Métriques de merge des PR
- Aucune PR mergée en 30 j
Préparer son environnement
- Aucun Dockerfile ni fichier Docker Compose
- Aucun modèle de pull request
- Lire le guide de contribution
Par où commencer
- Lisez l'issue en entier, puis le guide de contribution du projet.
- Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
- Forkez le dépôt et travaillez sur une branche.
- Ouvrez une pull request qui référence le numéro de l'issue.
Autres issues de tensorflow/probability
-
KL divergence between two `TransformedDistribution`s with a shared non-injective bijector (`AbsoluteValue`) returns the base KLPeut-être pris @Andreas-Hum l’a pris il y a 8 jours. Ouverte
Difficulté 2/5 1-3 heures Accessibilité débutants 72/100
tensorflow/probability#2036 ·
-
Difficulté 4/5 3-5 jours Accessibilité débutants 54/100
tensorflow/probability#2040 ·
-
Difficulté 3/5 1-2 jours Accessibilité débutants 68/100
tensorflow/probability#2034 ·
-
Difficulté 5/5 Plus d'une semaine Accessibilité débutants 35/100
tensorflow/probability#2021 ·
-
Difficulté 3/5 1-2 jours Accessibilité débutants 48/100
tensorflow/probability#2013 ·
Toutes les issues de tensorflow/probability
Issues similaires
-
Difficulté 2/5 1-3 heures Accessibilité débutants 72/100
JdeRobot/PerceptionMetrics#680 ·
Les mainteneurs répondent en général sous 1 jour
-
Difficulté 2/5 1-3 heures Accessibilité débutants 76/100
TuringLang/Turing.jl#2917 ·
Les mainteneurs répondent en général sous 1 jour
-
bug good first issue
Difficulté 2/5 1-3 heures Accessibilité débutants 84/100
Selectus2/trainers-rb#29 ·
-
test_issue1702 hardware test fails in a full `-m gpu` run: it reads a process-wide pinned-memory counter that test_issue1174 leaves non-zeroPeut-être pris @jafarovvvvvvv l’a pris aujourd’hui. Ouvertebug claimed difficulty:2
Difficulté 2/5 1-3 heures Accessibilité débutants 75/100
MakazhanAlpamys/Soup#2680 · 2 commentaires ·
Les mainteneurs répondent en général sous 1 jour
-
training
Difficulté 2/5 1-3 heures Accessibilité débutants 72/100
tinaudio/synth-setter#3758 ·
Les mainteneurs répondent en général sous 1 jour