熱線電話:13121318867

登錄
首頁大數據時代機器學習中最小二乘法是什么,如何實現?
機器學習中最小二乘法是什么,如何實現?
2020-07-24
收藏

最小二乘法,相信大家都不陌生,統計學中很是常見,而且其理論相對簡單,用途也很廣泛。今天小編就給大家具體介紹一下最小二乘法。

一、最小二乘概念

最小二乘,或者也可以叫做最小平方和,它目的就是通過最小化誤差的平方和,使得擬合對象無限接近目標對象。也就意味著,最小二乘法可以用于對函數的擬合。

最小二乘法是勒讓德( A. M. Legendre)于1805年在其著作《計算慧星軌道的新方法》中提出的。

線性回歸中,最小二乘法就是試圖找到一條直線,使所有樣本到直線的歐氏距離之和最小。更直觀的解釋:

假設有一條直線y=ax+b,要在這條直線上找到一點,距離(x0.y0)這個點的距離最短。如果用絕對值的方法尋找,也就是取min(|y?y0|+|x?x0|),由于絕對值最小為0.所以最小的情況就是x=x0或者y=y0處。

如果用平方和的方法尋找,就是取min(y?y0)2+(x?x0)2.可以看出該式是兩點間距離公式,也就是距離的概念。那么最短的距離,就是點到直線的垂線。

二、最小二乘核心思想

最小二乘的主要思想就是求解未知參數,使得理論值與觀測值之差(即誤差,或者說殘差)的平方和達到最?。?

三、直線擬合/多元線性回歸

求導計算最小值是通用解法,但矩陣法比代數法要簡潔,且矩陣運算可以取代循環,所以現在很多書和機器學習庫都是用的矩陣法來做最小二乘法。

損失函數定義為:(系數1/2是為了簡化計算添加的,求跡前和求跡后值不變)

應用矩陣跡的計算公式:

四、最小二乘法的適用場景

當樣本量m很少,小于特征數n的時候,這時擬合方程是欠定的,需要使用LASSO。當m=n時,用方程組求解。當m>n時,擬合方程是超定的,可以使用最小二乘法。

但是同時最小二乘也具有局限性:

1.最小二乘法需要計算(XTX)?1逆矩陣,有可能逆矩陣不存在,這樣就沒有辦法直接用最小二乘法。

2.如果是樣本特征n非常的大的情況,計算逆矩陣是一個極為耗時的工作,甚至是不可行,通常不超過10000個特征。

3.若擬合函數不是線性的,則無法使用最小二乘法,這時就需要通過一些技巧轉化為線性才能使用。

五、最小二乘實現


/*
最小二乘法的實現
C++版
命令行輸入數據文件
最后輸入x得到預測的y值
*/
#include<iostream>
#include<fstream>
#include<vector>
using namespace std;

class LeastSquare {
	double b0, b1;
public:
	LeastSquare(const vector<double>& x, const vector<double>& y)
	{
		double t1 = 0, t2 = 0, t3 = 0, t4 = 0;
		for (int i = 0; i<x.size(); ++i)
		{
			t1 += x[i] * x[i];
			t2 += x[i];
			t3 += x[i] * y[i];
			t4 += y[i];
		}
		
		b0 = (t1*t4 - t2*t3) / (t1*x.size() - t2*t2);        // 求得 B0
		b1 = (t3*x.size() - t2*t4) / (t1*x.size() - t2*t2);  // 求得 B1 
	}

	double getY(const double x) const
	{
		return b0+b1*x;
	}

	void print() const
	{
		if (b1>=0)
			cout << "y = " << b0 << "+" << b1 << 'x' << "\n";
		else
			cout << "y = " << b0 << "" << b1 << 'x' << "\n";
	}

};

int main(int argc, char *argv[])
{
	if (argc != 2)
	{
		cout << " data.txt don't exit " << endl;
		return -1;
	}
	else
	{
		vector<double> x;
		vector<double> y;
		int count = 1;
		ifstream in(argv[1]);
		for (double d; in >> d; count++)
			if (count % 2 == 1)
				x.push_back(d);
			else
				y.push_back(d);
		LeastSquare ls(x, y);
		ls.print();

		cout << "Input x:\n";
		double x0;
		while (cin >> x0)
		{
			cout << "y = " << ls.getY(x0) << endl;
			cout << "Input x:\n";
		}
	}
	int endline;
	cin >> endline;
}


數據分析咨詢請掃描二維碼

若不方便掃碼,搜微信號:CDAshujufenxi

數據分析師資訊
更多

OK
客服在線
立即咨詢
日韩人妻系列无码专区视频,先锋高清无码,无码免费视欧非,国精产品一区一区三区无码
客服在線
立即咨詢