机器学习知识点(四)最小二乘法Java实现
最小二乘法(又稱最小平方法)是一種數學優化技術。它通過最小化誤差的平方和尋找數據的最佳函數匹配。利用最小二乘法可以簡便地求得未知的數據,并使得這些求得的數據與實際數據之間誤差的平方和為最小。最小二乘法還可用于曲線擬合。通過一元線性模型應用來理解最小二乘法。
監督學習任務中,預測離散結果的是分類任務,預測連續結果的是回歸任務。在回歸任務中,預測結果y和x的函數關系中,一元線性回歸只包含一個屬性的,對應的線性關系;二元線性回歸包含兩個屬性,對應的平面關系;d元線性回歸就包括d個屬性,對應的超平面關系。
在一元線性回歸任務中,給定數據集{(x1,y1),(x2,y2),…,(xn,yn)},有n個(xi,yi)數據對,在坐標中對應n個點,要擬合這n個點為一條直線的線性關系,自然是直線在n個點中間最好。但顯然有很多直線滿足,怎么衡量呢?選擇怎樣的直線最好呢?標準是什么?選擇最佳直線的標準是:使總的擬合誤差(即總殘差)達到最小。
1)用“殘差和最小”確定直線位置,存在相互抵消的問題。
2)用“殘差絕對值和最小”確定直線位置,但絕對值的計算比較麻煩。
3)最小二乘法的原則是以“殘差平方和最小”確定直線位置,用最小二乘法除了計算比較方便外,得到的估計量還具有優良特性、對異常值非常敏感。
綜上,我們選用最小二乘法的誤差平方和最小作為標準來選出一條直線作為n個點的擬合直線。最常用的是普通最小二乘法( Ordinary? Least Square,OLS):所選擇的回歸模型應該使所有觀察值的殘差平方和達到最小。(Q為殘差平方和)- 即采用平方損失函數。
數學形式定義直線為:
f(xi)=yi=axi+b+ei;
其中,i∈[1,n],ei是樣本(xi,yi)的真實值yi=axi+b+ei和擬合值y’i= axi+b的誤差,即ei= yi-axi-b。
最小二乘法一元線性回歸模型的Java實現,參考代碼如下:
package sk.ml;import java.text.DecimalFormat; import java.util.Random;/** 功能:一元線性回歸模型最小二乘法Java實現* 作者:Jason.F* 時間:2017-01-16*/ public class LeastSquares {private final static int n=20;//隨機生成10個點的(x,y)public static void main(String[] args){//隨機生成20個坐標點Random random = new Random(); double[] x=new double[n];double[] y=new double[n];for(int i=0;i<n;i++){//隨機生成n個double數x[i]=Double.valueOf(Math.floor(random.nextDouble()*(99-1)));y[i]=Double.valueOf(Math.floor(random.nextDouble()*(999-1)));}/* y = a x + b* b = sum( y ) / n - a * sum( x ) / n* a = ( n * sum( xy ) - sum( x ) * sum( y ) ) / ( n * sum( x^2 ) - sum(x) ^ 2 )* */estimate(x, y, x.length );}/*** 預測* @param x,y,i*/public static void estimate( double[] x , double[] y , int i ) {double a = getA( x , y ) ;double b = getB( x , y , a ) ;//設置doubl字符串輸出格式,不以科學計數法輸出 DecimalFormat df=new DecimalFormat("#,##0.00");//格式化設置System.out.println("y="+df.format(a)+"x"+"+"+df.format(b));}/*** 計算 x的系數a* @param x, y* @return a*/public static double getA( double[] x , double[] y ){int n = x.length ;return ( n * pSum( x , y ) - sum( x ) * sum( y ) )/ ( n * sqSum( x ) - Math.pow(sum(x), 2) ) ;}/*** 計算常量系數b* @param x,y,a* @returnb*/public static double getB( double[] x , double[] y , double a ){int n = x.length ;return sum( y ) / n - a * sum( x ) / n ;}/*** 計算常量系數b* @param x, y* @return b*/public static double getC( double[] x , double[] y ){int n = x.length ;double a = getA( x , y ) ;return sum( y ) / n - a * sum( x ) / n ;}//計算和值private static double sum(double[] ds) {double s = 0 ;for( double d : ds ) s = s + d ;return s ;}//計算開平方和值private static double sqSum(double[] ds) {double s = 0 ;for( double d : ds ) s = s + Math.pow(d, 2) ;return s ;}//計算x和y積的和值private static double pSum( double[] x , double[] y ) {double s = 0 ;for( int i = 0 ; i < x.length ; i++ ) s = s + x[i] * y[i] ;return s ;} }隨機生成的一次執行結果如下: y=-0.29x+541.23
總結
以上是生活随笔為你收集整理的机器学习知识点(四)最小二乘法Java实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 机器学习笔记(三)线性模型
- 下一篇: 机器学习知识点(五)梯度下降法Java实