软件学报  2017, Vol. 28 Issue (6): 1389-1404   PDF    
一种面向软件配置管理制品的层次分类方法
徐培兴1,2, 陈伟1, 吴国全1,2,3, 高楚舒1, 魏峻1,2,3     
1. 中国科学院 软件研究所, 北京 100190;
2. 中国科学院大学, 北京 100049;
3. 计算机科学国家重点实验室(中国科学院 软件研究所), 北京 100190
摘要: 配置管理工具(configuration management tool,简称CMT)作为运维自动化的组成部分,是实现开发运维一体化(development and operations,简称DevOps)的重要支撑技术.当前,互联网开源社区中存在数量众多的CMT脚本制品,但是缺乏有效的层次分类管理,给快速检索和高效利用CMT脚本制品带来困难.针对该问题,提出一种面向CMT制品的基于在线非结构化描述文档分析的层次分类方法.该方法利用标签共现性关系(tag co-occurrence)建立层次类别体系,基于描述属性特征,实现对CMT制品的层次分类器;并使用混合的样本划分方式针对数据倾斜问题进行了改进.对超过11 000例训练数据和1 000例测试数据进行实验,结果表明:改进的样本划分方式得到的最佳查准率、查全率、调和平均值分别达到0.81、0.88、0.85,较传统方式查全率提高0.15,调和平均值提高0.06.该结果验证了层次分类方法的有效性.
关键词: CMT制品     层次分类     开源社区     开发运维一体化(DevOps)    
Hierarchical Categorization for Artifacts of Configuration Management Tool
XU Pei-Xing1,2, CHEN Wei1, WU Guo-Quan1,2,3, GAO Chu-Shu1, WEI Jun1,2,3     
1. Institute of Software, The Chinese Academy of Sciences, Beijing 100190, China;
2. University of Chinese Academy of Sciences, Beijing 100049, China;
3. State Key Laboratory of Computer Science(Institute of Software, The Chinese Academy of Sciences), Beijing 100190, China
Foundation item: National Natural Science Foundation of China (61402453); National key Research and Development Plan (2016YFB1000803)
Abstract: Configuration management tool (CMT), as an essential part of automated system operations, is an important technique to achieve DevOps (development and operations). There are a large amount of reusable CMT artifacts in the internet-scale open source communities and repositories. However, the lack of effective hierarchical categorization leads to the difficulties of effective retrieval and usage of those artifacts. This paper addresses the issue by proposing a hierarchical categorization method for CMT artifacts based on their online unstructured descriptions. This method firstly constructs a category system based on the co-occurrences of tags, and then designs the classifiers based on the features of CMT artifacts, including name and description. To improve the effectiveness of classifications affected by the unbalanced data set, the method builds a hybrid model to divide the sample data. Finally, extensive experiments are carried out to evaluate the method on more than 11000 CMT artifacts. The results show that this improved method based on hybrid model achieves up to 0.81 precision, 0.88 recall and 0.85 F-measure. Comparing to traditional approaches, the recall and F-measure of CMT artifacts classification improve significantly. The effectiveness of this method is verified.
Key words: CMT artifact     hierarchical categorization     open source community     development and operations (DevOps)    

配置管理工具(configuration management tool, 简称CMT)是实现开发运维一体化(development and operations, 简称DevOps)的重要支撑工具, 当前主流的CMT采用代码即基础设施(infrastructure as code, 简称IaC)[1]的方式, 通过代码来描述目标系统配置, 实现自动化的系统安装和配置, 从而满足DevOps所倡导的持续交付、快速部署和高效运维.基于此, 使用CMT已成为运维管理领域的主流趋势.据RightScale云计算年度报告[2], 2016年, 超过70%的企业正在使用Chef, Puppet, Ansible等CMT工具.CMT制品是CMT工具用以安装、配置和管理特定的软件系统的可复用执行脚本.在开源技术社区快速发展的背景下, CMT社区同样积累了大量并且持续快速增长的CMT制品, 例如, Chef[3], Puppet[4], Ansible[5]中3个CMT社区已有4 200多用户, 贡献超过14 000个CMT制品, 其中, Ansible社区自2014年至今, 其CMT制品数量由660增长为6 895, 两年间增长达10倍, 而且正吸引越来越多的贡献者.另一方面, 当前软件制品社区如OpenHub[6], SourceForge[7]等已有超过670 000个软件, 在DevOps的发展趋势下, 如果能全面实现自动化部署和配置, 那么CMT制品将出现更大规模的增长.

但是, 大量存在的CMT制品在提升工具的易用性和制品的复用性的同时, 也给正确选择和使用CMT制品带来了困难.当前主流CMT(如Puppet, Ansible)的官方社区仅提供简单资源列表以及关键字匹配的搜索服务, 用户在查找与需求匹配的脚本制品时, 需要花费大量时间对搜索结果进行浏览和细化.例如, 用户在Puppet社区中以monitoring作为关键字搜索面向监控软件的CMT制品时, 得到包括诸如zabbix[8], nagios[9]等在内的多达124个脚本制品, 用户仍需要额外花费大量的精力和时间从中找到满足特定系统和版本等需求的脚本制品.其他脚本制品库如Ansible, Chef社区等也存在类似的情况.针对上述问题, 部分资源库采用标签(tag)的方式来增强检索的准确性, 但标签可由开发者自定义创建, 缺乏规范性, 极大依赖于制品开发人员的领域知识和标签使用习惯.其次, 标签的扁平化特征无法反映出标签之间实际存在的层次化关系.因此, 软件运维管理领域迫切需要一种CMT制品的自动化层次分类机制, 以满足用户快速检索和准确定位目标制品的需求.层次化分类将大规模数据按照特征逐级划分, 细化范围, 将层次分类应用于CMT制品, 不仅提高检索效率和准确度, 还能够构建脚本制品间层次关联关系, 有助于脚本制品的维护管理, 提高CMT制品的利用率.但是, CMT制品的层次分类面临以下难题.

1) 与传统的软件库(如source forge)不同, 当前CMT领域并不存在面向CMT制品的可用的、预定义的层次分类体系, 因而也没有已进行层次类别标注的实验数据; 即使部分CMT制品库采用标签机制进行标识, 但是无法反映标签间的层次化关系;

2) CMT制品与特定的领域编程语言相关[10].例如, Chef, Ansible和CFEngine[11]使用命令式(imperative)的脚本语言实现面向特定软件系统的部署配置操作自动化, 而Puppet和SmartFrog[12]则通过声明式(declarative)语言描述期望达到的目标状态来实现任务的自动执行.因此, 无法使用传统的基于程序分析的方法[13-15]来实现制品分类.

