接口测试的核心概念是什么
259
2022-10-24
Web安全与机器学习(KNN篇)
sklearn之knn近邻算法
近邻算法检测异常操作
数据来源:User Data。其中包含50个用户的操作日志,每个日志包含1500条操作命令,前面5000条是正常的操作,后面的10000条日志中随即包含有异常操作。具体参考《Web安全机器学习入门》
基础知识
本来想自己写的,但是网上资料太多,就没必要写了。看下其他大佬写过的就行了:
1:随便选择一个user日志,里面每行代表一个命令。每150个命令弄成一个操作序列,保存在列表之中
def load_user(filename): most_cmd = [] mini_cmd = [] cmd_list = [] cmd_seq = [] # 获取操作序列 with open(filename, 'r', encoding="utf-8") as f: cmd = f.readline() temp = [] cnt = 0 while(cmd): cmd_list.append(cmd.strip('\n')) temp.append(cmd.strip('\n')) cnt = cnt + 1 if(cnt == 150): # 这里不按照书上的分,我这里按照150个命令为一个序列,刚好和标签对上号,因为标签只有100个值 cmd_seq.append(temp) cnt = 0 temp = [] cmd = f.readline()
Step 2:然后将user日志中所有的命令进行统计,统计出它们最频繁的50个命令,以及最不频繁的50个命令
# 获取最频繁的前50个命令,获取最不频繁的前50个命令 fdist = sorted(FreqDist(cmd_list).items(),key = operator.itemgetter(1), reverse = True) # 按照出现频率排序 most_cmd = [ item[0] for item in fdist[:50]] mini_cmd = [ item[0] for item in fdist[-50:]]
Step 3:特征化。在 Step 1 的操作序列上,我们按一个操作系列为单元,①统计其中不重复的命令个数、②最频繁的10个命令、③最不频繁的10个命令
user_feature = [] for cmd_list in user_cmd_list: # 获取每个序列不重复命令的个数 seq_len = len(set(cmd_list)) # 将每个序列按照出现频率由高到低的排列命令 fdist = sorted(FreqDist(cmd_list).items(), key=operator.itemgetter(1), reverse=True) seq_freq = [item[0] for item in fdist] # 获取最频繁和最不频繁的前10个命令 f2 = seq_freq[:10] f3 = seq_freq[-10:]
Step 4:因为KNN只能接收数值类型输入。在 Step 4 中,②和③都是字符串的命令,我们需要将其标量化。标量化的方式:统计最频繁使用的50个命令和最不频繁使用的50个命令计算重合程度
# 计算重合度 f2 = len(set(f2) & set(user_max_freq)) f3 = len(set(f3) & set(user_min_freq)) # 合并特征:①每个序列不重复的命令个数;②每个序列最频繁的前10个命令和user中最频繁的50个命令重合度; # ③每个序列最不频繁的前10个命令和user中最不频繁的前50个命令重合度; user_feature.append([seq_len, f2, f3])
python3完整代码如下
from nltk.probability import FreqDist # 统计命令出现频率 import operator from sklearn.neighbors import KNeighborsClassifier import numpy as np def load_user(filename): most_cmd = [] mini_cmd = [] cmd_list = [] cmd_seq = [] # 获取操作序列 with open(filename, 'r', encoding="utf-8") as f: cmd = f.readline() temp = [] cnt = 0 while(cmd): cmd_list.append(cmd.strip('\n')) temp.append(cmd.strip('\n')) cnt = cnt + 1 if(cnt == 150): # 这里不按照书上的分,我这里按照150个命令为一个序列,刚好和标签对上号,因为标签只有100个值 cmd_seq.append(temp) cnt = 0 temp = [] cmd = f.readline() # 获取最频繁的前50个命令,获取最不频繁的前50个命令 fdist = sorted(FreqDist(cmd_list).items(),key = operator.itemgetter(1), reverse = True) # 按照出现频率排序 most_cmd = [ item[0] for item in fdist[:50]] mini_cmd = [ item[0] for item in fdist[-50:]] return cmd_seq, most_cmd, mini_cmd def get_user_feature(user_cmd_list, user_max_freq, user_min_freq): user_feature = [] for cmd_list in user_cmd_list: # 获取每个序列不重复命令的个数 seq_len = len(set(cmd_list)) # 将每个序列按照出现频率由高到低的排列命令 fdist = sorted(FreqDist(cmd_list).items(), key=operator.itemgetter(1), reverse=True) seq_freq = [item[0] for item in fdist] # 获取最频繁和最不频繁的前10个命令 f2 = seq_freq[:10] f3 = seq_freq[-10:] # 计算重合度 f2 = len(set(f2) & set(user_max_freq)) f3 = len(set(f3) & set(user_min_freq)) # 合并特征:①每个序列不重复的命令个数;②每个序列最频繁的前10个命令和user中最频繁的50个命令重合度;③每个序列最不频繁的前10个命令和user中最不频繁的前50个命令重合度; user_feature.append([seq_len, f2, f3]) return user_feature def get_labels(filename): # 获取第三列的标签 labels = [] cnt = 0 with open(filename, 'r', encoding="utf-8") as f: temp = f.readline().strip('\n') while(temp): labels.append(int(temp[4])) cnt += 1 temp = f.readline().strip('\n') return labels if __name__ == "__main__": user_cmd_list, user_max_freq, user_min_freq = load_user('user.txt') user_feature = get_user_feature(user_cmd_list, user_max_freq, user_min_freq) labels = get_labels('labels.txt') # 切割数据集:训练集和测试集 x_train = user_feature[0:70] y_train = labels[0:70] x_test = user_feature[70:] y_test = labels[70:] # 训练数据 neight = KNeighborsClassifier(n_neighbors=3) neight.fit(x_train, y_train) # 预测 y_predict = neight.predict(x_test) # 计算得分 score = np.mean(y_test == y_predict) * 100 print(score) # 90.0
最终获得90%的正确率。
总结
①获取最频繁的前50个命令,书上的方式获取的并不是最频繁的前50个。在这里我改了下代码。②标签和数据对不上号,命令共有15000个,标签只有100个。书上的做法是每100个为一个操作序列,也就是有150个操作序列,然后在标签出再前面增加了50个标签。我的代码是将150个命令作为一个序列,这样下来刚好合适。
最后推荐下个人博客:https://unihac.github.io/
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~