我有一个线性回归算法,我想编辑,所以它需要两个向量。这两个向量是从csv文件中的数据创建的,我想使用线性回归来比较这两个向量中的数据,并基于它们进行预测。下面的算法只接受一个包含要比较的两个值的向量,但我想改变它,使它可以接受两个独立的向量,并比较两个向量之间的值。或者像算法那样把我的两个向量组合成单个向量会更容易吗?
#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 );
}
该算法确实与同时具有x
和y
的结构一起工作。最简单的方法是以这样的结构复制单独的向量:
std::vector<Data> transform(const std::vector<double>& x, const std::vector<double>& y) {
std::vector<Data> result(x.size());
for (int i=0; i < x.size(); ++i) {
result[i] = { x[i], y[i] };
}
return result;
}
这是相当昂贵的,因为它复制了所有的数据。也许您可以更改生成x
和y
的代码,使其生成一个std::vector
。如果要修改算法,只需替换任何出现的std::vector;带有两个独立
以及每个std::vector
;x,yv[i].x
和x[i]
。
PS该算法的实际问题在于它是在容器上工作,而不是在迭代器上工作。如果算法将使用迭代器,那么在不同类型的容器中使用它会更简单,而不需要复制数据或修改算法。