【安卓恶意软件检测-论文】DroidEvoler:自我进化的 Android 恶意软件检测系统

embedded/2024/11/17 14:54:05/

DroidEvolver:自我进化的 Android 恶意软件检测系统

摘要

鉴于Android框架的频繁变化和Android恶意软件的不断演变,随着时间的推移以有效且可扩展的方式检测恶意软件具有挑战性。为了应对这一挑战,我们提出了DroidEvolver,这是一种Android恶意软件检测系统,可以在恶意软件检测期间自动且持续地自我更新,无需任何人工参与。虽然大多数现有的恶意软件检测系统可以通过在具有真实标签的新应用程序上进行再训练来更新,但DroidEvolver既不需要再训练不需要真实标签来更新自身,主要是由于深入了解DroidEvolver使用具有不断发展的特征集和伪标签的在线学习技术进行必要且轻量级的更新。DroidEvolver的检测性能在六年内开发的33,294个良性应用程序和34,722个恶意应用程序的数据集上进行了评估。使用日期为2011年的6,286个应用程序作为初始训练集,DroidEvolver实现了高检测F-度量(95.27%),对于57,539个新出现的应用程序进行分类,在未来五年内平均每年仅下降1.06%。请注意,此类新应用程序可以使用新技术和新API,DroidEvolver在使用2011年应用程序初始化时不知道这些技术和新API。与最先进的超时恶意软件检测系统MAMADROID相比,DroidEvolver的F-度量平均高出2.19倍(第五年高出10.21倍),DroidEvolver在恶意软件检测期间的效率比MAMADROID高出28.58倍。DroidEvolver还显示出对典型代码混淆技术的鲁棒性

1 介绍

Android 应用程序和 Android 框架都随着时间的推移,由于各种原因(例如功能增强和错误修复)而不断发展[34]。因此,构建使用旧 Android 应用程序进行训练并在运行一段时间后能够有效且可扩展地检测来自新应用程序的恶意软件的 Android 恶意软件检测系统变得越来越困难。现有 Android 检测系统的快速老化引起了工业界和学术界的严重关注。据BlackHat 2016报道[21],百度开发的恶意软件检测系统的召回率在六个月内下降了7.6%。在研究文献中,最近的一项努力是通过 API 抽象使恶意软件检测能够适应 API 更改[24];然而,恶意软件检测的老化问题尚未得到完全解决。

为了使恶意软件检测更加准确,大多数恶意软件检测系统需要使用新应用程序及时、重复地进行重新训练。然而,此类解决方案面临一些挑战。首先,很难确定何时重新训练恶意软件检测系统。如果系统重新训练过于频繁,则会导致重新训练资源的浪费,而无法提供新的信息来丰富检测系统[19];否则,检测系统无法及时捕获一些新的恶意软件。其次,再培训过程需要对所有已处理的新应用程序进行手动标记,这受到可用资源的限制[19]。手动标记的高成本通常会导致重新训练频率松散[31];因此,检测性能受到影响。最后,大多数现有的恶意软件检测系统都使用累积数据集进行重新训练,包括原始训练数据集和新标记的应用程序。这种再训练过程成本高昂且不可扩展,尤其是在新应用程序数量随着时间的推移快速增长的情况下。为了应对这些挑战,我们提出了一种新颖的自我进化 Android 恶意软件检测系统,名为 DroidEvolver,通过不断发展的功能集对其检测模型进行必要的更新,使恶意软件检测随着时间的推移变得准确。 DroidEvolver 维护着不同检测模型的模型池,这些模型是使用各种在线学习算法通过一组标记的应用程序进行初始化的。维护模型池的直觉是,不同的检测模型在恶意软件检测中不太可能以相同的速度老化,即使它们是使用相同的数据集初始化的。在检测阶段,DroidEvolver 在“年轻”检测模型中进行加权投票,以根据 Android API 调用对每个应用程序进行分类。 DroidEvolver 提取 Android API 调用作为检测特征,因为它们自然地反映了 Android 框架和应用程序的演变,并且可以轻松地从字节码中提取以进行高效的恶意软件检测。检测到的应用程序的“年轻”模型是根据幼年化指标(JI)来确定的,JI是根据检测到的应用程序与已被检测模型分类到相同预测标签的一批应用程序之间的相似度计算的。如果检测模型相对于检测到的应用程序老化,DroidEvolver 会使用检测到的应用程序及其模型池生成的分类结果(即伪标签)来更新模型。 DroidEvolver 还更新其功​​能集以适应从应用程序发现的 API 更改。 DroidEvolver 使用 JI 来确定何时更新其功能集和每个检测模型。可以为每个检测模型和正在检测的每个新应用程序计算 JI。如果JI超出一定范围,则相应的检测模型被视为老化模型。如果模型池中的任何模型在检测该应用程序时老化,则将检测到的应用程序标识为漂移应用程序。老化模型对漂移应用程序进行分类具有局限性,其中可能包括新的 API 调用或新的 API 使用模式。因此,一旦识别出漂移应用程序,DroidEvolver 就会更新其功能集和所有老化模型。 DroidEvolver 不需要已处理应用程序的真实标签来更新恶意软件检测中的模型池。这避免了在DroidEvolver初始化后对任何应用程序进行手动标记的必要性,从而减少了DroidEvolver演进的资源和成本约束。当识别出漂移应用程序时,DroidEvolver会为该漂移应用程序生成一个伪标签,并根据该漂移应用程序及其伪标签更新所有老化模型,然后再继续处理下一个应用程序。在当前应用不是漂移应用的情况下(因此没有识别出老化模型),模型池中的所有模型都对分类结果有贡献,并且不进行模型更新。随着时间的推移,DroidEvolver 可以高效地检测恶意软件。初始化后不需要定期使用累积数据集进行任何重新训练;相反,只要识别和处理单个漂移应用程序,它就会有效地发展,除非在这种情况下所有模型都老化。为此,模型池中的所有检测模型均使用在线学习算法[3]进行初始化,该算法可以对流数据进行增量学习。与批量学习算法相比,在线学习算法更加高效和可扩展,因为它们不仅避免了在初始化阶段使用原始训练数据集进行批量处理,而且还避免了在检测阶段使用累积数据集进行定期再训练。虽然现有的在线学习算法仅适用于标记数据,但 DroidEvolver 使它们适用于在检测阶段与伪标签关联的应用程序。与现有的基于在线学习的方法(使用真实标签更新每个应用程序的检测模型)不同,DroidEvolver 仅更新每个漂移应用程序的老化模型。在更新过程中,DroidEvolver不需要任何真实标签与漂移应用程序关联;从这个意义上说,DroidEvolver比现有的基于在线学习的方法更实用。因此,只要有必要,衰老模型就会立即年轻化。这进一步提高了 DroidEvolver 的效率。 DroidEvolver 通过一系列数据集进行了严格评估,包括 2011 年至 2016 年的 34,722 个恶意应用程序和 33,294 个良性应用程序。DroidEvolver 的功效和效率与 MAMADROID 进行了比较,MAMADROID 是最先进的恶意软件检测系统 [24 ] 能够适应 API 随着时间的推移而发生的变化。在使用同一时间段开发的相同应用程序对 DroidEvolver 和 MAMADROID 进行训练和测试的情况下,DroidEvolver 显着优于 MAMADROID,在我们的实验中,F 测量平均高出 15.80%,精度高出 12.97%,召回率高出 17.57%。当在比训练集新一到五年的测试集上进行评估时,DroidEvolver 的平均 F 测量值分别为 92.32%、89.30%、87.17%、87.46% 和 89.97%。相比之下,MAMADROID 在相应情况下的平均 F 值分别为 68.01%、56.09%、45.88%、32.85% 和 8.81%。随着时间的推移,DroidEvolver 的总体 F 度量在恶意软件检测方面平均比 MAMADROID 高 2.11 倍。 DroidEvolver 的 F 度量在五年内平均每年下降 1.06%,而 MAMADROID 在同一情况下下降了 13.52%。此外,如果仅通过少量具有真实标签的数据进行更新,DroidEvolver 的 F-measure 仍会保持在较高水平,而 MAMADROID 的 F-measure 在这种情况下每年都会下降。然后我们评估 DroidEvolver 的效率,并将其与 MAMADROID 进行比较。 DroidEvolver 的初始化需要线性时间,随着原始训练数据集从 10,000 个应用程序增加到 50,000 个应用程序,该时间从 3 秒到 27 秒不等,而 MAMADROID 则需要非线性时间,从 26 秒到 1,207 秒不等。在检测阶段,DroidEvolver 平均需要 1.37 秒来处理未知应用程序,而 MAMADROID 在这种情况下平均需要 39.15 秒。我们还分析了随着时间的推移在恶意软件检测过程中发现的老化模型和漂移应用程序。 DroidEvolver 将 11.23% 的新应用程序识别为漂移应用程序,而每个检测模型平均对约 30.13% 的漂移应用程序进行了分类,显示出老化的迹象。当使用后期开发的应用程序进行评估时,这些百分比保持稳定。此外,超过50.00%的检测模型被识别为老化,对49.08%的漂移应用进行了分类。这些漂移的应用程序是错误分类的主要来源,老化模型的更新使 DroidEvolver 减缓了恶意软件检测的老化速度。本文的贡献总结如下。我们提出了一种新颖的自我进化且高效的 Android 恶意软件检测系统 DroidEvolver。 DroidEvolver 不仅能够准确检测与训练应用程序同期开发的应用程序,而且能够准确检测训练应用程序之后使用新技术和新 API 开发的新应用程序。 DroidEvolver 非常高效,因为 DroidEvolver 在恶意软件检测期间利用在线学习算法从各个漂移应用程序更新其老化模型,而不是以批量方式定期从累积应用程序集合中重新训练。与最先进的恶意软件检测系统 MAMADROID 相比,DroidEvolver 在我们的实验中实现了显着更高的准确性和更高的效率。论文的其余部分组织如下。第二节详细介绍了 DroidEvolver 的系统设计。第三节介绍了实验设置和实验中使用的参数调整。第四节从不同方面评估了 DroidEvolver,分析了实验结果并讨论了其局限性。第五节总结了相关工作,第六节总结了本文。

2 DROIDEVOLVER 的设计

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

DroidEvolver1的架构如图1所示。DroidEvolver由两个阶段组成,包括初始化阶段和检测阶段。在初始化阶段,DroidEvolver 将一组与真实标签(即“恶意”和“良性”)相关的已知应用程序作为输入,并输出一组特征和一组检测模型,这些模型被传输到检测阶段。在检测阶段,DroidEvolver 将每个真实标签未知的应用程序作为输入,并输出未知应用程序的预测标签。 DroidEvolver的初始化阶段由四个模块组成,包括预处理器、特征提取、向量生成和模型池构建。对于输入中的每个已知应用程序,预处理器应用 apktool [37] 反编译其 apk 文件并获取其反汇编的 dex 字节码,其中包括该应用程序中使用的 API 调用。然后,特征提取模块用于提取所有Android API并记录每个应用程序的Android API二进制存在作为该应用程序的检测特征。初始特征集是一个全序集,通过组合输入中所有应用程序的检测特征来构造。特征空间是通过从初始特征集中的所有特征到特征空间的维度的一对一映射来构造的。在向量生成模块中,DroidEvolver 通过将应用程序的检测特征映射到特征空间中,为所有检测模型生成每个应用程序的特征向量,其中落在初始特征集中的每个检测特征被映射到组件一,而其他组件设置为零。给定输入中所有应用程序生成的特征向量,模型池构建模块构建一个初始模型池,该模型池由一组检测模型组成。每个检测模型都使用不同的在线学习算法进行初始化,该算法根据其特征向量和真实标签处理所有输入应用程序。在初始化阶段结束时,DroidEvolver 将初始特征集和初始模型池传输到检测阶段。模型池中的每个检测模型都与一个特征集指示器相关联,该指示器指示检测模型可以处理的特征数量。所有特征集指标都被初始化为初始特征集的大小,并且在检测阶段可以增加到更大的值。在检测阶段,DroidEvolver 将每个未知应用程序分类为恶意或良性,并对功能集和检测模型执行必要的更新。检测阶段的前三个模块与初始化阶段的模块类似,除了(i)动态更新特征集以包含新特征,(ii)通过 1-to 为每个检测模型构建特征空间。 -1 从特征集中序号小于检测模型的特征集指示符的所有特征映射到特征空间的维度,并且 (iii) DroidEvolver 通过以下方式从每个应用程序为每个检测模型生成一个特征向量:将应用程序的检测特征映射到检测模型的特征空间。在特征提取模块中,DroidEvolver根据现有的Android API家族[24]提取Android API,包括android、java、javax、junit、apach、json、dom和xml。虽然 API 包的数量从 API 级别 1(2008 年 10 月发布的 Android 版本 1.0)的 96 个大幅增加到 API 级别 27(2017 年 11 月发布的 Android 8.1 版本)的 196 个,但 Android API 系列的名称随着时间的推移保持不变。在检测阶段,只要新 API 调用的 API 系列保持不变,DroidEvolver 就不会错过任何由 Android 框架演进引起的新 Android API 调用。检测阶段的最后一个模块是分类和进化。在此模块中,DroidEvolver 为输入中给出的每个未知应用程序生成分类结果(恶意或良性)。如果模型池中的某些检测模型在检测未知应用程序时老化,DroidEvolver 会通过包含未知应用程序中使用的所有新 Android API 调用来增量更新其功能集(不更改任何现有功能的序号),并更新每个老化模型的特征集指标到更新特征集的大小。此外,DroidEvolver 通过根据未知应用程序的分类结果和更新的特征向量进行学习来更新每个老化模型。本节的其余部分将阐明如何在初始化阶段构建模型池,以及如何在检测阶段实现分类和进化。

