Python 机器学习之线性回归详解分析
作者:路灯下的秃子ꈍ◡ꈍ 发布时间:2023-08-12 09:48:13
为了检验自己前期对机器学习中线性回归部分的掌握程度并找出自己在学习中存在的问题,我使用C语言简单实现了单变量简单线性回归。
本文对自己使用C语言实现单变量线性回归过程中遇到的问题和心得做出总结。
线性回归
线性回归是机器学习和统计学中最基础和最广泛应用的模型,是一种对自变量和因变量之间关系进行建模的回归分析。
代码概述
本次实现的线性回归为单变量的简单线性回归,模型中含有两个参数:变量系数w、偏置q。
训练数据为自己使用随机数生成的100个随机数据并将其保存在数组中。采用批量梯度下降法训练模型,损失函数使用平方损失函数。
上图为整个程序的函数调用关系。
下面贴代码:
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<time.h>
double w, q;
int m;
//模型
float Model(float x)
{
float y;
y = x * w + q;
return y;
}
//损失函数
double Loss(float *y,float *x)
{
double L=0;
//循环参数
int i, j, k;
for (i = 0; i < m; i++)
{
L += (pow((y[i] - Model(x[i])), 2)) / (2 * m);
}
return L;
}
//梯度下降优化函数
void Gradient_Descent_Optimizer(float *x,float *y,float a)
{
int j, i;
double Q = 0, W = 0;
for (i = 0; i < m; i++)
W += x[i] * (Model(x[i]) - y[i]);
W = W / m;
for (j = 0; j < m; j++)
Q += Model(x[j]) - y[j];
Q = Q / m;
printf("W:%f\nQ:%f\n", W, Q);
w = w - a * W;
q = q - a * Q;
}
//主函数;训练过程
int main()
{
//循环标志
int i, j;
//训练轮次
int epoch;
//损失函数
double L;
//学习率
float a;
float x[100], y[100];
//随机数生成
for (i = 0; i < 100; i++)
{
x[i] = 0.1*i;
y[i] = x[i] * 3 + 5; //+ ((rand() % 11) / 10);
printf("X:%.2f,Y:%.2f\n", x[i], y[i]);
}
//超参数设置
m = 100;
a = 0.05;
epoch = 1000;
//参数初始化
w = 2;
q = 3;
for (j = 0; j < epoch; j++)
{
Gradient_Descent_Optimizer(x, y, a);
L = Loss(y, x);
printf("训练轮次:%d,损失:%f,参数w的值:%lf,参数q的值:%lf\n", j+1, L, w, q);
}
printf("最终值:\nw:%lf\nq:%lf\n", w, q);
system("pause");
}
问题总结
下面对在编写过程中需要注意的问题进行总结:
1.参数更新
模型中的参数需要同步更新。所有参数的更新值经过梯度下降法计算得出后要在最后同时更新所有参数。
2.保留损失函数
在代码编写过程中自己认为不用单独写一个损失函数,只需在梯度下降的过程中利用求导后的公式进行相关的参数优化操作即可,但在运行没有算是函数的程序时,没有实时的损失函数结果评估模型训练效果可能会导致模型在错误的道路上越走越远。
3.注意数据类型
初次运行程序,在训练至十几轮时参数就不再变化,一直到第1000轮参数都保持不变。后来在检查代码时发现,在优化函数将一些参数的数据类型错误设置为整型。因此当参数值改变程度小于1时,参数将不再变化。
4.超参数的设置及参数的初始化
学习率,训练轮次等的设置是一个对程序编写者经验要求比较高的工作,需要多次尝试,找到合适的值,参数的初始化也是这样。
心得
本次只是实现了简单线性回归的最基本的功能,同时也试一下自己刚买的机械键盘(用起来真的很舒服)。这只是我用来练手的程序,如果真的要编写程序实现功能还是推荐使用python语言搭配TensorFlow、Pytorch等深度学习平台实现自己想要的功能。程序的可完善空间非常大,比如数据和模型的可视化,将数据和模型的训练效果直观的展示出来,后面还会有序的用C语言实现诸如多元线性回归,二分类问题,多分类问题甚至卷积神经网络等等。我会在下面贴出使用Python语言编写的线性回归的程序,可以两者结合起来比较一下异同。
# -*- coding: utf-8 -*-
"""
Spyder Editor
This is a temporary script file.
"""
import matplotlib.pyplot as plt
import tensorflow as tf
import numpy as np
np.random.seed(5)
x_data = np.linspace(-1,1,100)
y_data = 2 * x_data + 1.0 + np.random.randn(*x_data.shape) * 0.4
np.random.randn(10)
#x_data.shape
#np.random.randn(*x_data.shape)
#np.random.randn(100)
plt.scatter(x_data,y_data)
plt.plot(x_data, 2 * x_data + 1.0, color = 'red',linewidth=3)
x = tf.placeholder("float",name="x")
y = tf.placeholder("float",name="y")
def model(x,w,b):
return tf.multiply(x,w)+b
w = tf.Variable(1.0,name="w0")
b = tf.Variable(0.0,name="b0")
pred = model(x,w,b)
train_epochs = 10
learning_rate = 0.05
loss_function = tf.reduce_mean(tf.square(y-pred))
optimizer = tf.train.GradientDescentOptimizer(learning_rate).minimize(loss_function)
sess = tf.Session()
init = tf.global_variables_initializer()
sess.run(init)
i_ci=0
for epoch in range(train_epochs):
for xs,ys in zip(x_data,y_data):
_, loss=sess.run([optimizer,loss_function],feed_dict={x:xs,y:ys})
b0temp=b.eval(session=sess)
w0temp=w.eval(session=sess)
plt.plot(x_data,w0temp*x_data+b0temp)
print("w:",sess.run(w))
print("b:",sess.run(b))
plt.scatter(x_data,y_data,label='Original data')
plt.plot(x_data,x_data*sess.run(w)+sess.run(b),label='Fitted Line',color='r',linewidth=3)
plt.legend(loc=2)
来源:https://blog.csdn.net/qq_44313580/article/details/121192240
猜你喜欢
- 导入 python 库import matplotlib.pyplot as pltimport skimage.io as ioimpor
- 一、分组原理核心:1、不论分组键是数组、列表、字典、Series、函数,只要其与待分组变量的轴长度一致都可以传入groupby进行分组。2、
- 有时会统计某个目录下有哪些文件,每个文件的sha256及文件大小等相关信息,这里用python3写了个脚本用来实现此功能,此脚本可跨平台,同
- Windowns操作系统中安装Python,供大家参考,具体内容如下一.下载Python1.python 官网 下载安装包2.选择
- 前言之前我们分享过用Python进行可视化的9种常见方式。其实我们还能让可视化图形逼格更高一些,今天就分享一下如何让可视化秀起来:用Pyth
- 图像显示和打印面临的一个问题是:图像的亮度和对比度能否充分突出关键部分。这里所指的“关键部分”在 CT 里的例子有软组织、骨头、脑组织、肺、
- 就前面所讲,函数的基本内容已经完毕。但是,函数还有很多值得不断玩味的细节。这里进行阐述。参数的传递python中函数的参数通过赋值的方式来传
- 一个懒加载的树状表格实例实现一个树状表格,需要用到vxe-table这个库,虽然element-ui也能实现,但这个库是专门针对表格做了更多
- 下面我们就分别讲述,虽然说的是Insert语句, 但是Select、Update、Delete语句都是一样的。 假如有下述表格:
- 问题背景 基于PyQt5开发了一个可以用于目标跟踪的软件,在开发过程中遇到一个问题,就是如何在PyQt5的组件QLable中自主选定目标框
- 在pandas 基础操作大全之数据读取&清洗&分析 以及 pandas基础操作大全之数据合并 中介绍了p
- 特点:不需要另外加个清除DIV:after(伪对象)--设置在对象后发生的内容,通常和content配合使用,IE不支持此伪对象,非Ie 浏
- Select字句在逻辑上是SQL语句最后进行处理的最后一步,所以,以下查询会发生错误:SELECT YEAR(OrderDate) AS O
- 最终效果前言这是最近在学qt这个东西,然后又学会了调用api,然后就想了用pyqt5做一个GUI界面,后期也可以打包分享给其他人使用,所以就
- Python 常见字节码LOAD_CONST这个指令用于将一个常量加载到栈中。常量可以是数字、字符串、元组、列表、字典等对象。例如:>
- 前言Matplotlib 可能是 Python 2D-绘图领域使用最广泛的套件。它能让使用者很轻松地将数据图形化,并且提供多样化的输出格式。
- 有时候我们需要在某段字符串或者某段语句中去查找确认是否包含我们所需要的字符串信息,举例子说、某段变量是:A= ”My name is Cla
- SMTPSMTP是发送邮件的协议,Python内置对SMTP的支持,可以发送纯文本邮件、HTML邮件以及带附件的邮件。Python对SMTP
- 这里我们应用之前一篇写过的弹框效果,单选框我们运用伪元素自定义,不使用图片, 这个例子可以运用到很多情况;知识点:1、理解wx:if作用2、
- 今天写了一个java项目连接数据库,之后写了一个执行入库操作的模块。此时暴露出一个问题就是项目的中文插入到数据库时会是乱码:项目输出的中文: