Note
Go to the end to download the full example code.
Decision score and predictions based on the nudge mechanism#
RANDOM_SEED = 42
VERBOSE = False
# generate train / test data
from examples.utils.dataset import generate_train_data, generate_test_data
X_train, y_train = generate_train_data(n_normal=100, n_abnormal=20, random_seed=RANDOM_SEED)
X_test, y_test = generate_test_data(n_normal=100, n_abnormal=20, random_seed=RANDOM_SEED*2)
import matplotlib.pyplot as plt
import numpy as np
from pan import ParallelAnomalousNudge
fig, axes = plt.subplots(2, 1, figsize=(10, 10), sharex=True, sharey=True)
axes = axes.flatten()
scores = model.score_samples(X_test)
y_values = [np.ones_like(scores[y_test == 0]), np.ones_like(scores[y_test == 1])]
ax = axes[0]
ax.set_title(rf"Nudged scores and offset calculated based on $\nu={model.nu}$", loc="left")
ax.text(0, .8, s="inlier", va="center", ha="center", fontsize=12, color="white", bbox=dict(color="seagreen", boxstyle='round,pad=.6'), zorder=4)
ax.text(min(scores), .8, s="outlier", va="center", ha="center", fontsize=12, color="white", bbox=dict(color="indianred", boxstyle='round,pad=.6'), zorder=4)
ax.violinplot(scores, positions=[1], vert=False)
ax.scatter(scores[y_test == 0], y=y_values[0], marker="o", edgecolor="k", color="none", s=400, alpha=.75, label="True normal", zorder=2)
ax.scatter(scores[y_test == 1], y=y_values[1], marker="x", color="crimson", s=200, alpha=.75, label="True anomaly", zorder=3)
ax.axvline(model.offset_, 0, 1, color="k", linestyle="--")
ax.text(model.offset_, 1.2, s=rf"$\text{{offset}}={model.offset_:.3}$", va="center", ha="center", fontsize=12, color="white", bbox=dict(color="black", boxstyle='round,pad=.6'), zorder=4)
ax.legend()
ax.margins(.1)
scores = model.decision_function(X_test)
predictions = model.predict(X_test)
y_values = [np.ones_like(scores[predictions == 1]), np.ones_like(scores[predictions == -1])]
ax = axes[1]
ax.set_title(r"Decision scores (shifted nudged scores and offset)", loc="left")
ax.text(-model.offset_, .8, s="Pred 1", va="center", ha="center", fontsize=12, color="white", bbox=dict(color="seagreen", boxstyle='round,pad=.6'), zorder=4)
ax.text(min(scores), .8, s="Pred -1", va="center", ha="center", fontsize=12, color="white", bbox=dict(color="purple", boxstyle='round,pad=.6'), zorder=4)
ax.violinplot(scores, positions=[1], vert=False)
ax.scatter(scores[predictions == 1], y=y_values[0], marker="o", edgecolor="green", color="none", s=200, alpha=.75, label="Normal prediction", zorder=2)
ax.scatter(scores[predictions == -1], y=y_values[1], marker="s", edgecolor="purple", color="none", s=200, alpha=.75, label="Abnormal prediction", zorder=3)
ax.axvline(0, 0, 1, color="k", linestyle="--")
ax.text(0, 1.2, s=r"$\text{decision boundary}=0$", va="center", ha="center", fontsize=12, color="white", bbox=dict(color="black", boxstyle='round,pad=.6'), zorder=4)
ax.legend()
ax.margins(.1)
plt.yticks([])
plt.show()

/home/runner/work/PAN/PAN/examples/demonstrate_07_inspect_predictions.py:41: MatplotlibDeprecationWarning: vert: bool was deprecated in Matplotlib 3.11 and will be removed in 3.13. Use orientation: {'vertical', 'horizontal'} instead.
ax.violinplot(scores, positions=[1], vert=False)
/home/runner/work/PAN/PAN/examples/demonstrate_07_inspect_predictions.py:57: MatplotlibDeprecationWarning: vert: bool was deprecated in Matplotlib 3.11 and will be removed in 3.13. Use orientation: {'vertical', 'horizontal'} instead.
ax.violinplot(scores, positions=[1], vert=False)
Total running time of the script: (0 minutes 0.327 seconds)