hadoop 朋友推荐 基于hadoop的推荐系统_开发者


引用

Kim Mens and Angela Lozano. Source Code-Based Recommendation Systems. Recommendation Systems in Software Engineering, 2014, 93-130.

摘要

尽管今天的软件系统由各种各样的软件工件组成,但是源代码可以说仍然是最早更新的软件工件,因此也是最可靠的数据源。它提供了丰富而结构化的信息源,推荐系统可以依靠该信息源向软件开发者提供有用的推荐。基于源代码的推荐系统可以为诸如如何使用给定的 API 或框架这样的任务提供支持,提供代码中缺少内容的提示,建议如何重用或纠正现有代码,帮助新手学习新项目、编程范式、语言或风格等。本文重点介绍在开发基于源代码的推荐系统时涉及的相关决策。对我们所开发的特定系统的深入介绍可以具体说明构建此类系统时可能遇到的一些问题以及需要做出的开发选择。

1. 介绍

通常,推荐系统可帮助人们在执行任务时查找相关信息来做出正确的决定。软件工程推荐系统(RSSE)可以帮助开发者进行一系列活动,从重用代码到编写有效的错误报告等。本文的重点是基于源码的推荐系统(SCoReS),即通过分析软件系统的源代码来产生其推荐。

当前许多 SCoReS 旨在支持正确使用 API、库或框架。它们通常依赖于已有的 API 使用示例语料库,这些示例通过分析一些特定的应用程序获得的。这类推荐工具通常包括嵌入在 IDE 中的前端和存储语料库的后端。前端负责显示结果并从 IDE 或开发上下文中获取正确的信息,以便制定合适的查询。后端负责产生与这些查询匹配的结果并更新语料库。当开发者编辑程序时,推荐系统可以根据 API 的已有用法,推荐如何使用 API。此类推荐系统可以视为“智能”代码补全工具。匹配过程使用的信息与代码补全工具类似,例如目标对象的类型(预期的返回类型)以及开发者期望功能所需的对象类型。

除了此类 SCoReS 之外,还可以区分许多其他类型的 SCoReS,不仅取决于它们从源码中提取推荐的种类或使用的技术,而且取决于建立这些系统时所采用的设计。尽管存在各种各样的源代码分析技术,并且即使已经确定了开发者在编写代码时的信息需求,但将特定技术运用到成功的推荐工具中并不容易。

本文的目的是向基于源码的推荐系统领域的新手提供一些现有方法的概述,以使他们了解构建此类系统的问题和困难,并提出更系统的过程来开发 SCoReS。这个过程是从对现有方法的非详尽比较和分类以及我们在构建工具支持各种软件开发和维护任务的经验中提炼出来的。

2. 一系列基于源码的推荐系统

在提出 SCoReS 的设计过程之前,我们简要介绍五个推荐系统,这些系统将帮助我们说明某些设计决策的重要性。它们分别为 Rascal,FrUiT,Strathcona,Hipikat 和 CodeBroker。 选择这些系统是因为它们在设计方法方面是互补的。

2.1 Rascal

Rascal 是一种推荐系统,通过分析与当前正在编写的类相似的类来预测开发者可以使用的下一种方法。Rascal 依赖于协同过滤的传统推荐技术。协同过滤基于这样一种假设,即用户会聚集在偏好相同条目的用户组中。Rascal 的“用户”就是类,推荐的条目是要调用的方法。当前类和其他类之间的相似性正是基于它们所调用的方法。


hadoop 朋友推荐 基于hadoop的推荐系统_推荐系统_02


hadoop 朋友推荐 基于hadoop的推荐系统_基于jsp的网上推荐系统_03


Rascal 分为四个部分,负责推荐过程的不同阶段。首先,活动用户标识当前正在开发的类。其次,使用历史记录收集器,它自动为一组 API 中的所有类挖掘类方法使用矩阵和类方法顺序列表(图 1.1)。矩阵中的每个单元代表一个类调用特定方法的次数。第三,构造代码存储库,用于存储历史记录收集器挖掘的数据。第四,推荐程序代理器,它为用户推荐下一个方法,以供用户在光标当前所在的方法和类的实现中调用。推荐代理器从查找与当前所选类相似的类开始。两个类之间的相似性是通过比较它们调用的方法来计算的。考虑使用同一种方法的频率来识别明显的相似性。比较两个类时,像 toString()这样的常用方法比其他方法具有较低的权重。为了对推荐的方法进行排序,RASCAL 从最相似的类中选择那些包含当前类中使用的最后一个方法调用的类,然后按照优先级来推荐该方法调用之后的方法调用,以使它们出现在该方法调用之后(图 1.2)。

