Spaces:
Running
on
L4
Running
on
L4
import matplotlib.pyplot as plt | |
import numpy as np | |
def smooth_mapping( | |
confidence: float, | |
true_threshold=0.95, | |
false_threshold=0.40, | |
target_conf=0.60, | |
target_prob=0.78, | |
p_min=0.01, | |
p_max=0.99, | |
steepness_factor=0.7, # New parameter: 0-1 range, lower = less steep | |
) -> float: | |
"""Map confidence to probability using a sigmoid function with adjustable steepness. | |
Args: | |
confidence: Input confidence score | |
true_threshold: Upper threshold (0.78) | |
false_threshold: Lower threshold (0.40) | |
target_conf: Target confidence point (0.60) | |
target_prob: Target probability value (0.78) | |
p_min: Minimum probability (0.01) | |
p_max: Maximum probability (0.99) | |
steepness_factor: Controls curve steepness (0-1, lower = less steep) | |
""" | |
if confidence <= false_threshold: | |
return p_min | |
if confidence >= true_threshold: | |
return p_max | |
# Calculate parameters to ensure target_conf maps to target_prob | |
# For a sigmoid function: f(x) = L / (1 + e^(-k(x-x0))) | |
# First, normalize the target point | |
x_norm = (target_conf - false_threshold) / (true_threshold - false_threshold) | |
y_norm = (target_prob - p_min) / (p_max - p_min) | |
# Find x0 (midpoint) and k (steepness) to satisfy our target point | |
x0 = 0.30 # Midpoint of normalized range | |
# Calculate base k value to hit the target point | |
base_k = -np.log(1 / y_norm - 1) / (x_norm - x0) | |
# Apply steepness factor (lower = less steep) | |
k = base_k * steepness_factor | |
# With reduced steepness, we need to adjust x0 to still hit the target point | |
# Solve for new x0: y = 1/(1+e^(-k(x-x0))) => x0 = x + ln(1/y-1)/k | |
adjusted_x0 = x_norm + np.log(1 / y_norm - 1) / k | |
# Apply the sigmoid with our calculated parameters | |
x_scaled = (confidence - false_threshold) / (true_threshold - false_threshold) | |
sigmoid_value = 1 / (1 + np.exp(-k * (x_scaled - adjusted_x0))) | |
# Ensure we still hit exactly p_min and p_max at the thresholds | |
# by rescaling the output slightly | |
min_val = 1 / (1 + np.exp(-k * (0 - adjusted_x0))) | |
max_val = 1 / (1 + np.exp(-k * (1 - adjusted_x0))) | |
# Normalize the output | |
normalized = (sigmoid_value - min_val) / (max_val - min_val) | |
return p_min + normalized * (p_max - p_min) | |
def main(): | |
# Visualize the function | |
x = np.linspace(0, 1, 1000) | |
y = [smooth_mapping(xi) for xi in x] | |
plt.figure(figsize=(10, 6)) | |
plt.plot(x, y, "r-", label="Mapping Function", linewidth=2) | |
# Add vertical lines for thresholds | |
plt.axvline(x=0.40, color="b", linestyle="--", label="False Threshold (0.40)") | |
plt.axvline(x=0.95, color="g", linestyle="--", label="True Threshold (0.95)") | |
# Add horizontal lines for probability limits | |
plt.axhline(y=0.01, color="r", linestyle=":", alpha=0.5) | |
plt.axhline(y=0.99, color="g", linestyle=":", alpha=0.5) | |
plt.grid(True, alpha=0.3) | |
plt.xlabel("Confidence Score") | |
plt.ylabel("Mapped Probability") | |
plt.title("Confidence to Probability Mapping (Matching Red Line)") | |
plt.legend() | |
plt.ylim(-0.05, 1.05) | |
plt.savefig("calibration.png") | |
# Print some example values | |
test_values = [0.4, 0.425, 0.6, 0.85, 0.9] | |
for val in test_values: | |
print(f"Confidence {val:.3f} β Probability {smooth_mapping(val):.3f}") | |
if __name__ == "__main__": | |
main() | |