什么';在我的Python版本的玩具SVM中有什么错误?

什么';在我的Python版本的玩具SVM中有什么错误?,python,machine-learning,Python,Machine Learning,我现在正在看Andrej Karpathy的。在第2章:机器学习,二元分类中,他给出了一个(非常基本的)支持向量机的例子。这是Karpath的代码: var a = 1, b = -2, c = -1; // initial parameters for(var iter = 0; iter < 400; iter++) { // pick a random data point var i = Math.floor(Math.random() * data.length);

我现在正在看Andrej Karpathy的。在第2章:机器学习,二元分类中,他给出了一个(非常基本的)支持向量机的例子。这是Karpath的代码:

var a = 1, b = -2, c = -1; // initial parameters
for(var iter = 0; iter < 400; iter++) {
  // pick a random data point
  var i = Math.floor(Math.random() * data.length);
  var x = data[i][0];
  var y = data[i][1];
  var label = labels[i];

// compute pull
  var score = a*x + b*y + c;
  var pull = 0.0;
  if(label === 1 && score < 1) pull = 1;
  if(label === -1 && score > -1) pull = -1;

// compute gradient and update parameters
  var step_size = 0.01;
  a += step_size * (x * pull - a); // -a is from the regularization
  b += step_size * (y * pull - b); // -b is from the regularization
  c += step_size * (1 * pull);
}
“->”后面的第一个值是正确的标签,第二个值是分数,即学习标签

除第一个标签外,所有矢量/读入标签都是正确的(即分配了一个符号正确的值)

我不确定这是什么原因:我的代码有错误吗?我检查了几次,但什么也没找到。或者我忘记了一些Python特有的东西。或者,最后,是否有一些与ML相关的原因导致在这种情况下无法识别正确的标签。但请对此表示怀疑,否则Karpath得到正确结果是没有意义的


非常感谢您的任何意见或帮助。

我相信我发现了问题:

(A) 您的数据集没有线性切割

(B) Karpath的“Monte Carlo”梯度下降法对这样一个数据集进行了研究

(C) 你和Karpath使用了不同的数据

DATA SETS
label   Karpathy's      yours
  1     [1.2, 0.7]      [1.2, 0.7]
 -1     [-0.3, -0.5]    [-0.3, 0.5]
  1     [3.0, 0.1]      [-3, -1]
 -1     [-0.1, -1.0]    [0.1, 1.0]
 -1     [-1.0, 1.1]     [3.0, 1.1]
  1     [2.1, -3]       [2.1, -3]
您提供的数据集几乎有一条大致相同的切割线(超平面) y=1/3x+1/2,但靠近这条线的三个点一直在争论划分。事实证明,最好的除法器明显不同,将[1.2,0.7]严重地放在了错误的一边,但对此非常不高兴

原始数据在大致y=-3x+1处有一条整齐的切割线,该算法大致用(四舍五入)0.6x-0.1y-0.5近似

同样,该算法寻求的是最小成本拟合,而不是最宽分离通道的“纯”SVM。即使存在整齐的切割线,该算法也不会收敛于该切割线;相反,它通过黑客攻击,找到了一个可接受的解决方案

它选择一个随机点。如果该点被严格分类——分数为右符号且大小大于1——则不会发生任何事情。但是,如果该点位于线路的错误一侧,或者过于接近舒适度,则它会提取参数以进行更有利的处理

除非海峡有2个单位宽,否则争议领土内的各点将继续轮流将其推来推去。没有收敛标准。。。事实上,在某一点之后,没有收敛保证

仔细查看Karpath的代码:主要算法对分数<1或>-1的数据点进行更改(取决于培训课程)。但是,如果结果的符号正确,评估算法将宣布胜利。这是合理的,但并不完全符合培训功能。在我的试验中,第一个点的分数总是小于0.07,但实际值在0的两边都是模糊的。其他点都远离0,但只有两个通过1。关于这条线应该在哪里有四点争论



这对你来说清楚了吗?

我熟悉神经网络,但不是特别熟悉SVM。我的问题是:你确定这是错误的吗?在给它你的数据集和400次迭代学习之后,它已经得出了最好的a、b、c值,可以近似所有结果。然而,这可能是因为这种类型的模型没有足够的表达能力,无法使它们都正确无误。在后台网络中,我可能会考虑添加隐藏节点。我不知道如何推荐特别修改这个SVM结构,但我可能会考虑一下。我也不是专家,但SVM通常以对偶形式(拉格朗日乘数)求解。我很少看到这样做,我不确定这个简单的无约束梯度下降应该如何解决受约束的原始问题。。。例如,我还没有完成代码,但我可能会提供一些帮助。首先,梯度下降是支持向量机算法找到提供最佳分类的膜的一种方法,特别是当集之间没有很好的连接时。其次,线性分类器在面对无法清晰划分的数据集时可能具有奇怪的特性。我已经习惯于对我的一些数据集进行错误分类。如果我正确绘制了你的数据,就没有线来分隔这两组数据。你也运行原始代码了吗?输出学习值?据我所知,您的代码应该与提供的代码相同。所以我猜这就是它处理特定数据集的方式。@RobertB为延迟的回答道歉。我认为这是错误的,因为教程指出,相同的数据集/完全由提供的代码学习。所以我的第一个问题是,我的代码错了吗。正如您在下面所写的,代码似乎是正确的,但这毕竟可能是一个学习问题。非常感谢您提供了这个极其详细的答案。明天我有一个重要的截止日期,所以我只有机会真正看看你的答案,看看从现在起一两天内我是否理解了。现在,我将投票赞成,稍后将回到它(并将标记为已回答)。好的,第一句话:绝对没有看到我使用了错误的数据集。在您找到的实际数据之上,Karpath列出了另一个数据集(就在二元分类章节的下方),这就是我使用的数据集。这两个似乎基本相同,我现在想知道是否第一个数据集导致了我发现的问题,这就是为什么他在以后的开发中更改了一些值(然后忘记更正第一个数据集)。仍然试图理解/为什么/它不起作用(这意味着我需要查找线性切割的正式含义),我正在简化术语。所谓“线性切割”,我的意思是数据有一条完美的、直线的分界线:你可以画一条线,在一边有所有的+1数据,在另一边有所有的-1数据。简单的支持向量机都使用线性除法器,但有些实现允许多项式和高斯部分
1.2 , 0.7 --> 1 vs. -0.939483353298
-0.3 , 0.5 --> -1 vs. -0.589208602761
-3.0 , -1.0 --> 1 vs. 0.651953448705
0.1 , 1.0 --> -1 vs. -0.921882586141
3.0 , 1.1 --> -1 vs. -1.44552077331
2.1 , -3.0 --> 1 vs. 0.896623596303
DATA SETS
label   Karpathy's      yours
  1     [1.2, 0.7]      [1.2, 0.7]
 -1     [-0.3, -0.5]    [-0.3, 0.5]
  1     [3.0, 0.1]      [-3, -1]
 -1     [-0.1, -1.0]    [0.1, 1.0]
 -1     [-1.0, 1.1]     [3.0, 1.1]
  1     [2.1, -3]       [2.1, -3]