2.2 FrUiT

FrUiT 是一个 Eclipse 插件,用于支持框架的使用。FrUiT 显示了框架的源代码关系,该关系显露在开发者当前正在编辑的文件的上下文中。图 1.3 展示了 FrUiT 的屏幕截图。源码编辑器 (1) 确定开发者的上下文,在本例中为 Demo.java 文件。在 IDE 的外围视图中展示了该文件的 FrUiT 提示 (2),并且还显示了每个实现提示的原理(例如“实例化 Wizard”) (3)。对于每种实现的提示,开发者还可以阅读所推荐的类或方法的 Javadoc (4)。


hadoop 朋友推荐 基于hadoop的推荐系统_推荐系统_04


FrUiT 的推荐分三个阶段进行计算。首先,FrUiT 使用给定的框架或 API 从一组应用程序中提取结构关系。这些结构关系包括继承(类 A 继承类 B),实现(类 A 实现接口 B),覆盖(类 A 覆盖继承的方法 m),调用(类 A 的任何方法调用方法 m)以及实例化(从类 A 的实现中调用类 B 的构造函数)。其次,FrUiT 使用关联规则挖掘来识别每当使用框架或 API 时常见的结构关系。关联规则为


hadoop 朋友推荐 基于hadoop的推荐系统_基于jsp的网上推荐系统_05


,可以将其解释为“ if-then”规则。例如,规则


hadoop 朋友推荐 基于hadoop的推荐系统_开发者_06


意味着使用框架的应用程序每次调用方法 m 时,它也倾向于(在 80%的情况下)调用类 B 的构造函数。请注意,FrUiT 还显示了每种情况下关联规则是否成立(参见图 1.3 中 IDE 的右下角)。鉴于关联规则挖掘往往会产生结果的组合爆炸,因此有必要对结果进行过滤以确保该工具仅产生相关信息。 最后,对于 Eclipse 编辑器当前关注的文件,FrUiT 推荐在该文件之前或之后提及的所有规则。

2.3 Strathcona

Strathcona 也是一个 Eclipse 插件,推荐使用第三方库方法的示例(请参见图 1.4(d))。用户高亮源代码片段,以向 Strathcona 请求第三方库方法使用方式的示例(请参见图 1.4(a))。这些示例取自使用相同第三方库的其他应用程序。

Strathcona 通过提取源码的结构上下文来工作。这种结构上下文包括方法的签名、声明的类型和父类型、调用的方法、访问的字段的名称以及每种方法引用的类型。提取的结构上下文可以通过两种方式使用。首先,作为自动查询,描述开发者请求支持的源代码片段。其次,使用该工具支持的库来构建一个包含类的结构上下文的数据库。通过在 Strathcona 数据库中识别具有与所分析片段之一相似的结构上下文的实体,可以找到相关示例(请参见图 1.4(b)和(c))。


hadoop 朋友推荐 基于hadoop的推荐系统_基于hadoop的商品推荐系统_07


2.4 Hipikat


hadoop 朋友推荐 基于hadoop的推荐系统_hadoop 朋友推荐_08


Hipikat 帮助软件项目新人找到有关维护任务的相关信息。Hipikat 的想法是根据其源代码、电子邮件讨论、错误报告、更改历史记录和文档来收集检索项目历史记录的相关部分。图 1.5 展示了 Hipikat 的屏幕截图。IDE 的主窗口显示了开发者要修复的错误报告(参见图 1.5(a))。开发者从上下文菜单中选择“查询 Hipikat”后,该工具将返回相关工件的列表。与 bug 相关的工件在单独的视图中显示(图 1.5(b))。对于找到的每个工件,Hipikat 会显示其名称、类型(网页,新闻文章,CVS 修订版或 Bugzilla 项),推荐它的理由以及它与查询工件的相关性。可以在 IDE 的主窗口中打开工件,以继续查询 Hipikat。

2.5 CodeBroker

CodeBroker 根据开发者光标当前所在的方法的注释和签名,推荐要调用的方法。该系统的目标是通过找到已经(部分)实现了目标功能的方法来支持新方法的开发。

CodeBroker 的前端监视光标,使用当前上下文中的相关信息查询后端,并显示结果。后端分为两部分。首先,一种论述模型可以存储和更新一组库、API 和框架中方法的注释和签名,以供重用。其次,一种用户模型,用于从推荐列表中删除方法、类或包,图 1.6(c)说明了右键单击推荐来将其从推荐列表中删除。


hadoop 朋友推荐 基于hadoop的推荐系统_推荐系统_09


CodeBroker 是与源代码编辑器(emacs)集成的推荐工具。一旦开发者编写代码,该工具就会通过监视方法声明及其描述来主动识别推荐的需求。这意味着每次游标更改位置时,它都会自动查询后端存储库。该查询旨在查找具有与正在开发的方法相似注释和签名的方法。然后根据焦点方法中使用的类型和匹配类型之间的相似性来过滤文本搜索结果。一旦查询响应,就会在源码编辑器的外围视图中显示按相关性排序的匹配方法(请参见图 1.6(a))。最后,图 1.6(d)展示了 CodeBroker 如何允许开发者引导后端找到相关建议,通过将方法、类或包的名称添加到“过滤的组件”中使它们从结果中被排除,或添加到感兴趣的组件以便搜索被限制在这些实体范围内。

3. 建立 SCoReS 时的开发决策

在基于源代码的推荐系统的整个开发过程中,需要做出许多重要的决定。这些决策可以沿两个维度进行分类。 第一个维度是开发周期阶段:是与系统需求、设计、实现还是最终验证相关的决策?另一个维度是系统如何与用户交互的。表 1.1 对主要决策类别进行了说明。


hadoop 朋友推荐 基于hadoop的推荐系统_基于jsp的网上推荐系统_10


3.1 过程

假设我们遵循从需求开始的传统开发周期,表 1.1 中的数字表明了如何以及何时做出这些决策的过程:

  1. 首先考虑系统的意图,这些意图均与推荐方法的目的有关。
  2. 然后确定人机交互,即终端用户(通常是开发者)如何与 SCoReS 交互。
  3. 一旦确定了功能和用户交互要求,请选择系统将用来提供建议的数据源。
  4. 接下来,根据一般投入产出决策来完善先前采取的人机交互决策。
  5. 现在确定推荐方法的细节,即与如何实施推荐过程有关的所有细节。
  6. 由于上一步的决定可能会更详细地说明“输入输出”,因此接下来,我们可以决定该方法需要什么样的精确信息作为输入,以及它是什么以及如何产生其输出。
  7. 实施系统后,我们需要选择如何验证它。主要问题是系统要为其提供推荐的任务提供支持的能力。
  8. 最后关于验证需要做出一些决策,以决定如何评估不同用户与 SCoReS 的交互。

3.2 意图

3.2.1 目标用户