A. 模型池构建

在初始化阶段给定一组已知应用程序及其相关的真实标签,DroidEvolver 使用一组在线学习算法构建模型池,而不是用于恶意软件检测的任何单一检测模型。由于其能力有限,单一检测模型可能并不总是提供准确的检测结果[33]。模型池可以帮助检测和减轻任何单个检测模型的偏差,并在检测阶段生成更可靠的检测结果。模型池中的每个检测模型都是使用不同的在线学习算法构建的,该算法一次处理一个应用程序。在线学习的复杂度与输入中的应用程序数量成线性关系,这与需要同时处理一组应用程序的批量学习不同。下面给出了 DroidEvolver 中在线学习算法的常见流程。
0

被动攻击(PA)。

在线梯度下降(OGD)

权重向量的自适应正则化(AROW)。

正则化双重平均 (RDA)。

自适应前向-后向分裂(Ada-FOBOS)。

B. Classification and Evolvement

漂移应用程序识别 - 何时发展。

分类和伪标签生成 - 随之演变。

衰老模型年轻化——如何进化。

三.实验设置和参数调整

代码

feature_set_initialization

import pickle as pkl 
import os
import sysdef main():feature = []names = ['--list of app names developed in 2011 ----']for app_name in names:app_feature = pkl.load(open(app_name + '.feature', 'rb'))for item in app_feature:if item not in feature:feature.append(item)with open('feature_set.pkl','wb') as result:pkl.dump(feature, result)if __name__ == "__main__":main()

feature_extraction.py

'''
Extract detection feature for each app according to included Android APIinput: smali files of an app stored under /app_name/
output: detection features for the app stored in app_name.feature'''
import os
import sys
import string
import pickle as pkl
import argparse
import glob
import operatordef extract_feature(filedir):feature = []for dirpath, dirnames, filenames in os.walk(filedir):for filename in [f for f in filenames if f.endswith ('.smali')]:fn = os.path.join(dirpath, filename) # each smali filelines = open(fn,'r').readlines()lines = [line.strip() for line in lines]for line in lines:# get all class names in invoketry:start = line.index(', ') + len(', ')end = line.index(';', start)classes = line[start:end]except ValueError:classes = ''# get invoking method nametry:start = line.index(';->') + len(';->')end = line.index('(', start)methods = line[start:end]except ValueError:methods = ''objects = classes.split('/')a = len(objects)current_class = classes[:-(len(objects[a-1])+1)]if current_class in packages: # android apife = classes + ':' + methodsfeature.append(fe)with open(filedir + '.feature', 'wb') as result:pkl.dump(feature, result)def main():family = ['android','google','java','javax', 'xml','apache', 'junit','json', 'dom']# correspond to the android.*, com.google.*, java.*, javax.*, org.xml.*, org.apache.*, junit.*, org.json, and org.w3c.dom.* packagesglobal packagespackages = open('android_package.name','r').readlines()packages = [package.strip() for package in packages] # packages correspond to familyprint 'official package number:', len(packages)names = ['--list of app names ----']for app_name in names:extract_feature(app_name)if __name__ == "__main__":main()

vector_generation

#!/usr/bin/python
#coding:utf-8
'''
generate 2011.libsvm (i.e., the initialization dataset) from *.feature developed in 2011label: 1 = malicious, -1 = benign
'''import sys
import os
import string
import glob
import re
import string
import pickle as pkl
import argparsedef extract_benign(filedir):app_feature = pkl.load(open(filedir + '.feature','rb'))  # type: objectresult = []result.append('-1 ')for i in range(len(features)):if features[i] in app_feature:result.append(str(i+1) + ':1 ')data.append(result)def extract_malicious(filedir):app_feature = pkl.load(open(filedir + '.feature','rb'))result = []result.append('1 ')for i in range(len(features)):if features[i] in app_feature:result.append(str(i+1) + ':1 ')data.append(result)def main():global featuresfeatures = []features = pkl.load(open('feature_set.pkl','rb'))features = [feature.strip() for feature in features]print 'feature size:', len(features)print type(features)global data data = []# generate initialization datasetbenign_names = ['--list of benign apps developed in 2011 ---']for benign_app in benign_names:extract_benign(benign_app, marker)malicious_names = ['--list of malicious apps developed in 2011 --']for malicious_app in malicious_names:extract_malicious(malicious_app, marker)data_file = open('2011.libsvm', 'w') # apps developed in 2011 is the initialization datasetfor item in data:data_file.writelines(item)data_file.writelines('\n')data_file.close()if __name__ == "__main__":main()

