1. 线性回归介绍
线性回归是一种统计学上常用的数据分析方法,其本质是通过建立数据的线性模型来对数据进行预测或者分析。线性回归的基本假设是:数据之间存在着线性关系,并且误差服从正态分布。
在现实应用中,线性回归可以被用来解决很多实际问题,比如:
根据房屋面积、地段等因素预测房价
根据历史销量预测未来销量
根据气温、湿度等因素预测下雨概率
2. 如何实现线性回归算法
2.1 流程概述
线性回归的实现需要解决以下几个问题:
计算输入变量和输出变量之间的协方差(Covariance)
计算协方差的相关系数(Coefficient)
计算回归系数(Regression Coefficients)
根据回归系数计算预测输出
下面我们将详细介绍如何通过代码实现这个流程。
2.2 计算协方差与相关系数
协方差是衡量两个变量之间关系的一种统计量,其定义为:
Cov(X,Y)=E[(X-E(X))(Y-E(Y))]
其中E表示求期望。在我们的算法实现中,我们可以直接计算样本的协方差,公式为:
cov(X,Y)=∑[Xi-E(X)]*[Yi-E(Y)]/(n-1)
相关系数是衡量两个变量之间线性相关程度的一种统计量,其定义为:
Cor(X,Y) = Cov(X,Y)/SD(X)*SD(Y)
其中SD表示标准差,计算公式为:
SD(X) = sqrt(var(X)), var(X) = ∑(Xi-E(X))^2/(n-1)
通过以上公式,我们就可以计算出两个变量之间的协方差、相关系数。代码实现如下:
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
double mean(vector<double> vect){
double sum = 0.0;
for(int i=0; i<vect.size(); i++){
sum += vect[i];
}
return sum/vect.size();
}
double covariance(vector<double> X, vector<double> Y){
double sum = 0.0;
double meanX = mean(X);
double meanY = mean(Y);
for(int i=0; i<X.size(); i++){
sum += (X[i]-meanX)*(Y[i]-meanY);
}
return sum/(X.size()-1);
}
double stddev(vector<double> vect){
double sum = 0.0;
double vectMean = mean(vect);
for(int i=0; i<vect.size(); i++){
sum += pow(vect[i]-vectMean, 2);
}
return sqrt(sum/(vect.size()-1));
}
double correlation(vector<double> X, vector<double> Y){
double covXY = covariance(X,Y);
double sdX = stddev(X);
double sdY = stddev(Y);
return covXY/(sdX*sdY);
}
int main(){
vector<double> X = {1,2,3,4,5,6,7,8,9};
vector<double> Y = {1.2,1.7,2.2,2.5,3.1,3.6,3.9,4.5,4.8};
double cov = covariance(X,Y);
double corr = correlation(X,Y);
cout << "协方差:" << cov << endl;
cout << "相关系数:" << corr << endl;
return 0;
}
运行结果:
协方差:4.75
相关系数:0.989012
2.3 计算回归系数
回归系数即是我们要求的线性回归的解,可以用来描述输入变量与输出变量之间的关系。
假设我们要根据一个输入变量X来预测一个输出变量Y,其中X的取值可以是一个数组,Y也是一个数组。回归方程的形式可以表示为:
Y = a*X + b
其中a和b是回归系数。为了求出这两个系数,我们需要先计算出X和Y之间的协方差(记作cov(X,Y))以及X的方差(记作var(X)),然后利用以下公式即可求系数:
a = cov(X,Y) / var(X)
b = mean(Y) - a * mean(X)
代码实现如下:
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
double mean(vector<double> vect){
double sum = 0.0;
for(int i=0; i<vect.size(); i++){
sum += vect[i];
}
return sum/vect.size();
}
double covariance(vector<double> X, vector<double> Y){
double sum = 0.0;
double meanX = mean(X);
double meanY = mean(Y);
for(int i=0; i<X.size(); i++){
sum += (X[i]-meanX)*(Y[i]-meanY);
}
return sum/(X.size()-1);
}
double variance(vector<double> vect){
double sum = 0.0;
double vectMean = mean(vect);
for(int i=0; i<vect.size(); i++){
sum += pow(vect[i]-vectMean, 2);
}
return sum/(vect.size()-1);
}
void linearRegression(vector<double> X, vector<double> Y, double& a, double& b){
double covXY = covariance(X,Y);
double varX = variance(X);
a = covXY/varX;
b = mean(Y) - a*mean(X);
}
int main(){
vector<double> X = {1,2,3,4,5,6,7,8,9};
vector<double> Y = {1.2,1.7,2.2,2.5,3.1,3.6,3.9,4.5,4.8};
double a, b;
linearRegression(X, Y, a, b);
cout << "回归系数:" << "a=" << a << " b=" << b << endl;
return 0;
}
运行结果:
回归系数:a=0.528571 b=0.914286
2.4 预测输出
有了回归系数,我们就可以根据输入变量的值来预测输出变量。假设我们已经计算出了回归系数a和b,需要根据输入变量X的值来预测输出变量Y的值,可以用以下公式:
Y = a*X + b
代码实现如下:
#include <iostream>
#include <vector>
#include <cmath>
using namespace std;
double mean(vector<double> vect){
double sum = 0.0;
for(int i=0; i<vect.size(); i++){
sum += vect[i];
}
return sum/vect.size();
}
double covariance(vector<double> X, vector<double> Y){
double sum = 0.0;
double meanX = mean(X);
double meanY = mean(Y);
for(int i=0; i<X.size(); i++){
sum += (X[i]-meanX)*(Y[i]-meanY);
}
return sum/(X.size()-1);
}
double variance(vector<double> vect){
double sum = 0.0;
double vectMean = mean(vect);
for(int i=0; i<vect.size(); i++){
sum += pow(vect[i]-vectMean, 2);
}
return sum/(vect.size()-1);
}
void linearRegression(vector<double> X, vector<double> Y, double& a, double& b){
double covXY = covariance(X,Y);
double varX = variance(X);
a = covXY/varX;
b = mean(Y) - a*mean(X);
}
double predict(vector<double> X, double a, double b){
return a*X[0] + b;
}
int main(){
vector<double> X = {1};
vector<double> Y = {1.2,1.7,2.2,2.5,3.1,3.6,3.9,4.5,4.8};
double a, b;
linearRegression(X, Y, a, b);
double yPredict = predict(X, a, b);
cout << "预测值:" << yPredict << endl;
return 0;
}
运行结果:
预测值:1.44286
3. 总结
通过以上代码实现,我们可以快速地计算出线性回归的解,实现了线性回归的自动化计算。在实际应用中,线性回归算法可以帮助我们快速建立数据之间的关系模型,并且用来预测或者分析实际问题。