21、个性化代码格式化器:检测与修复

个性化代码格式化器:检测与修复

1. 模型聚合

在建模的最后一步,需要将两个独立模型的决策进行合并。整体流程从需要检查格式错误的初始源代码开始,包括代码的分词、生成相应的标记,以及预测阶段。在预测阶段,将标记输入到选定的两个模型——LSTM和SVM One-Class中。对于初始源代码中的每个标记,模型会输出该标记在特定位置错误出现的概率。接下来,将两个模型的预测结果进行合并,形成最终的概率。通过对每个模型计算出的概率进行平均,能够修正单个模型做出的一些模糊决策。例如,一个标记可能被一个模型误分类为格式错误,但预测概率较低,而另一个模型可能会以较高的概率将其正确分类。

2. 代码片段评分

为了优化识别格式错误出现位置的结果,增加了一个额外的步骤,即对代码片段进行评估并计算得分。这个得分反映了代码片段在格式错误和样式偏差方面相对于真实情况的纯净度。
- 操作步骤
1. 设计一个代码片段评分函数,将给定的代码作为输入。
2. 使用分词器将初始代码转换为标记,并将标记分割成预定义大小的集合,称为代码片段。
3. 处理每个代码片段,将标记分割成二元组(两个连续的标记构成一个二元组)。
4. 计算每个二元组在开发者提供的训练文件集中出现的频率。二元组在训练语料库中出现的频率越高,它是格式错误的可能性就越小。
5. 根据以下公式计算每个代码片段的最终得分:
[Score = \frac{\sum_{bigrams}(1 - norm\ freq)}{#bigrams}]
其中, norm freq 是二元组在训练语料库中出现的归一化频率,范围在 [0, 1] 之间, #bigrams 是代码片段中二元组的总数。归一化频率为 0 表示该二元组在任何训练文件中都未找到,而归一化频率为 1 表示该二元组在所有训练文件中都出现。
6. 使用上述公式计算的得分,调整建模阶段的概率,使其包含该得分的影响。具体来说,每个标记的概率乘以它所在代码片段的得分值,公式如下:
[Final\ token\ probability = snippet\ score * initial\ probability]
其中, snippet score 是根据公式 5 为标记所属的代码片段计算的得分, initial probability 是模型聚合阶段计算出的标记的聚合概率。
7. 最后,对标记及其相应的概率进行排序,形成可能是格式错误的标记的降序排列。

3. 可能的修复方法

接下来,需要生成一组可能的格式错误修复方法。一般来说,当一个标记未对齐或位置错误时会出现格式错误,通常可以通过以下三种不同的方式来修改这个特定标记进行修复:
- 添加一个额外的标记到错误位置标记之前的标记列表中。
- 删除产生格式错误的标记。
- 用另一个标记替换错误位置的标记。

为了生成可能的修复集合,需要考虑上述三种情况:
- 添加额外标记 :使用生成模型(即 LSTM 模型)的预测结果。具体来说,LSTM 预测的 5 个最可能的标记(即 LSTM 预测为标记序列中实际下一个的标记)是可能添加到标记序列中错误位置标记之前的潜在标记。将这些标记分别添加到序列中,并将预测结果输入到系统的下一步。
- 删除标记 :这种更改比较简单,只需要删除错误位置的标记。
- 替换标记 :再次使用 LSTM 模型的顶级预测结果作为被检查标记的潜在替换标记。

生成标记序列的可能更改列表后,首先需要识别并丢弃那些导致语法无效代码的更改。为此,使用适当的语言解析器(在本例中为 javac 解析器)来检查相应结果的语法有效性。显然,上一步中不能产生语法正确代码的可能修复方法将被丢弃,其余的将进入下一步进行排序。

4. 修复建议

在最后一步,会为开发者提供一个排序后的可能修复列表作为建议。在验证了剩余修复方法的语法有效性后,需要计算一个得分,以反映修复方法相对于用户所选代码样式的适用性。
- 操作步骤
1. 再次使用代码片段评分机制来为每个可能的修复方法计算得分。
2. 对于修复集合中的每个候选修复方法,根据其包含的二元组在训练语料库中出现的频率计算得分。
3. 使用公式 5 计算每个可能修复方法的最终得分。
4. 对所有可能的修复方法列表进行排序,将排名靠前的预测结果作为最佳可能的更改提供给开发者,以修复检测到的格式错误。

5. 评估

为了评估所提出的方法在识别格式错误、与全球通用代码样式的偏差以及提供修复建议方面的性能,在多个方面进行了几种评估场景。
- 检测评估
- 首先,使用 Codrep 数据集对系统进行测试。Codrep 是一个将机器学习应用于源代码的竞赛,2019 年竞赛的主要目标是识别代码文件中格式错误出现的位置。Codrep 数据集包含 8000 个 Java 文件,每个文件在特定字符位置包含一个格式错误,同时还提供了一个文件,其中包含每个文件中格式错误出现的字符位置。
- 根据 Codrep 规则,参赛程序应接收一个包含 Java 源代码的文件作为单一输入,并根据计算出的概率输出字符偏移量的降序排名,以估计它们包含格式错误的可能性。最后将字符的最终排名与实际包含格式错误的字符进行比较,并计算评估指标。
- 使用平均倒数排名(MRR)指标来评估系统的性能,公式如下:
[MRR = \frac{1}{|Q|}\sum_{q \in Q}\frac{1}{rank_q}]
其中, Q 是评估文件的集合, rank_q 是在有序列表中找到给定文件 q 的正确答案的排名。MRR 的最佳可能值为 1,表示在评估集中的每个文件中,格式错误的正确位置都在预测的第一位找到;而 MRR 值为 0 表示未找到格式错误的正确位置。

模型 未使用代码片段评分 使用代码片段评分
LSTM 0.70 0.72
7 - gram SVM 0.63 0.63
7 - gram SVM & LSTM 0.78 0.79
10 - gram SVM 0.57 0.61
10 - gram SVM & LSTM 0.85 0.88

从表中的 MRR 值可以看出,由 LSTM 和 10 - gram SVM 组成的组合模型,再加上代码片段评分机制,取得了最佳结果。这些值远高于随机猜测格式错误位置的结果。

为了应对 MRR 指标的严格性,还计算了正确答案在有序列表中位置的直方图。结果表明,大多数情况下,正确预测(即识别源代码中的格式错误)排在第一位。两个模型(LSTM 和 SVM)的组合明显改善了结果,选择 10 - gram 而不是 7 - gram 也有积极影响。代码片段评分机制的添加似乎也改善了结果,增强了检测效果。

为了进一步检查方法在识别格式错误和与全球通用代码样式偏差方面的性能,还进行了以下场景评估:从排序后的标记列表及其可能是格式错误的概率中,仅将前 k 个标记返回给用户,前提是它们是格式错误的概率高于预定义的阈值。对于这些标记,检查是否包含实际的格式错误,并计算 precision@k recall@k f - measure@k 指标。

graph LR
    A[初始源代码] --> B[分词]
    B --> C[生成标记]
    C --> D[预测阶段]
    D --> E[LSTM 模型]
    D --> F[SVM One - Class 模型]
    E --> G[模型聚合]
    F --> G
    G --> H[代码片段评分]
    H --> I[可能的修复方法生成]
    I --> J[语法有效性检查]
    J --> K[修复建议排序]
    K --> L[提供修复建议]

个性化代码格式化器:检测与修复

6. 实际应用中的格式错误修复

为了进一步评估该方法在为开发者提供可直接应用于源代码并修复已识别格式错误的有用建议方面的有效性,将该方法应用于实际场景中,以评估其在开发过程中提供可操作建议的能力。

随机选择了一些来自最流行 GitHub 仓库的小型 Java 文件进行测试。以下是两个具体的示例:
- 示例一 :在一个文件中,检测到第 12 行存在格式错误,问题在于额外使用了一个换行符。插入这个新字符会降低代码的整体可读性,因为没有正确的缩进。系统能够识别出格式错误的位置,修复机制会评估可能的修复方法并生成一个排序后的列表。得分最高的修复方法是移除这个多余的换行符,修复后的文件更易于开发者理解,正确的缩进有助于理解代码流程。
- 示例二 :另一个文件中,第 11 行的格式错误是额外使用了一个制表符。这个新字符的插入改变了开发者阅读和理解代码内容的方式。系统将该格式错误排在所有可能位置的首位,修复机制提供的第一个建议是移除这个制表符。修复后的文件,代码的理解更加自然流畅。

尽管这些示例看起来规模较小,修复操作似乎微不足道,但在大型项目中,不同开发者有不同的编码风格,检测和修复这些格式错误可以显著提高代码的可读性和可理解性。

7. 有效性威胁

该方法在识别与先前选定代码样式的格式偏差并为开发者提供可能的修复建议方面似乎具有较高的内部有效性,这在前面的评估中得到了证明。

然而,该方法的外部有效性存在一些限制和威胁,主要体现在以下两个方面:
- 训练数据集的选择 :在方法的第一步,为了定义所需的代码样式,使用了从 GitHub 上挖掘的前 10000 个 Java 仓库中提取的超过 200 万个语法有效文件的数据集。实际上,可以使用不同的项目或仓库来训练系统的代码样式。不过,该方法可以直接应用于任何仓库或基准数据集,涵盖多种不同的评估场景。
- 用例的选择 :为了评估该方法,使用了 Codrep 竞赛,其主要目标是识别与广泛接受的编码标准的格式偏差。一个外部有效性的威胁在于将该方法应用于不同场景的评估,即该方法在一组不同代码样式上的泛化能力。不过,所选的用例被认为是最常见和必要的,并且与其他场景没有显著差异。

8. 结论与展望

本文提出了一种自动化机制,能够识别与先前定义的代码样式的偏差,并为开发者提供修复建议。该系统基于 LSTM 和 SVM 两种算法,从不同角度对问题进行建模,并使用代码片段评分机制来评估给定代码在格式错误方面的纯净度。

该方法的主要贡献之一是不需要手动定义规则,而是通过机器学习模型自动学习代码样式。实验结果表明,由 LSTM 和 10 - gram SVM 组成的组合模型,结合代码片段评分机制,在识别格式错误方面取得了最佳效果。

未来的工作可以考虑以下几个方向:
- 扩展训练数据集 :使用更多不同来源和风格的代码文件进行训练,以提高系统在各种代码样式下的泛化能力。
- 优化模型 :尝试使用其他机器学习算法或对现有模型进行改进,以进一步提高检测和修复格式错误的准确性。
- 集成到开发工具中 :将该系统集成到常见的开发工具(如 IDE)中,为开发者提供更便捷的格式错误检测和修复功能。

未来工作方向 具体内容
扩展训练数据集 使用更多不同来源和风格的代码文件进行训练
优化模型 尝试其他机器学习算法或改进现有模型
集成到开发工具中 将系统集成到常见开发工具中
graph LR
    A[未来工作] --> B[扩展训练数据集]
    A --> C[优化模型]
    A --> D[集成到开发工具中]
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值