model_pool_construction

'''
Construct model pool according to initialization dataset, e.g., apps developed in 2011'''
import pylibol
import numpy as np
import scipy
from scipy.stats import logistic
from scipy.special import expit
from numpy import dot
import sklearn
from sklearn.datasets import load_svmlight_file
import os
import sys
import string
from decimal import *
import collections
from pylibol import classifiers
from classifiers import *
import time
import random
import argparsedef main():parser = argparse.ArgumentParser()parser.add_argument('--starting', type=int, help='initialization dataset') # to use = args.initializationargs = parser.parse_args()starting_year = args.startingX_train,Y_train=load_svmlight_file(str(starting_year) + '.libsvm')print 'X_train data shape' , type(X_train), X_train.shapeglobal clfsclfs = [PA1(), OGD(), AROW(), RDA(), ADA_FOBOS()]print 'model pool size: ', len(clfs) # number of models in the model poolori_train_acc = []directory = './' + str(starting_year) + 'train/' if not os.path.exists(directory):os.makedirs(directory)# initialization process of all models print 'All model initialization'for i in xrange(len(clfs)): # i = every model in model poolprint clfs[i]print 'training'train_accuracy,data,err,fit_time=clfs[i].fit(X_train,Y_train, False)ori_train_acc.append(train_accuracy)clfs[i].save('./' + str(starting_year) + 'train/' + str(starting_year) + '_' + str(i) + '.model')print 'original model accuracy', ori_train_accif __name__ == "__main__":main()

classification_evolvement.py