针对上述问题, 本文提出了一种基于制品描述信息(profile)的CMT制品层次分类方法:首先, 该方法以CMT制品库中频繁使用的标签作为类别标识, 通过挖掘这些标签间的隶属关系来构建层次化分类体系; 然后, 该方法基于监督学习训练并建立一组分类器支持CMT制品的自动分类.方法通过标签匹配(tag matching)对Puppet和Ansible的CMT制品进行标注并将其作为训练数据, 接着以CMT制品描述信息中的名称(name)和描述(description)作为描述文档, 采用TF-IDF(term frequency-inverse document frequency)[16]抽取文档特征, 最后使用机器学习方法实现CMT制品的分类器.

最后, 本文基于对3个主流CMT资源库超过11 000个制品进行层次化分类实验进行评价.实验结果表明: (1) 本文方法抽取了90个细粒度的类别标识, 并构建了基于这些类别的4层分类体系, 有助于用户更加准确的定位目标CMT制品; (2) 本文方法在CMT制品分类方面具有较好的准确率(precision)、召回率(recall)和调和平均数(F-Measure), 分别达到0.81, 0.88和0.85.

本文的主要贡献归纳如下:

1) 提出一种面向CMT制品的层次分类方法.该方法基于制品描述信息提取分类特征, 不依赖于特定领域语言, 能够对制品实施细粒度的层次化分类;

2) 本文面向超过11 000个CMT制品构建了包含90个分类标识、细粒度的多层次分类体系;

3) 基于多个CMT社区制品数据的实验和方法评价.本文选取当前主流CMT工具的上万个脚本制品及其社区数据为对象, 对文中提出的分类方法进行了实验、对比和评价.实验结果表明:本文方法在调和平均值方面达到0.85, 较类似的软件制品分类方法[17]提高0.2;使用混合方式的正反面样本划分策略改进分类模型, 相比传统划分策略, 查全率提高0.15, 调和平均值提高0.06, 整体分类效果得到有效的提升.

本文第1节介绍研究动机, 并在此基础上对本文方法进行概述.第2节详细介绍面向CMT制品的层次分类方法.第3节基于本文方法开展CMT制品分类的相关实验和结果评价分析.第4节介绍相关研究工作.最后, 第5节对本文工作进行总结.

1 研究动机

配置管理工具通过CMT制品对应用进行部署和配置管理, CMT制品由特定领域语言(DSL)实现, 一般包含配置代码、安装文件、模板、说明文件等部分, 是独立的可复用和共享的配置单元.例如:cookbook[18]是Chef进行配置和管理的脚本制品, 每个cookbook包含recipes(配置代码)、参数、安装文件、模板、说明文件; Puppet制品包含manifests(配置代码)、模板、说明文件等.

制品由各自的CMT社区知识库(如puppet forge, chef cookbook supermarket[3])管理, 开发者向知识库中提交自己开发的制品时, 要提供制品的名称、描述、标签以方便识别.图 1展示了名称为“BoxUpp/mysql”用以安装配置MySQL的Puppet制品主页, 显示了制品的名称、描述、标签等属性.

Fig. 1 Page of BoxUpp/mysql in Puppet Forge 图 1 Puppet Forge中的BoxUpp/mysql主页

目前, Puppet, Ansible和Chef是最流行的配置管理工具, 3种工具的知识库共有超过14 000例CMT制品.表 1列出了不同知识库中的CMT制品示例.这些制品功能相似但名称和描述不完全相同, 其中, Chef知识库中的制品没有标签属性.

Table 1 Examples of CMT scripts 表 1 CMT制品示例

为了将上述CMT制品的进行自动化层次分类, 需要解决以下技术问题.

1) 不同于文献[17]关于软件制品层次分类的已有工作, CMT制品没有预定义的层次类别, 如何进行划分?

2) 标签能够在一定程度上标识制品类别特征, 如何从扁平化的标签中构建出层次类别?

3) 对于某个层次类别, 如何建立与具体CMT制品描述信息(如名称、描述、标签)的关联?

4) 不同领域的制品数量相差很大, 如Ansible知识库中有3 000例制品标注“system”标签, 而被标注为“server”的只有45例, 如何处理类似非平衡的数据集?

通常情况下, 开发者为所提交制品进行标注时会选择与制品本身功能特性符合的关键字, 如表 1中的标签database, sql, db, mysql等, 类似标签在MySQL相关的制品中大量出现.因此, 可以将标签作为制品的类别主题.同时, 通过观察发现, CMT制品的不同标签间隐含了隶属关系, 例如, BoxUpp/mysql与puppetlabs/mongodb含有相同的标签database, 这表明, database比mysql和mongodb更一般化, 即, mysql和mongodb可以作为database的子类别(subcategory).基于此, 能够建立标签层级分类, 并将带有标签属性的制品进行划分.

表 1中所列出的制品为例, CMT制品的名称反映该制品所管理的应用, 描述简要介绍了制品功能, 标签以关键字形式概括该制品的特征.同时, 一些相同关键词频繁出现在相似的制品描述中, 如表中有3个CMT制品描述都出现了mysql, 该词也出现在其标签列表中.这表明CMT制品的名称、描述与其标签具有关联性, 注意到Chef制品没有标签属性, 因此可以利用CMT制品共有的名称和描述作为特征, 对Chef制品进行聚合并划分到已有的分类体系中.

我们依据标签, 将Puppet和Ansible的制品匹配到对应类别中作为训练集, 利用名称和描述的文本特征进行分类器训练, 以实现对无标签Chef制品的层次分类.为了应对非平衡的分类数据集问题, 本文提出一种混合策略, 依据分类树中兄弟类别数目, 在同层次类别划分中分别使用one-against-rest和divide-by-2[19]的两种样本划分方法.

2 CMT制品层次分类方法

图 2展示了面向CMT制品的自动层次分类过程, 该过程主要有3个步骤.

Fig. 2 Process of classification for CMT artifacts 图 2 脚本制品层次分类过程

1) 构建层次类别.从Puppet和Ansible知识库中爬取包含标签属性的10 790个CMT制品, 找出常用标签作为类别关键字, 从中挖掘出隶属关系来构建层次分类;

2) 训练分类器.使用标签匹配方法将Puppet和Ansible的CMT制品标注到对应分类中, 再基于有监督学习方法, 通过训练上述CMT制品的说明文档特征(名称、描述)构建一系列层次化的分类器;

3) CMT制品分类.使用得到的分类器实现对其他CMT知识库(如Chef)的制品的层次分类.

2.1 构建层次类别

