我目前正在尝试使用Scikit Learn创建一个简单的异常检测代码段。
程序将接收一个.csv文件,然后将其分解为熊猫的DataFrame。 数据框有8列:“ Src IP”; “ Dst IP”; '运动'; 'dPort'; '协议'; '加载'; “数据包”; “ TCP标志”。
我将数据放入一个IsolationForest中,就像这样:
iForest = IsolationForest(n_estimators=128, max_samples='auto', max_features=1, behaviour='new', contamination='auto', random_state=None, n_jobs=-1, verbose=0, bootstrap=True)
usecols=["Src IP","Dst IP","sPort","dPort","Protocol","Load","Packets","TCP Flags"]
iForest.fit(data[usecols])
然后从IForest获取异常值/异常值:
pred = iForest.predict(data[usecols])
data['anomaly']=pred
outliers=data.loc[data['anomaly']==-1]
一切正常,但是,我的问题是: 如何在不依赖“污染”属性的情况下使用隔离林检测网络上的异常情况?
在IDS中,低的误报率至关重要。就我而言,我是通过选择百分比来确定哪些条目被“污染”了。
我的目标是让Isolation Forest自动设置污染因子,因为如果x.csv清除了100%的污染,然后在y.csv上找到了污染的百分比。
这应该是混合IDS的一部分,它同时使用签名分析和行为来基于流数据(NetFlow)检测入侵。
TLDR :IsolationForest需要接收一个干净的.csv(无污染),然后才能检测到一组新数据(另一个.csv或管道数据)上的异常。使用ScikitLearn怎么可能?
答案 0 :(得分:1)
如果您的训练集仅包含普通数据,则设置contamination=0
。要为异常选择合适的阈值,请使用验证集并绘制异常分数的直方图。没有标签数据,只能通过启发式方式完成:
要获得最大的“正肯定”(但要牺牲“误肯定”),请根据您拥有多少可用于寻找“肯定”的资源的预算来设置阈值。您可以根据入站数据速率,直方图统计数据中的期望正值以及每次评估的成本(时间/金钱)来计算此值。
要最大程度地减少误报,请将阈值设置为稍微超出现有分数。然后假设训练/验证实际上不包含异常,并且任何新的和不同的都是异常的。有时这称为新颖性检测。
如果可以通过查看数据确定某项是真还是假异常,那么我建议对异常得分最高的大约10-100个项目执行此操作。与标记所有数据相比,这通常会非常快,并且可以帮助估计误报率。
当您将此模型投入生产时,处理异常的方案应确保对案例进行评估并将其计为异常/非异常。然后,这就是您将来标记的验证/测试数据,可用于调整阈值。
如果您确实在验证/测试集中标记了异常/未异常(但在训练中未标记),则可以使用此参数来优化阈值,以使用超参数搜索来最大化/最小化所需指标。