'''
Use the model pool initialized with 2011 apps to detect malware from apps developed in 2012, 2013, 2014, 2015, 2016
Model pool and feature set (i.e., feature_set.pkl) are evolved during detection.'''
import pylibol
import numpy as np
import scipy
from scipy.stats import logistic
from scipy.special import expit
from numpy import dot
import sklearn
from sklearn.datasets import load_svmlight_file
import os
import sys
import string
from decimal import *
import collections
from pylibol import classifiers
from classifiers import *
import time
import random
import pickle as pkl
import argparse
import shutilclass app(object):def __init__(self, a, y, pl):self.a = aself.y = yself.pl = pldef extract_benign(filedir):app_feature = pkl.load(open(filedir + '.feature','rb'))result = []result.append('-1 ')new = []for i in range(len(features)):if features[i] in app_feature:result.append(str(i+1) + ':1 ')for item in app_feature:if item not in features: # this is a new feature, store new features in advance to save timep = 1# append the new feature to the data# the model won't process this new feature unless update # the model will only process the first |len(features)| featuresresult.append(str(len(features) + p) + ':1 ') new.append(item)p += 1return result, newdef extract_malicious(filedir):app_feature = pkl.load(open(filedir + '.feature','rb'))result = []result.append('1 ')new = []for i in range(len(features)):if features[i] in app_feature:result.append(str(i+1) + ':1 ')for item in app_feature:if item not in features: # this is a new featurep = 1# append the new feature to the data# the model won't process this new feature unless update # the model will only process the first |len(features)| features# if this app is a drifting app, the new identified feature will be added into feature_set.pklresult.append(str(len(features) + p) + ':1 ') new.append(item)p += 1return result, newdef evaluation(Y_test, instances):n = p = tp = fn = tn = fp = right = 0print 'evaluating predictions'for e in xrange(len(Y_test)):if Y_test[e] != 1 and instances[e].pl != 1: # true label, prediction labeln += 1tn += 1if Y_test[e] != 1 and instances[e].pl == 1:n += 1fp +=1if Y_test[e] == 1 and instances[e].pl == 1:p += 1tp += 1if Y_test[e] == 1 and instances[e].pl != 1:p += 1fn += 1if Y_test[e] == instances[e].pl:right += 1print type(Y_test), len(Y_test)print 'all', n+p, 'right', right ,'n', n , 'p:', p, 'tn', tn, 'tp',tp, 'fn',fn, 'fp',fpaccu = (Decimal(tp) + Decimal(tn))*Decimal(100) / (Decimal(n) + Decimal(p))tpr = Decimal(tp)*Decimal(100)/Decimal(p)fpr = Decimal(fp)*Decimal(100)/Decimal(n)f1 = Decimal(200)*Decimal(tp)/(Decimal(2)*Decimal(tp) + Decimal(fp) + Decimal(fn))precision = Decimal(tp)*Decimal(100)/(Decimal(tp) + Decimal(fp))print 'model pool f measure: ', float(format(f1, '.2f')), 'precision: ', float(format(precision, '.2f')), 'recall: ', float(format(tpr, '.2f'))return float(format(accu, '.2f')), float(format(f1, '.2f')), float(format(precision, '.2f')), float(format(tpr, '.2f')), float(format(fpr, '.2f'))def metric_calculation(i, j, buffer_size):larger = 0if len(app_buffer) <=buffer_size:app_temp = [item[j] for item in app_buffer]positive = sum(app_tt > 0 for app_tt in app_temp)negative = sum(app_tt <= 0 for app_tt in app_temp) if confidences[i][j] > 0: # prediction label = 1 = maliciouslarger = sum(confidences[i][j] >= app_t and app_t > 0 for app_t in app_temp)p_ratio = float(Decimal(larger)/Decimal(positive))else: # <= 0 = benignlarger = sum(confidences[i][j] <= app_t and app_t <= 0 for app_t in app_temp)p_ratio = float(Decimal(larger)/Decimal(negative))else: app_temp = [item[j] for item in app_buffer[len(app_buffer)-buffer_size:]] positive = sum(app_tt > 0 for app_tt in app_temp) negative = sum(app_tt <= 0 for app_tt in app_temp)if confidences[i][j] > 0: # prediction label = 1 = maliciouslarger = sum(confidences[i][j] >= app_t and app_t > 0 for app_t in app_temp)p_ratio = float(Decimal(larger)/Decimal(positive))else:larger = sum(confidences[i][j] <= app_t and app_t <= 0 for app_t in app_temp)p_ratio = float(Decimal(larger)/Decimal(negative))return p_ratiodef all_model_label(i, age_threshold_low, age_threshold_up):young = aged = a_marker = y_marker = 0for j in xrange(len(clfs)):if age_threshold_low <= p_values[i][j] <= age_threshold_up: # not an aged model, can voteyoung += confidences[i][j]y_marker += 1 # number of young modelelse: # this is an aged model, need to be updatedaged += confidences[i][j]aged_model.append(j) # record aged model indexa_marker += 1 # num of aged model for this drifting appreturn young, aged, a_marker, y_markerdef generate_pseudo_label(aged_marker, young_marker, aged_value, young_value):if young_marker == 0: # young models are not available; weighted voting using aged modelif aged_value > 0:temp = app(aged_marker, young_marker, 1.)else:temp = app(aged_marker, young_marker, -1.)fail += 1else: # young models are available; weighted voting using young modelif young_value > 0:temp = app(aged_marker, young_marker, 1.)else:temp = app(aged_marker, aged_marker, -1.)instances.append(temp)def save_model(current_year, checkpoint_dir):for m in xrange(len(clfs)):print m, clfs[m]clfs[m].save( checkpoint_dir + str(current_year) + '_' + str(m) + '.model')def main():# set argument for past year and current yearparser = argparse.ArgumentParser()parser.add_argument('--past', type=int, help='past year')parser.add_argument('--current', type=int, help='current year')parser.add_argument('--starting', type=int, help='starting year') # initialization year = 2011parser.add_argument('--low', type=float, help='low threshold value')parser.add_argument('--high', type=float, help='high threshold value')parser.add_argument('--buffer', type=int, help = 'buffer size value')args = parser.parse_args()buffer_size = args.bufferage_threshold_low = args.lowage_threshold_up = args.highglobal featuresfeatures = pkl.load(open('feature_set.pkl','rb'))whole_directory = './'+ str(args.starting) + 'train/'current_directory = str(age_threshold_low) + '_' + str(age_threshold_up) + '_' + str(buffer_size) + '/' checkpoint_dir = whole_directory + current_directoryif not os.path.exists(checkpoint_dir):os.makedirs(checkpoint_dir)global clfsclfs = [PA1(), OGD(), AROW(), RDA(), ADA_FOBOS()]print 'model pool size: ', len(clfs)ori_train_acc, ori_test_acc, weights, pool_acc, pool_fscore, pool_precision, pool_tpr, pool_fnr, pool_fpr, pool_difference = ([] for list_number in range(10))print 'Loading trained model from ', args.pastif args.starting == args.past: # copy the initial detection model into checkpoint_dirfor i in xrange(len(clfs)):shutil.copy2( whole_directory + str(args.past) + '_' + str(i) + '.model' , checkpoint_dir )for i in xrange(len(clfs)): # for each model in the model poolclfs[i].load( checkpoint_dir + str(args.past) + '_' + str(i) + '.model')# get original model weightw = clfs[i].coef_[1:]weight = [] # [i][j]: i = model index, j = feature indexfor w_num in xrange(len(w)):weight.append(w[w_num])weights.append(weight)print 'original weight size'for c in xrange(len(weights)):print c, len(weights[c])print 'App buffer generation'global app_bufferapp_buffer = []if '2011' in str(args.past): # buffer is not existprint 'App buffer not exists'print 'App buffer initialization'print 'Loading data from ', args.past, ' to initialize app buffer ...' # load the 2011 data to initialized app bufferX_train,Y_train=load_svmlight_file( str(args.past) + '.libsvm')train_size, _  = X_train.shaperandom_app_index = np.random.randint(train_size, size = buffer_size)X_train_temp = X_train[random_app_index, :]for i in xrange(buffer_size):app_buffer_temp = []for j in xrange(len(clfs)):app_buffer_temp.append(clfs[j].decision_function(X_train_temp[i])[0])app_buffer.append(app_buffer_temp)else: # load buffer from str(args.past).bufferprint 'App buffer exists'app_buffer = pkl.load(open( checkpoint_dir + str(args.past) + '_buffer.pkl', 'rb'))print 'Load app buffer from ', args.past, '_buffer.pkl'print 'Start evolving'global confidences, new_confidences, p_values, instances, model_credits, model_confidencesconfidences, new_confidences, p_values, instances, model_credits, model_confidences = ([] for list_number in range(6))all_fail = 0 # a special case, all model are agednum_of_update = num_of_update_model =  0wrong_update = 0wrong_update_benign = wrong_update_malicious = right_update_benign = right_update_malicious = 0Y_test = [] # save ground truth of test data ; for final evaluation onlynames = ['---list of test app names -----'] # names of apps developed in the current_year, e.g., names of apps developed in 2012for i in xrange(len(names)):# generate test dataapp_name = names[i] # for each test app# according to the ground truth to get the true label# the true label is for evaluation only, won't be processed by the modeldata = []if 'malicious' in app_name:d, new_feature = extract_malicious(app_name)data.append(d)else:d, new_feature = extract_benign(app_name)data.append(d)# skip if do not need to save test datasave_data = open(app_name + '.libsvm', 'w')for item in data:save_data.writelines(item)save_data.writelines('\n')data_file.close()X_test, y_t=load_svmlight_file(app_name + '.libsvm')X_testt,y_testt=load_svmlight_file(app_name + '.libsvm')Y_test.append(y_t)print 'X_test data shape', type(X_test), X_test.shapextest_dense = scipy.sparse.csr_matrix(X_testt).todense()print 'X_test', xtest_dense.shape	# calculate JI valuepre, conf, new_conf, app_b, p_value = ([] for list_number in range(5))for j in xrange(len(clfs)):xtest_current = xtest_dense[ ,:len(weights[j])] score = xtest_current.dot(weights[j])conf.append(score[0,0])app_b.append(score[0,0])new_conf.append(abs(score[0,0]))confidences.append(conf)new_confidences.append(new_conf)app_buffer[random.randint(0, buffer_size-1)] = app_b # randomly replace a processed app with the new appfor j in xrange(len(clfs)):pv = metric_calculation(i, j, buffer_size)p_value.append(pv)p_values.append(p_value) global aged_modelaged_model = [] # store the index of aged model for current app iyoung_value = aged_value = aged_marker = young_marker = 0young_value, aged_value, aged_marker, young_marker = all_model_label(i, age_threshold_low, age_threshold_up)# generate  pseudo labelgenerate_pseudo_label(aged_marker, young_marker, aged_value, young_value)# drifting app is identified and young model existsif (aged_marker != 0) and (young_marker >= 1): update_label = np.array([instances[i].pl]) # update label = pseudo label of the drifting app# update aged modelsfor model_index in aged_model: # update clfs[a] with X_test, update_label; a is the aged model index# update with drifting app and corresponding pseudo labeltrain_accuracy,data,err,fit_time=clfs[model_index].fit(X_test,update_label, False)w = clfs[model_index].coef_[1:] updated_w = []for w_num in xrange(len(w)):updated_w.append(w[w_num])weights[model_index] = updated_w # update weight matrix in the weight matrix list for the next new app# updat feature setfor new_identified_feature in new_feature:features.append(new_identified_feature)a, f, preci, tprr, fprr = evaluation(Y_test, instances)pool_acc.append(a)pool_fscore.append(f)pool_precision.append(preci)pool_tpr.append(tprr)pool_fnr.append(100-tprr)pool_fpr.append(fprr)print buffer_size, len(app_buffer)print 'pool accuracy', pool_accprint 'pool fscore', pool_fscoreprint 'pool precision', pool_precisionprint 'pool tpr', pool_tprprint 'pool fnr', pool_fnrprint 'pool fpr', pool_fprprint 'evolved weight length'for c in xrange(len(weights)):print c, len(weights[c])# save evolved model for each yearprint 'Save model evolved in Year ', args.current, 'into directory /', checkpoint_dircurrent_year = args.currentsave_model(current_year, checkpoint_dir)# save feature setwith open('feature_set.pkl','wb') as feature_result:pkl.dump(features, feature_result)print 'Save app buffer evolved in Year', args.currentpkl.dump(app_buffer, open( checkpoint_dir + str(args.current) + '_buffer.pkl', 'wb'))if __name__ == "__main__":main()

