C / C ++ 基於梯度下降法的線性回歸法(適用於機器學習)

来源:https://www.cnblogs.com/masonzhang/archive/2019/02/24/10425223.html
-Advertisement-
Play Games

寫在前面的話: 在第一學期做項目的時候用到過相應的知識,覺得挺有趣的,就記錄整理了下來,基於C/C++語言 原貼地址:https://helloacm.com/cc-linear-regression-tutorial-using-gradient-descent/ 前言 在機器學習和數據挖掘處理等 ...


寫在前面的話:

在第一學期做項目的時候用到過相應的知識,覺得挺有趣的,就記錄整理了下來,基於C/C++語言

原貼地址:https://helloacm.com/cc-linear-regression-tutorial-using-gradient-descent/

---------------------------------------------------------------前言----------------------------------------------------------------------------------

在機器學習和數據挖掘處理等領域,梯度下降(Gradient Descent)是一種線性的、簡單卻比較有效的預測演算法。它可以基於大量已知數據進行預測, 並可以通過控制誤差率來確定誤差範圍。

--------------------------------------------------------準備------------------------------------------------------------------------

Gradient Descent

回到主題,線性回歸演算法有很多,但Gradient Descent是最簡單的方法之一。對於線性回歸,先假設數據滿足線性關係,例如:

tex_ed4c4e514024a13b91a95f5ff3ae7998 C/C++ Linear Regression Tutorial Using Gradient Descent c / c++ linear regression machine learning

所以,作為線性回歸,我們的任務就是找到最合適 B0 和 B1, 使最後的結果Y滿足可接受的準確度。作為起步,首先讓我們對B0和B1賦值初始值0,如下所示:

tex_5f81a28beb7b49761ae7d3330ab97f98 C/C++ Linear Regression Tutorial Using Gradient Descent c / c++ linear regression machine learning

設誤差 Error 為 e, 並引入下麵幾個點做例子:

 

x y
1 1
2 3
4 3
3 2
5 5

 

如果我們計算第一個點的誤差,則得到 tex_828f763c4c7dfb9e40de8664c6bbc3be C/C++ Linear Regression Tutorial Using Gradient Descent c / c++ linear regression machine learning ,其中P(i)為表中的數據值,則 e 結果為  -1。但這隻是開始,下麵我們可以使用Gradient Descent來更新Y中的繫數。這就涉及到數據 / 機器學習, 所謂的 數據 / 機器學習,其實可以大致理解為在相應的函數模型下,通過不停地更新其中繫數,使新函數曲線可以擬合原始數據並預測走勢的過程。

回到主題,設剛纔的初始狀態為 t ,那麼對於下一個狀態 t+1 , B0可表示為 :

tex_d14a895022e2b0c107953079c69c9a4b C/C++ Linear Regression Tutorial Using Gradient Descent c / c++ linear regression machine learning

其中 B0(t + 1)是繫數的更新版本,為套入下一個點做準備。 是學習率,即為精度,這個我們可以自己設定。 越大,說明每次學習的跨度就越大,預測結果在相應的正確答案兩邊的擺幅也就越大,所以此情況下學習次數不易過多,否則越擺越離譜。Ps:有次因為 值太大的原因導致結果不精準,結過以為是學習次數不夠多,後來等到把2.3的數值擺到10個億才反應過來是出來問題。話說10個億真是個小目標呢。

言歸正傳,這裡取 ∂ = 0.01,即可得以下式子,B0=0.01.

tex_c22ab9e2b14643149f3646211bc724d3 C/C++ Linear Regression Tutorial Using Gradient Descent c / c++ linear regression machine learning .

現在再來看 B1,在 t+1時刻,公式變為:

tex_54be8006754d3ca774c76c55789450d9 C/C++ Linear Regression Tutorial Using Gradient Descent c / c++ linear regression machine learning

同樣賦值,也同樣得到:

tex_d647c2788dbaf918d0af28939a5e16a0 C/C++ Linear Regression Tutorial Using Gradient Descent c / c++ linear regression machine learning

--------------------------------------------------------操作------------------------------------------------------------------------

現在,我們可以重覆迭代這種過程到下一個點,再到下下個點,一直到所有點結束,這稱為1回(an epoch)。但是我們可以通過反覆不停地迭代,來使得到的線性擬合曲線更接近初始數據。比如迭代4回,每回5個點,也就是20次。C / C ++代碼如下:

double x[] = {1, 2, 4, 3, 5};
double y[] = {1, 3, 3, 2, 5};
 
double b0 = 0;
double b1 = 0;
double alpha = 0.01;
 
for (int i = 0; i < 20; i ++) {
    int idx = i % 5; //5個點
    double p = b0 + b1 * x[idx];
    double err = p - y[idx];
    b0 = b0 - alpha * err;
    b1 = b1 - alpha * err * x[idx];
}

把B0、B1還有 誤差(Error)的結果列印出來:

B0 = 0.01, B1 = 0.01, err = -1
B0 = 0.0397, B1 = 0.0694, err = -2.97
B0 = 0.066527, B1 = 0.176708, err = -2.6827
B0 = 0.0805605, B1 = 0.218808, err = -1.40335
B0 = 0.118814, B1 = 0.410078, err = -3.8254
B0 = 0.123526, B1 = 0.414789, err = -0.471107
B0 = 0.143994, B1 = 0.455727, err = -2.0469
B0 = 0.154325, B1 = 0.497051, err = -1.0331
B0 = 0.157871, B1 = 0.507687, err = -0.354521
B0 = 0.180908, B1 = 0.622872, err = -2.3037
B0 = 0.18287, B1 = 0.624834, err = -0.196221
B0 = 0.198544, B1 = 0.656183, err = -1.56746
B0 = 0.200312, B1 = 0.663252, err = -0.176723
B0 = 0.198411, B1 = 0.65755, err = 0.190068
B0 = 0.213549, B1 = 0.733242, err = -1.51384
B0 = 0.214081, B1 = 0.733774, err = -0.0532087
B0 = 0.227265, B1 = 0.760141, err = -1.31837
B0 = 0.224587, B1 = 0.749428, err = 0.267831
B0 = 0.219858, B1 = 0.735242, err = 0.472871
B0 = 0.230897, B1 = 0.790439, err = -1.10393

怎麼樣,能發現什麼?不容易看出來沒關係,我們把點畫下來:

Error 曲線

從圖中,我們可以看到誤差正逐漸變小,所以我們的最終模型也就是第20次的模型:

tex_d715622360d1440c56b67b7fc96fd76a C/C++ Linear Regression Tutorial Using Gradient Descent c / c++ linear regression machine learning

 

所以最後的曲線擬合結果如下:

曲線擬合結果

到這裡其實不一定死板地局限於20次,也並不是迭代次數越多越好,因為這個過程像一個開口向下的二次函數, 適合的才是最好的。

因為最合適的點可能就在中間,迭代太多次就跑偏了。解決這個問題可以在源代碼里簡單地加一個 If () 函數,當誤差滿足xxx時跳出迴圈就完事了。

 

到這裡應該就結束了。但原文章里多算了一次 Root-Mean-Square 值,也就是均方根,常用來分析雜訊或者誤差,公式如下:

tex_c9db262ace38a6ef07977d709300dff4 C/C++ Linear Regression Tutorial Using Gradient Descent c / c++ linear regression machine learning    把每個點帶入,得到RMSE=0.72。

--------------------------------------------------------總結------------------------------------------------------------------------

其實Gradient Descent 通常適用於 量非常大且繁瑣的數據(不在乎有那麼幾個因為跑偏而被淘汰的值)。

