我正在为单变量线性回归编写一个小的d3.js可视化,其中两个参数是通过成本函数的梯度下降来学习的(平方误差之和a.k. a。 SSE ))。
到目前为止,我们可以看到最适合调整的线条,因为梯度下降会逐渐减少成本最小化的参数选择,“alpha'和' beta'”,其中
y_i = alpha + beta * x_i
在javascript中,数据表示为具有' x'的对象数组。并且' y'属性。数据生成如下:
其中误差从正态分布中采样,均值为零且方差 errorVariance 。
我已经编写了一些d3.js代码来实现渐变下降,当我观察可视化时,似乎没有正确学习拦截术语。这是因为算法经常调整斜率参数,但仅从其初始值(随机选择)稍微调整截距参数。有三种可能性:
我无法弄清楚答案是什么。因此,我将发布一个简化的代码设置,希望有人能够为我提供一些启示。您还可以以当前形式查看可视化(并查看完整源代码)here。我们现在只担心数学问题。如果有人希望我发布将数据加入svg元素的代码,我很乐意,但我认为这个问题更可能出现在这里。
// Section 1: GENERATE DATA
var n = 60;
var upBound = 20;
var lowBound = -20;
var errorVariance = 6;
var data = []
// grab a random x value.
var randomX = function() {
return Math.random() * (upBound - lowBound) + lowBound;
}
// zero-mean normally distributed error.
var error = d3.random.normal(0, errorVariance);
// The following function defines the "data-generating-process":
// y = 3x - 10 + error
var dgp = function(x) {
return 3*x - 10 + error();
}
// Randomly generate data according to the dgp.
for (var i = 0; i < n; i++) {
var newX = randomX()
var newY = dgp(newX);
data.push({
"x": newX,
"y": newY
});
}
这一切都很好,花花公子。然后在第2节中,我提供了用于执行梯度描述的实用程序。
// define parameters for Gradient Descent
var learningRate = 0.00001;
var convThreshold = 0.005;
// Per Observation Cost Function
var obsCost = function(alpha, beta, data, i) {
return .5 * Math.pow(((alpha + beta * data[i]["x"]) - data[i]["y"]), 2);
}
// Sum of Squared Errors
var costFuncLR = function(alpha, beta, data) {
var sse = 0;
for (var j = 0; j < n; j++) {
sse += obsCost(alpha, beta, data, j);
}
return sse;
}
var obsErr = function(alpha, beta, data, i) {
return (alpha + data[i]["x"] * beta) - data[i]["y"];
}
// Partial derivative of cost w.r.t. alpha
var pJpAlpha = function(alpha, beta, data) {
var sum = 0;
for (var i = 0; i < n; i++) {
sum += obsErr(alpha, beta, data, i);
}
//return sum;
return Math.sqrt(2 * costFuncLR(alpha, beta, data));
}
// Partial derivative of cost w.r.t. beta
var pJpBeta = function(alpha, beta, data) {
var sum = 0
for (var j = 0; j < n; j++ ) {
sum += obsErr(alpha, beta, data, j) * data[j]["x"];
}
return sum;
}
// Performs one iteration of Gradient Descent.
var gradientDescentIter = function(data, alphaOld, betaOld, learningRate) {
var pjpa = pJpAlpha(alphaOld, betaOld, data)
var pjpb = pJpBeta(alphaOld, betaOld, data)
var temp0 = alphaOld - (learningRate * pjpa);
var temp1 = betaOld - (learningRate * pjpb);
var alphaNew = temp0;
var betaNew = temp1;
var out = [];
out.push(alphaNew);
out.push(betaNew);
console.log(costFuncLR(alphaNew, betaNew, data));
return out;
}
我提前感谢您的帮助。
有些不相关,我想通过参数空间中的等高线图或欧几里德3空间中嵌入的表面(z轴为成本)显示成本函数的水平集,并观察参数也改变了那个空间。我找到了mike bostock关于如何使用等高线图的帖子,但是