部分软件社区存在软件制品的分类体系, 如SourceForge社区将软件分为Audio & Video, Business & Enterprise等10类别, 每个类别内再进行更细粒度的划分.CMT制品的分类与软件分类相似, 但CMT制品本身用于管理和配置软件, 尤其是复杂的大规模软件系统, 如数据库系统、负载均衡、Web应用等, 这些系统大部分运行于类Unix平台, 以开发类、工具类为主, 与通用软件的领域有所不同, 因此, 目前的软件制品分类体系无法满足CMT制品的分类需求, 有必要构建CMT领域的分类层次.

正如前文所提到, 标签能够反映制品的类别主题, 因此, 我们使用标签作为类别关键字构建分类.然而标签由开发者自行选择关键字标注, 受限于开发者领域知识差别, 存在一些同义词标签, 因此需要将标签进行标准化.我们使用StackOverFlow社区的同义词库[20]来实现这一过程, 如, 将mongo, mongod转换为标准描述mongodb, 将zmq, 0mq转换为标准描述zeromq.同时, 为保证作为类别关键字的标签具有代表性, 排除拼写错误, 我们过滤掉出现频度小于阈值(30次)的标签.

目前已有标签是扁平化的, 如表 1中, mysql, sql, database等标签共同标注MySQL制品, 不能直接反映标签间的逻辑隶属关系; 然而, database标签还会出现在mongodb制品中, 我们使用标签对(mysql, database)及(mongodb, database)分别表示database标签在两个制品的出现.database同时概括两个制品的特征, 表明该标签可以作为mysql, mongodb逻辑上的父类标签, 因此, 我们基于该标签共现(tag co-occurrence)[21]在大量标签对中挖掘隶属关系.

对于给定的两个标签AB, 我们使用AB表示AB的子类别.如果满足如下条件, 我们认为AB关系成立.

1) 如果某一制品被标注A标签, 那么该制品很可能被同时标注B标签.即:A标签出现情况下, 其父标签B很可能同时出现.我们使用AB表示这一可能性;

2) |A|<|B|.即:对于所有的制品, 带有A标签的制品数量小于B标签的数量.

我们使用p(t)表示标签t出现的可能性:

$ p(\mathit{t}) = \frac{{\left| t \right|}}{N} $ (1)

其中, N为CMT制品的总数, |t|是所有制品中带有标签t的数量.

基于上述条件, 标签共现AB可使用公式(2) 表示:

$ \begin{array}{l} support(A \to \mathit{B}) = \mathit{p}(\mathit{A} \cap \mathit{B}) = \frac{{\left| {\mathit{A} \cap \mathit{B}} \right|}}{N}\\ confidence(\mathit{A} \to \mathit{B}) = \mathit{p}(\mathit{B}|\mathit{A}) = \frac{{\left| {\mathit{A} \cap \mathit{B}} \right|}}{{\mathit{p}(\mathit{A})}}\\ lift(\mathit{A} \to \mathit{B}) = \frac{{p(\mathit{B}|A)}}{{\mathit{p}(\mathit{B})}} \end{array} $ (2)

其中, 共现支持度support(AB)表示同时标注AB标签的制品比例; 共现置信度confidence(AB)表示当制品被标注A后, B标签出现的后验概率; 提升度lift(AB)表示A, B标签相关性的验证.

当上述3个值满足公式(3) 时, 可认为AB的隶属关系成立:

$ support(A \to \mathit{B}) > {\alpha _s}, confidence(\mathit{A} \to \mathit{B}) > {\alpha _\mathit{c}}, lift(\mathit{A} \to \mathit{B}) > {\alpha _l} $ (3)

其中, αs, αc, αl分别表示最小支持度、最小置信度以及提升度阈值.

通过上述分析, 我们从10 790例Puppet和Ansible制品中得到了带有隶属关系的标签对集.表 2所示nosql, mongodb, redis, elasticsearch是4个常用标签, 一方面, 其他标签都与nosql频繁同时出现; 另一方面, nosql的频度要多于其余3个标签, 因此可以推断出, nosql可以作为mongodb, redis, elasticsearch的父类别.

Table 2 Example of extracting hierarchical relations 表 2 隶属关系示例

同时需要注意到, 隶属关系具有传递性.例如, mysql, sql, database三者中, mysqlsqlsqldatabase, 则有mysqldatabase.因此, 可以通过树形结构表示层次分类, 向树中添加新的带有隶属关系的标签对, 最终实现整个分类树的构建.算法1展示了层次分类树的构建过程.该算法以宽度优先搜索构建层次分类树.首先, 使用一个Root节点初始化分类树(Mtree), 遍历标签集(T), 找到所有无父类别的顶级标签, 将其作为Root的孩子节点并添加到节点标签队列(qt)中.然后, 对于节点队列中的每个标签(t), 从该标签相关的标签对集合(Subt)中找到子标签集(Tc), 检测该集合中的标签(tc)是否已存在于分类树中:如果不存在, 直接将(t, tc)作为新的分支添加到树中, 并将tc加入队列qt; 否则, 比较已有标签对(tc.parent, tc)与(t, tc)的置信度, 保留置信度高的分支.最后得到以分类树形式表示的层次类别.

算法1.构建层次分类树算法.

Input:标签集T, 标签对集Subt, 分类树根节点Root;

Output:层次分类树Mtree.

qt=ø;

Mtree=Root;

for(i=0; iT.size(); i++) do

  t=T.get(i);

  if(t.parent()==null) then

     qt.add(t);

     Root.appendChild(t);

for(j=0; jqt.lenght(); j++)do

     t=qt.get(j);

     Tc=Subt.getChildren(t);

    /*get subcategory tags of t*/

    for each tc in Tc do

       if(qt.contian(tc)) then

         if(confidence(tc.parent, tc)<confidence(t, tc)) then

         /*keep the tag pair with max confidence*/

         Tc.parent.removeChidl(tc);

         t.appendChild(tc);

       else

         qt.add(tc);

         t.appendChild(tc);

return Mtree;

2.2 训练分类器

我们使用Puppet和Ansible知识库中的制品作为训练数据集, 把说明文档作为分类特征, 采用基于二元分类器的自上而下(top-down)分类方法[22], 并应用监督学习的几种分类算法来训练分类模型.

CMT制品的说明文档是制品名称与描述特征的文本聚合, 我们采用应用最广泛的TF-IDF模型[15]实现文本特征向量的抽取.该模型基本思想是:如果词w在某类文档中出现频率高, 而在其他文档中很少出现, 则词w具有很好的类别区分能力.公式(4) 展示了词项w在文档d中的TF-IDF的计算过程:

$ \left. \begin{array}{l} T{F_{w, d}} = \frac{{{n_{w, d}}}}{{\sum\nolimits_k {{n_{k, d}}} }}\\ ID{F_w} = {\rm{log}}\frac{{\left| U \right|}}{{{n_w}}}\\ TF\_ID{F_{w, d}} = T{F_{w, d}} \times ID{F_w} \end{array} \right\} $ (4)

