用C語言實現乙個簡單的一元線性回歸演算法

2021-10-08 06:26:41 字數 4005 閱讀 4784

今天我們用c語言實現乙個簡單的線性回歸演算法;在**前面我們在回顧一下線性回歸。

線性回歸是回歸問題中的一種,線性回歸假設目標值與特徵是線性相關的,即滿足乙個多元一次方程式。通過構建損失函式,來求解損失函式最小時的引數w和b。通常表示式可以表示如下:

其中 y 為**值,自變數x和因變數y是已知的,我們要想實現的是,當乙個新增的x出現時,我們要**y的值。因此我們構建這個函式關係,是通過已知的資料求解函式模型中位置的w和b這兩個引數。

我們用均方誤差為損失函式即:

將函式帶入即為:

我們現在的任務就是求解最小化  l 時的w 和b,即將核心目標優化為

此處我們用梯度下降法進行求解

為了求偏導數,當只有乙個樣本時,即: 

我們這裡就簡單的處理為求解

理解了最小誤差的求解原理我們就開始上**了。

linerregression.h

#ifndef linerregression_linerregression_h

#define linerregression_linerregression_h

//初始化函式

void set_config(double learning_rate,long int max_iter,int x_len);

//訓練

void fit(double *train_x,double *train_y);

//計算

double* _f(const double *train_x,double w,double b);

//**

double* predict(double *train_x);

//損失

double loss(const double *y_true,const double *y_pred);

//求梯度

void _calc_gradient();

//單步更新

void _train_step();

#endif

linerregression.c

#include #include #include #include "linerregression.h"

//設定固定學習率

double g_learning_rate = 0.01;

//設定梯度更新次數

long int g_max_iter = 100;

//設定初始化 w

double g_w = 5;

//設定初始化 b

double g_b = 5;

//定義儲存損失的指標

double *loss_arr_pt;

//定義儲存時時計算y的指標

double *g_out_y_pt;

//定義儲存時時**y的指標

double *y_pred_pt;

//輸入 x

double *x_pt;

//輸入 y

double *y_pt;

//訓練資料長度

int g_x_len;

//更新 梯度

double d_w;

double d_b;

double loss_val[1];

void set_config(double learning_rate, long int max_iter, int x_len)

void fit(double *train_x, double *train_y)

}double *_f(const double *train_x, double w, double b)

return g_out_y_pt;

}//**

double *predict(double *train_x)

y_pred_pt = _f(train_x, g_w, g_b);

return y_pred_pt;

}//計算損失

double loss(const double *y_true, const double *y_pred)

double loss_total = 0;

for (int i = 0; i < g_x_len; i++)

loss_val[0] = loss_total / g_x_len;

return loss_val[0];

}//求梯度

void _calc_gradient()

d_w = d_w_total / g_x_len;

d_b = d_b_total / g_x_len;

}//更新 w 和 b

void _train_step()

main.c

#include "utils/util.h"

#include "src/multiplelinearregression.h"

#include "src/linerregression.h"

int main()

for (int j = 0; j < data_size; ++j) else

}set_config(learning_rate, iteration_count, train_size);

fit(train_x, train_y);

其中用到生成隨機輸入變數方法如下:

int* getrand(double *a,int len)

return a;

}

可以看到在計算1000之後 w 和 b已經很接近我們初時設定的值了:

step 989:  g_w = 20.235078,g_b = 14.003770, loss = 0.210872

step 990: g_w = 20.234798,g_b = 14.005839, loss = 0.209997

step 991: g_w = 20.234518,g_b = 14.007905, loss = 0.209125

step 992: g_w = 20.234238,g_b = 14.009966, loss = 0.208257

step 993: g_w = 20.233959,g_b = 14.012023, loss = 0.207393

step 994: g_w = 20.233681,g_b = 14.014076, loss = 0.206532

step 995: g_w = 20.233403,g_b = 14.016124, loss = 0.205674

step 996: g_w = 20.233126,g_b = 14.018169, loss = 0.204821

step 997: g_w = 20.232849,g_b = 14.020209, loss = 0.203970

step 998: g_w = 20.232573,g_b = 14.022244, loss = 0.203124

step 999: g_w = 20.232298,g_b = 14.024276, loss = 0.202281

至此我們簡單的一元線性回歸就這樣實現了。至於學習率更優雅的指定和學習停止條件我們後面再討論。

用C語言實現簡單的多元線性回歸演算法 一

簡單的一元線性回歸演算法已經在這裡 c語言簡單的一元線性回歸演算法 並且也簡單闡述了梯度求解推導過程。今天我們再呈上多元線性回歸演算法梯度下降的c語言實現,中已經加入了相應的注釋。如下 multiplelinearregression.h ifndef multiplelinearregressio...

用C語言實現乙個簡單的Linux殼層(Shell)

期末考試考完,進入聖誕假期,終於騰出手寫這篇文章了。這是我們os課的第乙份作業,要求實現乙個簡單的linux shell,用c寫出乙個類似terminal的東西。大致要求 可以迴圈接收command,根據內容實現相應動作,實現幾個常見command即可。作業目的是熟悉幾個知識點 linux的pare...

c語言 實現乙個棧

include include include include 入棧出站操作 typedef struct nodenode,pnode typedef struct stack pstack,stack void init pstack void push pstack,int bool isem...