總結來說:html
1. 在異常檢測中,異常點是少之又少,大部分是正常樣本,異常只是相對小几率事件 2. 異常點的特徵表現很是不集中,即異常種類很是多,千奇百怪。直白地說:正常的狀況大同小異,而異常各不相同。這種狀況用有限的正例樣本(異常點)給有監督模型學習就很難從中學到有效的規律
這塊主要依靠龐大的打標樣本,藉助像DLearn這樣的網絡對打標訓練樣本進行擬合python
有幾種方法能夠幫助咱們儘量地去獲取到更多打標的安全攻擊/入侵事件linux
1. 本身構造攻擊數據(Inject fake malicious data into data storage) 2. 利用MFS/POWERSLPOIT等工具採集攻擊日誌(Employ commonly used attack tools) 3. 紅藍滲透測試團隊參與測試,而後抓取日誌(Red team manually pen-tests) 4. 簡單保守規則: 面對一類檢測問題,大多數狀況下是這樣的狀況: 80%的分類很是明顯,甚至肉眼都能看出,對這類問題只要採起保守策略應用一些簡單粗暴的正則/統計規則便可將異常找出來,對這部分樣本,在收集打標樣本的時候能夠稍微放寬規則,儘量地獲取多的打標正例樣本 5. 樣本擴增(Synthetic Minority Oversampling Technique (SMOTE)): 咱們能夠理解爲SMOTE對不平衡的數據集分配了不一樣的權重,爲了彌補數據集中出現概率較小的那部分數據集對訓練過程的影響,它每每會在過程當中屢次重複地抽取那部分小樣本集來參與訓練,從而必定程度上彌補數量少帶來的問題
Relevant Link:git
https://software.oreilly.com/learning/strategies-to-validate-your-security-detections?log-in http://contrib.scikit-learn.org/imbalanced-learn/auto_examples/index.html#dataset-examples https://en.wikipedia.org/wiki/Oversampling_and_undersampling_in_data_analysis https://en.wikipedia.org/wiki/Undersampling https://github.com/scikit-learn-contrib/imbalanced-learn https://www.jair.org/media/953/live-953-2037-jair.pdf https://gerardnico.com/wiki/data_mining/anomaly_detection
對於進程異常事件來講,白樣本很好獲取,直接根據全量進程事件group by,取top 5000的事件,幾乎100%都是正常進程事件,由於偶發性的攻擊事件和龐大的正常運維事件來講只是佔很小的一部分。黑樣本的獲取就是一個相對來講的難題了,咱們只能根據已知的攻防經驗總結出一些攻擊場景化的異常事件模型來提供黑樣本,而後儘量地去提升神經網絡模型的泛化能力github
在進程事件中,可能會遇到中文等特殊字符,對於這個問題,個人思路過程是這樣的web
1. 採用ascii 0 - 255編碼,這樣個人字符維度只有256,可是對非ascii字符只能歸一化爲"*"星號,這是一種"失真降維",即丟失了一部分原始輸入字符串的信息 2. 採用utf-8編碼,那樣全部的字符均可以獲得有效的編碼化,可是帶來一個更嚴重的問題是,由於大多數的進程事件字符串都是純英文的,而僅僅有少數的非ascii參雜其中,因此咱們用utf8編碼化後,整個進程事件字符串vector出現了很明顯的"稀疏特性",這種稀疏特性嚴重影響了後面神經網絡模型對細節特徵的提取
因此最終我把非ascii字符都編碼爲了星號算法
def sequence(string,maxlen=200): tokens = [] for c in string: if not c in printable: tokens.append(printable.index("*")) tokens.append(printable.index(c)) tokens = tokens[-maxlen:] if len(tokens) < maxlen: tokens = [0]*(maxlen-len(tokens))+tokens return tokens
在代碼中能夠看到,對長度不足的字符串也進行了padding處理sql
模型的第一層是一個帶raw input length歸一化的詞向量嵌入模型,咱們將咱們的輸入(進程事件字符串: 父進程 + 子進程命令行)歸一化後,截斷/padding爲一個定長的s length字符串,而後投影到一個32維度的emberding空間中,在這個32維的emberdding空間中,字符串中的每個字符都表明了一個向量(v1, v2, ...v32),從而整個輸入字符串被轉化爲了一個s x 32的張量,張量能夠理解爲一個多位數組shell
Embedding layer is optimized jointly with the rest of the model through backpropagation, optimizing the individual characters’ embedding vectors to be more reflective of their semantic meaning, resulting in pairs of semantically similar characters being embedded closer to each other if they have similar attributes編程
emberdding詞向量嵌入層在以後的模型train過程當中,也會接收到BP反向傳播帶來的影響,從而不斷調整詞向量參數,最終的效果是使得emberding中的詞向量權重更加擬合訓練集,同一方向的詞序列更加切進一個個有意義的進程事件,例如
1. 造成有意義的windows、linux盤符 2. 造成有意義的進程名 3. 造成有意義的指令字符串
In our implementation we set s = 200(輸入進程事件字符串定長200) and m = 32(emberding維度32維)
def sum_1d(X): return K.sum(X, axis=1) def getconvmodel(filter_length,nb_filter): model = Sequential() model.add(Convolution1D(nb_filter=nb_filter, input_shape=(200,32), filter_length=filter_length, border_mode='same', activation='relu', subsample_length=1)) model.add(Lambda(sum_1d, output_shape=(nb_filter,)))
這裏咱們對(200, 32)的第二個維度,即emberdding 32維度進行了sumup降維
Relevant Link:
https://www.zhihu.com/question/51325408?from=profile_question_card
到了這一層,咱們的輸入數據是一個s(200) x m(32)矩陣,咱們接下要要利用深度神經網絡來自動實現特徵提取
特徵提取階段咱們主要有2種結構組成
1. CNN卷積層: 1) 4個不一樣濾波窗口size的CNN卷積層(修正線性relu激活函數): Conv(np_filters=256, kernel_size=2/3/4/5, step_size=1) 2) sum: 根據emberdding降維 3) Dropout(0.5): 防止過擬合 2. SumPool: aggregate the results across the entire sequence by summing the kernels’ activations using SumPool K.sum(X, axis=1): 沿着emberdding的維度進行降維求和 sumup降維後的結果是一個 s(200) x vector(4 * 256 = 1024)的matrix,即每一個向量是1024 verctor
注意到這裏有4個不一樣np_filters的CNN,分別用size = 2/3/4/5長度的領域濾波去提取特徵
而且這裏使用了多輸入的函數式編程,將4層不一樣濾波窗口大小的CNN進行merge操做,這個模型的損失函數將由4部分共同組成,這樣作的好處是最大程序地提取並反映出原始輸入數據的細節特徵,即便其中一個損失函數的梯度發生彌散,來自其餘CNN的損失函數的信息也可以訓練Embeddding和CNN層。這體現了一種良好的正則化思想
在繼續往下闡述以前,咱們來稍微花一些時間計算一下這個merge CNN層的神經元個數 =
(200 - 2 + 1) * (32 - 2 + 1) * 256 + (200 - 3 + 1) * (32 - 3 + 1) * 256 + (200 - 4 + 1) * (32 - 4 + 1) * 256 + (200 - 5 + 1) * (32 - 5 + 1) * 256 = 5967360
CNN層的輸出爲1024維
這裏咱們來總結一下這樣設計神經網絡模型背後的意義
1. 每一個卷積濾波器(不一樣kernel_szie)負責檢測一組不一樣的類似序列模式,並經過sum_up其激活值獲得一個最終的序列模式 2. 類比於圖像濾波獲得的像素紋理,若是咱們用ascii的角度來看咱們的文本字符串,這裏學習到的特徵本質也是一種"文本紋理" 咱們獲得了這些模式發生的程度 3. 選擇CNN的另外一個好處在於"特徵子序列"能夠出如今字符串中的任何位置,還依然可以被卷積檢測到
規範化的目的是解決樣本量不足的問題,同時加速收斂、控制過擬合、能夠少用或不用Dropout和正則、下降網絡對初始化權重不敏感 、容許使用較大的學習率
能夠選擇使用層級別(layer wise)的BatchNormalization或者Dropout
使用fully connected Dense層來進行分類判斷邏輯
每層的結構以下
middle = Dense(1024,activation='relu')(main_input) middle = Dropout(0.5)(middle) middle = BatchNormalization()(middle) middle = Dense(1024,activation='relu')(main_input) middle = Dropout(0.5)(middle) middle = BatchNormalization()(middle) output = Dense(1,activation='sigmoid')(middle) model = Model(input=main_input,output=output) model.compile(loss='binary_crossentropy', optimizer=optimizer) return model
在梯度降低算法中,咱們尋則了adam算法,Adam能夠理解爲momutum SGD和RMSPROP的綜合改進版本,同時引入了動態調整特性以及動量V特性。Adam(Adaptive Moment Estimation)本質上是帶有動量項的RMSprop,它利用梯度的一階矩估計和二階矩估計動態調整每一個參數的學習率。Adam的優勢主要在於通過偏置校訂後,每一次迭代學習率都有個肯定範圍,使得參數比較平穩。公式以下
Relevant Link:
https://keras-cn.readthedocs.io/en/latest/layers/normalization_layer/ https://github.com/joshsaxe/eXposeDeepNeuralNetwork/blob/master/src/modeling/models.py http://keras-cn.readthedocs.io/en/latest/layers/convolutional_layer/ http://www.cnblogs.com/LittleHann/p/6629069.html https://arxiv.org/pdf/1702.08568.pdf
paper的主要設計思想是根據已有的異構事件數據,包括
1. 進程對文件的操做: 讀/寫文件 2. 進程對SOCKET的操做
從這些異構數據源抽象出一種表明了information flow(數據流動)的event事件,每一個event都關聯了兩個實體entity,分別表明sender/reveiver的角色,例如
1. vim 1.txt:entityA(FILE) flow-> entityB(PROCESS) 2. http request:entityC(PROCESS) flow-> entityD(ISOCKET)
在生成graph的訓練初期,須要先根據主機進程的歸約性規律(進程能夠打開文件(文件信息流到進程中)、進程寫入文件(進程信息流到文件中)、進程不能打開進程),以及時間順延序列來生成一些"候選路徑",全部的候選路徑生成一張有向無環圖
接下來對全部路徑上的每一條變edge,都計算sender/receiver的分值,每一個有向edge的分值由訓練樣本中的該flow event發生的總時間窗口決定
舉例來講,若是/usr/bn/httpd write /var/log/access.log是一個高頻詞事件,則該事件所表明的edge在整個訓練集中的T(時間窗口)就會較大,相對的它的機率也較大,這也暗示着它是一個常規事件
而像vim /etcpasswd這種低頻次事件,在訓練樣本集中就應該較少出現,反過來,這個事件的abnormal score就要越高
經過這種方法,咱們基於訓練集獲得的事件information flow graph,來評估新的樣本事件中哪些是疑似可疑事件,可是這裏要注意的一個問題是,long term event sequence和short term event sequence的歸一化,爲了防止長序列的事件序列累加獲得的異常分值太高問題,咱們須要將全部分值根據path length進行歸一化
Relevant Link:
https://arxiv.org/pdf/1608.02639.pdf https://github.com/corbinmcneill/Graph-Based-Network-Intrusion-Detection/tree/master/mr_code/GraphCreation/src/graphcreator http://www.freepatentsonline.com/20160330226.pdf http://www.freepatentsonline.com/y2016/0330226.html
相關討論可參閱這篇文章
Relevant Link:
https://github.com/jnasante/IDS
iForest算法用於挖掘異常(Anomaly)數據,或者說離羣點挖掘,是在一大堆數據中,找出與其它數據的規律不太符合的數據,異常數據的兩個特徵(少且不一樣: few and different)
1. 異常數據只佔不多量; 2. 異常數據特徵值和正常數據差異很大
iForest 適用與連續數據(Continuous numerical data)的異常檢測,將異常定義爲「容易被孤立的離羣點 (more likely to be separated)」——能夠理解爲分佈稀疏且離密度高的羣體較遠的點。用統計學來解釋,在數據空間裏面,分佈稀疏的區域表示數據發生在此區域的機率很低,於是能夠認爲落在這些區域裏的數據是異常的
iForest屬於Non-parametric(無參數反饋調整訓練)和unsupervised(無監督)的方法,即不用定義數學模型也不須要有標記的訓練。
對於如何查找哪些點是否容易被孤立(isolated),iForest使用了一套很是高效的策略。、
假設咱們用一個隨機超平面(某一個維度切面)來切割(split)數據空間(data space), 切一次能夠生成兩個子空間(想象拿刀切蛋糕一分爲二)。以後咱們再繼續用一個隨機超平面來切割每一個子空間,循環下去,直到每子空間裏面只有一個數據點爲止。
直觀上來說,咱們能夠發現那些密度很高的簇是能夠被切不少次纔會中止切割,可是那些密度很低的點很容易很早的就停到一個子空間了。
上圖裏面,紅色點(離羣點),就很容易被切幾回就停到一個子空間,而白色/綠色的點(高頻正常點) 須要切不少次才中止。
怎麼來切這個數據空間是iForest的設計核心思想,因爲切割是隨機的,因此須要用ensemble的方法來獲得一個收斂值(蒙特卡洛方法),即反覆從頭開始切,而後平均每次切的結果。iForest 由t個iTree(Isolation Tree)孤立樹 組成,每一個iTree是一個二叉樹結構,其實現步驟以下:
1. 初始化IsolationForest的時候須要指定樹(tree)的數量,實驗發現,在100顆樹的時候,路徑的長度就已經覆蓋得比較好了,所以選100顆也就夠 2. 對於每一棵樹,咱們都重複如下過程 1) 從訓練數據中隨機選擇Ψ個點樣本點做爲subsample(通常是無放回抽樣),放入樹的根節點。樣,是爲了更好的將正常數據和異常數據分離開來。有別於其它模型,採樣數據越多,反面會下降iForest識別異常數據的能力。由於,一般使用256個樣本,這也是scikit-learn實現時默認使用的採樣數 2. 咱們的輸入樣本多是高維空間的向量數據,隨機指定一個維度(attribute)(一棵tTree建樹過程當中的每一輪切分選取的維度均可能不同),在當前節點數據中的這個維度(從這個維度的超平面去切)上的值計算[min, max],從[min, max]中隨機產生一個切割點p,切割點產生於當前節點數據中指定維度的最大值和最小值之間,至關於用一個超平面去對當前節點的數據集進行切割 3) 以此切割點生成了一個超平面,而後將當前節點數據空間劃分爲2個子空間 3.1) 把指定維度裏小於p的數據放在當前節點的左孩子 3.2) 把大於等於p的數據放在當前節點的右孩子 4) 在孩子節點中遞歸步驟2和3,不斷構造新的孩子節點,直到 孩子節點中只有一個數據(沒法再繼續切割) 或 孩子節點已到達限定高度(例如: log2(ψ)) 3. 得到t個iTree以後,iForest 訓練就結束,而後咱們能夠用生成的iForest來評估測試數據了
能夠看到,咱們在C語言課上學的二叉樹排序算法,本質上就是一個1-d向量數據的tTree建樹過程,可是在大數據分析中,高維/超高維數據是很常見的狀況,所以咱們才須要在建二叉樹的過程當中隨機地選取不一樣維度的超平面(隨機森林思想)進行二分分類。我我的對iForest算法背後體現的思想的理解是這樣的
# 先用1-d維數據點說明 擺在咱們面前有大堆大小不等的小球,例若有: [6, 6.1, 6.2, 5.9, 5.8, 6.3, 6.4, 6.5, 33]這些大小直徑的小球,咱們拿到的任務是把這些小球儘可能地去平分爲大小相同的堆,若是分到最後一堆中只剩一個球了,就中止分類。 咱們發現從這裏面隨機選取一個值做爲切分點,例如5.9,則33馬上就被分到"大於切分點"那一類,而且在第一輪就中止了分類,這體現的是若是輸入樣本數據中孤立點是"少且數值突兀的",則這類數據點有更大的可能在很短的時間內中止切分。 咱們還注意到一點,因爲孤立點是偶發小比例的數值點,則在隨機選擇切分點的時候,孤立點有更大的概率被選在切分點的另外一側,從而中止分類 # >=2維數據點 高維數據的狀況要更復雜一些,在一個廣場上有一大羣人,它們每一個人都有3個屬性(即3個維度): [膚色, 年齡, 性別],咱們假設廣場上大部分都是白種人,21-22歲之間的年輕女性,可是其中混雜了2個黑人男性,分別是21歲和23歲。 咱們隨機選取其中一個維度: 膚色,而後大喊一聲,白種人站左邊,黑種人站右邊。這時那2個黑人男性就馬上被分類到了右子樹。 在第二輪的分類中,咱們選取年齡做爲超平面切分,選擇22歲最爲切分點,這時左子樹中又進行了一次切分,右子樹的那2個黑人男性被分紅了2顆葉子,而且中止了繼續的切分 能夠看到,只要輸入數據自己確實存在孤立離羣特性,這這些數據點有"更大的機率被儘早的分到葉子中"
得到t個iTree以後,iForest 訓練就結束,而後咱們能夠用生成的iForest來評估測試數據了。對於一個輸入數據x,咱們令其遍歷每一棵iTree,而後計算x最終落在每一個樹第幾層(x在樹的高度)。而後咱們能夠得出x在每棵樹的高度平均值,即 the average path length over t iTrees。
得到每一個測試數據的average path length後,咱們能夠設置一個閾值(邊界值)
1. average path length 低於此閾值的測試數據即爲異常。也就是說 「iForest identifies anomalies as instances having the shortest average path lengths in a dataset 」(異常在這些樹中只有很短的平均高度). *值得注意的是,論文中對樹的高度作了歸一化,得出一個0到1的數值 1) 若是分數越接近1,其是異常點的可能性越高 2) 若是分數都比0.5要小,那麼基本能夠肯定爲正常數據 3) 若是全部分數都在0.5附近,那麼數據不包含明顯的異常樣本 2. 未歸一化前,樣本在森林中平均高度越高,則說明該數據有越大可能屬於
4個測試樣本遍歷一棵iTree的例子以下
b和c的高度爲3,a的高度是2,d的高度是1。能夠看到d最有多是異常,由於其最先就被孤立(isolated)了
生成一棵iTree的詳細算法
X爲獨立抽取的訓練樣本。參數e的初始值爲0。h是樹能夠生成的最大高度。iForest算法默認參數設置以下
subsample size: 256 Tree height: 8 Number of trees: 100
code
# -*- coding: utf-8 -*- import numpy as np import matplotlib.pyplot as plt from sklearn.ensemble import IsolationForest pointerDim = 2 rng = np.random.RandomState(42) # Generate train data X = 0.3 * rng.randn(256, pointerDim) # 100 2-d pointer #print X # 獲得一個相對距離爲4個族羣 X_train = np.r_[X + 2, X - 2] # Generate some regular novel observations # 測試集和訓練集採用一樣的方法產生2個族羣 X = 0.3 * rng.randn(52, pointerDim) # 20 2-d poineter X_test = np.r_[X + 2, X - 2] # Generate some abnormal novel observations # 隨機產生20個[-4,4]隨機點 X_outliers = rng.uniform(low=-4, high=4, size=(52, pointerDim)) # fit the model clf = IsolationForest(max_samples=100, random_state=rng) clf.fit(X_train) # clf.predict直接返回iForest對數據點的"離羣"判斷結果 y_pred_train = clf.predict(X_train) y_pred_test = clf.predict(X_test) y_pred_outliers = clf.predict(X_outliers) print "y_pred_train" print y_pred_train print "y_pred_test" print y_pred_test print "y_pred_outliers" print y_pred_outliers # plot the line, the samples, and the nearest vectors to the plane # 構建整個50 * 50的網格點 xx, yy = np.meshgrid(np.linspace(-5, 5, 50), np.linspace(-5, 5, 50)) print "np.c_[xx.ravel(), yy.ravel()]" print np.c_[xx.ravel(), yy.ravel()] # 不直接進行預測,只讓模型輸出異常分值 Z = clf.decision_function(np.c_[xx.ravel(), yy.ravel()]) print "len(Z)" print len(Z) print "Z[0]" print Z[0] print "xx.shape" print xx.shape # 將2500-d異常分值vector拉伸爲50 * 50的異常分值matrix Z = Z.reshape(xx.shape) print "Z" print Z plt.title("IsolationForest") # 這裏只是將整個50 * 50網格化,並計算每個點和聚類中心的相關度(離羣指數),越靠近同一類,類似度越高,分值越高,顏色越淡; plt.contourf(xx, yy, Z, cmap=plt.cm.Blues_r) b1 = plt.scatter(X_train[:, 0], X_train[:, 1], c='white') b2 = plt.scatter(X_test[:, 0], X_test[:, 1], c='green') c = plt.scatter(X_outliers[:, 0], X_outliers[:, 1], c='red') plt.axis('tight') plt.xlim((-5, 5)) plt.ylim((-5, 5)) plt.legend([b1, b2, c], ["training observations", "new regular observations", "new abnormal observations"], loc="upper left") plt.show()
Relevant Link:
http://www.jianshu.com/p/1b020e2605e2 https://zhuanlan.zhihu.com/p/25040651 http://www.tk4479.net/ssw_1990/article/details/71436714 http://qf6101.github.io/machine%20learning/2015/08/01/Isolation-Forest http://www.17bigdata.com/%E5%BC%82%E5%B8%B8%E6%A3%80%E6%B5%8B%E7%AE%97%E6%B3%95-isolation-forest.html http://scikit-learn.org/stable/auto_examples/ensemble/plot_isolation_forest.html#sphx-glr-auto-examples-ensemble-plot-isolation-forest-py
one-class SVM特別適合黑白樣本嚴重不平衡的檢測場景下,例如安全入侵檢測中,白樣本數量很是多且很容易獲得,可是表明異常事件的黑樣本自己就不多(入侵是偶發事件)且即便是有限的黑樣本也強依賴安全人員的分析經驗來經過正則規則的方式緩慢積累
one-class svm針對白樣本進行聚類,獲得一個分類邊界。即one-class svm主要學習的是儘量地學習到白樣本的邊界,而後以後預測時採起"非黑即白"的策略,將邊界外的標記爲可疑樣本
# -*- coding: utf-8 -*- import numpy as np import matplotlib.pyplot as plt import matplotlib.font_manager from sklearn import svm if __name__ == '__main__': xx, yy = np.meshgrid(np.linspace(-5, 5, 500), np.linspace(-5, 5, 500)) # Generate train data X = 0.3 * np.random.randn(100, 2) X_train = np.r_[X + 2, X - 2] # Generate some regular novel observations X = 0.3 * np.random.randn(20, 2) X_test = np.r_[X + 2, X - 2] # Generate some abnormal novel observations X_outliers = np.random.uniform(low=-4, high=4, size=(20, 2)) # fit the model clf = svm.OneClassSVM(nu=0.1, kernel="rbf", gamma=0.1) clf.fit(X_train) y_pred_train = clf.predict(X_train) y_pred_test = clf.predict(X_test) y_pred_outliers = clf.predict(X_outliers) n_error_train = y_pred_train[y_pred_train == -1].size n_error_test = y_pred_test[y_pred_test == -1].size n_error_outliers = y_pred_outliers[y_pred_outliers == 1].size # plot the line, the points, and the nearest vectors to the plane Z = clf.decision_function(np.c_[xx.ravel(), yy.ravel()]) Z = Z.reshape(xx.shape) plt.title("Novelty Detection") plt.contourf(xx, yy, Z, levels=np.linspace(Z.min(), 0, 7), cmap=plt.cm.PuBu) a = plt.contour(xx, yy, Z, levels=[0], linewidths=2, colors='darkred') plt.contourf(xx, yy, Z, levels=[0, Z.max()], colors='palevioletred') s = 40 b1 = plt.scatter(X_train[:, 0], X_train[:, 1], c='white', s=s) b2 = plt.scatter(X_test[:, 0], X_test[:, 1], c='blueviolet', s=s) c = plt.scatter(X_outliers[:, 0], X_outliers[:, 1], c='gold', s=s) plt.axis('tight') plt.xlim((-5, 5)) plt.ylim((-5, 5)) plt.legend([a.collections[0], b1, b2, c], ["learned frontier", "training observations", "new regular observations", "new abnormal observations"], loc="upper left", prop=matplotlib.font_manager.FontProperties(size=11)) plt.xlabel( "error train: %d/200 ; errors novel regular: %d/40 ; " "errors novel abnormal: %d/40" % (n_error_train, n_error_test, n_error_outliers)) plt.show()
one-class svm對數據集數量、數據是否歸一化、核函數參數選擇都很是敏感,調優的過程須要仔細的思考和不斷地嘗試
SVM模型有兩個很是重要的參數C與gamma
1. C是懲罰係數,即對偏差的寬容度 1) c越高,說明越不能容忍出現偏差,可是容易過擬合 2) C越小,容易欠擬合 3) C過大或太小,泛化能力變差 2. gamma是選擇RBF函數做爲kernel後,該函數自帶的一個參數。隱含地決定了數據映射到新的特徵空間後的分佈 1) gamma越大,支持向量越少,運算速度越快 2) gamma值越小,支持向量越多 3) 支持向量的個數影響訓練與預測的速度
RBF公式裏面的sigma和gamma的關係以下
gamma的物理意義是RBF(高斯核)的幅寬,它會影響每一個支持向量對應的高斯的做用範圍,從而影響泛化性能
若是gamma設的太大,會很小,
很小的高斯分佈長得又高又瘦, 會形成只會做用於支持向量樣本附近,對於未知樣本分類效果不好(過擬合)
若是gamma設的太小,會很大,則會形成平滑效應太大,沒法在訓練集上獲得特別高的準確率,也會影響測試集的準確率。
RBF核應該能夠獲得與線性核相近的效果(按照理論,RBF核能夠模擬線性核),可能好於線性核,也可能差於,可是,不該該相差太多。
固然,不少問題中,好比維度太高,或者樣本海量的狀況下,你們更傾向於用線性核,由於效果至關,可是在速度和模型大小方面,線性核會有更好的表現。
Relevant Link:
http://rvlasveld.github.io/blog/2013/07/12/introduction-to-one-class-support-vector-machines/ http://scikit-learn.org/stable/auto_examples/svm/plot_oneclass.html#sphx-glr-auto-examples-svm-plot-oneclass-py https://thisdata.com/blog/unsupervised-machine-learning-with-one-class-support-vector-machines/ http://kdd.ics.uci.edu/databases/kddcup99/kddcup99.html http://blog.sina.com.cn/s/blog_6a41348f0101ep7w.html http://blog.sina.com.cn/s/blog_57a1cae80101bit5.html http://blog.csdn.net/bryan__/article/details/51506801 http://scikit-learn.org/stable/auto_examples/svm/plot_rbf_parameters.html
無論咱們的特徵集合中有多少特徵,一元高斯分佈模型要求咱們「一次一個」進行「特徵變量異常分析」。
正態分佈又名高斯分佈,是一個在數學,物理以及工程等領域都很是重要的機率分佈。因爲這個分佈函數有不少漂亮的性質,使得其在諸多設計統計科學離散科學等許多領域都有着重大的影響力。
若隨機變量X服從一個位置參數爲 μμ 尺度參數爲 σσ 的機率分佈,記爲:
則其機率密度函數爲
正態分佈的數學指望值或指望值 μ 等於位置參數,決定了分佈的位置;
其方差 σ2 的開平方或標準差 σ 等於尺度參數,決定了分佈的幅度。
不一樣參數的正態分佈圖:
1. 密度函數關於平均值對稱 2. 函數曲線下68.268949%的面積在平均數左右的一個標準差 σ 範圍內。 3. 函數曲線下95.449974%的面積在平均數左右兩個標準差 2σ 的範圍內。 4. 函數曲線下99.730020%的面積在平均數左右三個標準差 3σ 的範圍內。 5. 函數曲線下99.993666%的面積在平均數左右四個標準差 4σ 的範圍內。
高斯分佈的這些特性能夠做爲異常統計的依據。
在正態分佈的假設下,區域 μ±3σ 包含了99.7% 的數據,若是某個值距離分佈的均值 μ 超過了3σ,那麼這個值就能夠被簡單的標記爲一個異常點(outlier)。
假設 n 維的數據集合形如,那麼能夠計算每一個維度的均值和方差μj,σj,j∈{1,...,n}。
具體來講,對於j∈{1,...,n},能夠計算
在正態分佈的假設下,若是有一個新的數據 x⃗ ,能夠計算機率 p(x⃗ ) 以下:
根據機率值的大小就能夠判斷 x 是否屬於異常值。
讀者須要特別注意的是,在使用高斯分佈進行異常統計前,咱們須要先關注一下咱們的數據自己是否知足必定的分佈。
小樣本 N 條件下,大數定理自己都不必定能成立,數據的出現帶有很強的隨機性,所以,在小樣本 N 條件下,使用高斯分佈獲得的異常統計,會更容易出現誤報。
下圖是一個一元統計量的觀測值。
能夠看到,數據集的分佈集中在了橫軸的兩頭。
這個case是筆者在項目中遇到的一個實際案例,真實的狀況是,大部分的「正常」樣本集中在橫軸的低值域區域,而咱們要檢測的少部分「異常」樣本集中在橫軸的高值域區域。
顯然,這部分高值域區域的點集就是咱們要檢測的異常點,可是問題來了,在這種分佈下,計算出來的 均值 會落在中間的區域(很容易想象出來),這樣,兩頭的數據點都成了所謂的異常點,沒法達到咱們想要的效果。
出現這種狀況的緣由是什麼呢?首先,樣本量 N 不夠確定是罪魁禍首;其次,在不少狀況下,異常點和正常點的關係並非「對稱的高斯分佈」,而是單邊高斯分佈。用傳統的雙邊高斯分佈的統計方法來進行數據建模(統計高斯模型)確定是不行的。
對於webshell來講,存在如下幾種異常的狀況:
1. 文件夾自己保存的是正常的網站文件,忽然某天出現了少許惡意shell文件 2. 整個文件夾自己就是一個「馬場」,佈滿了shell文件 3. 文件夾自己保存的是正常的網站文件,可是被黑客重複入侵,文件夾下充斥了大量的惡意shell文件,數量甚至超過了原始的正常文件數量
經過散點圖描述:
第一種狀況:基於樣本偏離均值的程度進行判斷,能夠進行有效建模
第二種狀況:方差自己超過必定閾值就能夠做爲一個二分類決策指標,可是若是該文件夾下存在正常文件,要研究下用什麼統計把它們篩選出來。能夠採起統計文件create_time小於均值兩側範圍內多少%比認爲是正常的。
在開始建模以前,咱們須要先探查目標樣本的幾個問題:
1. 單個維度是否都具有線性可分特徵。若是存在這種特徵,則說明找到了「強特徵」!恭喜你!簡單一個where條件就能夠完成你的二分類目標了。一個感知機神經元判別器就能夠搞定。
2. 單個特徵維度都沒法作到線性可分,可是多個組合特徵之間能夠經過複合線性函數進行有效二分類。這個時候要麼經過專家經驗編寫多個if-else條件,或者直接訓練一個有監督二分類模型,例如隨機森林,進行二分類
分佈統計模型可以work的一個前提是:目標樣本數據須要在某一些特徵維度上呈現出必定的「分佈特性」。若是這個前提不成立,異常統計是沒法進行的。
筆者一個典型的場景是:SEO批量插馬/掛馬模式。
SEO惡意文件會對目標文件夾進行遍歷,對全部文件都插入一段惡意shellcode;或者新建一個文件夾,在該文件夾下惡意shell文件。
這種行爲致使的結果就是,該文件夾下全部文件的file_create_time都相同,看起來和正常的業務文件夾在統計分佈上是同樣的,沒法區分。
1. 基礎統計特徵 -- file md5 whole aliyun ecs statistic info a.uuid_cn_by_md5, a.aliuid_cn_by_md5, a.path_cn_by_md5, -- file path whole aliyun ecs statistic info uuid_cn_by_path, aliuid_cn_by_path, md5_cn_by_path, -- directory statistic info b.path_cn_by_directory, b.md5_cn_by_directory, b.fileext_cn, b.avg_file_create, b.stddev_file_create, b.median_file_create, b.avg_uuid_cn_by_md5, b.stddev_uuid_cn_by_md5, b.median_uuid_cn_by_md5, b.avg_aliuid_cn_by_md5, b.stddev_aliuid_cn_by_md5, b.median_aliuid_cn_by_md5, b.avg_path_cn_by_md5, b.stddev_path_cn_by_md5, b.median_path_cn_by_md5, b.avg_uuid_cn_by_path, b.stddev_uuid_cn_by_path, b.median_uuid_cn_by_path, b.avg_aliuid_cn_by_path, b.stddev_aliuid_cn_by_path, b.median_aliuid_cn_by_path, b.avg_md5_cn_by_path, b.stddev_md5_cn_by_path, b.median_md5_cn_by_path, -- gaussion statistic between file and directory ABS(a.file_create_int - b.avg_file_create) AS file_create_by_avg_distance, ABS(a.uuid_cn_by_md5 - b.avg_uuid_cn_by_md5) AS uuid_cn_by_md5_by_avg_distance, ABS(a.aliuid_cn_by_md5 - b.avg_aliuid_cn_by_md5) AS aliuid_cn_by_md5_by_avg_distance, ABS(a.path_cn_by_md5 - b.avg_path_cn_by_md5) AS path_cn_by_md5_by_avg_distance, ABS(a.uuid_cn_by_path - b.avg_uuid_cn_by_path) AS uuid_cn_by_path_by_avg_distance, ABS(a.aliuid_cn_by_path - b.avg_aliuid_cn_by_path) AS aliuid_cn_by_path_by_avg_distance, ABS(a.md5_cn_by_path - b.avg_md5_cn_by_path) AS md5_cn_by_path_by_avg_distance 2. 加工特徵: 本質上和DNN隱層中的扭曲效果相似 -- 表徵了距離高斯均值中心的距離和標準差的比例,經過構造特徵進行迴歸擬合,能夠避免手工調整 N 倍或 N.N倍 標準差的繁雜過程 file_create_by_avg_distance / stddev_file_create uuid_cn_by_md5_by_avg_distance / stddev_uuid_cn_by_md5 aliuid_cn_by_md5_by_avg_distance / stddev_aliuid_cn_by_md5 path_cn_by_md5_by_avg_distance / stddev_path_cn_by_md5 uuid_cn_by_path_by_avg_distance / stddev_uuid_cn_by_path aliuid_cn_by_path_by_avg_distance / stddev_aliuid_cn_by_path md5_cn_by_path_by_avg_distance / stddev_md5_cn_by_path 3. 歸一化特徵 -- 標準差依賴於數據自己的scale,可能不能充分說明問題。使用標準離差率(標準差除以平均值)來更客觀評價離羣程度 b.stddev_file_create / b.avg_file_create, -- b.stddev_uuid_cn_by_md5 / b.avg_uuid_cn_by_md5, b.stddev_aliuid_cn_by_md5 / b.avg_aliuid_cn_by_md5, b.stddev_path_cn_by_md5 / b.avg_path_cn_by_md5, b.stddev_uuid_cn_by_path / b.avg_uuid_cn_by_path, b.stddev_aliuid_cn_by_path / b.avg_aliuid_cn_by_path, b.stddev_md5_cn_by_path / b.avg_md5_cn_by_path,
使用autoXGB進行自動特徵重要性評估獲得結論以下:
original_name feature_name feature_importance path_cn_by_md5: 3889.0: 該文件的md5在全網出現的路徑path數量, 體現了該文件可能被不一樣的人使用分發到不一樣路徑下 path_cn_by_directory: 3350.0: 該文件所在的目錄下文件數 md5_cn_by_directory: 2862.0: 該文件所在的目錄下文件數 uuid_cn_by_md5: 2741.0: 該文件的md5在全網多少uuid出現,對於批量抓雞黑客來講,經常會使用同一個webshell批量傳播到大量的機器上 cv_path_cn_by_md5: 2658.0: 一個目錄下全部文件的md5散步path廣度,若是標準離差很大, 說明可能出現了可疑文件 median_path_cn_by_md5: 2494.0: path_cn_by_md5_outlier_rate: 2466.0: 文件的md5在全網出現的路徑path數量這個指標和該文件所在目錄的均值高斯異常比值。 aliuid_cn_by_md5: 2396.0: 該文件的md5在全網多少aliuid出現 avg_path_cn_by_md5: 2370.0 stddev_path_cn_by_md5: 2111.0 path_cn_by_md5_by_avg_distance: 2079.0 file_create_by_avg_distance: 1903.0: 該文件的建立時間和該目錄下全部文件的平均建立時間均值的差值 cv_aliuid_cn_by_md5: 1639.0 median_uuid_cn_by_md5: 1589.0 uuid_cn_by_md5_outlier_rate: 1554.0 cv_uuid_cn_by_md5: 1530.0 avg_uuid_cn_by_md5: 1484.0 file_create_outlier_rate: 1464.0: 文件建立時間孤立程度離羣率 median_aliuid_cn_by_md5: 1387.0 stddev_uuid_cn_by_md5: 1383.0 aliuid_cn_by_md5_outlier_rate: 1368.0 uuid_cn_by_md5_by_avg_distance: 1311.0 aliuid_cn_by_md5_by_avg_distance: 1272.0 stddev_aliuid_cn_by_md5: 1268.0 avg_aliuid_cn_by_md5: 1257.0 path_cn_by_md5_outlier_rate_cv: 758.0 cv_md5_cn_by_path: 561.0 avg_md5_cn_by_path: 547.0 stddev_md5_cn_by_path: 487.0 md5_cn_by_path_by_avg_distance: 441.0 uuid_cn_by_md5_outlier_rate_cv: 407.0 aliuid_cn_by_md5_outlier_rate_cv: 400.0 fileext_cn: 380.0 uuid_cn_by_path: 275.0 md5_cn_by_path: 251.0 median_md5_cn_by_path: 212.0 avg_uuid_cn_by_path: 186.0 md5_cn_by_path_outlier_rate: 179.0 cv_uuid_cn_by_path: 135.0 aliuid_cn_by_path: 123.0 uuid_cn_by_path_by_avg_distance: 119.0 median_uuid_cn_by_path: 116.0 cv_aliuid_cn_by_path: 111.0 aliuid_cn_by_path_by_avg_distance: 109.0 avg_aliuid_cn_by_path: 83.0 stddev_uuid_cn_by_path: 82.0 stddev_aliuid_cn_by_path: 73.0 median_aliuid_cn_by_path: 68.0 aliuid_cn_by_path_outlier_rate: 49.0 uuid_cn_by_path_outlier_rate: 48.0 md5_cn_by_path_outlier_rate_cv: 22.0 aliuid_cn_by_path_outlier_rate_cv: 18.0 uuid_cn_by_path_outlier_rate_cv: 14.0
筆者在對大數據組件分析進行人工分析的時候,發現了幾個有趣的現象:
1. 再次體會到:數據中蘊含着規律!有時候這種規律甚至超過了專家的認知,好比上面的特徵排序有幾個維度是令我一開始感到驚訝的,可是仔細一分析又能夠理解。 2. 專家經驗仍是靠譜的,總體上看,xx_by_path這個維度的特徵,筆者在提取的時候,根據網絡安全從業的經驗,就已經認爲是重要性不高的,組件分析出來的結果和個人預期是一致的。 3. xx_by_md5特徵比較靠前,基本上說明一個md5是能夠惟一表明一個惟一文件的依據。 4. md5文件的全網分佈廣度特徵排名比較靠前 ,這再次證實了大數據狀況下,是有機會得到比單機日誌更好的分類效果,大數據的優點是能看到上帝視角!必定要多思考大數據的優點!不僅僅是數據量大,而是大數據自己! 5. 高斯統計分佈的離羣特徵確實有很強的表徵能力,此類特徵的排名也比較靠前。
Relevant Link:
https://blog.csdn.net/Gamer_gyt/article/details/76692188 https://blog.csdn.net/wyl1813240346/article/details/79059647 https://cloud.tencent.com/developer/article/1054267
咱們經過一個例子來講明爲何須要多元高斯分佈模型而不是多個單元高斯分佈模型的混合模型(boosting思路)
假設在數據中心監控機器的例子中,咱們有以下的內存和CPU使用數據:
其中對於這兩個維度的數據(分別作投影),都服從正態分佈:
若是如今在咱們的測試集中,有一個異常數據點出如今下圖的位置中:
那麼在這種狀況下咱們會發現,這一點對應的兩個維度下的機率(分別對兩個維度作投影)其實都不低,從單維度p(x)的結果上,咱們沒法準確預測這個樣本是否屬於異常。
產生這個問題的實際緣由實際上是從x1和x2這兩個維度來看,咱們的正常數據和"異常點數據"都處在一個高几率區間內
爲了解決這個問題,要用到多元高斯分佈(多元正態分佈)
在多元高斯分佈中,對於n維特徵x∈Rn,不要把模型p(x1),p(x2),....,p(xn)分開,而要創建p(x)總體的模型。
多元高斯分佈的參數包括一個均值向量 u 和一個 n * n 的協方差矩陣:
帶入以後計算 p(x)機率分佈:,公式中
這一項,表明了協方差矩陣的行列式
咱們來對比一下不一樣的 u 和不一樣的 Σ 組合後,對應的p(x)的形狀
表格從上到下依次是三種狀況對應的參數、三維圖像以及俯視圖。從圖中能夠看出
1. 3個高斯分佈在x1和x2維度的投影都是以0爲中心的高斯分佈(鐘形曲線),這是由於它們的均值向量 u 都是0 2. 當縮小協方差時,中心區域的凸起就會變得更細長 3. 當擴大協方差時,中心區域的凸起就會變得更扁
接下來咱們嘗試對協方差中使用不一樣的數值份量,來觀測p(x)形狀的變化
能夠看:
1. 當咱們縮小x1的值,而x2保持原來不變時,至關因而對特徵x1的方差進行了縮小,因此圖像在x1的方向上會顯得更細長 2. 當咱們放大x1的值,而x2保持原來不變,至關因而對特徵x1的方差進行了放大,因此圖像在x1的方向上會顯得更扁平
咱們繼續經過改變協方差Σ非對角線上的元素來獲得不一樣的高斯分佈:
能夠看出來,當我改變了非對角線上元素的值時,p(x)p(x)的圖像也變得傾斜了;當我增大了這些元素時,這個傾斜的分佈圖像變得更細長了。
咱們繼續把非對角線上元素設置爲負數
能夠看到圖像朝反方向傾斜
若是咱們改變µ,圖像p(x)會在對應爲維度方向上平移
能夠看到,多元高斯分佈有不少好處
1. 它能夠將多個維度的變量綜合到一個公式中獲得一個平滑的機率值 2. 它可以讓咱們瞭解到兩個特徵變量之間存在的正相關或者負相關性(這經過協方差矩陣左右對角線的值得以體現)
在進行預測以前,咱們須要對咱們定義的多元高斯模型進行參數擬合訓練(即參數估計)
假設咱們有以下的訓練樣本
到這一步爲止,咱們獲得的反映訓練數據(一組特徵維度組合)的高斯分佈,也能夠理解爲獲得了一個 f(x)函數,這個函數能夠將新輸入的特徵向量轉化爲一個高斯機率值
計算的時候須要帶入在訓練時獲得的模型參數,即:由訓練數據的均值向量和協方差矩陣
這一步的作法有不少,能夠直接作絕對值的異常判斷,即,若是p(x)<ε時,就把它標記爲是一個異常樣本,反之,若是p(x)>=ε則不標記爲異常樣本。
或者作相對值的離羣比較:
具體來講就是例如只採集一臺機器的日誌進行異常入侵檢測,若是你的數據集是混合了全部的機器的全量日誌,這裏不能直接進行數值比較,由於它們的量綱不在同一個範疇內,能夠採起的方法是比例除法的方式:
pdf_center:歷史訓練數據的(x1_var均值,x2_var均值)計算PDF,至關於獲得鐘形分佈中心點的Y值
pdf_待檢測樣本點:當前樣本點的(x1,x2)計算PDF,獲得對應的Y值
pdf_center / pdf_待檢測樣本點:這個比例反應了這個特徵維度組合的二元變量(x1,x2)在總體高斯分佈上的異常離心程度。固然,總體高斯模型的形狀由訓練樣本集的均值向量和協方差矩陣決定
原始模型 | 多元高斯模型 |
---|---|
捕捉到這兩個特徵,創建一個新的特徵x3x3(好比x3=x1x2x3=x1x2),去嘗試手工組合並改變這個新的特徵變量,從而使得算法能很好的工做。 | 自動捕捉不一樣特徵變量之間的相關性。 |
運算量小(更適用於特徵變量個數nn很大的狀況) | 計算更復雜(Σ是n×nn×n的矩陣,這裏會涉及兩個n×nn×n的矩陣相乘的邏輯,計算量很大) |
即便訓練樣本數mm很小的狀況下,也能工做的很好 | 必須知足m>nm>n,或者ΣΣ不可逆(奇異矩陣)。這種狀況下,還能夠幫助你省去爲了捕捉特徵值組合而手動創建額外特徵變量所花費的時間。 |
scipy.stats.multivariate_normal
A multivariate normal random variable.
The mean keyword specifies the mean. The cov keyword specifies the covariance matrix.
# -*- coding:utf-8 -*- from scipy.stats import multivariate_normal import matplotlib.pyplot as plt import numpy as np x, y = np.mgrid[-1:1:.01, -1:1:.01] pos = np.empty(x.shape + (2,)) pos[:, :, 0] = x pos[:, :, 1] = y rv = multivariate_normal([0.5, -0.2], [[2.0, 0.3], [0.3, 0.5]]) plt.contourf(x, y, rv.pdf(pos)) plt.show()
https://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.stats.multivariate_normal.html
Relevant Link:
http://studyai.site/2017/05/26/斯坦福機器學習課程%20第九周%20(3)多元高斯分佈(選學)/#%E5%BC%82%E5%B8%B8%E6%A3%80%E6%B5%8B%E7%AE%97%E6%B3%95%E6%97%A0%E6%B3%95%E8%A7%A3%E5%86%B3%E7%9A%84%E9%97%AE%E9%A2%98 https://www.cnblogs.com/yan2015/p/7419972.html https://www.cnblogs.com/activeshj/p/3954213.html http://www.bubuko.com/infodetail-2275360.html http://blog.csdn.net/u012328159/article/details/51462942 https://www.cnblogs.com/gczr/p/6483762.html https://blog.datascienceheroes.com/anomaly-detection-in-r/ https://www.jisilu.cn/question/253057 http://blog.csdn.net/ironyoung/article/details/49334343
基於機率統計學習的異常檢測,是一種最純粹的異常檢測思想。它基於的理論依據是堅實的機率統計理論,能夠這麼說,機率統計模型是最能表現咱們的樣本數據規律的模型。但同時機率統計模型也很是依賴於訓練樣本的準確性以及其中機率分佈的完整性。
1. 設計一套特徵工程框架: 機率統計模型的每一個隨機變量就是咱們定義的特徵所對應的值,特徵工程的設計能夠儘可能融入領域經驗以及先驗知識,以提升特徵向量的表徵性 2. 對正例白樣本進行數值化的特徵提取和分析 3. 根據白樣本的特徵向量創建機率統計模型,即獲得模型參數,該參數描述了機率統計模型的分佈 - 這一步至關於模型train過程 4. 將線上真實樣本使用一樣的特徵工程框架進行特徵抽取,將獲得特徵向量輸入上一步獲得的模型中,根據獲得的值域斷定"異常程度" - 這一步至關於模型predict過程
須要注意的是,機率統計異常檢測通常是針對單變量進行建模和檢測的,基於多變量的機率統計函數很是難計算,計算的成本也隨着隨機變量的增長而急劇增長。
因此咱們通常的作法是逐個針對單個隨機變量進行異常機率統計。以後再基於多個單個隨機變量的異常結果進行綜合評分,獲得一個整體的異常程度的判斷。
咱們知道,異常檢測是基於白樣本進行機率統計模型建模,隨後進行predict離羣值計算的。可是一個很尷尬的問題的是:如何定義白樣本?如何保證白樣本就是白的?
在工程中,咱們經常這麼玩,即把歷史 N 小時的數據當作是白樣本,在完成模型建模以後,將當前的時刻的樣本輸入模型進行異常檢測。
怎麼作的出發點固然也沒錯,這是一種典型的異常基線的思惟方式,可是憑什麼認爲歷史數據就是白的呢?若是歷史數據裏參雜了黑的髒數據呢?
或者說若是此時此刻,歷史的數據不但不是白,並且是全黑的呢?基於這樣的數據擬合的機率統計模型去預測新的白樣本又會獲得什麼呢?
評價函數的做用是基於已知的數據集(例如白樣本)進行模型擬合,獲得一份模型參數,這個過程本質上能夠理解爲生成模型的訓練過程。以後基於該已知模型輸入待預測值獲得的值能夠用於進行異常程度的評價。
這個過程也能夠被描述爲一個假設檢驗過程,所謂假設檢驗,即先定義出一個假設(基於白樣本擬合出一個模型分佈),而後檢驗新的樣本數據是否符合這個假設,若是不符合,則認爲是異常點。
能夠很容易理解,評價函數應該對數據的變化和異常(離羣程度)有較強的描述和區分能力。咱們在這個小節來討論一下有哪些函數能夠用於評價函數。
,其中
咱們經過 的正態分佈解釋下,首先,
就是指的是曲線下
部分的面積:
下面的動圖表現了整個馬爾科夫不等式的變化趨勢:
越大於平均值,機率越低。
,其中
,
是指望,
是標準差。
仍是經過 的正態分佈來感覺一下切比雪夫不等式:
越遠離平均值,機率越低。
可是注意到切比雪夫不等式和馬爾科夫不等式的一個區別是,切比雪夫不等式考慮了訓練樣本方差的考量因素,若是樣本的方差特別大,則主要稍微偏離一些平均值,機率下降的速度會更快。
Relevant Link:
https://www.zhihu.com/question/27821324
Grubbs' Test爲一種假設檢驗的方法,常被用來檢驗服從正太分佈的單變量數據集(univariate data set)Y 中的單個異常值。
如有異常值,則其必爲數據集中的最大值或最小值。原假設與備擇假設以下:
H0:數據集中沒有異常值
H1:數據集中有一個異常值
Grubbs'test算法的異常點檢測過程是一個迭代的過程,每輪從當前數據集中尋找出一個異常點(outlier)
H0:數據集中沒有異常值
H1:數據集中有一個異常值
注意到公式中使用了絕對值,因此這是一個two-tail的檢驗統計量,即同時檢驗最大值和最小值。
本輪假設是否成立的判斷依據就是下式是否成立:
當上式成立時:假設H0被拒絕,假設H1被接受,統計量對應 Yi(極大值/極小值)就是異常值,須要被剔除。提出異常值後,繼續回到步驟3開始下一輪迭代。
當上式不成立時:假設H1被拒絕,假設H0被接受,則本輪沒有發現任何的異常值,算法迭代結束
實際上,Grubbs' Test可理解爲:檢驗最大值、最小值偏離均值的程度是否爲異常。
在基於訓練數據集計算臨界值的時候,因爲個別異常值會極大地拉伸均值和方差,從而致使算法未能很好地捕獲到部分異常點,召回率偏低。
爲了解決這個問題,採用了更具魯棒性的中位數與絕對中位差(Median Absolute Deviation, MAD)替換公式中的均值與標準差
咱們對服務器的ssh/rdp/sqlserver的登陸記錄創建一個基本假設:在一個時間窗口內,這臺服務器的來訪者若是是一個正常的運維管理員,他在整個互聯網上的行爲軌跡應該出現出一個正態分佈,而若是這個來訪者是一個惡意攻擊者,它的行爲模式會呈現出顯著的異常統計特性。
能夠看到,上圖中,咱們明顯看到,來自臺灣省的這個來訪IP在各個維度呈現出的行爲模式基本處於整個數據集的「正態中心」位置,所以這個來訪者大機率是正常的,而其餘的點呈現出明顯的異常特徵。
grubbs test的檢測結果也印證了這點:
在實踐中咱們發現,grubbs test的這種根據分組樣本數據自適應(自動計算數據的正態均值中心)地進行異常發現,比咱們以前經過人工經驗硬編碼一些特定的閾值進行二分類,模型的檢測漏報率有顯著降低。
另一個頗有趣的發現是,咱們對來訪者ip的4個維度分別進行grubbs test異常假設統計,在4個維度上都變現出了一致的統計異常特徵,這也從側面說明了歷來訪者IP的角度來講,若是其確實存在異常行爲模式,則其在各個維度都會變現出異常的統計特徵。
另一個須要注意的問題是,作這種基於區間日誌的異常假設統計分析,要特別注意統計的時間區間的長度,若是過短,極可能致使沒法積累足夠的正常行爲數據,致使異常事件自己被誤判爲異常。
Relevant Link:
https://en.wikipedia.org/wiki/Grubbs%27_test_for_outliers https://blog.csdn.net/sunshihua12829/article/details/49047087 https://www.zhihu.com/question/280696035/answer/417665007 https://www.cnblogs.com/en-heng/p/9202654.htm
此種異常爲序列數據中的點異常,語境異常點必定是處在序列數據的上下文中的異常點,以下圖(橫座標表明時間,縱座標表明溫度)
t1處和t2處的取值是同樣的,可是t2屬於異常點,而t1是正常的溫度。
顧名思義,就是子序列的方式與總體序列的模式大不相同。
此種是給出一個基礎的序列,判斷測試序列與基礎序列相比是否異常。
1. 異常子序列的長度難以有效肯定 2. 異常未在訓練集中出現 3. 序列常常存在比較大的噪聲,會產生像離羣點檢測同樣的淹沒效應(異常點和正常點的距離很小,甚至難以分別)以及掩蔽效應(異常點增多,致使其密度增大)
這個問題筆者目前爲止也沒有一個完美的答案,的確,學術界和工程界真的有很是多的異常檢測算法。拋開場景不談,這些算法真的是很是好,很是完美的算法,細細去品味算法的核心思想,你會驚歎於它們的合理性近乎於哲學。
可是遺憾的是,筆者在不少工程項目中寫完代碼後,線上的狀況每每並不總能盡如人意,其中有不少的緣由在於:
1. 無論是生成模型/機率統計模型/假設檢測模型/無監督聚類模型,它們都須要基於一個基本假設,例如格拉斯異常檢測算法的一個最基本假設是,你的數據集符合一個正態分佈,而偏離正態分佈均值中心的點,是異常點的機率會逐漸增大。 可是,在安全攻防領域(筆者是作安全攻防工做的),不少時候,咱們面對的是海量的用戶業務日誌以及黑客入侵日誌,不少時候,這種假設不必定100%能成立,好比一個黑客入侵也可能產生大量密集的異常事件,這些事件可能從統計上並不能呈現出明顯的tail-side abnormal現象,固然這也涉及到你的統計時間窗口怎麼設計的問題。 2. 異常檢測,尤爲是機率統計/假設檢驗類的異常檢測,是一個純數學上的機率計算問題。而安全入侵檢測是一個物理世界的現實問題。物理問題能夠經過數字向量來抽象嗎?這個問題很是關鍵,答案應該是不能的,至少不能100%完美的表明,不少時候,咱們根據咱們本身的一些領域先驗知識進行的特徵工程,這個過程已經包含了一些信息丟失了,在一份存在信息損失的向量上進行算法檢測,獲得的結果的準確性也天然會降低。
咱們知道,在PAC可學習理論中,一個很重要的概念是,待搜索的假設類的越被限制,估計風險就會減少,但同時估計風險會升高。可是整體來講,獲得的最終模型效果會提升。
縮小假設類的方法有不少,例如正則化懲罰、提早剪枝等等。
可是一個最重要的方法是經過引入領域先驗知識,來直接對假設類進行縮小。換句通俗的話來講:
若是你對的業務場景已經知道了一個很是強的先驗知識,一個好的作法是直接將其hard coding爲一個規則,而最好不要經過特徵向量的方法表徵後輸入算法模型,「指望」算法模型去「學習」你的這種經驗,這可能會致使欠擬合問題。
Copyright (c) 2018 LittleHann All rights reserved