目标用户,即首先应确定系统预期用户的角色。尽管大多数 SCoReS(都是针对开发者的,但其他角色类型也需要考虑,例如维护人员,逆向工程师,重构者,经理,测试人员,文档编写员或研究人员。第二个决策因素与目标用户的体验水平有关。尽管某些推荐系统不去假设用户的经验水平,但部分推荐系统专门针对新手或专家。例如,Hipikat 可以帮助新人加入某个项目,而 CodeBroker 可以根据其用户的经验水平进行个性化设置。

3.2.2 任务支持

如前所述,许多 SCoReS 旨在支持正确使用 API,库或框架。一些支持 API 演化或语言迁移的映射。还有一些则推荐代码更正、重用代码(方法重用,如 CodeBroker)、代码更改或代码提示。另外一些 SCoReS(例如 Hipikat)可以支持新手学习新项目。或者提供相关信息来帮助开发者了解如何实现某些问题或解决某些错误。

3.2.3 认知支持

据 German 等人的研究,另一个重要的决策是推荐系统如何支持用户认知来完成某些任务。换句话说,系统可以帮助您回答有关任务的哪些问题,可以区分为五类问题:who,why,when,what 以及 how。

系统的推荐解释信息往往取决于其应用环境。提供 API 支持并与 IDE 集成的代码补全工具通常不提供详细信息来帮助用户评估推荐的合适性。另一方面,未嵌入为代码补全工具的 API 支持工具往往会提供多重视图,以解释每个推荐的理由。但是,提供信息的详细程度不仅仅取决于系统与 IDE 的集成方式。

由 SCoReS 提供的另一种流行的认知支持(如 FrUiT 和 Strathcona)为开发者提供了如何完成其任务的信息。提供的详细程度取决于系统提供的支持类型。具有特定目标的系统(例如,如何替换不推荐使用的方法或如何从另一个类型的实例中获取目标类型的实例)比涉及广泛目标的系统(例如,如何补全方法)需要的背景知识更少,目标广泛的系统可能需要用户输入或者指明方法如何使用。

只有很少的系统回答有关特定实现选择背后的原因(why);最接近的是那些寻找与工件相关的实体,但是这些实体之间的关系仍然必须由开发者发现。同样,回答时间问题(when)的系统也很少,这可能是由于它们通常不依赖于变更信息。但是,此类时间信息可能会有助于回答基本原理问题,因为它可以揭示更改背后的痕迹。最后,SCoReS 很少回答作者(who)的问题,这是因为源代码很少包含作者的信息,除非有其他来源对此进行补充。

3.2.4 推荐信息

一些推荐系统不仅推荐做什么,而且还推荐如何做。对于大多数直接推荐做法的系统,用户要做的事情就是选择他们认为适合当前上下文或任务的更改,然后系统将自动执行更改(例如,在最后一条语句后插入代码)。

像 FrUiT,Rascal 和 CodeBroker 一样,另一种常见的输出类型是源代码实体,即更改或使用的内容,而不是更改方式。根据当前的任务和推荐系统的类型,可能需要对推荐的结果做进一步的解释。例如,推荐系统可能会推荐以非常特定的方式修改源代码实体,但是系统与 IDE 的集成不够全面无法自动执行操作,因此需要用户手动执行。

示例可以帮助用户理解在类似情况下如何解决类似问题。用户的工作是确定示例内容的哪个部分与当前任务相关,以及如何将示例应用到当前情况。

最后,SCoReS 可以推荐相关的软件工件(即非源代码实体的软件开发过程的任何副产品),以帮助开发者更好地理解手头任务的含义。这些推荐的有用性和有效性取决于信息的相关性以及开发者可以从系统提供的信息中抽象出来的联结。

3.3 人机交互

在系统意图相关的决策之后,我们现在将注意力转向人机交互。这些决策使我们能够建立用户与 SCoReS 之间的预期交互。包括系统类型,系统推荐类型以及用户的预期输入。

3.3.1 系统类型

推荐系统可以是 IDE 插件,独立应用程序或其他类型,例如命令行工具或系统用户要使用的内部或外部 DSL。鉴于我们分析的大多数 SCoReS 都是针对开发者的,因此它们往往与开发环境集成在一起。这可以更轻松地检测用户上下文或活动,有时还可以更轻松地访问该上下文中使用的句法实体和关系。推荐系统的另一种选择是独立的应用程序,例如 Rascal。为降低侵入性,编程式 SCoReS 一般较少作为实现。

3.3.2 推荐类型

诸如 Hipikat 和 Strathcona 之类的推荐系统是专用的搜索引擎,可以为手头上的特定任务找到相关信息。Strathcona 查找给定 API 的使用示例,而 Hipikat 查找与源代码工件相关的信息。其他系统如 FrUiT,Rascal 和 CodeBroker,则侧重于向用户推荐某些行动方案。例如,Rascal 建议需要添加哪些方法调用。许多其他系统更多地关注验证源码的某些属性,例如遵守某些约定或设计规则。

3.3.3 用户参与

一个重要决策是 SCoReS 需要什么样的用户参与。例如,它需要手动输入还是需要用户过滤输出?通常,可以从编程上下文中自动提取 SCoReS 所需的输入。例如正在编写的方法、已调用的方法、已使用的类型、调用方法的顺序,最后创建的语句或标识符等。假定大多数 SCoReS 仅依赖于正在编辑的源码,无需手动输入。然而,如果 SCoReS 需要无法从编程上下文中提取数据,则必须确定用户将以哪种方式提供所需信息。

另一个重要决策是用户是否可以过滤推荐。可以像在 FrUiT 或 CodeBroker 中那样反复进行此过滤,也可以诸如 Strathcona,Rascal 和 CodeBroker 从最终结果组中进行迭代。有趣的是,结果过滤也可以用来排除。例如,CodeBroker 通过查看他们的本地历史记录来消除用户已知的结果。另一个值得考虑的方法是允许按用户会话或模块过滤结果

3.4 语料库

决定 SCoReS 的主体就等于决定系统需要依赖哪些数据源来提供推荐。SCoReS 使用的主要信息来源是程序代码,但有时也会使用其他信息来源,例如变更管理、缺陷跟踪存储库、非正式通信、本地历史记录等。当合并多个数据来源时,明确决定如何关联这些来源。

3.4.1 程序代码

关于语料库,要做的第一个重要决策是系统根据开发者正在开发的应用程序还是基于他们正在使用的应用程序来计算其推荐。前者从单个应用程序(正在构建的应用程序)的代码构建主体,而后者从多个应用程序(正在被使用的应用程序)中构建主体。这种选择会对可用于计算推荐的技术、方法、存储需求及其实用性产生影响。基于多个应用程序语料库的 SCoReS 可以使用通用数据分析技术,但需存储先前收集的数据,且它们的推荐通常限于特定库或框架的分析。因此,其有用性取决于 SCoReS 用户使用的 API 与服务器上可用 API 之间的匹配。相反,分析单个应用程序的 SCoReS 不需要单独的存储也不需要预取数据,但通常需要基于启发式的数据分析技术,这些 SCoReS 适合封闭源应用程序。

3.4.2 补充信息

除源代码或源代码存储库之外,推荐系统还可以从程序执行跟踪、软件配置管理系统、问题管理系统、开发者之间的非正式交流记录(电子邮件讨论,即时消息,论坛等)、用户的导航和编辑行为及用户历史记录中提取的有用信息。

3.4.3 相关信息

所有非源码数据的 SCoReS 都需要将其与源代码相关联。如果系统不能将多个数据源组合成超出独立事实的数据便没有价值。因此,需做出的一个相关决策是如何将程序代码的信息与互补资源中提取的信息进行混合。例如可以将 CVS 信息库中文件的作者信息和时间戳与这些文件中包含的源代码相关联,以推断出哪些源代码实体可能一起更改的。

3.5 通用输入/输出

3.5.1 输入机制

无论何时触发推荐,第一个决策都是考虑 SCoReS 是否从当前活动的源码实体或工件推断出其输入。该决策取决于是否需要从源代码上下文中获得的信息来计算推荐信息。尽管大多数 SCoReS 会从用户的当前上下文或活动中隐式推断出他们的输入(例如 FrUiT,Strathcona 和 Rasca),但也有一些系统部分或完全依赖于用户的输入来请求的任务或实体的推荐,如 CodeBroker 和 Hipikat。

3.5.2 输入的性质

输入的性质直接影响用户对使用该系统易用性的看法。大多数 SCoReS 都要求输入(片段)源代码以提供有关该源代码的具体推荐,例如 FrUiT 或 Rascal。其他系统隐式或显式地考虑了用户的上下文和活动,例如 Strathcona 和 CodeBroker。编程上下文通常限于关注的焦点或正在使用的源代码实体。另外,某些系统以自然语言查询或其他非代码工件的形式接收输入。

3.5.3 响应触发器

构建 SCoReS 时还需要确定何时触发系统以计算推荐。可以根据用户的明确请求来计算推荐,也可以在发生某些上下文时主动计算。但是,即使是在开发环境中隐式发现输入的 SCoReS,除了少数如 CodeBroker 之类的系统会不断更新其结果,计算推荐的请求仍然是显式的。该决策被认为与侵入性有关,大多数 SCoReS 仅在开发者明确请求后才触发响应,并在外围视图而不是在主编程视图中提出推荐及其理由,从而避免形成干扰。

3.5.4 输出的性质

输出的性质也会影响 SCoReS 的可用性。例如,对于作为输入的源代码片段,Strathcona 向开发者提供了类似的源代码示例。由三部分组成:类似于 UML 的图形化概述说明示例与查询片段的结构相似性,推荐原因的文字说明,以及突出显示与查询的源代码片段。

SCoReS 没有典型的输出类型。尽管其中一些限制发送某些原始文本描述中要求的信息,但其他一些旨在将推荐集成到 IDE 中,以便无缝地使用它。包括导航和浏览辅助工具。尽管现有的 SCoReS 往往多使用 UML 图,但目前为止,SCoReS 的中间数据表示(例如,图形,树,矢量)确实已被忽略,无法作为提供推荐的方式。我们认为,在某些情况下,以这种风格呈现推荐而不是仅呈现列表,可能为终端用户提供了一种更直观的方式来理解结果。

3.5.5 输出类型

SCoReS 的有用性还取决于为支持任务而产生的输出的适当性。这些输出的示例包括现有软件工件或与用户当前任务相关的源代码实体、缺少源代码实体或片段、或映射实体的推荐(如语句或方法)。相关实体指作为输入的源代码实体通常使用或更改的其他实体。例如,重用的方法、更改的方法、下一个要调用的方法或要调用的一组方法。映射指示一个实体的组件如何使用或被替换为另一实体的组件。实现关系显示出可能被遗忘的句法或结构关系(例如,实现接口,调用方法,使用类型等)。

3.6 方法

3.6.1 数据选择

SCoReS 的开发者还必须决定数据收集的详细程度,这意味着 SCoReS 可以做哪些分析以及用户可以使用哪些信息。还需预先描述数据收集的原理,尤其是如何使用它来提供有用的推荐,以便选择适当的粒度级别。在分析面向对象的源代码时,大多数 SCoReS 的首选是方法和方法之间的关系(例如调用语句、覆盖信息、继承,实现)。但是,类型信息(例如方法的返回类型或其参数的类型)对于连接不同的源代码实体也非常有用。源代码实体名称中的令牌是另一重要信息,可以进行词汇分析。使用的其他源代码信息包括注释、文件、类型、字段、文字、签名、包含/实例化语句、访问信息、语句、和代码的变更信息等。

3.6.2 分析类型

最简单的分析方法是直接对源代码进行文本分析。像 Hipikat 和 CodeBroker 一样,词汇方法或基于令牌的技术使用词汇分析将代码转换为一系列词汇令牌。语法方法将源代码转换为解析树或抽象语法树,并在这些树的基础上执行其后续分析,就像 FrUiT,Strathcona,Rascal 和 CodeBroker 一样。语义感知方法通过依赖动态程序分析技术在语义层次上执行其分析。

3.6.3 数据要求

此决策说明了数据的特定限制,以使系统能够正常工作,例如系统所针对的编程范例(面向对象还是过程)或特定编程语言(Java,Smalltalk,C 等)。做出此决定通常是出于务实的原因,例如能够将 SCoReS 的结果与另一个结果进行比较,这需要能够分析相同的源代码,或者使用某些辅助工具进行数据提取和处理。

最常见范例是面向对象的,因为它在当前的工业实践中更为普遍,尽管其中有一些限于程序范例。但是,对面向对象代码所做的许多假设可以转换为过程,反之亦然。Java 似乎是 SCoReS 最普遍支持的语言之一。其他语言包括 C 和 SmallTalk。尽管实现语言的选择似乎微不足道,但是像 Smalltalk 这样的动态类型语言可能使原型化工具更加容易,但是另一方面,动态类型语言不能确保像 Java 这样的静态类型语言所做的所有假设。例如,方法签名可以唯一地链接到类型,方法可以返回特定类型的变量,或者其参数为特定类型。类似地,尽管方法名称可以用 Java 之类的语言表示类似的问题,但对于 Smalltalk 之类的语言(方法的名称和签名之间没有区别),这种指示更难于验证。

除了语言之外,对系统所需的数据可能还有其他特殊要求,例如应有足够的使用特定 API 的示例代码,例如 Strathcona。

3.6.4 中间数据表示

该决策涉及将原始数据处理成合适的格式以进一步处理的情况。关于这种中间格式,SCoReS 的设计人员可以通过程序依赖或调用关系使用基于图的方法;也可以通过转换抽象语法树或其他树结构采取基于树的方法;Rascal 和 CodeBroker 使用矢量和矩阵作为中间表示,FrUiT,Hipikat 及 Strathcona 等基于事实来组织逻辑或事实集的数据。其他方法可能会使用度量标准或文本数据来做推论。Hybrid 体现了多种方法的结合使用。

以图和事实为基础似乎是最受欢迎的表示形式之一,可能是因为它们提供了灵活且众所周知的机制来查找内在关系,而这些关系可以用来解释推荐背后的原理。向量或矩阵表示可提供高性能的运算,同时也能准确说明相关事实。文本和数字表示形式似乎不太适合 SCoReS,因为它们缺乏可追溯性。因此,基于搜索的技术通常在矩阵或矢量表示之上而不是文本表示之上进行操作。

3.6.7 分析技术

下一个关键决策是选择实际算法或者说技术,该算法或技术将从提取的数据中产生相关推荐。

传统推荐技术通常基于要推荐的项目和这些项目的用户。推荐系统旨在通过确定用户的需求或偏好,然后找到满足这些需求的最佳项目,从而将用户与项目匹配。为了确定用户的需求,推荐技术可以考虑当前用户的先前评分(社会标签),人口统计信息,商品功能或商品对当前用户的适用性。匹配完成后,可以根据用户评分对项目进行优先级排序。这些策略结果的组合导致了不同种类的推荐技术。 Rascal 是依赖传统推荐技术的典型示例。

但实际上,除非 SCoReS 推荐的 API 调用具有大量示例应用程序,否则通常很难依靠传统的推荐技术,因为使用同样或相似代码的用户群体是栈少数的。因此,SCoReS 最流行的分析技术是通过使用传统的分类技术(如聚类分析,关联规则挖掘,频繁项集)来计算输入和其他待分析实体之间的相似度。其他一些方法依赖于基本的或高级的搜索技术,从机器学习或逻辑推理中获得灵感,或者像 Hipikat 和 Strathcona 一样依赖于启发式技术。启发式方法是一种流行的选择,因为它们可以挖掘频繁关系未描述的实体之间的预期相似性。在分类技术中,那些对次要异常有弹性的技术(如频繁项集分析和关联规则)优先于那些考虑了所有信息的技术(如形式概念分析),在区分不同源码实体的特质的同时不会影响结果。

3.6.8 过滤

过滤(也称为数据清除)目的是避免在结果中产生噪音(误报)。许多 SCoReS 使用两阶段过滤方法。第一阶段查找与用户上下文有关的实体或属性。在第一阶段中丢弃信息也称为预过滤。常见的预过滤包括:使用停用词黑名单、排除手动导入的库,排除系统类或生成的代码等。第二阶段从第一阶段中选择最合适的结果。在第二阶段中丢弃信息称为后过滤。后过滤旨在消除琐碎、无关或错误的推荐,按相关性对它们进行排序,并仅显示最合适的推荐。

过滤常常是通过将源代码实体或其他工件与当前开发上下文进行比较来完成的。可以通过基于某种相似性度量,基于出现次数的频率(如 FrUiT 和 Strathcona)或基于某些评分机制(如 CodeBroker)来完成比较。可以使用相似性,频率或等级信息来完成预过滤和后过滤。频率是评级的一种形式,但是频率往往比评级更可取,这样即使在推荐系统的早期阶段(当尚未给出评级时)也可以提供推荐。不过,要使用频率这一指标,必须先有几个示例,这也是 API 推荐作为推荐系统支持的首选任务的原因之一。评级被较少采用的另一个原因是,早期的 SCoReS 报告称它们是侵入性的,并且是引入噪声的来源。但评分可能是收集方法有用性数据以及进一步迈向传统推荐技术而不仅仅是挖掘技术的好方法。

3.7 详细输入/输出

有关详细输入/输出的决策涉及 SCoReS 所需的详细信息(通常从开发上下文中提取或明确请求)以及 SCoReS 提供的结果数量。

3.7.1 输入类型

除了语料库(3.4 小节)之外,SCoReS 的构建者还需要确定系统分析所需的其他信息。该决策是对输入机制和 3.5 小节中描述的输入决策性质的改进。

某些推荐系统(如 Hipikat)从用户给出的搜索查询开始,而其他推荐系统可能从特定的源代码实体开始(部分实现,例如 Strathcona 和 Rascal 或者空实现,例如 CodeBroker),或者某种方式映射的成对的实体或工件,又或者是共同表示某种更高级别概念的实体集。

如果用户没有明确的起点,则某些系统允许从提供的信息中(例如,当前正在编辑的文件中的任何标识符或文字)来找到它。

3.7.2 输出的数量

应该谨慎选择 SCoReS 提出推荐的数量。在推荐系统的设计中,提供简洁准确的结果至关重要。将结果限制在一个合理的范围内,可使开发者评估其适当性和价值,相应地去选择或丢弃它们。如果 SCoReS 产生单个结果,则可以避免用户选择最相关结果的负担,但也可能丢失其他相关结果。当返回多个结果时,可以通过对它们进行优先排序来减轻选择最合适的结果的负担,而不是显示无序的结果列表。

3.8 支持

这一决策着重于与 SCoReS 所支持任务的适用性相关的方面。它有助于预见验证系统有用性或正确性的方法。

3.8.1 经验验证

如果 SCoReS 的构建者希望从示例论证之外评估他们的系统,则重要的是使用哪种经验验证来评估其系统。验证 SCoReS 的典型方法是案例研究(或对特定应用程序的深入分析)、基准测试、自动模拟系统使用、将系统的结果与某种 Oracle 或行业标准进行比较、具有因变量和自变量的受控实验、从业人员进行的验证或实地研究等。

验证的最常见类型包括分析开发者如何使用系统,或与类似系统进行比较。大多数方法选择开源系统进行验证。在这种情况下,必须准确提及所使用的版本,以使验证结果易于复制。还应考虑是否提供收集的语料和获得的结果。向其他人提供此信息的访问权限,使他们可以验证和复制每个论证步骤,并有助于构建基准和模拟。还需提供验证语料库是否能正确构建的可能性,并可以识别使用同一语料库的不同 SCoReS 给出的推荐之间的差异。

3.8.2 有效性

可以从三个方面验证 SCoReS 与它支持的任务的相关性:评估 SCoReS 是否使用户以更快地完成给定任务,或者说花费更少的精力。

大多数情况下,为了验证系统,SCoReS 构建者仅进行案例研究来论证其系统推荐的实用性,而不进行定量的验证。但是,无论选择哪种验证类型,都应注意特定验证选择的要求。例如,针对任务被令人满意的完成了,就需要对任务进行明确说明,何时完成,以及唯一正确的响应是怎样的。最后还要意识到,用户忽略的推荐不一定表示不正确或无效的推荐。通过对现有 SCoReS 的分析及其验证,我们认为仍然存在很多机会可以更好地评估推荐系统的有效性。

3.8.3 正确性

关于 SCoReS 产生结果的质量,典型的正确性度量包括精度(正确推荐的百分比)和召回率(推荐在多大程度上覆盖了所需功能)。相关性也可以测量,但是通常是用户的主观看法,因此很难自动收集。

请注意,为了测量精度或召回率,有必要针对每个用户上下文建立正确的推荐进行比较。实际上,根据推荐的性质,可能无法获得理想的正确答案。此外,在进行这种类型的验证时,重要的是能够断言所分析的用户上下文是典型用户上下文的重要示例。

3.9 交互

最后一组决策集中于不同类型的用户如何与 SCoReS 进行交互。第一类用户是使用 SCoReS 作为其工作支持的开发者。对于此类用户,重要的是评估他们与 SCoReS(进行交互的难易程度以及在多大程度上可以轻松掌握 SCoReS。第二类用户是研究人员,他们可能想将自己的方法与 SCoReS 进行比较。这些用户担心系统的可用性,但更担心数据的可用性,因为他们希望可以重现和比较结果。

3.9.1 易用性

关于 SCoReS 对预期的终端用户(通常是开发者)的易用性,应仔细评估几个标准,如系统的响应时间、结果的简洁性,使用的容易程度和可伸缩性。但衡量 SCoReS 的易用性并非易事。简单的方式是度量简洁性或响应时间。但即使如此,除非将 SCoReS 的测量结果与类似系统的测量结果进行比较,否则这些测量结果本身并不能为 SCoReS 提供可靠依据。

3.9.2 系统可用性

该决策描述了将以何种形式提供系统:仅提供源代码如 FrUiT;仅作为二进制文件;仅提供系统描述的如 Hipikat 和 Strathcona,或像 Rascal 和 CodeBroker 一样并不能直接使用。根据系统构建者的预期目标,此决策可能会有很大不同。

3.9.3 推荐数据的可用性

最后一个决策是,是否提供 SCoReS 经验验证的结果。将所有产生的数据公开,可以让其他研究人员复制验证并比较系统之间的结果。有几个级别的数据可用性需要考虑: SCoReS 收集或使用的语料库,或者 SCoReS 在不同目标系统上产生的结果。最后,还可以存储目标系统的版本,以便将它们用于创建基准或将给定 SCoReS 与其他 SCoReS(或相同 SCoReS 的未来版本)产生的结果进行比较。

致谢

感谢国家重点研发计划课题:基于协同编程现场的智能实时质量提升方法与技术(2018YFB1003901)和国家自然科学基金项目:基于可理解信息融合的人机协同移动应用测试研究(61802171)支持!

本文由南京大学软件学院 2018 级硕士生袁阳阳翻译转述。