http://www.ppmy.cn/embedded/138278.html

相关文章

【Qt实现虚拟键盘】

Qt实现虚拟键盘 &#x1f31f;项目分析&#x1f31f;实现方式&#x1f31f;开发流程 &#x1f31f;项目分析 需求&#xff1a;为Linux环境下提供可便捷使用的虚拟键盘OS环境&#xff1a;Windows 7/11、CentOS 7开发语言&#xff1a;Qt/C IDE&#xff1a;QtCreator 、Qt5.14.2功…

HarmonyOS4+NEXT星河版入门与项目实战--------开发工具与环境准备

文章目录 1、熟悉鸿蒙官网1、打开官网2、下载 DevEco Studio3、HarmonyOS 资源库4、开发指南与API 2、安装 DevEco Studio1、软件安装2、配置开发工具 1、熟悉鸿蒙官网 1、打开官网 百度搜索 鸿蒙开发者官网 点击进入开发者官网&#xff0c;点击开发&#xff0c;可以看到各种…

Postman接口测试(断言、关联、参数化、输出测试报告)

基本界面展示 Get、Post请求 Postman断言 使用postman来判断预期结果与实际结果是否一致 响应状态码断言 响应包含字符串 断言判断字符串的格式 关联 用于解决http请求之间存在依赖关系 依赖&#xff1a;一个http请求的响应结果中的数据&#xff0c;被另一个请求使用 登…