其中, nw, d表示词w在文档d出现的频率, nw表示含有词w的文档个数, |U|表示文档全集的个数.

针对多类别层次分类, 有两类主要的分类方法:全局层次分类(big-bang)和自上而下分类(top-down)[22].全局层次分类对同层次整个类别学习一个多类别的分类器, 然而这种方法在类别总数较多时难以训练出效果良好的统一分类器.相反, 自上而下分类方法采用分而治之的策略, 按照类别层次自上而下对每一个类别单独构建分类器, 分解为局部分类问题, 然后在某类别内部再次构建分类器.文献[23, 24]指出, 自上而下分类方法在时间、空间开销方面都要优于全局层次分类.因此, 本文采用自上而下的分类方法.

在分类算法的方面, 目前有支持向量机(SVM)、k最近邻(kNN)以及朴素贝叶斯(Naïve Bayes)等多种算法, 其中, SVM算法是文本分类的最有效方法之一[25, 26].因此, 本文将使用SVM算法实现层次分类器; 同时, 也分别基于kNN及NB算法进行实验以验证和对比分类效果.

上一节我们从标签中得到了层次类别, 在这里, 我们使用标签匹配的方式, 将带有标签的制品分别对应到不同层次的类别中.在构建分类器时, 我们为每个类别都训练一个二类分类器, 这就需要确定该分类器的正面和反面样本.由于自上而下的分类方法使用分而治之策略, 因此, 这里的正反面样本都是在同一父类别范围内而言.

在多类别的分类问题中, 正反面样本的划分方式主要有3种[19].

1) one-against-one方法.每两个类别的数据分别作为正反面样本构建一个二类分类器, n个类别将有n(n-1)/2个分类器, 新样本的预测取决于分类器的分类选举; 这种方法分类器规模庞大且复杂;

2) one-against-rest方法.每个类别的样本与剩余所有类别的样本分别作为正反面样本, n个类别将构建n个二类分类器, 新样本通过n个二类分类器预测;

3) divide-by-2(DB2) 方法.将类别划分成样本规模相当的两个组, 分别作为正反面样本, 构建这两个组的分类器; 然后, 每个组内继续二分.如图 3所示, 以类别数目为5的分类问题为例, 首先将5个类划分成两组(a, b, c)及(d, e), 再分别进行组内划分, 最终构建了4个分类器来区分5个类别.

Fig. 3 Diagram of two-divide model 图 3 divide-by-2模型示意图

在CMT制品样本中, 不同类别的样本数量相差较大, 分布不均衡, 这将导致数据倾斜(unbalanced training data)问题.例如:在Ansible制品中, 标注为system标签的制品数量超过3 000例, 而标注为server的仅有45例; 而在同层级类别较多时, 使用one-against-rest划分样本, 某类别样本与该层级所有其他类别的样本也将形成数据倾斜.不平衡的数据集严重影响分类准确度, 为应对该问题, 本文提出一种混合的正反面样本划分策略, 将同一父类别的兄弟类别数目作为决策标准, 当该数目超过设定阈值(nsibling)时, 使用divide-by-2方法划分样本为两组, 直到组内类别数目不超过nsibling; 否则, 使用one-against-rest方法.其中, divide-by-2方法能够减小数据倾斜, 控制分类模型的复杂度, one-against-rest方法减小分类的出错率.

2.3 分类预测

在训练得到分类器后, 我们使用逐步细化的方法对CMT制品预测分类.算法2展示了对于给定新制品样本的分类过程.

算法2.分类预测算法.

Function main(Root, m)

  Input:分类树根节点Root, 待分类制品m;

  Output:目标类别tm.

  return findCategory(Root, m);

Function findCategory(t, m)

  Input:类别节点t, 待分类制品m;

  Output:目标类别tm.

  tcur=t;

  tm=t;

  qchildren=getChildren(tcur);

  /*get subcategories*/

  If(qchildren.isEmpty()==false) then

   isFind=fasle;

   /*a variable shows ending of search*/

   for(i=0; iqchildren.length(); i++) do

      tsub=qchildren.get(i);

      If(belongsTo(m, tsub) then

         isFind=true;

         return findCategory(tsub, m);

         /*execute recursively*/

   If(isFind==false) then

      returntm;

else

   returntm;

Function belongsTo(m, t)

  Input:类别t, 待分类制品m;

  Output:如果m属于t, 输出真; 否则为假.

   tclassifier=t.getClassifier();

   /*get the trained classifier*/

   mfeature=tf-idf(m);

   /*get the TF-IDF feature vector of m*/

     If(1==tclassifier.predict(mfeature)then

     return true;

  else

     return false;

算法2中, belongsTo方法判断制品样本m是否属于特定的类别t, 该方法从m中解析名称和描述作为说明文档, 并计算出该文档的TF-IDF特征向量(mfeature), 然后将该向量作为分类器预测的依据.我们从层次分类树的根节点Root开始, 调用findCategory方法, 以递归形式搜索m的目标类别, 如果给定制品样本m属于当前节点类别t, 那么m将继续在tn个子类别(t1, t2, …, tn)中继续划分, 直到m不属于t的任何子类别或搜索到达叶子节点.对于第1种情况, 当前的节点类别t即是制品的目标类别; 第2种情况下, 所到达的叶子节点类别是目标类别.考虑到某个制品可能属于多个分类的情况, 该算法对制品在多个类别中分别预测, 因此无需特别改动.

图 4展示了database类别下sql, nosql等子类以及其包含的CMT制品情况.算法2将puppetlabs/mysql以及arioch/redis分别划分到mysql和redis类别下, 然而golja/influxdb在被划分到database类别后没有进一步找到子类别, 因此将其直接划分到database类别下.

Fig. 4 Node of database and its children in hierarchical category tree 图 4 层次分类树中database节点示意图

3 实验及结果分析

本文设计了3组实验, 分别验证和评价本文的分类树构建方法和CMT制品分类方法的有效性, 并评估混合方式正反面样本划分策略对分类效果的影响.

3.1 实验数据预处理

本文基于Python的urlib2[27]和Beautiful Soup[28]实现了爬虫系统, 用以自动地从Puppet, Chef和Ansible制品库中爬取CMT制品.对于每个制品, 本文方法进行如下预处理.

1) 解析元数据中的说明文件, 抽取制品名称、描述、标签, 去除无描述和标签的制品数据;

2) 对3个属性进行分词处理, 利用停用词库去除a, of等停用词, 去除 & , *等无义字符, 保留词干; 另外, 数据中存在同一词语有多种表述形式的情况, 如zeromq可能被拼写为zmq或0mq, 论文从Stack Overflow[20]社区爬取了同义词库, 包含2 900组同义词, 通过同义词替换, 将相同含义的不同词汇规范成统一表述;

