在编码风格上进行监督学习 - 特征选择(Scikit Learn)

8
我正在研究是否有可能基于编程风格自动评分学生的代码。这包括避免重复的代码、被注释掉的代码、变量命名不规范等等。
我们试图通过过去学期的组成成绩(从1到3)来学习,这很适合监督学习。基本思路是从学生提交的作业中提取特征,生成特征向量,然后使用scikit-learn中的逻辑回归进行训练。我们还尝试了各种方法,包括对特征向量运行PCA以减少维度。
我们的分类器只是猜测最常见的类别,即得分为2分。我认为这是因为我们的特征根本没有任何预测性。监督学习算法只猜测主导类别的其他可能原因是什么?有没有办法防止这种情况发生?
由于我认为这是由于特征没有预测性,那么如何确定“好”的特征是什么?(好的意思是可以区分或预测)
注意:作为一个副实验,我们测试了过去的成绩评分的一致性,让读者评分已经评分过的作业。只有55%的人给出了相同的组成成绩(1-3)。这可能意味着这个数据集根本无法分类,因为人类甚至不能一致地评分。有关其他想法的任何提示?或者那是否属实?
特征包括:重复代码行数、平均函数长度、1个字符变量数量、包含注释代码行数、最大行长度、未使用导入、未使用变量、未使用参数的计数。还有一些...我们可视化了所有特征,并发现虽然平均值与成绩相关,但变异性非常大(不太令人鼓舞)。
编辑:我们项目的范围:我们只试图从一个班级中一个特定项目(给出框架代码)中学习。我们目前不需要泛化。

1
+1. 哇!这是一个好问题! - Yavar
然而,这里的答案将更多地受统计学的驱动,而不是计算机科学。 - Yavar
包括“统计”作为一个标签。谢谢! - stogers
请澄清您在问题末尾的注释:“测试了过去的成绩如何一致,并确定它们根本不一致”。一致是根据什么来衡量的?您是如何进行测试的? - dan3
这更像是线性回归(数值预测)而不是逻辑回归(分类任务)。使用线性回归,您将获得数字如1.2、1.8、1.5等,而不仅仅是简单的标签“2”,这可能会给您一些见解。此外,请注意线性模型(在线性和逻辑回归中)可能只是表示变量之间关系的一种糟糕方式。因此,您也可以尝试其他方法,例如通过超平面分割数据(SVM,可能具有非线性核函数)或计算概率(例如朴素贝叶斯)。顺便问一下,您使用的特征是什么(一些示例会很有帮助)。 - ffriend
显示剩余6条评论
3个回答

1
功能包括:重复代码行数、平均函数长度、1个字符变量数量、包含注释掉的代码行数、最大行长度、未使用的import、未使用的变量、未使用的参数数量。还有更多...
你尝试过对这些功能进行标准化吗?似乎你想训练一个神经网络,使其能够将任何给定的代码分类。现在,不同的代码可能会有不同数量的重复代码行和未使用变量,但它们可能同样糟糕。因此,您需要通过例如“有用”代码的总行数来标准化您的参数。
找不到好特征非常令人沮丧。停滞时,始终要遵循直觉。如果人类可以完成任务,计算机也可以。由于您的功能看起来相当适度,可用于评估任何给定的代码,因此它们应该有效(前提是它们被正确使用)。
总结:对功能进行标准化应该可以解决问题。

如果我理解你的意思,我认为我们实际上并没有遇到问题。至少在我们项目的范围内,我们只是试图从一个特定课程中的一个特定项目中学习。由于我们的需求非常具体,我们不需要通过像项目总行数这样的方式进行规范化。(抱歉我在问题中没有提到这一点)。 - stogers
好的。在这种情况下,看起来给定的问题很难通过线性模型解决。你尝试过任何非线性模型吗?比如使用非线性核的SVM或GMM? - hrs

1

只是一个想法 - Andrew Ng在Coursera上教授机器学习课程(https://www.coursera.org/course/ml)。在整个课程中,学生提交了几个编程作业。我记得读过一篇文章(可惜现在找不到了),说有些正在进行的研究试图对来自该班级的学生提交的编程作业进行聚类,其背后的想法是学生在作业上会犯一些常见的错误。

不确定这是否对您有所帮助,但也许将此视为一个无监督学习问题可能更有意义(例如,仅查找不同代码样本之间的相似性,并且认为相似的代码样本应该获得相似的分数)。


谢谢!我一定会考虑这条路。我相信你所提到的是下面这篇论文吧?http://people.csail.mit.edu/zp/moocshop2013/paper_16.pdf我的教授也指引我们朝着这个方向前进,所以我认为这可能是我们接下来的方法! - stogers

0
  1. 你想平衡目标类别(接近相等数量的1、2、3分数)。你可以随机抽样过大的类别,bootstrap抽样过小的类别,或使用考虑不平衡数据的算法(不确定Python中哪个算法)。

  2. 确保进行交叉验证以防止过拟合。

  3. 有几种方法可以确定哪些属性是重要的:

    • 尝试所有属性组合,从其中一个开始
    • 或尝试所有属性组合,从它们全部开始
    • 或随机尝试属性组合(或使用遗传算法)

选择具有最高交叉验证准确性的属性组合。

您还可以将属性列的乘积相乘,以查看它们是否共同产生影响。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接