【数据结构】10.线索二叉树

一、线索二叉树的产生 采用先序、中序、后序三种方法遍历二叉树后都可以得到一个线性序列&#xff0c;序列上的每一个结点&#xff08;除了第一个和最后一个&#xff09;都有一个前驱和一个后继&#xff0c;但是&#xff0c;这个线性序列只是逻辑的概念&#xff0c;不是物理结…

深度学习在边缘检测中的应用及代码分析

摘要&#xff1a; 本文深入探讨了深度学习在边缘检测领域的应用。首先介绍了边缘检测的基本概念和传统方法的局限性&#xff0c;然后详细阐述了基于深度学习的边缘检测模型&#xff0c;包括其网络结构、训练方法和优势。文中分析了不同的深度学习架构在边缘检测中的性能表现&am…

ESP32C3单片机使用笔记---烧录MicroPython

使用MicroPython在ESP32C3单片机上编程&#xff0c;首先需要将MicroPython运行环境烧录到ESP32C3的Flash中去&#xff0c;步骤如下&#xff1a; 1.下载esptool烧录工具&#xff0c;下载地址&#xff1a; https://github.com/espressif/esptool 直接使用git clone git clone…

MongoDB自定义顺序排序

自定义顺序排序方法 以下是在MongoDB中实现自定义顺序排序的方法&#xff1a; 在数据集中添加一个自定义字段。使用update命令或$set操作符为每个文档添加自定义字段。在我们的例子中&#xff0c;我们可以通过以下命令为每个学生添加”grade”字段&#xff1a; db.students.…

androidstudio入门到放弃配置

b站视频讲解传送门 android_studio安装包&#xff1a;https://developer.android.google.cn/studio?hlzh-cn 下载安装 开始创建hello-world 1.删除缓存 文件 下载gradle文件压缩&#xff1a;gradle-8.9用自己创建项目时自动生成的版本即可&#xff0c;不用和我一样 https://…