同一个问题可能有多种建模方法,举一反三,理解为什么这么做 ~
1.数据收集和数据清洗
训练数据有50个用户的操作日志,每个日志有15000条操作命令,前500条是正常操作,后10000条中存在攻击操作。我们只选择了一个用户3来进行机器学习训练。
使用词集模型,将全部命令去重后形成一个大型向量空间,每个命令代表一个特征,用户3的数据有107个特征,这种玩法不适合词集太庞大的数据。
词集(107个):
['gs', 'tset', 'basename', 'uname', 'touch', 'find', 'ln', 'unpack', 'jar', 'tail', 'ls', 'lp', 'ld_', 'ksh', 'get', 'xdm', 'xterm', 'cpio', 'getpgrp', 'grep', 'gethost', 'mimencod', 'dbx', 'logname', 'as1', 'readacct', 'cfe', 'FIFO', 'fvwm', 'sed', 'ex', 'download', 'dirname', 'seecalls', 'sendmail', 'rm', 'wc', 'bc', 'netstat', 'nawk', 'post', 'xargs', 'rlogin', 'admin', 'od', 'xmodmap', '.java_wr', 'tcppost', 'col', 'ptelnet', 'postprin', 'tcpostio', 'javac', 'xsetroot', 'ugen', 'chmod', 'sccs', 'xrdb', 'diff', 'pr', 'ps', 'pq', 'java', 'dbxpcs', 'ppost', 'mkdir', 'MediaMai', 'hpost', 'rmdir', 'man', 'matlab', 'more', 'xhost', 'sim301bK', 'LOCK', 'telnet', 'sim301bS', 'delta', 'GoodStuf', 'true', 'netscape', 'stty', 'expr', 'tracerou', 'FvwmPage', 'cat', 'runnit', 'launchef', 'mailx', 'file', 'id', 'bdiff', 'egrep', 'generic', 'make', 'hostname', 'a.out', 'getopt', 'Xsession', 'driver', 'cpp', 'UNLOCK', 'awk', 'date', 'nslookup', 'sh', 'gzip']
2.特征化
使用词集将操作命令向量化。
第一步:对150条记录向量化
每个记录里有100个操作,去重后可能有20个,对这20个操作填1到词集中,得到一个向量:
[0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0]
这样的向量称作特征,有150个特征。
第二步:打标签
用户3的前50条记录都是正常的0,后100条记录有0有1。
这150个标签,对应到第二步中的150个特征。前面110个作为训练,后面40个作为测试。
3.训练模型
使用KNN函数进行训练。
neigh = KNeighborsClassifier(n_neighbors=3)
neigh.fit(x_train, y_train)
y_predict=neigh.predict(x_test)
4.效果验证
嗯,也是出乎意料。
实际上我们应该采用交叉,10次随机取样和验证,提高验证可信度。
100.0
5.完整代码
import sys
import urllib
import urlparse
import re
import numpy as np
from sklearn.externals import joblib
import HTMLParser
import nltk
import csv
from nltk.probability import FreqDist
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import classification_report
from sklearn import metrics
#测试样本数
N=110
def load_user_cmd_new(filename):
cmd_list=[]
dist=[]
with open(filename) as f:
i=0
x=[]
for line in f:
line=line.strip('\n')
x.append(line)
dist.append(line)
i+=1
if i == 100:
cmd_list.append(x)
x=[]
i=0
fdist = FreqDist(dist).keys()
return cmd_list,fdist
def get_user_cmd_feature_new(user_cmd_list,dist):
user_cmd_feature=[]
for cmd_list in user_cmd_list:
v=[0]*len(dist)
for i in range(0,len(dist)):
if dist[i] in cmd_list:
v[i]+=1
user_cmd_feature.append(v)
return user_cmd_feature
def get_label(filename,index=0):
x=[]
with open(filename) as f:
for line in f:
line=line.strip('\n')
x.append( int(line.split()[index]))
return x
if __name__ == '__main__':
user_cmd_list,dist=load_user_cmd_new("../data/MasqueradeDat/User3")
user_cmd_feature=get_user_cmd_feature_new(user_cmd_list,dist)
labels=get_label("../data/MasqueradeDat/label.txt",2)
y=[0]*50+labels
x_train=user_cmd_feature[0:N]
y_train=y[0:N]
x_test=user_cmd_feature[N:150]
y_test=y[N:150]
neigh = KNeighborsClassifier(n_neighbors=3)
neigh.fit(x_train, y_train)
y_predict=neigh.predict(x_test)
score=np.mean(y_test==y_predict)*100
print score