但如果要求數據足夠精確、且數據模型複雜,不適合一次函數模型,那Gradient Descent  並不見得是一個好方法。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 首先,不論是在Windows、Linux還是Mac上,Webassembly的編譯都是主要依賴於Emscripten SDK這個工具的。但是,在這裡必須要吐槽一下,不論是WebAssembly官網、WebAssembly中文網還是Emscriptem官網安裝文檔上給出的安裝方式基本都是這樣的(中文網 ...
  • 需要實現的功能有: 1、圖上點擊要素會出現自定義的信息視窗 2、將視圖內的要素顯示到右側的標簽中 3、點擊右側的標簽,定位到指定要素視圖 1、圖上點擊要素會出現自定義的信息視窗——註意書寫順序,不規範結果是出不來的 var map = new Map({ basemap:"dark-gray" }) ...
  • 設置預設值 這是被廣泛流傳的js技巧之一,這種編碼應該說是很壞的習慣。 ||的問題 js是一種弱類型的編程語言,代表著傳入的變數並不清楚作為何種類型使用。 這樣的定義在js是不存在的, 對js來說傳入的任意參數都應該考慮不同類型的結果 ,而不是單單考慮一種情況。若傳入0、false等,||所要實現默 ...
  • 上面是將有序數組轉為二叉樹的代碼~ 二分查找的速度為O(log n), 遍歷二叉樹的速度為O(n) ...
  • 近期有一個需求,需要對優惠券可用商品列表加個排序,只針對面值類的券不包括折扣券。 需求是這樣的,假設有一張面值券 50 塊錢,可用商品列表 A 100、B 40、C 10,當用戶查詢當前券可用商品列表的時候優先將卡券可以直接抵扣且不需要用戶在額外支付的商品排在前面。 ...
  • 編程界不論是PHP、Python都有這麼兩種編程思想,oop面向對象、pop面向過程,這兩種在功能上沒有多大區別,但是在代碼編寫上卻有很大區別。今天就記錄一下麵向對象和麵向過程的優點、缺點、定義、實現過程。 oop 面向對象 面向對象有兩個重要的概念:類和對象。 什麼是類?類是具備某項功能的抽象模型 ...
  • 作者:中華石杉 來源:https://github.com/doocs/advanced java/blob/master/docs/high concurrency/mq time delay and expired failure.md 一、面試題 如何解決消息隊列的延時以及過期失效問題?消息隊 ...
  • 題意 "題目鏈接" Sol 這題可以動態dp做。 設$f[i]$表示以$i$為結尾的最大子段和,$g[i]$表示$1 i$的最大子段和 那麼 $f[i] = max(f[i 1] + a[i], a[i])$ $g[i] = max(g[i 1], f[i])$ 發現只跟前一項有關,而且$g[i]從 ...
一周排行
    -Advertisement-
    Play Games
  • 前言 本文介紹一款使用 C# 與 WPF 開發的音頻播放器,其界面簡潔大方,操作體驗流暢。該播放器支持多種音頻格式(如 MP4、WMA、OGG、FLAC 等),並具備標記、實時歌詞顯示等功能。 另外,還支持換膚及多語言(中英文)切換。核心音頻處理採用 FFmpeg 組件,獲得了廣泛認可,目前 Git ...
  • OAuth2.0授權驗證-gitee授權碼模式 本文主要介紹如何筆者自己是如何使用gitee提供的OAuth2.0協議完成授權驗證並登錄到自己的系統,完整模式如圖 1、創建應用 打開gitee個人中心->第三方應用->創建應用 創建應用後在我的應用界面,查看已創建應用的Client ID和Clien ...
  • 解決了這個問題:《winForm下,fastReport.net 從.net framework 升級到.net5遇到的錯誤“Operation is not supported on this platform.”》 本文內容轉載自:https://www.fcnsoft.com/Home/Sho ...
  • 國內文章 WPF 從裸 Win 32 的 WM_Pointer 消息獲取觸摸點繪製筆跡 https://www.cnblogs.com/lindexi/p/18390983 本文將告訴大家如何在 WPF 裡面,接收裸 Win 32 的 WM_Pointer 消息,從消息裡面獲取觸摸點信息,使用觸摸點 ...
  • 前言 給大家推薦一個專為新零售快消行業打造了一套高效的進銷存管理系統。 系統不僅具備強大的庫存管理功能,還集成了高性能的輕量級 POS 解決方案,確保頁面載入速度極快,提供良好的用戶體驗。 項目介紹 Dorisoy.POS 是一款基於 .NET 7 和 Angular 4 開發的新零售快消進銷存管理 ...
  • ABP CLI常用的代碼分享 一、確保環境配置正確 安裝.NET CLI: ABP CLI是基於.NET Core或.NET 5/6/7等更高版本構建的,因此首先需要在你的開發環境中安裝.NET CLI。這可以通過訪問Microsoft官網下載並安裝相應版本的.NET SDK來實現。 安裝ABP ...
  • 問題 問題是這樣的:第三方的webapi,需要先調用登陸介面獲取Cookie,訪問其它介面時攜帶Cookie信息。 但使用HttpClient類調用登陸介面,返回的Headers中沒有找到Cookie信息。 分析 首先,使用Postman測試該登陸介面,正常返回Cookie信息,說明是HttpCli ...
  • 國內文章 關於.NET在中國為什麼工資低的分析 https://www.cnblogs.com/thinkingmore/p/18406244 .NET在中國開發者的薪資偏低,主要因市場需求、技術棧選擇和企業文化等因素所致。歷史上,.NET曾因微軟的閉源策略發展受限,儘管後來推出了跨平臺的.NET ...
  • 在WPF開發應用中,動畫不僅可以引起用戶的註意與興趣,而且還使軟體更加便於使用。前面幾篇文章講解了畫筆(Brush),形狀(Shape),幾何圖形(Geometry),變換(Transform)等相關內容,今天繼續講解動畫相關內容和知識點,僅供學習分享使用,如有不足之處,還請指正。 ...
  • 什麼是委托? 委托可以說是把一個方法代入另一個方法執行,相當於指向函數的指針;事件就相當於保存委托的數組; 1.實例化委托的方式: 方式1:通過new創建實例: public delegate void ShowDelegate(); 或者 public delegate string ShowDe ...