1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
|
#include <iostream>
#include <fstream>
#include <iomanip>
#include <vector>
#include <string>
using namespace std;
// Some data
istringstream str( "1 3\n"
"2 5\n"
"3 7\n"
"4 9\n"
"5 11\n" );
//======================================================================
struct Data{ double x, y; };
//======================================================================
vector<Data> getData( istream &in )
{
vector<Data> result;
for ( double x, y; in >> x >> y; ) result.push_back( { x, y } );
return result;
}
//======================================================================
void regression( const vector<Data> &data, double &m, double &c )
{
int N = data.size();
double Sx = 0, Sy = 0, Sxx = 0, Sxy = 0, Syy = 0;
for ( Data d : data )
{
double x = d.x, y = d.y;
Sx += x;
Sy += y;
Sxx += x * x;
Sxy += x * y;
Syy += y * y;
}
m = ( N * Sxy - Sx * Sy ) / ( N * Sxx - Sx * Sx ); // slope
c = ( Sy - m * Sx ) / N; // intercept
}
//======================================================================
void training( const vector<Data> &data, double &m, double &c, double alpha, int passes )
{
m = c = 0.0;
while( passes-- )
{
for ( Data d : data )
{
double error = m * d.x + c - d.y;
c -= alpha * error;
m -= alpha * error * d.x;
}
}
}
//======================================================================
void write( const vector<Data> &data, double m, double c )
{
#define fmt << setw( 20 ) <<
cout << "Regression line is y = " << m << "x + " << c << "\n\n";
cout << fixed << setprecision( 6 );
cout << "For comparison (x, y, ypred):\n";
for ( Data d : data ) cout fmt d.x fmt d.y fmt m * d.x + c << '\n';
}
//======================================================================
int main()
{
double m, c; // slope and intercept; y = mx+c
vector<Data> data = getData( str );
cout << "Read " << data.size() << " points\n\n";
// STANDARD METHOD
cout << "Regression (STANDARD METHOD)\n";
regression( data, m, c );
write( data, m, c );
// GRADIENT-DESCENT METHOID
int passes = 5;
double alpha = 0.1;
cout << "\n\nRegression (GRADIENT DESCENT)\n";
training( data, m, c, alpha, passes );
write( data, m, c );
}
| |