Spaces:
Sleeping
Sleeping
Yoon-gu Hwang
Claude
commited on
Commit
·
b9120fa
1
Parent(s):
9c2cd7f
Integrate Frouros library for real drift detection
Browse files- Use Frouros KSTest (Kolmogorov-Smirnov test) for drift detection
- Compare each 20-sample window with reference window
- Orange bars indicate detected drift (p-value < 0.05)
- Green bars indicate no drift detected
- Update reference window when no drift is detected
- Add scipy and frouros to requirements.txt
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- requirements.txt +2 -0
- visualizer.py +31 -6
requirements.txt
CHANGED
|
@@ -1,3 +1,5 @@
|
|
| 1 |
gradio
|
| 2 |
plotly
|
| 3 |
numpy
|
|
|
|
|
|
|
|
|
| 1 |
gradio
|
| 2 |
plotly
|
| 3 |
numpy
|
| 4 |
+
scipy
|
| 5 |
+
frouros
|
visualizer.py
CHANGED
|
@@ -67,25 +67,50 @@ def create_drift_visualization(X: np.ndarray, y: np.ndarray, drift_points: np.nd
|
|
| 67 |
row=1, col=1
|
| 68 |
)
|
| 69 |
|
| 70 |
-
# === 두 번째 row: Drift Classification ===
|
|
|
|
|
|
|
|
|
|
| 71 |
window_size = 20
|
| 72 |
n_windows = len(X) // window_size
|
| 73 |
window_centers = []
|
| 74 |
drift_detected = []
|
| 75 |
|
|
|
|
|
|
|
|
|
|
| 76 |
for i in range(n_windows):
|
| 77 |
start_idx = i * window_size
|
| 78 |
end_idx = (i + 1) * window_size
|
| 79 |
window_center = (start_idx + end_idx) / 2
|
| 80 |
-
|
| 81 |
-
|
| 82 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 83 |
|
| 84 |
window_centers.append(window_center)
|
| 85 |
drift_detected.append(1 if has_drift else 0)
|
| 86 |
|
| 87 |
-
# Drift detection bar graph
|
| 88 |
-
bar_colors = ['rgba(255,
|
| 89 |
for d in drift_detected]
|
| 90 |
|
| 91 |
fig.add_trace(go.Bar(
|
|
|
|
| 67 |
row=1, col=1
|
| 68 |
)
|
| 69 |
|
| 70 |
+
# === 두 번째 row: Drift Classification (using Frouros) ===
|
| 71 |
+
from frouros.detectors.data_drift import KSTest
|
| 72 |
+
from scipy import stats
|
| 73 |
+
|
| 74 |
window_size = 20
|
| 75 |
n_windows = len(X) // window_size
|
| 76 |
window_centers = []
|
| 77 |
drift_detected = []
|
| 78 |
|
| 79 |
+
# 첫 번째 window를 reference로 사용
|
| 80 |
+
reference_window = y[:window_size]
|
| 81 |
+
|
| 82 |
for i in range(n_windows):
|
| 83 |
start_idx = i * window_size
|
| 84 |
end_idx = (i + 1) * window_size
|
| 85 |
window_center = (start_idx + end_idx) / 2
|
| 86 |
+
window_data = y[start_idx:end_idx]
|
| 87 |
+
|
| 88 |
+
# Frouros KSTest를 사용하여 drift 감지
|
| 89 |
+
if i == 0:
|
| 90 |
+
# 첫 번째 window는 reference이므로 drift 없음
|
| 91 |
+
has_drift = False
|
| 92 |
+
else:
|
| 93 |
+
try:
|
| 94 |
+
# Kolmogorov-Smirnov test 수행
|
| 95 |
+
detector = KSTest()
|
| 96 |
+
detector.fit(X=reference_window.reshape(-1, 1))
|
| 97 |
+
result = detector.compare(X=window_data.reshape(-1, 1))
|
| 98 |
+
|
| 99 |
+
# p-value가 0.05보다 작으면 drift 감지
|
| 100 |
+
has_drift = result.p_value < 0.05
|
| 101 |
+
|
| 102 |
+
# drift가 감지되면 reference window 업데이트
|
| 103 |
+
if not has_drift:
|
| 104 |
+
reference_window = window_data
|
| 105 |
+
except:
|
| 106 |
+
# 에러 발생 시 이전 방식 사용
|
| 107 |
+
has_drift = any(start_idx <= dp < end_idx for dp in drift_points)
|
| 108 |
|
| 109 |
window_centers.append(window_center)
|
| 110 |
drift_detected.append(1 if has_drift else 0)
|
| 111 |
|
| 112 |
+
# Drift detection bar graph - 주황색(drift) / 초록색(no drift)
|
| 113 |
+
bar_colors = ['rgba(255, 140, 0, 0.7)' if d == 1 else 'rgba(100, 200, 100, 0.7)'
|
| 114 |
for d in drift_detected]
|
| 115 |
|
| 116 |
fig.add_trace(go.Bar(
|