二元函数求最小值 c语言,用C语言实现简单的多元线性回归算法(二)
上一篇我们贴上了简单粗暴的线性回归的代码,里面各种参数都设置的是固定参数,不具有可扩展性,今天我们在上一篇的基础上做了部分改进,当然对于熟悉C语言的大侠来说可能这篇博客会太low了,您完全可以跳过。我们在这里只是讲如何用C语言自己实现一个有实用性的线性回归。有人会说用python不是很简单吗,干嘛费劲巴拉的用C语言实现。首先这里是为了满足某些只支持C语言的环境,例如IOT的部分设备;另外也是为了加深对算法的理解和思考。至于线性回归原理网上到处是,我们在这里只贴一下参数更新的推导过程公式,
线性回归模型的代价函数是下面这样子:
其中,f(x)为:
我们的目标是求最小J(w)
即在当J(w)取最小值时,对应的W的值,这时候梯度下降就用上了,用公式可表示为如下样式:
我们把J(w)对w的偏导求出来:
把(2)带入(1)可得:
以上就是线性回归中的梯度下降算法。
下面我们贴上代码,代码中会有比较详细的注释,在这里就不多废话了。
MultipleLinearRegressionTest.h:
//
// Created by lenovo on 2020/7/26.
//
#ifndef MULTIPLELINEARREGRESSION_MULTIPLELINEARREGRESSIONTEST_H
#define MULTIPLELINEARREGRESSION_MULTIPLELINEARREGRESSIONTEST_H
//初始化参数
void init_test(double learning_rate, long int X_Len,long int X_arg_count,int channel,double *y_pred_pt,double* theta_pt,double* temp_pt);
//开始训练
void fit_test(double *X_pt,double *Y_pt);
#endif //MULTIPLELINEARREGRESSION_MULTIPLELINEARREGRESSIONTEST_H
MultipleLinearRegressionTest.c:
//
// Created by lenovo on 2020/7/26.
//
#include #include "MultipleLinearRegressionTest.h"
// 样本个数,这里其实是bachsize的意思,只不过我们只有一个bach
long int g_data_len = 10;
//学习率
double g_learning_rate = 0.01;
//参数个数
long int g_param_count = 6;
//通道数
int g_channel = 1;
double g_out_Y_pt = 0;
//预测输出值指针
double *g_pred_pt = 0;
//参数指针
double *g_theta_pt = 0;
double *temp = 0;
//损失值
double loss_val = 1.0;
//初始化各个参数
void init_test(double learning_rate, long int data_len,long int param_count,int channel,double *y_pred_pt,double* theta_pt,double*temp_pt){
g_learning_rate = learning_rate;
g_data_len = data_len;
g_param_count = param_count;
g_channel = channel;
g_pred_pt = y_pred_pt;
g_theta_pt = theta_pt;
temp = temp_pt;
}
//更新参数值
void train_step_test(const double *temp_step, double *theta) {
for (int i = 0; i < g_param_count; i++) {
//这里的temp_step[i] 其实就是算出来的梯度值
theta[i] = theta[i] - temp_step[i];
printf(" theta[%d] = %f\n",i, theta[i]);
}
}
//计算一个样本的输出值 y = WX + b
double f_test(const double *train_x_item,const double *theta){
g_out_Y_pt = -1;
for (int i = 0; i < g_param_count; ++i) {
g_out_Y_pt += theta[i]*(*(train_x_item+i));
}
return g_out_Y_pt;
}
//预测
double* predict_test(double *train_x,double *theta){
for (int i = 0; i < g_data_len; ++i) {
g_pred_pt[i] = f_test(train_x+i*g_param_count,theta);
}
return g_pred_pt;
}
//求损失
double loss_test(double *train_x,const double *train_y,
double *theta,double loss_val){
predict_test(train_x,theta);
loss_val = -1;
for (int i = 0; i < g_data_len; i++) {
loss_val += (train_y[i] - g_pred_pt[i]) * (train_y[i] - g_pred_pt[i]);
}
//次数计算的是一个bachsize 的平均损失(避免个别离群值引起过拟合)
loss_val = loss_val / g_data_len;
printf(" loss_val = %f\n", loss_val);
return loss_val;
}
//求梯度
void calc_gradient_test(const double *train_x, const double *train_y,
double *temp_step, double *theta) {
//对每个参数分别子梯度
for (int i = 0; i < g_param_count; i++) {
double sum = 0;
//用一个bachsize的平均梯度表示当前参数的梯度(temp_step[i])
for (int j = 0; j < g_data_len; j++) {
double hx = 0;
for (int k = 0; k < g_param_count; k++) {
hx += theta[k] * (*(train_x+j*g_param_count+k));
}
sum += (hx - train_y[j]) * (*(train_x+j*g_param_count+i));
}
temp_step[i] = sum / g_data_len * 0.01;
}
printf("--------------------\n");
train_step_test(temp_step, theta);
}
// 开始训练 (次数迭代60000次)
void fit_test(double *X_pt,double *Y_pt) {
for (int i = 0; i < 60000; ++i) {
printf("\nstep %d: \n", i);
calc_gradient_test(X_pt,Y_pt,temp,g_theta_pt);
loss_val = loss_test(X_pt,Y_pt,g_theta_pt,loss_val);
}
}
main.c :
#include "src/MultipleLinearRegressionTest.h"
int main() {
//该数据由 Y= 4*X1 + 9*X2 + 10*X3 + 2*X4 + 1*X5 + 6 产生(数据中尚为加入噪声)
//数据总的第一列都设置为1,是为了表示截距(Y=WX+B)的参数
double X_pt[10][6] = {{1, 7.41, 3.98, 8.34, 8.0, 0.95},
{1, 6.26, 5.12, 9.57, 0.3, 7.79},
{1, 1.52, 1.95, 4.01, 7.96, 2.19},
{1, 1.91, 8.58, 6.64, 2.99, 2.18},
{1, 2.2, 6.88, 0.88, 0.5, 9.74},
{1, 5.17, 0.14, 4.09, 9.0, 2.63},
{1, 9.13, 5.54, 6.36, 9.98, 5.27},
{1, 1.17, 4.67, 9.02, 5.14, 3.46},
{1, 3.97, 6.72, 6.12, 9.42, 1.43},
{1, 0.27, 3.16, 7.07, 0.28, 1.77}};
double Y_pt[10] = {171.81, 181.21, 87.84, 165.42, 96.26, 89.47, 181.21, 156.65, 163.83, 108.55};
double pred_pt[10] ={1,2,3,4,5,6,7,8,9,0};
// 参数
double theta_pt[6] = {1.0,1.0,1.0,1.0,1.0,2.0};
//临时变量
double temp_pt[6] = {1.0,1.0,1.0,1.0,1.0,2.0};
// 学习率(次数我们还是指定为一个固定值)
double learning_rate = 0.02;
// 样本个数
int data_len = 10;
// 参数个数
int param_count = 6;
//通道数
int channel = 1;
init_test(learning_rate, data_len,param_count,channel,pred_pt,theta_pt,temp_pt);
fit_test((double *) X_pt, Y_pt);
return 0;
}
以上便是线性归回模型梯度下降求解的代码实现。各位大侠如有疑问或者问题欢迎交流。
二元函数求最小值 c语言,用C语言实现简单的多元线性回归算法(二)相关推荐
- 二元函数求最小值 c语言,遗传算法C语言源代码(一元函数和二元函数)
<遗传算法C语言源代码(一元函数和二元函数)>由会员分享,可在线阅读,更多相关<遗传算法C语言源代码(一元函数和二元函数)(15页珍藏版)>请在人人文库网上搜索. 1.C语言遗 ...
- python多元函数求极小值_使用遗传算法求二元函数的最小值
二元函数为y=x1^2+x2^2,x∈[-5,5] NIND=121; %初始种群的个数(Number of individuals) NVAR=2; %一个染色体(个体)有多少基因 PRECI=20 ...
- python多元函数求解_使用遗传算法求二元函数的最小值
二元函数为y=x1^2+x2^2,x∈[-5,5] NIND=121; %初始种群的个数(Number of individuals) NVAR=2; %一个染色体(个体)有多少基因 PRECI=20 ...
- 遗传算法求二元函数极值怎么编码_使用遗传算法求二元函数的最小值
二元函数为y=x1^2+x2^2,x∈[-5,5] NIND=121; %初始种群的个数(Number of individuals) NVAR=2; %一个染色体(个体)有多少基因 PRECI=20 ...
- python二元函数求导_用Excel和python实现二元函数梯度下降的人工智能,之用,excel,一元...
梯度下降法和牛顿法的总结与比较 机器学习的本质是建立优化模型,通过优化方法,不断迭代参数向量,找到使目标函数最优的参数向量.最终建立模型 通常用到的优化方法:梯度下降方法.牛顿法.拟牛顿法等.这些优化 ...
- [数值计算-10]:一元非线性函数求最小值 - 导数与梯度下降法Python法代码示例
作者主页(文火冰糖的硅基工坊):https://blog.csdn.net/HiWangWenBing 本文网址:https://blog.csdn.net/HiWangWenBing/article ...
- 求二元函数最大值matlab,利用matlab, 二元函数求最大值
求二元函数 z=0.2323*x^2-0.2866^2+2*(-0.5406)*a0^2+1.0203*a0^2*x^2/((x^2+y^2)^0.5*tanh(2*(x^2+y^2)^0.5)-x^ ...
- MATLAB一元函数与二元函数求极小值
%%一元函数极小值fminbnd dh = @(m)m^2-10*m+25; %%输出为极小值所对应的坐标 min = fminbnd(dh, 1,10) %%同时输出坐标和极值 [min, zhi] ...
- 用C语言实现一个简单的一元线性回归算法
今天我们用C语言实现一个简单的线性回归算法:在代码前面我们在回顾一下线性回归. 线性回归是回归问题中的一种,线性回归假设目标值与特征是线性相关的,即满足一个多元一次方程式.通过构建损失函数,来求解损失 ...
最新文章
- 赤兔四足机器人的作用_跑得快,打不死!清华大学开发“小强”机器人,壮汉狂踩也挡不住前进步伐...
- python给函数设置超时时间_在 Linux/Mac 下为Python函数添加超时时间
- CSS各种选择符的优先级
- Spring陷阱:事务测试被认为是有害的
- 比java好的_Java Spring真的比直接进行Java编程好吗
- Python-IndexError: list index out of range
- 如何在面试中通过工厂模式来给自己加分?逆袭面经分享
- 南京Uber优步司机奖励政策(12月28日到1月3日)
- 专研自动驾驶,深动科技春季招聘启动,含社招和实习
- 崩坏学园2及大部分采用ETC1压缩格式的Unity3D游戏的拆包图处理
- 【Android综合编程】CH2EventBus
- VC++中实现报警声音
- Intellij Idea配置提高速度
- 动态网站加速,cdn义不容辞
- Hbuilder连接NOX夜神模拟器
- bilibili 哔哩哔哩 2018秋招试题
- view-ui中select全选实现
- 解决问题“The App ID ‘XXXXX‘ appears to be in use by the App Store, so it can not be removed at this ti”
- Application was not properly initialized at startup, could not find Factory:
- SQL的采集与查询教程