Add full probability distributions to dashboard
This commit is contained in:
@@ -858,6 +858,10 @@ export function ProbabilityDistribution({
|
|||||||
? formatBucketDisplayLabel(topProbability, detail)
|
? formatBucketDisplayLabel(topProbability, detail)
|
||||||
: null;
|
: null;
|
||||||
const topProbabilityTemp = topProbability ? getBucketTemp(topProbability) : null;
|
const topProbabilityTemp = topProbability ? getBucketTemp(topProbability) : null;
|
||||||
|
const probabilitiesForMarketContracts =
|
||||||
|
view.probabilitiesAll?.length > 0
|
||||||
|
? view.probabilitiesAll
|
||||||
|
: view.probabilities || [];
|
||||||
const marketContractRows = useMemo<ProbabilityDisplayRow[]>(() => {
|
const marketContractRows = useMemo<ProbabilityDisplayRow[]>(() => {
|
||||||
if (!isToday || !marketScan?.available || marketAllBuckets.length === 0) {
|
if (!isToday || !marketScan?.available || marketAllBuckets.length === 0) {
|
||||||
return [];
|
return [];
|
||||||
@@ -867,7 +871,7 @@ export function ProbabilityDistribution({
|
|||||||
const seenKeys = new Set<string>();
|
const seenKeys = new Set<string>();
|
||||||
for (const marketBucket of marketAllBuckets) {
|
for (const marketBucket of marketAllBuckets) {
|
||||||
const probability = getAggregatedModelProbabilityForMarketBucket(
|
const probability = getAggregatedModelProbabilityForMarketBucket(
|
||||||
view.probabilities || [],
|
probabilitiesForMarketContracts,
|
||||||
marketBucket,
|
marketBucket,
|
||||||
detail,
|
detail,
|
||||||
);
|
);
|
||||||
@@ -886,7 +890,13 @@ export function ProbabilityDistribution({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
return rows;
|
return rows;
|
||||||
}, [detail, isToday, marketAllBuckets, marketScan?.available, view.probabilities]);
|
}, [
|
||||||
|
detail,
|
||||||
|
isToday,
|
||||||
|
marketAllBuckets,
|
||||||
|
marketScan?.available,
|
||||||
|
probabilitiesForMarketContracts,
|
||||||
|
]);
|
||||||
const modelProbabilityRows = useMemo<ProbabilityDisplayRow[]>(
|
const modelProbabilityRows = useMemo<ProbabilityDisplayRow[]>(
|
||||||
() =>
|
() =>
|
||||||
(view.probabilities || []).slice(0, 6).map((bucket, index) => {
|
(view.probabilities || []).slice(0, 6).map((bucket, index) => {
|
||||||
@@ -938,7 +948,7 @@ export function ProbabilityDistribution({
|
|||||||
topProbabilityLabel ||
|
topProbabilityLabel ||
|
||||||
null;
|
null;
|
||||||
const aggregatedMarketProbability = getAggregatedModelProbabilityForMarketBucket(
|
const aggregatedMarketProbability = getAggregatedModelProbabilityForMarketBucket(
|
||||||
view.probabilities || [],
|
probabilitiesForMarketContracts,
|
||||||
linkedMarketBucket,
|
linkedMarketBucket,
|
||||||
detail,
|
detail,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -488,6 +488,7 @@ export interface CityDetail {
|
|||||||
probabilities?: {
|
probabilities?: {
|
||||||
mu?: number | null;
|
mu?: number | null;
|
||||||
distribution?: ProbabilityBucket[];
|
distribution?: ProbabilityBucket[];
|
||||||
|
distribution_all?: ProbabilityBucket[];
|
||||||
engine?: string | null;
|
engine?: string | null;
|
||||||
calibration_mode?: string | null;
|
calibration_mode?: string | null;
|
||||||
calibration_version?: string | null;
|
calibration_version?: string | null;
|
||||||
@@ -496,6 +497,7 @@ export interface CityDetail {
|
|||||||
calibrated_mu?: number | null;
|
calibrated_mu?: number | null;
|
||||||
calibrated_sigma?: number | null;
|
calibrated_sigma?: number | null;
|
||||||
shadow_distribution?: ProbabilityBucket[];
|
shadow_distribution?: ProbabilityBucket[];
|
||||||
|
shadow_distribution_all?: ProbabilityBucket[];
|
||||||
};
|
};
|
||||||
hourly?: {
|
hourly?: {
|
||||||
times?: string[];
|
times?: string[];
|
||||||
|
|||||||
@@ -1212,7 +1212,15 @@ export function getProbabilityView(detail: CityDetail, targetDate?: string | nul
|
|||||||
engine: detail.probabilities?.engine ?? null,
|
engine: detail.probabilities?.engine ?? null,
|
||||||
mu: detail.probabilities?.mu ?? null,
|
mu: detail.probabilities?.mu ?? null,
|
||||||
probabilities: detail.probabilities?.distribution || [],
|
probabilities: detail.probabilities?.distribution || [],
|
||||||
|
probabilitiesAll:
|
||||||
|
detail.probabilities?.distribution_all ||
|
||||||
|
detail.probabilities?.distribution ||
|
||||||
|
[],
|
||||||
shadowProbabilities: detail.probabilities?.shadow_distribution || [],
|
shadowProbabilities: detail.probabilities?.shadow_distribution || [],
|
||||||
|
shadowProbabilitiesAll:
|
||||||
|
detail.probabilities?.shadow_distribution_all ||
|
||||||
|
detail.probabilities?.shadow_distribution ||
|
||||||
|
[],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1223,7 +1231,9 @@ export function getProbabilityView(detail: CityDetail, targetDate?: string | nul
|
|||||||
engine: null,
|
engine: null,
|
||||||
mu: daily?.deb?.prediction ?? null,
|
mu: daily?.deb?.prediction ?? null,
|
||||||
probabilities: daily?.probabilities || [],
|
probabilities: daily?.probabilities || [],
|
||||||
|
probabilitiesAll: daily?.probabilities || [],
|
||||||
shadowProbabilities: [],
|
shadowProbabilities: [],
|
||||||
|
shadowProbabilitiesAll: [],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -169,7 +169,7 @@ def _bucket_probabilities(
|
|||||||
sigma: float,
|
sigma: float,
|
||||||
max_so_far: Optional[float],
|
max_so_far: Optional[float],
|
||||||
city_name: str,
|
city_name: str,
|
||||||
) -> Tuple[List[Dict[str, Any]], List[Tuple[int, float]]]:
|
) -> Tuple[List[Dict[str, Any]], List[Tuple[int, float]], List[Dict[str, Any]]]:
|
||||||
sigma = max(0.1, float(sigma))
|
sigma = max(0.1, float(sigma))
|
||||||
min_possible = (
|
min_possible = (
|
||||||
apply_city_settlement(city_name, max_so_far) if max_so_far is not None else -999
|
apply_city_settlement(city_name, max_so_far) if max_so_far is not None else -999
|
||||||
@@ -193,24 +193,24 @@ def _bucket_probabilities(
|
|||||||
|
|
||||||
total = sum(probs.values())
|
total = sum(probs.values())
|
||||||
if total <= 0:
|
if total <= 0:
|
||||||
return [], []
|
return [], [], []
|
||||||
|
|
||||||
normalized = {key: val / total for key, val in probs.items()}
|
normalized = {key: val / total for key, val in probs.items()}
|
||||||
sorted_probs = sorted(normalized.items(), key=lambda item: item[1], reverse=True)
|
sorted_probs = sorted(normalized.items(), key=lambda item: item[1], reverse=True)
|
||||||
distribution = []
|
full_distribution = []
|
||||||
for value, prob in sorted_probs[:4]:
|
for value, prob in sorted_probs:
|
||||||
if is_exact:
|
if is_exact:
|
||||||
bucket_range = "[{0}.0~{1}.0)".format(value, value + 1)
|
bucket_range = "[{0}.0~{1}.0)".format(value, value + 1)
|
||||||
else:
|
else:
|
||||||
bucket_range = "[{0}~{1})".format(value - 0.5, value + 0.5)
|
bucket_range = "[{0}~{1})".format(value - 0.5, value + 0.5)
|
||||||
distribution.append(
|
full_distribution.append(
|
||||||
{
|
{
|
||||||
"value": int(value),
|
"value": int(value),
|
||||||
"range": bucket_range,
|
"range": bucket_range,
|
||||||
"probability": round(prob, 3),
|
"probability": round(prob, 3),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
return distribution, sorted_probs
|
return full_distribution[:4], sorted_probs, full_distribution
|
||||||
|
|
||||||
|
|
||||||
def _top_bucket_value(distribution: Optional[List[Dict[str, Any]]]) -> Optional[int]:
|
def _top_bucket_value(distribution: Optional[List[Dict[str, Any]]]) -> Optional[int]:
|
||||||
@@ -299,7 +299,9 @@ def apply_probability_calibration(
|
|||||||
"mode": selected_mode,
|
"mode": selected_mode,
|
||||||
"engine": ENGINE_MODE_LEGACY,
|
"engine": ENGINE_MODE_LEGACY,
|
||||||
"distribution": legacy_distribution or [],
|
"distribution": legacy_distribution or [],
|
||||||
|
"distribution_all": legacy_distribution or [],
|
||||||
"shadow_distribution": [],
|
"shadow_distribution": [],
|
||||||
|
"shadow_distribution_all": [],
|
||||||
"raw_mu": raw_mu,
|
"raw_mu": raw_mu,
|
||||||
"raw_sigma": raw_sigma,
|
"raw_sigma": raw_sigma,
|
||||||
"calibrated_mu": None,
|
"calibrated_mu": None,
|
||||||
@@ -314,7 +316,9 @@ def apply_probability_calibration(
|
|||||||
"mode": selected_mode,
|
"mode": selected_mode,
|
||||||
"engine": ENGINE_MODE_LEGACY,
|
"engine": ENGINE_MODE_LEGACY,
|
||||||
"distribution": legacy_distribution or [],
|
"distribution": legacy_distribution or [],
|
||||||
|
"distribution_all": legacy_distribution or [],
|
||||||
"shadow_distribution": [],
|
"shadow_distribution": [],
|
||||||
|
"shadow_distribution_all": [],
|
||||||
"raw_mu": raw_mu,
|
"raw_mu": raw_mu,
|
||||||
"raw_sigma": raw_sigma,
|
"raw_sigma": raw_sigma,
|
||||||
"calibrated_mu": None,
|
"calibrated_mu": None,
|
||||||
@@ -384,7 +388,7 @@ def apply_probability_calibration(
|
|||||||
calibrated_mu = observed_floor
|
calibrated_mu = observed_floor
|
||||||
calibrated_sigma = max(0.1, _blend_value(raw_sigma, calibrated_sigma, blend_alpha_sigma))
|
calibrated_sigma = max(0.1, _blend_value(raw_sigma, calibrated_sigma, blend_alpha_sigma))
|
||||||
calibrated_sigma = _clamp_sigma(raw_sigma, calibrated_sigma, sigma_constraints)
|
calibrated_sigma = _clamp_sigma(raw_sigma, calibrated_sigma, sigma_constraints)
|
||||||
calibrated_distribution, calibrated_sorted = _bucket_probabilities(
|
calibrated_distribution, calibrated_sorted, calibrated_distribution_all = _bucket_probabilities(
|
||||||
calibrated_mu,
|
calibrated_mu,
|
||||||
calibrated_sigma,
|
calibrated_sigma,
|
||||||
max_so_far=max_so_far,
|
max_so_far=max_so_far,
|
||||||
@@ -393,23 +397,29 @@ def apply_probability_calibration(
|
|||||||
|
|
||||||
engine = ENGINE_MODE_LEGACY
|
engine = ENGINE_MODE_LEGACY
|
||||||
selected_distribution = legacy_distribution or []
|
selected_distribution = legacy_distribution or []
|
||||||
|
selected_distribution_all = legacy_distribution or []
|
||||||
selected_sorted: List[Tuple[int, float]] = []
|
selected_sorted: List[Tuple[int, float]] = []
|
||||||
shadow_distribution: List[Dict[str, Any]] = []
|
shadow_distribution: List[Dict[str, Any]] = []
|
||||||
|
shadow_distribution_all: List[Dict[str, Any]] = []
|
||||||
shadow_sorted: List[Tuple[int, float]] = []
|
shadow_sorted: List[Tuple[int, float]] = []
|
||||||
if selected_mode == ENGINE_MODE_EMOS_PRIMARY:
|
if selected_mode == ENGINE_MODE_EMOS_PRIMARY:
|
||||||
engine = "emos"
|
engine = "emos"
|
||||||
selected_distribution = calibrated_distribution
|
selected_distribution = calibrated_distribution
|
||||||
|
selected_distribution_all = calibrated_distribution_all
|
||||||
selected_sorted = calibrated_sorted
|
selected_sorted = calibrated_sorted
|
||||||
elif selected_mode == ENGINE_MODE_EMOS_SHADOW:
|
elif selected_mode == ENGINE_MODE_EMOS_SHADOW:
|
||||||
shadow_distribution = calibrated_distribution
|
shadow_distribution = calibrated_distribution
|
||||||
|
shadow_distribution_all = calibrated_distribution_all
|
||||||
shadow_sorted = calibrated_sorted
|
shadow_sorted = calibrated_sorted
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"mode": selected_mode,
|
"mode": selected_mode,
|
||||||
"engine": engine,
|
"engine": engine,
|
||||||
"distribution": selected_distribution,
|
"distribution": selected_distribution,
|
||||||
|
"distribution_all": selected_distribution_all,
|
||||||
"selected_sorted_probs": selected_sorted,
|
"selected_sorted_probs": selected_sorted,
|
||||||
"shadow_distribution": shadow_distribution,
|
"shadow_distribution": shadow_distribution,
|
||||||
|
"shadow_distribution_all": shadow_distribution_all,
|
||||||
"shadow_sorted_probs": shadow_sorted,
|
"shadow_sorted_probs": shadow_sorted,
|
||||||
"raw_mu": raw_mu,
|
"raw_mu": raw_mu,
|
||||||
"raw_sigma": raw_sigma,
|
"raw_sigma": raw_sigma,
|
||||||
@@ -551,7 +561,7 @@ def fit_calibration(
|
|||||||
== apply_city_settlement(city, actual_high)
|
== apply_city_settlement(city, actual_high)
|
||||||
else 0.0
|
else 0.0
|
||||||
)
|
)
|
||||||
legacy_distribution, _ = _bucket_probabilities(
|
legacy_distribution, _, _ = _bucket_probabilities(
|
||||||
legacy_mu,
|
legacy_mu,
|
||||||
legacy_sigma,
|
legacy_sigma,
|
||||||
max_so_far=None,
|
max_so_far=None,
|
||||||
@@ -627,7 +637,7 @@ def fit_calibration(
|
|||||||
city = row["city"]
|
city = row["city"]
|
||||||
crps_values.append(_gaussian_crps(actual_high, mu_hat, sigma_hat))
|
crps_values.append(_gaussian_crps(actual_high, mu_hat, sigma_hat))
|
||||||
mae_values.append(abs(mu_hat - actual_high))
|
mae_values.append(abs(mu_hat - actual_high))
|
||||||
distribution, _ = _bucket_probabilities(
|
distribution, _, _ = _bucket_probabilities(
|
||||||
mu_hat,
|
mu_hat,
|
||||||
sigma_hat,
|
sigma_hat,
|
||||||
max_so_far=None,
|
max_so_far=None,
|
||||||
|
|||||||
@@ -594,7 +594,9 @@ def analyze_weather_trend(
|
|||||||
|
|
||||||
# === Probability Engine ===
|
# === Probability Engine ===
|
||||||
probabilities: List[Dict[str, Any]] = []
|
probabilities: List[Dict[str, Any]] = []
|
||||||
|
probabilities_all: List[Dict[str, Any]] = []
|
||||||
shadow_probabilities: List[Dict[str, Any]] = []
|
shadow_probabilities: List[Dict[str, Any]] = []
|
||||||
|
shadow_probabilities_all: List[Dict[str, Any]] = []
|
||||||
forecast_miss_deg = 0.0
|
forecast_miss_deg = 0.0
|
||||||
probability_features = None
|
probability_features = None
|
||||||
calibration_summary = {
|
calibration_summary = {
|
||||||
@@ -621,6 +623,7 @@ def analyze_weather_trend(
|
|||||||
probabilities = [
|
probabilities = [
|
||||||
{"value": settled_wu, "range": f"[{settled_wu-0.5}~{settled_wu+0.5})", "probability": 1.0}
|
{"value": settled_wu, "range": f"[{settled_wu-0.5}~{settled_wu+0.5})", "probability": 1.0}
|
||||||
]
|
]
|
||||||
|
probabilities_all = probabilities
|
||||||
elif (ens_p10 is not None and ens_p90 is not None) or fallback_sigma:
|
elif (ens_p10 is not None and ens_p90 is not None) or fallback_sigma:
|
||||||
# Forecast miss magnitude
|
# Forecast miss magnitude
|
||||||
if max_so_far is not None and forecast_median is not None:
|
if max_so_far is not None and forecast_median is not None:
|
||||||
@@ -665,6 +668,7 @@ def analyze_weather_trend(
|
|||||||
)
|
)
|
||||||
mu = probs_result.get("mu", mu)
|
mu = probs_result.get("mu", mu)
|
||||||
probabilities = probs_result.get("probabilities", [])
|
probabilities = probs_result.get("probabilities", [])
|
||||||
|
probabilities_all = probs_result.get("probabilities_all", probabilities)
|
||||||
sorted_probs = probs_result.get("sorted_probs", [])
|
sorted_probs = probs_result.get("sorted_probs", [])
|
||||||
|
|
||||||
probability_features = build_probability_features(
|
probability_features = build_probability_features(
|
||||||
@@ -698,10 +702,12 @@ def analyze_weather_trend(
|
|||||||
"calibration_source": calibration_result.get("calibration_source"),
|
"calibration_source": calibration_result.get("calibration_source"),
|
||||||
}
|
}
|
||||||
shadow_probabilities = calibration_result.get("shadow_distribution") or []
|
shadow_probabilities = calibration_result.get("shadow_distribution") or []
|
||||||
|
shadow_probabilities_all = calibration_result.get("shadow_distribution_all") or shadow_probabilities
|
||||||
if calibration_result.get("engine") == "emos":
|
if calibration_result.get("engine") == "emos":
|
||||||
mu = calibration_result.get("calibrated_mu", mu)
|
mu = calibration_result.get("calibrated_mu", mu)
|
||||||
sigma = calibration_result.get("calibrated_sigma", sigma)
|
sigma = calibration_result.get("calibrated_sigma", sigma)
|
||||||
probabilities = calibration_result.get("distribution") or probabilities
|
probabilities = calibration_result.get("distribution") or probabilities
|
||||||
|
probabilities_all = calibration_result.get("distribution_all") or probabilities_all or probabilities
|
||||||
sorted_probs = calibration_result.get("selected_sorted_probs") or sorted_probs
|
sorted_probs = calibration_result.get("selected_sorted_probs") or sorted_probs
|
||||||
|
|
||||||
if sorted_probs:
|
if sorted_probs:
|
||||||
@@ -926,7 +932,9 @@ def analyze_weather_trend(
|
|||||||
structured = {
|
structured = {
|
||||||
"mu": mu,
|
"mu": mu,
|
||||||
"probabilities": probabilities,
|
"probabilities": probabilities,
|
||||||
|
"probabilities_all": probabilities_all or probabilities,
|
||||||
"shadow_probabilities": shadow_probabilities,
|
"shadow_probabilities": shadow_probabilities,
|
||||||
|
"shadow_probabilities_all": shadow_probabilities_all or shadow_probabilities,
|
||||||
"probability_engine": calibration_summary["engine"],
|
"probability_engine": calibration_summary["engine"],
|
||||||
"probability_calibration_mode": calibration_summary["mode"],
|
"probability_calibration_mode": calibration_summary["mode"],
|
||||||
"probability_calibration_version": calibration_summary["calibration_version"],
|
"probability_calibration_version": calibration_summary["calibration_version"],
|
||||||
@@ -999,21 +1007,24 @@ def calculate_prob_distribution(
|
|||||||
total_p = sum(probs.values())
|
total_p = sum(probs.values())
|
||||||
sorted_probs = []
|
sorted_probs = []
|
||||||
probabilities = []
|
probabilities = []
|
||||||
|
probabilities_all = []
|
||||||
|
|
||||||
if total_p > 0:
|
if total_p > 0:
|
||||||
norm_probs = {k: v / total_p for k, v in probs.items()}
|
norm_probs = {k: v / total_p for k, v in probs.items()}
|
||||||
sorted_probs = sorted(norm_probs.items(), key=lambda x: x[1], reverse=True)
|
sorted_probs = sorted(norm_probs.items(), key=lambda x: x[1], reverse=True)
|
||||||
for t, p in sorted_probs[:4]:
|
for t, p in sorted_probs:
|
||||||
rng_str = f"[{t}.0~{t+1}.0)" if is_exact else f"[{t-0.5}~{t+0.5})"
|
rng_str = f"[{t}.0~{t+1}.0)" if is_exact else f"[{t-0.5}~{t+0.5})"
|
||||||
probabilities.append({
|
probabilities_all.append({
|
||||||
"value": int(t),
|
"value": int(t),
|
||||||
"range": rng_str,
|
"range": rng_str,
|
||||||
"probability": round(p, 3)
|
"probability": round(p, 3)
|
||||||
})
|
})
|
||||||
|
probabilities = probabilities_all[:4]
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"mu": mu,
|
"mu": mu,
|
||||||
"sigma": sigma,
|
"sigma": sigma,
|
||||||
"probabilities": probabilities,
|
"probabilities": probabilities,
|
||||||
|
"probabilities_all": probabilities_all,
|
||||||
"sorted_probs": sorted_probs
|
"sorted_probs": sorted_probs
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -96,6 +96,7 @@ def test_shadow_mode_keeps_legacy_distribution(tmp_path):
|
|||||||
assert result["shadow_distribution"]
|
assert result["shadow_distribution"]
|
||||||
assert result["calibrated_mu"] == 10.5
|
assert result["calibrated_mu"] == 10.5
|
||||||
assert result["calibrated_sigma"] == 1.2
|
assert result["calibrated_sigma"] == 1.2
|
||||||
|
assert len(result["shadow_distribution_all"]) >= len(result["shadow_distribution"])
|
||||||
|
|
||||||
|
|
||||||
def test_primary_mode_switches_to_calibrated_distribution(tmp_path):
|
def test_primary_mode_switches_to_calibrated_distribution(tmp_path):
|
||||||
@@ -129,6 +130,7 @@ def test_primary_mode_switches_to_calibrated_distribution(tmp_path):
|
|||||||
assert result["calibrated_mu"] == 10.5
|
assert result["calibrated_mu"] == 10.5
|
||||||
assert result["calibrated_sigma"] == 1.2
|
assert result["calibrated_sigma"] == 1.2
|
||||||
assert result["distribution"]
|
assert result["distribution"]
|
||||||
|
assert len(result["distribution_all"]) >= len(result["distribution"])
|
||||||
assert result["distribution"][0]["value"] >= 10
|
assert result["distribution"][0]["value"] >= 10
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -2006,7 +2006,9 @@ def _analyze(
|
|||||||
from src.analysis.trend_engine import analyze_weather_trend as _trend_analyze, calculate_prob_distribution
|
from src.analysis.trend_engine import analyze_weather_trend as _trend_analyze, calculate_prob_distribution
|
||||||
|
|
||||||
probabilities = []
|
probabilities = []
|
||||||
|
probabilities_all = []
|
||||||
shadow_probabilities = []
|
shadow_probabilities = []
|
||||||
|
shadow_probabilities_all = []
|
||||||
mu = None
|
mu = None
|
||||||
probability_engine = "legacy"
|
probability_engine = "legacy"
|
||||||
probability_calibration_mode = "legacy"
|
probability_calibration_mode = "legacy"
|
||||||
@@ -2022,7 +2024,9 @@ def _analyze(
|
|||||||
# Use structured data from shared engine
|
# Use structured data from shared engine
|
||||||
mu = sd.get("mu")
|
mu = sd.get("mu")
|
||||||
probabilities = sd.get("probabilities", [])
|
probabilities = sd.get("probabilities", [])
|
||||||
|
probabilities_all = sd.get("probabilities_all", probabilities)
|
||||||
shadow_probabilities = sd.get("shadow_probabilities", [])
|
shadow_probabilities = sd.get("shadow_probabilities", [])
|
||||||
|
shadow_probabilities_all = sd.get("shadow_probabilities_all", shadow_probabilities)
|
||||||
probability_engine = sd.get("probability_engine", "legacy")
|
probability_engine = sd.get("probability_engine", "legacy")
|
||||||
probability_calibration_mode = sd.get("probability_calibration_mode", "legacy")
|
probability_calibration_mode = sd.get("probability_calibration_mode", "legacy")
|
||||||
probability_calibration_version = sd.get("probability_calibration_version")
|
probability_calibration_version = sd.get("probability_calibration_version")
|
||||||
@@ -2406,6 +2410,7 @@ def _analyze(
|
|||||||
"probabilities": {
|
"probabilities": {
|
||||||
"mu": round(mu, 1) if mu is not None else None,
|
"mu": round(mu, 1) if mu is not None else None,
|
||||||
"distribution": probabilities,
|
"distribution": probabilities,
|
||||||
|
"distribution_all": probabilities_all or probabilities,
|
||||||
"engine": probability_engine,
|
"engine": probability_engine,
|
||||||
"calibration_mode": probability_calibration_mode,
|
"calibration_mode": probability_calibration_mode,
|
||||||
"calibration_version": probability_calibration_version,
|
"calibration_version": probability_calibration_version,
|
||||||
@@ -2414,6 +2419,7 @@ def _analyze(
|
|||||||
"calibrated_mu": probability_calibrated_mu,
|
"calibrated_mu": probability_calibrated_mu,
|
||||||
"calibrated_sigma": probability_calibrated_sigma,
|
"calibrated_sigma": probability_calibrated_sigma,
|
||||||
"shadow_distribution": shadow_probabilities,
|
"shadow_distribution": shadow_probabilities,
|
||||||
|
"shadow_distribution_all": shadow_probabilities_all or shadow_probabilities,
|
||||||
},
|
},
|
||||||
"trend": trend_info,
|
"trend": trend_info,
|
||||||
"peak": {
|
"peak": {
|
||||||
|
|||||||
Reference in New Issue
Block a user