3) 将CMT制品名称和描述聚合, 作为该CMT制品描述文档, 而标签用于构建层次分类树.

经过上述处理, 得到数据集详细信息见表 3, 最终得到来自Puppet和Ansible社区的10 790例有效数据.除此之外, 我们还爬取了2 720个Chef脚本制品.由于Chef制品没有分类标签, 我们对其中的1 000例进行人工分类标注, 作为后续实验验证部分评价方法有效性的基准(baseline).

Table 3 Details of dataset 表 3 数据集详细信息

3.2 实验评价指标

分类问题通常采用查准率(precision)、查全率(recall)以及调和平均数F(F-measure)来评价分类器的效果, 对于层次分类问题, 需要对所有分类器的整体分类效果做出评价, 因此, 本文采用微平均的方式综合模型中所有分类器的分类效果, 这也是层次分类研究常用到的度量方法之一[29], 见公式(5).

$ \left. \begin{array}{l} Micro\_P = \frac{{\sum\nolimits_i {T{P_i}} }}{{\sum\nolimits_i {T{P_i}} + \sum\nolimits_i {F{P_i}} }}\\ Micro\_R = \frac{{\sum\nolimits_i {T{P_i}} }}{{\sum\nolimits_i {T{P_i}} + \sum\nolimits_i {F{N_i}} }}\\ Micro\_{F_1} = \frac{{{\rm{2}} \times Micro\_P \times Micro\_R}}{{Micro\_P + Micro\_R}} \end{array} \right\} $ (5)

微平均考虑每个分类器样本规模在整体模型中的权重, 计算整体分类器模型的查准率、查全率, 然后计算调和平均值F1.公式(5) 中, TPi, FPi, FNi分别表示类别i的真阳性(ture positive)、假阳性(false positive)和假阴性(false negative)样本数量.

3.3 分类树构建实验

本文在第2.3节介绍了类别标签隶属关系的挖掘方法, 本节采用划分置信度梯度方法进行实验, 通过观察有向标签对在不同置信度下隶属关系的合理性, 来确定最小置信度αc.本实验中, 设定有向标签对的最小支持度αs=0.0005, 提升度αl=1, 把每10 000例样本中标注5个以上且具有正向关联关系的共现标签作为候选, 共得到891个符合AB关系的有向标签对.首先把有向标签对按照置信度降序排列, 以0.1为梯度将所有标签对划分为10组; 然后随机抽取每组中20%的标签对, 通过人工判断标签对隶属关系是否是合理的(reasonable); 最后统计该组的合理比例, 得到表 4的统计结果.

Table 4 Statistic data of tag pairs with different confidences 表 4 不同置信区间的标签对统计

从表中可看出, 标签对的合理比例随置信区间的下移而降低, 在区间(0.3, 0.4]下降到0.5以下.当置信度在(0.4, 1.0]区间内时, 各组标签对的合理比例都在0.6以上, 对该区间内各组合理比例加权计算, 得到整体合理比例为0.79.文献[23]中对社会化标签提出一种整合了主题模型的层次聚类方法, 平均正确率达到0.79.参考此基准, 本文将最小置信度αc设置为0.4, 对于构建分类树是比较好的选择.

我们对置信度在(0.4, 1.0]内的标签对应用分类树构建算法, 得到了包括4层的90个类别的分类树体系, 其中, 第1层类别下有包括system, server等9个分类, 第2层~第4层分别包含33, 42, 6个分类.然后, 通过标签关键字匹配的方法, 对所有的10 790例CMT制品进行类别标注, 表 5列出了类别及标注结果的统计数据.需要注意的是:由于父类别的样本包括了子类别样本, 表中不同层次平均样本数存在重复计数.本文另外对获取的Chef制品中1 000例样本进行了人工标注, 该数据在后续实验中作为测试样本用于验证.

Table 5 Statistic data of hierarchical categories 表 5 分类层次统计数据

3.4 CMT制品分类实验

本实验用以分析评价不同分类算法对于最终分类结果所产生的影响.本实验在仅使用one-against-rest方法划分正反面样本情况下, 分别采用支持向量机(SVM)、k最近邻(kNN)、朴素贝叶斯(Naïve Bayes)这3种算法作为基本分类器, 对比分析3种分类算法在CMT制品层次分类问题的效果.实验中使用了基于Python的Scikit-Learn[30]机器学习方法库, 3种算法均使用Scikit-Learn方法库的默认参数.

实验将CMT制品描述文档中词语的TF-IDF作为特征向量, 首先使用Puppet及Ansible社区的10 790例CMT制品进行5折交叉验证(cross validation), 将数据随机等分为5份, 使用其中4份作为训练, 另外1份作为测试, 循环做5次实验, 所得到分类器指标为5次的平均值.图 5展示了交叉验证的实验结果.

Fig. 5 Cross calidation of categorization based on algorithms of SVM, kNN and Naïve Bayes 图 5 分别使用SVM, kNN, Naïve Bayes算法的交叉验证实验结果

从图中可看出:3种算法中, SVM, kNN与Naïve Bayes查准率相差不大, 都达到0.9左右; 3种算法查全率则要远低于查准率, 最大差距在0.2以上, 尤其是kNN算法查全率最低; 综合查准率与查全率的调和平均值F1也出现明显差别.总体上, SVM算法要优于其他两种算法, 这个结果与相关研究的结果是一致的.

在上述实验基础上, 本文将10 790例制品用作训练数据, 另外对1 000例Chef制品人工标注, 作为新的实验测试数据, 在相同实验环境和参数下再次进行验证, 结果如图 6所示.该实验结果相比于交叉验证实验, 3种算法各项评价指标都有所下降; 其中, Naïve Bayes算法的查全率与调和平均值F1下降明显; 而SVM算法的性能较稳定, 仅有约0.07的下降幅度, 仍然是三者中最优的分类算法.由于新测试数据和训练数据分别属于不同的CMT社区, 开发者的领域知识及文档的撰写习惯有所差别, 导致文本数据中词语的分布稍有不同, 所以出现分类性能的下降.其中, 朴素贝叶斯算法对数据形式最为敏感, 因而在两次实验中性能指标下降幅度最大.由于第2次实验是在实际分类场景下的对新数据的测试, 因此本文将该结果作为层次分类器的实际效果.从两次实验结果总体来看, 查全率严重影响了整体分类效果.我们分析原因是:实验中仅使用one-against-rest的样本划分方法, 单一类别的正样本数量与剩余类别的总体负样本数量相差巨大, 出现数据倾斜问题, 影响了查全率.

