-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathplot_feature_binning.py
More file actions
58 lines (46 loc) · 1.93 KB
/
Copy pathplot_feature_binning.py
File metadata and controls
58 lines (46 loc) · 1.93 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
import numpy as np
import matplotlib.pyplot as plt
def plot_feature_binning(x, y, bins=10, feature_name="Feature"):
mask = ~np.isnan(x)
x = x[mask]
y = y[mask]
quantiles = np.unique(np.quantile(x, np.linspace(0, 1, bins + 1)))
if len(quantiles) <= 2:
print("Not enough unique bins to plot.")
return
bin_edges = quantiles[1:-1]
x_binned = np.digitize(x, bin_edges, right=True)
# Init arrays
y0_counts = np.zeros(len(quantiles) - 1)
y1_counts = np.zeros(len(quantiles) - 1)
target_rates = np.zeros(len(quantiles) - 1)
for b in range(len(quantiles) - 1):
in_bin = x_binned == b
bin_y = y[in_bin]
y0_counts[b] = np.sum(bin_y == 0)
y1_counts[b] = np.sum(bin_y == 1)
target_rates[b] = np.mean(bin_y) if bin_y.size > 0 else np.nan
idx = np.arange(len(y0_counts))
fig, ax1 = plt.subplots(figsize=(10, 5))
# Bar plot on left y-axis
ax1.bar(idx, y0_counts, color="skyblue", label="y = 0")
ax1.bar(idx, y1_counts, bottom=y0_counts, color="salmon", label="y = 1")
ax1.set_ylabel("Count")
ax1.set_xlabel(feature_name)
ax1.set_title(f"Binned Distribution of {feature_name} (Stacked + Target Rate)")
# Twin y-axis for target rate
ax2 = ax1.twinx()
ax2.plot(idx, target_rates, color="black", marker="o", label="Target Rate")
ax2.set_ylabel("Target Rate", color="black")
ax2.tick_params(axis="y", labelcolor="black")
# X-axis bin labels
bin_labels = [f"[{quantiles[i]:.2f}, {quantiles[i+1]:.2f})" for i in range(len(quantiles) - 1)]
ax1.set_xticks(idx)
ax1.set_xticklabels(bin_labels, rotation=45)
# Combine legends from both axes
handles1, labels1 = ax1.get_legend_handles_labels()
handles2, labels2 = ax2.get_legend_handles_labels()
ax1.legend(handles1 + handles2, labels1 + labels2, loc="upper right")
ax1.grid(axis="y", linestyle="--", alpha=0.4)
plt.tight_layout()
plt.show()