การตรวจจับความผิดปกติ (Anomaly Detection) ครั้งที่สองนี้จะใช้กับข้อมูลหลายมิติ เมื่อใช้หลายฟีเจอร์พร้อมกัน เราจะจับความผิดปกติที่มองไม่เห็นจากตัวแปรเดียวได้
1. เตรียมข้อมูลทดลอง #
เพิ่มคอลัมน์ใหม่ให้ข้อมูลเซนเซอร์เดิม เพื่อให้เป็นข้อมูล 2 มิติ
import numpy as np
import pandas as pd
from adtk.data import validate_series
s_train = pd.read_csv("./training.csv", index_col="timestamp", parse_dates=True)
s_train = validate_series(s_train)
# เพิ่มฟีเจอร์ใหม่ (ผสม sin และ cos จากค่าต้นฉบับ)
s_train["value2"] = s_train["value"].apply(lambda v: np.sin(v) + np.cos(v))
s_train.head()
from adtk.visualization import plot
plot(s_train)
2. แนวคิดของการตรวจจับแบบหลายมิติ #
- มิติเดียว จะดู outlier ของฟีเจอร์นั้น ๆ
- หลายมิติ จะดูจุดที่ “ความสัมพันธ์ระหว่างฟีเจอร์” ผิดปกติ
ตัวอย่าง:
valueและvalue2ดูปกติทีละตัว → ปกติ- แต่ความสัมพันธ์ระหว่างสองตัวผิดปกติ → ผิดปกติ
3. วิธีที่ใช้ในตัวอย่าง #
ทดลอง 3 วิธีหลัก
(1) OutlierDetector (LOF) #
ใช้ Local Outlier Factor (LOF)
วัดความหนาแน่นเฉพาะจุดเพื่อบอกว่าเป็น outlier หรือไม่
$$ LOF_k(x) = \frac{\sum_{o \in N_k(x)} \frac{\text{lrd}_k(o)}{\text{lrd}_k(x)}}{|N_k(x)|} $$
\(\text{lrd}\) คือ local reachability density
ค่า LOF สูง → จุดนั้น “โดดเดี่ยว” จากเพื่อนบ้าน
(2) RegressionAD (ความคลาดเคลื่อนจากรีเกรสชัน) #
ทำนายฟีเจอร์หนึ่ง (เช่น value2) จากฟีเจอร์อื่น แล้วใช้ความคลาดเคลื่อนเป็นสัญญาณผิดปกติ
$$ e_t = y_t - \hat{y}_t, \quad |e_t| > c \cdot \sigma \Rightarrow \text{ผิดปกติ} $$
(3) PcaAD (PCA) #
ลดมิติด้วย PCA แล้วมองจุดที่ไม่สามารถอธิบายในมิติลดรูปได้
- แยกองค์ประกอบหลักของเมทริกซ์ \(X\)
- ดูค่าคลาดเคลื่อนหลังการสร้างกลับ $$ | X - X_{\text{reconstructed}} | > \text{threshold} $$
4. โค้ดทดลอง #
import matplotlib.pyplot as plt
from adtk.detector import OutlierDetector, PcaAD, RegressionAD
from sklearn.linear_model import LinearRegression
from sklearn.neighbors import LocalOutlierFactor
model_dict = {
"OutlierDetector": OutlierDetector(LocalOutlierFactor(contamination=0.05)),
"RegressionAD": RegressionAD(regressor=LinearRegression(), target="value2", c=3.0),
"PcaAD": PcaAD(k=2),
}
for model_name, model in model_dict.items():
anomalies = model.fit_detect(s_train)
plot(
s_train,
anomaly=anomalies,
ts_linewidth=1,
ts_markersize=3,
anomaly_color="red",
anomaly_alpha=0.3,
curve_group="all",
)
plt.title(model_name)
plt.show()
5. การแสดงผล #

สรุป #
- การตรวจจับแบบหลายมิติช่วยให้เห็นความผิดปกติที่เกิดจากความสัมพันธ์ของฟีเจอร์
- LOF: ตรวจจากความหนาแน่นเฉพาะจุด
- RegressionAD: ใช้ความคลาดเคลื่อนจากการพยากรณ์
- PCA: ตรวจจากส่วนที่อธิบายด้วยองค์ประกอบหลักไม่ได้
- การพิจารณาความสัมพันธ์หลายฟีเจอร์ช่วยเพิ่มความแม่นยำในงานจริง