Fig. 6 Result of categorization using new test dataset of Chef 图 6 使用Chef新测试数据集的实验结果

3.5 基于SVM的混合样本划分实验

上组实验中, SVM算法取得了最好的效果.本节基于SVM算法, 在相同实验环境下, 采用one-against-rest与divide-by-2结合的混合样本划分模型进行实验.当分类树中同层次兄弟类别数目大于类别阈值时, 使用divide-by-2划分正反面样本, 否则使用one-against-rest确定正反面样本.每次divide-by-2划分都将样本数据分为规模相当的两组, 直到组内类别数小于阈值为止.该类别阈值能够表示divide-by-2方法在模型中的参与程度, 由于分类树中最大兄弟类别数目为9, 因此本文调整该阈值大小, 在[2, 10]区间内进行多次实验, 以验证混合样本划分模型的有效性.最终的实验结果如图 7所示.

Fig. 7 The impact of threshold of brother-class-number 图 7 不同兄弟类别阈值对分类结果的影响

图 7可以看出:随着兄弟类别阈值降低, 查准率从0.91下降到0.77;查全率从0.69提升到0.92;两者的调和平均值F1从0.78上升到0.85后稍有下降.当类别阈值为4时, 调和平均值F1达到最大, 分类效果最好.当兄弟类别阈值为10时, 查准率、查全率以及调和F1值退化与上组实验结果接近.

图 8将类别阈值为4时的混合样本划分实验结果与仅使用one-against-rest原始划分方法的实验结果对比.从图中可以看出:相比于原始划分方法, 混合样本划分方法准确度稍有下降, 但查全率大幅提升, 整体调和平均值F1比原来提升0.06.这表明混合样本划分方法能够有效减小数据倾斜, 提升层次分类效果.

Fig. 8 Compare results between orginal functionand hybird function for dividing samples 图 8 原始样本划分与混合样本划分方法分类效果对比

综合图 7图 8, 一方面我们分析查全率上升和查准率下降的原因, 由于类别阈值降低, divide-by-2样本划分方法在模型中使用更加频繁, 使得每个分类器在训练时的正负样本规模差距减小, 降低了分类模型中分类器的数据倾斜程度, 从而提高了查全率.查准率的下降是由传递误差累计导致.由于层次分类模型仅当上层父节点输出为真时, 制品样本才会在下一层子节点进行预测, 被上一层分类器拒绝的样本无法传递给子节点分类器参与预测, 即, 父类别的误差累计到了子类别中.随着divide-by-2对类别分组更加频繁, 分类器的层次也在增加, 引起的误差累计越大, 导致整体查准率有所下降.

另一方面, F-measure相比于查准率和查全率更具有综合评价的参考意义, 是评价分类器的综合指标.本文采用的微平均评价方式, 实例数量较多的类别在微平均过程中占有更大比重, 而该部分类别一般处在较低深度层次, 累计误差对其查准率影响较小, 从而整体查准率下降程度小于查全率的上升.综合两者的F-measure得到了提高, 这也表明该方法的有效性.因此在使用混合样本划分策略时, 需要对兄弟类别阈值的设定进行权衡, 以达到最优的分类效果.

3.6 其他案例分析

通过对比制品人工分类和采用本文方法进行制品自动分类所花费的时间, 本文初步分析和评价了方法的执行效率.对1 000个Chef脚本制品进行人工分类标注花费了近20个小时, 而采用本文方法则仅仅花费了5分钟即可完成, 同时也具有较高的准确率(0.87).

我们采用mysql作为关键词进行Puppet和Ansible制品库的搜索, 获取了498个软件制品.但是除了其中103个确实是mysql相关的制品外, 其余制品皆与之无关, 例如postfix, collectd, zabbix等等, 因此搜索精度仅有0.21.采用本文方法, 我们能够得到mysqlrmdedatabase类别下的153个mysql相关制品, 其中137个经过人工确认为正确的, 具有0.89的准确率.我们使用几个案例来证明本文方法能够帮助用户缩小搜索范围, 并完成更为准确合理的分类.

1) 基于mysql的关键词搜索结果包含了Puppet的一个脚本制品puppet/zabbix, 它是用来支持监控系统Zabbix的安装与管理操作, 与mysql无关.我们的分类方法则将该制品划分到zabbixmonitoringsystem类别下, 显然更加合理;

2) Ansible脚本库中的一个mysql相关制品cranework.mysql被错误的标记为Web, 本文分类方法则能够正确的将其划分到mysqlsqldatabase类别下;

3) Ansbile脚本库中的制品brisho.sSMTP缺少对应的标签信息, 这个制品能够为邮件服务器提供管理功能.本文方法通过自动分类将其划分到emailserver类别, 符合该制品的功能和特征.

上述案例分析证明, 本文方法能够在制品分类的准确性和合理性方面提供有效的帮助.

3.7 讨论

实验和分析结果表明:本文方法对于CMT脚本制品的结构化层次分类具有较好的表现, 能够帮助用户更加准确地查找期望的目标制品.但是存在以下方面影响本文方法的有效性.

从外部来看, 影响本文方法有效的因素主要在于方法是否具有普适性.首先, 影响方法普适性的因素来自于与本文方法所选取的样本和数据是否具有代表性.由于脚本制品是CMT工具相关的, 因此很难判定本文方法对于所有CMT工具的制品都适用.本文通过尽量选取最为主流的和具有代表性的CMT工具制品来降低这一因素的影响, 主要采用Puppet, Ansible, Chef的超过14 000例CMT制品作为数据集.同时, 本文将在后续工作中通过扩大数据规模和CMT工具类型范围来进一步验证工作的通用性.其次, 制品标签是用户相关的, 具有随机性, 这对于构造层次化分类体系产生影响.本文从两个方面来应对这一问题:一方面, 我们过滤掉不常用的标签来提高标签的正确性; 另一方面, 通过引入Stack Overflow的同义词库来进行同义标签的标准化.Stack Overflow作为全世界最为活跃和最受欢迎的计算机领域问答社区积累了上千条同义词记录, 具有实际的借鉴意义.

在内部影响因素方面, 本文方法目前只采用了制品的名称和描述作为构建分类器的文本特征信息, 并没有考虑诸如脚本作者和使用说明等其他更多类型的文本信息.除此之外, 本文方法在构建层次化分类时只是基于标签的共现性(co-ocurrence)来分析他们之间可能存在的层次包含关系, 并没有分析标签的语义信息.尽管实验结果验证了方法的有效性, 但是本文后续工作将考虑引入更多的特征信息以及标签的语义信息.

4 相关工作

本文是首个针对配置管理工具制品进行层次化分类的工作, 其相关工作主要包括软件分类和配置管理两个方面.

