Wednesday, December 21, 2016

Gradient Descent Linear Regression Curve Fitting Simple Implementation in C++


Explanation:

This code made following Andrew NG's machine learning course on coursera. The program has no input for simplicity, all input data are hard coded. Beware the tolerance version of code can not handle random data, please use the one with fixed iteration count.

TODO

Visualization:

Applying hypothesis in a random sample:

This is another example taking some random numbers and try to fit a line through them to minimize error.



Code Random Sample with Tolerance:

/**
* Author: Asif Ahmed
* Site: https://quickgrid.blogspot.com
* Problem: Linear Regression gradient descent curve fitting though points in 2-space.
* Details: Please remove windows.h header if any trouble with compilation.
*/
#include<bits/stdc++.h>
#include<windows.h>
#define M 5
#define TOLERANCE 0.3
int x[M] = {1, 2, 3, 4, 5};
int y[M] = {2, 4, 6, 6, 10};
float alpha = 0.1;
float J(float theta0, float theta1){
float Jerror = 0;
for(int i = 0; i < M; ++i){
Jerror = Jerror + ( y[i] - theta0 - ( theta1 * x[i] ) ) * ( y[i] - theta0 - ( theta1 * x[i] ) );
}
return Jerror / ( 2 * M );
}
int main(){
float theta0 = 0;
float theta1 = 0;
printf("Initial Hypothesis: y = %f + %fx\n", theta0, theta1);
printf("Error: %f\n", J(theta0, theta1) );
while( J(theta0, theta1) > TOLERANCE ){
//
float temp0 = 0;
for(int i = 0; i < M; ++i){
temp0 = temp0 - ( y[i] - theta0 - (theta1 * x[i]) );
}
temp0 = temp0 / M;
//
float temp1 = 0;
for(int i = 0; i < M; ++i){
temp1 = temp1 - ( ( y[i] - theta0 - (theta1 * x[i]) ) * x[i] );
}
temp1 = temp1 / M;
//Sleep(1000);
//printf("DEBUG\n");
//
theta0 = theta0 - alpha * temp0;
theta1 = theta1 - alpha * temp1;
}
printf("DONE\n");
printf("Initial Hypothesis: y = %f + %fx\n", theta0, theta1);
printf("Error: %f\n", J(theta0, theta1) );
return 0;
}


Code Random Sample with Fixed Iterations:

/**
* Author: Asif Ahmed
* Site: https://quickgrid.blogspot.com
* Problem: Linear Regression gradient descent curve fitting though points in 2-space.
* Details: Please remove windows.h header if any trouble with compilation.
*/
#include<bits/stdc++.h>
#include<windows.h>
#define M 5
#define MAX_ITERATIONS_COUNT 3000
int x[M] = {1, 2, 3, 4, 5};
int y[M] = {2, 4, 6, 6, 10};
float alpha = 0.001;
float J(float theta0, float theta1){
float Jerror = 0;
for(int i = 0; i < M; ++i){
Jerror = Jerror + ( y[i] - theta0 - ( theta1 * x[i] ) ) * ( y[i] - theta0 - ( theta1 * x[i] ) );
}
return Jerror / ( 2 * M );
}
int main(){
float theta0 = 0;
float theta1 = 0;
printf("Initial Hypothesis: y = %f + %fx\n", theta0, theta1);
printf("Error: %f\n", J(theta0, theta1) );
int iter = 0;
while( iter < MAX_ITERATIONS_COUNT ){
//
float temp0 = 0;
for(int i = 0; i < M; ++i){
temp0 = temp0 - ( y[i] - theta0 - (theta1 * x[i]) );
}
temp0 = temp0 / M;
//
float temp1 = 0;
for(int i = 0; i < M; ++i){
temp1 = temp1 - ( ( y[i] - theta0 - (theta1 * x[i]) ) * x[i] );
}
temp1 = temp1 / M;
//Sleep(1000);
//printf("DEBUG\n");
//
theta0 = theta0 - alpha * temp0;
theta1 = theta1 - alpha * temp1;
++iter;
}
printf("DONE\n");
printf("Final Hypothesis: y = %f + %fx\n", theta0, theta1);
printf("Error: %f\n", J(theta0, theta1) );
return 0;
}


Code Curve Fitting through Prime Numbers:

/**
* Author: Asif Ahmed
* Site: https://quickgrid.blogspot.com
* Problem: Linear Regression gradient descent curve fitting though points in 2-space.
* Details: Please remove windows.h header if any trouble with compilation.
*/
#include<bits/stdc++.h>
#include<windows.h>
#define M 10
#define MAX_ITERATIONS_COUNT 9000
int x[M] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int y[M] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29};
float alpha = 0.01;
float J(float theta0, float theta1){
float Jerror = 0;
for(int i = 0; i < M; ++i){
Jerror = Jerror + ( y[i] - theta0 - ( theta1 * x[i] ) ) * ( y[i] - theta0 - ( theta1 * x[i] ) );
}
return Jerror / ( 2 * M );
}
int main(){
float theta0 = 0;
float theta1 = 0;
printf("Initial Hypothesis: y = %f + %fx\n", theta0, theta1);
printf("Error: %f\n", J(theta0, theta1) );
int iter = 0;
while( iter < MAX_ITERATIONS_COUNT ){
//
float temp0 = 0;
for(int i = 0; i < M; ++i){
temp0 = temp0 - ( y[i] - theta0 - (theta1 * x[i]) );
}
temp0 = temp0 / M;
//
float temp1 = 0;
for(int i = 0; i < M; ++i){
temp1 = temp1 - ( ( y[i] - theta0 - (theta1 * x[i]) ) * x[i] );
}
temp1 = temp1 / M;
//Sleep(1000);
//printf("DEBUG\n");
//
theta0 = theta0 - alpha * temp0;
theta1 = theta1 - alpha * temp1;
++iter;
}
printf("DONE\n");
printf("Final Hypothesis: y = %f + %fx\n", theta0, theta1);
printf("Error: %f\n", J(theta0, theta1) );
return 0;
}


Prime numbers on a graph:

This is before applying any hypotheses. Just putting the prime numbers in the graph against their index or order.



Applying hypotheses calculated by program:

A line a can never go though all the prime number points. So the task is to minimize the distance of all the points to curve is minimized. In other words the task is to optimize in such a way that the error value is minimum.


No comments: