Линейная регрессия основана на уравнении Линии в форме
y = w1 * x + b
Термины
dcost_dreg += -2*(yRegression-yTarget);
dcost_dtar += -2*(yRegression-yTarget)*point[0];
должен вычислять погрешность уравнения линии в сравнении с точками выборки, но ваш расчет неверен.
Постоянная ошибка (b
error) - это разницакоординаты y выборки и координаты y, которая вычисляется по линейному уравнению для координаты x выборки.
Линейная ошибка (w1
ошибка) рассчитывается по разности градиентов.Разница в градиенте - это отношение высоты и ширины (г / х), а не произведение.
Это означает, что вычисление должно быть:
dcost_dreg += (yTarget-yRegression);
dcost_dtar += (yTarget-yRegression)/point[0];
Выражения
w1 += learningRate * (dcost_dtar/allData.length);
b += learningRate * (dcost_dreg/allData.length);
Рассчитайте среднюю ошибку выборок и примените поправку к уравнению линии, учитывая скорость обучения.
Измените функцию draw
, чтобы решить проблему:
void draw(){
background(255);
axes();
//Draw Points
for(int j=0;j<allData.length;j+=1){
float[] point = allData[j];
advancedPoint(point[0],point[1],color(181, 16, 32),10);
}
//Gradient descend, thats the confusing part...
if(i<10000){
i += 1;
float dcost_dreg = 0;
float dcost_dtar = 0;
for(int j=0;j<allData.length;j+=1){
float[] point = allData[j];
float yTarget = point[1];
float yRegression = w1*point[0] + b;
dcost_dreg += (yTarget-yRegression);
dcost_dtar += (yTarget-yRegression)/point[0];
}
w1 += learningRate * (dcost_dtar/allData.length);
b += learningRate * (dcost_dreg/allData.length);
}
//Draw Regression
linearPoints(w1, b);
}
Кстати, рекомендуем использовать line()
для рисования оси и уравнения текущей линии:
void linearPoints (float w1, float b){
strokeWeight(3);
stroke(100,100,255);
float x0 = -width;
float x1 = width;
float y0 = x0 * w1 + b;
float y1 = x1 * w1 + b;
line(x0+width/2, -y0+height/2, x1+width/2, -y1+height/2);
}
void axes(){
strokeWeight(1);
stroke(255,100,0);
line(0,height/2, width, height/2);
line(width/2, 0, width/2, height);
}