4.1 配置管理

针对如何提高CMT制品质量的问题, 相关工作提出了解决方法, 包括静态验证[31]和自动化测试[32, 33]等.Collard等人[31]提出了一种基于静态验证的方法来检测Puppet module的执行结果是否具有确定性(determinism).Hummer等人[32]提出了一种基于黑盒的自动化测试方法来检测Chef cookbooks的执行操作是否具有幂等性(idempotence).该方法在执行Chef cookbooks的过程中, 通过分析目标系统的变化来分析判断当前的CMT制品(cookbooks)是否具有幂等性.创建可靠的自动化系统配置脚本十分困难, Hanappi等人[33]针对这一问题提出了基于模型的自动化测试框架, 用来检测系统配置是否能够最终收敛到一个稳定的、期望的目标状态.Sharma[34]对Puppet脚本制品源代码进行分析, 挖掘脚本编写设计和实现过程中容易出现的代码错误和不规范, 以案例分析形式总结出20条最佳范例, 指导脚本制品的开发.

在DevOps知识获取与制品管理方面也存在着相关的研究工作.Leymann等人[35]提出了基于众包(crowdsourcing)与自动爬取相结合的方法来获取、管理和使用DevOps知识.通过集成知识库、基于谓词逻辑的查询方法和策略框架(policy framework), 该方法提出了一整套用以组织、存储、查询和使用DevOps领域知识的途径.特别的, 在DevOps工具、制品和服务分类方面提出了一种系统化的方法, 该方法基于人工提出的分类体系进行DevOps相关实体(entity)的类别划分.

与本文工作不同, 以上多数工作主要关注CMT制品的质量问题.虽然Leymann等人的工作涉及到CMT制品的分类管理, 但是他们采取的是一种基于人工建立分类体系的方法, 不同于本文提出的基于标签自动建立层次化分类体系.

4.2 软件制品分类

软件制品分类的相关工作可以分为两类, 即, 基于内部特征(internal feature)的分类方法和基于外部特征(external feature)的分类方法.

基于内部特征的分类方法主要基于软件源代码、注释和API调用信息实现分类.Ugurel[15]提出的方法分析程序源码结构并抽取标识符, 然后结合注释关键字组成文档代表该软件, 最后利用支持向量机(support vector machine, 简称SVM)方法将软件划分到对应主题和语言类别中.Linares[25]发现, 对于部分软件(如基于Java的软件)可以收集并分析软件制品对第三方平台API的调用信息.基于此, 他提出通过API反映的软件功能预测其类别的方法.CMT制品领域语言相关, 不适于采用基于内部特征和代码分析的方法进行分类.

基于外部特征的方法通过挖掘软件制品的外部特征, 如软件制品在资源库中的名称、描述等在线属性实现软件分类.Wang[36]对Freecode软件仓库中软件标签分析, 基于共现性度量标签相似度, 提出一种基于k-means算法的软件标签层次构建分类方法.Dumitru[37]从大量软件描述中提取相关特征, 利用增量扩散聚类算法实现基于初始输入特征的交互式软件关联推荐.Wang[26]基于SourceForge、Freecode等资源库, 将相同软件的描述和标签属性聚合, 通过SVM等文本分类算法, 将软件划分到预定义的层次类别体系中.与本文工作不同, 该工作基于SourceForge预先定义的层次分类体系实现软件分类, 而本文则通过分析挖掘CMT制品标签间的层次包含关系来自动构建分类体系, 解决了CMT制品不存在预定义分类体系的问题.

总体而言, 当前面向CMT制品的分类仍然需要人工进行, 缺乏高效的分类和检索体系.同时, CMT制品的源代码、API信息等受领域特定语言限制难以抽取有效信息.因此, 本文受软件制品分类启发, 整合多个CMT制品资源库, 分析CMT制品在线非结构化描述文档, 实现CMT制品的层次分类.

5 总结

互联网为软件开发与维护提供海量资源, 有效提取、组织与管理资源对DevOps实践有重要意义.本文提出了一种基于描述文档对CMT制品进行层次分类的方法, 能够实现对配置管理工具(CMT)的脚本制品进行自动化分类.该方法不依赖于CMT制品的脚本代码和领域特定语言, 具有良好的分类效果和扩展性.本文方法首先基于制品标签提出了一种层次分类体系的自动构建方法, 基于该方法, 本文对超过11 000个制品建立了包含90个细粒度类别的多层次分类树.然后基于监督学习方法, 本文建立并训练了一组分类器实现对脚本制品的自动分类.特别的, 针对分类器训练过程中, 正反样本划分划分存在的数据倾斜问题, 本文还提出一种改进的混合样本划分模型, 有效提升了整体层次分类效果.

下一步工作包括:一方面, 从CMT制品的源代码、配置文件等角度提取制品技术特征, 与描述文档互为补充, 探索新的脚本制品分类模型; 另一方面, 获取Saltstack、Cfengine[11]等更多配置管理工具的脚本制品, 构建跨CMT的脚本制品知识库, 研究充分利用CMT制品资源辅助软件开发的途径.

