数学建模社区-数学中国
标题:
数学建模:异常检测算法
[打印本页]
作者:
杨利霞
时间:
2021-7-16 15:24
标题:
数学建模:异常检测算法
& v9 E( ]& D& t* Y+ e& I
数学建模:异常检测算法
8 f4 a4 `/ }, Q1 B! p! f6 e. L
一、简介 – 关于异常检测
$ Y0 c2 D2 q6 L, S( u
异常检测(outlier detection)在以下场景:
1 e0 v' w) e# D& o/ i
" Y$ s, O- [9 i& A* Q
: s6 b" I2 `& o7 N+ g1 I! b/ O2 ~
数据预处理
# Z2 H) A7 T4 n3 N/ B
病毒木马检测
' ^" ~* ?+ l' s* r
工业制造产品检测
" ~0 c) @0 B2 C9 p
网络流量检测
: d; I( T) g! i! _2 u+ B9 N
等等,有着重要的作用。由于在以上场景中,异常的数据量都是很少的一部分,因此诸如:SVM、逻辑回归等分类算法,都不适用,因为:
4 K! ?& [, i4 ~
8 b) b* O* n: p
! k w2 A! ?0 m- ~! F
监督学习算法适用于有大量的正向样本,也有大量的负向样本,有足够的样本让算法去学习其特征,且未来新出现的样本与训练样本分布一致。
" ~1 V# b& } j# h
2 L n: V, o5 P1 l: N4 A
% U: Y: D% R7 n7 p
以下是异常检测和监督学习相关算法的适用范围:
: C" P3 f* \) T t
+ T# f' m* |$ B
, d. R. K. O( J7 t; v4 z4 Z7 {. v0 b
异常检测
' H7 t; _, l! g" H) I0 C
信用卡诈骗
6 }# q: q5 t% {& g6 O4 `' v" h
制造业产品异常检
; N) A% _- M$ G
数据中心机器异常检
3 ?3 C- [) Z0 a# V+ W
入侵检测
" ]* H. o3 C: s; H+ E
监督学习
; |2 L7 q" q( u3 F
垃圾邮件识别
4 X) T" J4 U" c* R6 D9 [3 Q
新闻分类
+ X! K6 P$ w. I- e, M; R. t
二、异常检测算法
1 I- v6 @, m/ l [4 C
4 M! ?+ g; `7 Z
7 E9 f; W, Q c5 X
' Q+ Q. c) c8 r1 y: x" y1 I
: ~" }0 Y9 U% |3 a% B' j
! f0 z6 t3 R f0 C* b% a
; U3 y5 t _# J4 B
import tushare
5 b# E9 Z1 {! ^6 p# N: D- s
from matplotlib import pyplot as plt
: v# \7 V1 X V/ g
& B7 Z: q6 W5 O/ B5 U
df = tushare.get_hist_data("600680")
" n& e; \ }8 s* `
v = df[-90: ].volume
2 g' Z7 v0 `, H0 j# J
v.plot("kde")
8 X9 z8 L# m) ^; u0 E7 K8 c' x
plt.show()
5 D' e/ x' M6 B' _
1
1 l& ^! e' R/ w$ I
2
& P+ X* u+ j) k; q1 l
3
, K$ F$ [; | j. H' G' @2 x/ ]
4
; f" x1 d6 C# i. z, }
5
S* `& i: G# d0 L: o; O% b
6
' s' C& K4 l1 |! _
7
! m: n6 N( Y( f' g8 A
近三个月,成交量大于200000就可以认为发生了异常(天量,嗯,要注意风险了……)
* m; T5 h u8 t p
* e% M8 X& G3 a, K8 Q; R1 B
( g. ]; k h% }4 o; s* P! V# N$ O
( C) [+ m4 V) O: w; n: |% S" g7 _
) K I2 X2 s& q0 O+ O- d; {! L* i
$ C' I8 O& p* H
/ } E1 f% K0 E: X7 j4 {- m
) f7 T' g+ u3 x$ |; l7 H; @
1 }! s% c( t, U' e- c
2. 箱线图分析
. K3 t- m g" {/ ?" N% J, d
import tushare
: K8 f( n9 H5 J
from matplotlib import pyplot as plt
( }: e9 O1 ]' y: d+ H( W) w5 T. K
: b; Z& p3 ~7 f# s* q# t5 J
df = tushare.get_hist_data("600680")
! `( Q8 B! M; e8 ? H
v = df[-90: ].volume
9 q4 X/ V- `% k# o1 S& a( K
v.plot("kde")
; W# ^" \; Z f
plt.show()
: Y d; O" X; @0 s6 o. K# l, P
1
4 J$ J7 W3 X4 G$ j% j% v
2
& }. S4 f9 Y# @8 t0 F( [
3
6 d1 p: f. Q3 S/ m# I8 o6 R2 ^
4
! _$ j7 |9 O G& ~$ s
5
3 g" I3 ?5 O) j( R- N
6
& B+ l7 K2 z' b% L, I) U
7
- G# W0 v+ f9 K( O
' R( u- i, L6 T7 f3 ]7 i
0 A3 U1 [2 r( E8 `' b# @0 X+ v+ h" F
大体可以知道,该股票在成交量少于20000,或者成交量大于80000,就应该提高警惕啦!
, g7 e0 X( V5 q E
3 F! e+ J+ R$ S
5 ?# x9 y& h9 p
3. 基于距离/密度
5 [& z6 z( s: \
典型的算法是:“局部异常因子算法-Local Outlier Factor”,该算法通过引入“k-distance,第k距离”、“k-distance neighborhood,第k距离邻域”、“reach-distance,可达距离”、以及“local reachability density,局部可达密度 ”和“local outlier factor,局部离群因子”,来发现异常点。
P. S2 C9 `. g! ?3 O- O
0 o& }6 K& N: Z; s
0 g& [" m8 w& x: D; e
用视觉直观的感受一下,如图2,对于C1集合的点,整体间距,密度,分散情况较为均匀一致,可以认为是同一簇;对于C2集合的点,同样可认为是一簇。o1、o2点相对孤立,可以认为是异常点或离散点。现在的问题是,如何实现算法的通用性,可以满足C1和C2这种密度分散情况迥异的集合的异常点识别。LOF可以实现我们的目标。
! ^$ v2 p4 k; c3 X9 I) {0 X
7 k8 R. k/ @9 z& G% K
- r/ \" I7 |: `
X9 Z1 @9 t. N. K* H
" e) U0 g. b5 w5 t. K0 O% ~1 P1 C
2 ^9 z: w: [ I' j" H
; j# Z1 i7 h' S1 A, G8 N( C
$ O6 [; b+ h: C/ O/ F: ~1 u6 |
4 }) t- h% ]1 r' H+ g
4. 基于划分思想
6 T9 i& v& L% f2 s) s0 p O7 H
典型的算法是 “孤立森林,Isolation Forest”,其思想是:
5 z7 x1 }( w8 k1 l3 x3 X4 z
8 i" J) Q! }8 m9 H
- F+ K" ]. f0 P8 {6 ]- f, d
假设我们用一个随机超平面来切割(split)数据空间(data space), 切一次可以生成两个子空间(想象拿刀切蛋糕一分为二)。之后我们再继续用一个随机超平面来切割每个子空间,循环下去,直到每子空间里面只有一个数据点为止。直观上来讲,我们可以发现那些密度很高的簇是可以被切很多次才会停止切割,但是那些密度很低的点很容易很早的就停到一个子空间了。
5 F* u! e0 ]- U' h/ l" N
5 P# t) }. ?5 |0 `
, E4 c* U* v2 U% Z, P
这个的算法流程即是使用超平面分割子空间,然后建立类似的二叉树的过程:
, l3 m2 {. P; J
?; T2 W1 S; _
7 ?5 `& z- T0 E% _" I9 v( |
import numpy as np
$ T/ {, V+ u+ [% `8 ~% L& U
import matplotlib.pyplot as plt
/ N; j+ @1 V' [* _( r
from sklearn.ensemble import IsolationForest
! _" |# \* i' F/ _/ t4 l: ?4 G& F
$ b/ z8 C; c, D6 R! Q: N2 H. E
) ?4 g0 M- U& ] Y) X
rng = np.random.RandomState(42)
8 G' k* F& q9 p1 g4 I
, {, A# d# m! _4 o5 v
" H3 j* Q' J# O" g$ G0 |, w( ~/ O
# Generate train data
) o2 [4 x; h1 k/ c" F( D: U( P2 Y2 D
X = 0.3 * rng.randn(100, 2)
; z" v- p; `: y3 j0 _
X_train = np.r_[X + 1, X - 3, X - 5, X + 6]
, F( ]8 L1 L3 e5 l9 j2 F5 {
# Generate some regular novel observations
- \, E, o* P Y+ \
X = 0.3 * rng.randn(20, 2)
3 R) @ d$ Y* q; A- n9 A
X_test = np.r_[X + 1, X - 3, X - 5, X + 6]
+ t) ]% M7 o B+ v; |
# Generate some abnormal novel observations
5 h' P% \$ U% }0 o
X_outliers = rng.uniform(low=-8, high=8, size=(20, 2))
) ]" ~& D9 U2 k/ x6 @) C8 p+ d
( E( f ~+ R) L4 a+ U/ w+ h! m) J( D
+ p, F6 C& |# c; }8 `
# fit the model
0 ]2 j7 P4 U7 K: r+ @
clf = IsolationForest(max_samples=100*2, random_state=rng)
0 h( @0 k+ U* g; f6 e+ j6 a* _
clf.fit(X_train)
5 S! w0 @+ ~% K& o" z/ {3 U
y_pred_train = clf.predict(X_train)
0 b: n* G2 o* ~ \ f* N% r$ L
y_pred_test = clf.predict(X_test)
7 H: j p2 \. |* ^. J" i
y_pred_outliers = clf.predict(X_outliers)
# o. e& Q7 ]5 ^& ~; M
9 I, G) C! y; c4 H
6 n7 S" m9 m1 ~1 w9 G4 d, q4 m% X
# plot the line, the samples, and the nearest vectors to the plane
( w. t! G9 n" ^0 \7 J/ i1 K
xx, yy = np.meshgrid(np.linspace(-8, 8, 50), np.linspace(-8, 8, 50))
' v: Z! [/ a; @, f5 O/ u
Z = clf.decision_function(np.c_[xx.ravel(), yy.ravel()])
5 `; ?1 B0 h$ q* O' |' M
Z = Z.reshape(xx.shape)
2 b7 ]7 e5 V4 u# K
+ I( n( a. N$ U- j5 I
) k2 T* d7 a. E, c5 x M. u
plt.title("IsolationForest")
, i1 F% \. w& _. s
plt.contourf(xx, yy, Z, cmap=plt.cm.Blues_r)
6 k9 z$ K5 T/ a
5 s4 k0 W2 _+ t" j2 B" Z4 z2 E& r
5 @1 W5 Q2 p1 x1 E1 @+ P9 B
b1 = plt.scatter(X_train[:, 0], X_train[:, 1], c='white')
3 A8 ~4 } C. ~
b2 = plt.scatter(X_test[:, 0], X_test[:, 1], c='green')
" A& T8 R: u9 ~- e4 C
c = plt.scatter(X_outliers[:, 0], X_outliers[:, 1], c='red')
- z' R8 P, C2 ~8 Z3 m* [( @
plt.axis('tight')
6 O9 _" g$ u# w1 [( I, f
plt.xlim((-8, 8))
+ m" k0 W, R7 c7 ^, D
plt.ylim((-8, 8))
8 @: M2 a$ I, o
plt.legend([b1, b2, c],
; p, X [) S2 g$ F$ o
["training observations",
8 A0 V3 d, ^8 | Y3 e
"new regular observations", "new abnormal observations"],
4 N) W# K, P( b" J9 Y2 S
loc="upper left")
) p) e. V3 I+ H' a4 v2 C- h
plt.show()
& s+ ?! E2 c- l% R# [$ D
1
/ S0 E2 [* S/ ]: c" r- d
2
1 n+ G2 ~4 \3 x/ ^7 E
3
7 y7 w- } k" I( I. H
4
; x% t/ W+ f. y/ P+ g
5
" Q0 X2 x- S6 v8 i
6
3 c+ [, k9 U( k- n; q% y$ x/ @
7
' p7 A3 ~! `# z) a6 U V
8
: f& m+ f+ [/ Z+ b5 e
9
1 [* T2 z, y! S7 v' [' T) X9 u+ P# ~
10
) e8 W# `5 v5 Q! K( l/ s
11
2 A n/ Y( m2 T* M; D1 b! G
12
- f6 Y8 f9 K1 ?' k
13
' }( H# v/ e0 c
14
! u% P! j9 y; A1 p0 _) r) c
15
& X1 i: W" a1 h* s
16
- ?8 `* |, Z. X3 l. j
17
. ~1 r' b. B$ y4 E6 t1 g# I5 s; c# b. R
18
( c* |' U& t( B9 }/ Z; O
19
8 b- Z2 ?" ^% h$ i% a' X/ n( z! \
20
! h$ z) N4 m+ E
21
0 k* n1 r- k/ T$ X9 U! Y
22
6 B2 a# y0 }' Q6 r* o
23
5 N- l! m; |# v# f
24
( T; y- j: n5 z- |6 _5 G. P
25
. I8 `, i2 w: Q/ E2 C/ ~1 o8 N
26
: w! M2 Y/ s% Q; F& {/ f# G
27
# I7 C8 W9 Q% d" x1 p
28
5 l+ @, S, w% |) S3 E# J; h8 w
29
/ s* r% J+ K- [7 s, U( |+ i2 R4 Y$ t* a
30
$ }& S# U6 g: e5 u
31
6 e" A4 d# t" J
32
1 e- p; f' {" r" K. M' v* N
33
7 r7 i i, q( w; }. I* f
34
4 G% }: E {& g2 b" `
35
Z+ f, q. ^* |1 f0 ^
36
$ ~' d6 f% r! k* s) i
37
4 N# i' L( v3 `1 Q4 F4 C
38
0 F; f7 [$ g6 N
39
( e6 N/ { `0 k6 j
40
- K0 O2 {* R A# u3 z3 l8 `5 ^( I
41
' S( P& {8 f4 a
& m; {! ?/ |+ b# \5 z/ L6 g& S( D
- c8 v: Z. \* _$ G3 f# F! R, K0 ]
————————————————
5 u' m* ^8 s' W c( @) X
版权声明:本文为CSDN博主「数模实验室-教你学建模」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
! X+ n5 ^2 y& ~
原文链接:https://blog.csdn.net/weixin_50732647/article/details/112023129
) p- n* n# v% ~+ h, P) M/ a
# Q8 b. s2 |+ r5 w" r+ E# ^) y
# L7 ]% a$ i0 ^) W9 l. Q/ S( {
欢迎光临 数学建模社区-数学中国 (http://www.madio.net/)
Powered by Discuz! X2.5