参考文献
[1] Hüttermann M. Infrastructure as Code. In:Proc. of the DevOps for Developers. Apress, 2012. 135-156.[doi:10.1007/978-1-4302-4570-4_9]
[2] RightScale. 2016 State of the cloud report. 2016. http://www.rightscale.com/lp/2016-state-of-the-cloud-report
[3] Chef Supermarket. Repositories of chef. 2016. https://supermarket.chef.io/cookbooks/
[4] Puppet Forge. Repositories of puppet module. 2016. https://forge.puppetlabs.com
[5] Ansible Galaxy. Repositories of ansible role. 2016. https://galaxy.ansible.com/list
[6] OpenHub. Discover, track and compare open source. 2016. https://www.openhub.net/explore/projects
[7] SourceForge. Find, create, and publish open source software for free. 2016. https://sourceforge.net/
[8] Zabbix SIA. Zabbix, the enterprise-class monitoring solution for everyone. 2016. http://www.zabbix.com/
[9] Galstad E. Nagios, the industry standard in IT infrastructure monitoring. 2016. http://www.nagios.org/
[10] Fu W, Cheney J, Anderson P. An operational semantics for a fragment of the puppet configuration language. ArXiv preprint arXiv:1608.04999, 2016 . https://arxiv.org/pdf/1608.04999.pdf
[11] CFEngine, Automate large-scale, complex and mission critical IT infrastructure. 2016. https://cfengine.com/
[12] Goldsack P, Guijarro J, Loughran S, Coles A, Farrell A, Lain A, Murray P, Toft P. The SmartFrog configuration management framework. ACM SIGOPS Operating Systems Review, 2009, 43(1): 16–25 . [doi:10.1145/1496909.1496915]
[13] Kawaguchi S, Garg PK, Matsushita M, Inoue K. Mudablue:An automatic categorization system for open source repositories. Journal of Systems and Software, 2006, 79(7): 939–953 . [doi:10.1016/j.jss.2005.06.044]
[14] Tian K, Revelle M, Poshyvanyk D. Using latent dirichlet allocation for automatic categorization of software. In:Proc. of the 6th IEEE Int'l Working Conf. on Mining Software Repositories. IEEE, 2009. 163-166.[doi:10.1109/msr.2009.5069496]
[15] Ugurel S, Krovetz R, Giles CL. What's the code? Automatic classification of source code archives. In:Proc. of the 8th ACM SIGKDD Int'l Conf. on Knowledge Discovery aAnd Data Mining. ACM Press, 2002. 632-638.[doi:10.1145/775047.775141]
[16] Manning C, Raghavan P. Introduction to Information Retrieval. Online Edition, Cambridge University Press, 2009: 118–120 . [doi:10.1017/CBO9780511809071]
[17] Wang T, Wang H, Yin G, Ling CX, Li X, Zou P. Mining software profile across multiple repositories for hierarchical categorization. In:Proc. of the 29th Int'l Conf. on Software Maintenance. 2013. 240-249.[doi:10.1587/transinf.2014EDP7007]
[18] Cookbooks. About cookbooks. 2016.https://docs.chef.io/cookbooks.html
[19] Vural V, Dy JG. A hierarchical method for multi-class support vector machines. In:Proc. of the 21st Int'l Conf. on Machine Learning. ACM Press, 2004. 105.[doi:10.1145/1015330.1015427]
[20] StackOverflow tag synonyms. http://stackoverflow.com/tags/synonyms/
[21] Liu K, Fang B, Zhang W. Ontology emergence from folksonomies. In:Proc. of the 19th ACM Int'l Conf. on Information and Knowledge Management. ACM Press, 2010. 1109-1118. 10.1145/1871437.1871578
[22] Silla Jr CN, Freitas AA. A survey of hierarchical classification across different application domains. Data Mining and Knowledge Discovery, 2011, 22(1-2): 31–72 . [doi:10.1007/s10618-010-0175-9]
[23] Xue GR, Xing D, Yang Q, Yu Y. Deep classification in large-scale text hierarchies. In:Proc. of the 31st Annual Int'l ACM SIGIR Conf. on Research and Development in Information Retrieval. ACM Press, 2008. 619-626.[doi:10.1145/1390334.1390440]
[24] He L, Jia Y, Han WH, Tan S, Chen ZK. Research and development of large scale hierarchical classification problem. Chinese Journal of Computers, 2012, 35(10): 2101–2115 (in Chinese with English abstract). [doi:10.3724/sp.j.1016.2012.02101]
[25] Linares-Vásquez M, McMillan C, Poshyvanyk D, Grechanik M. On using machine learning to automatically classify software applications into domain categories. Empirical Software Engineering, 2014, 19(3): 582–618 . [doi:10.1007/s10664-012-9230-z]
[26] Wang T, Wang H, Yin G, Yang C, Li X, Zou P. Hierarchical categorization of open source software by online profiles. IEICE Trans. on Information and Systems, 2014, 97(9): 2386–2397 . [doi:10.1587/transinf.2014edp7007]
[27] Python3. Extensible library for opening URLs. 2016. https://docs.python.org/2/library/urllib2.html
[28] Leonard Richardson. Beautiful soup. 2016. https://www.crummy.com/software/BeautifulSoup/
[29] Sun A, Lim EP. Hierarchical text classification and evaluation. In:Proc. of the IEEE Int'l Conf. on Data Mining (ICDM 2001). IEEE, 2001. 521-528.[doi:10.1109/icdm.2001.989560]
[30] Pedregosa F, Varoquaux G, Gramfort A, Michel V, Thirion B, Grisel O, Blondel M, Prettenhofer P, Weiss R, Dubourg V, Vanderplas J, Passos A, Cournapeau D, Brucher M, Perrot M, Duchesnay E. Scikit-Learn:Machine learning in python. Journal of Machine Learning Research, 2011, 12: 2825–2830 . http://ieeexplore.ieee.org/document/989560/
[31] Shambaugh R, Weiss A, Guha A. Rehearsal:A configuration verification tool for puppet. In:Proc. of the 37th ACM SIGPLAN Conf. on Programming Language Design and Implementation. ACM Press, 2016. 416-430.[doi:10.1145/2980983.2908083]
[32] Hummer W, Rosenberg F, Oliveira F, Eilam T. Testing idempotence for infrastructure as code. In:Proc. of the ACM/IFIP/USENIX Int'l Conf. on Distributed Systems Platforms and Open Distributed Processing. Berlin, Heidelberg:Springer-Verlag, 2013. 368-388.[doi:10.1007/978-3-642-45065-5_19]
[33] Hanappi O, Hummer W, Dustdar S. Asserting reliable convergence for configuration management scripts. In:Proc. of the 2016 ACM SIGPLAN Int'l Conf. on Object-Oriented Programming, Systems, Languages, and Applications. ACM Press, 2016. 328-343.[doi:10.1145/2983990.2984000]
[34] Sharma T, Fragkoulis M, Spinellis D. Does your configuration code smell? In:Proc. of the 13th Int'l Workshop on Mining Software Repositories. ACM Press, 2016. 189-200.[doi:10.1145/2901739.2901761]
[35] Wettinger J, Andrikopoulos V, Leymann F. Automated capturing and systematic usage of devops knowledge for cloud applications. In:Proc. of the 2015 IEEE Int'l Conf. on Cloud Engineering (IC2E). IEEE, 2015. 60-65.[doi:10.1109/IC2E.2015.23]
[36] Wang S, Lo D, Jiang L. Inferring semantically related software terms and their taxonomy by leveraging collaborative tagging. In:Proc. of the 28th IEEE Int'l Conf. on Software Maintenance (ICSM). IEEE, 2012. 604-607. [doi:10.1109/ICSM.2012.6405332]
[37] Dumitru H, Gibiec M, Hariri N, Cleland-Huang J, Mobasher B, Castro-Herrera C, Mirakhorli M. On-Demand feature recommendations derived from mining public product descriptions. In:Proc. of the 33rd Int'l Conf. on Software Engineering (ICSE). IEEE, 2011. 181-190.[doi:10.1145/1985793.1985819]
[24] 何力, 贾焰, 韩伟红, 谭霜, 陈志坤. 大规模层次分类问题研究及其进展. 计算机学报, 2012, 35(10): 2101–2115. [doi:10.3724/sp.j.1016.2012.02101]