简单线性回归和分类讲解及python和c++实现

入门机器学习,首先要接触到的就是线性回归,里面包含的思想是后面机器学习的一个重要的基础。(ps:趁着简单,多琢磨琢磨

一.最小二乘法拟和一元线性回归
目标方程:y = wx + b,通过确定w,b来使得方程 E = ∑(y-wx-b)^2的值最小化
首先来对w,b分别求导,然后令导数为零,即可使得E的值最小,E被称为损失函数,又称为代价函数。求导过程很简单的,大家可以直接手动去求一下,代码里面也有w,b的表达式。

import matplotlib.pyplot as plt   #导入绘图包
def main():
    x = [1, 2, 3, 4, 5, 6, 7, 8, 9]  # 样本x
    y = [1.1, 2.5, 3.2, 4.6, 5.1, 5.4, 6.7, 6.7, 8.1]  # 样本y
    x_sum = 0  # x的总和
    y_sum = 0  # y的总和
    x2_sum = 0  # x的平方和
    y2_sum = 0  # y的平方和
    for i in range(len(x)):
        x_sum += x[i]
        y_sum += y[i]
        x2_sum += x[i] * x[i]
        y2_sum += y[i] * y[i]
    x_mean = x_sum / float(len(x))  # x的平均值
    y_mean = y_sum / float(len(y))  # y的平均值
    x_y_sum = 0  # y(x-x_mean)求和
    for i in range(len(x)):
        x_y_sum += y[i] * (x[i] - x_mean)

    w = x_y_sum / (x2_sum - (1.0 / len(x)) * x_sum * x_sum)  # 求解w
    b = y_mean - w * x_mean  # 求解 b
    y_pred = []
    for i in x:
        y_pred.append(w*i+b)
    
    plt.scatter(x,y)     #绘图
    plt.plot(x, y_pred)
    plt.show()


if __name__ == '__main__':
	main()
		

下面是c++的实现,基本和python差不多,适合新手。

#include <iostream>

using namespace std;

int main(void)
{
	int i;
	double w, b;   //需要拟和的系数
	double x[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
	double y[] = { 1.1, 2.5, 3.2, 4.6, 5.1, 5.4, 6.7, 6.7, 8.1 };
	double x_sum = 0, y_sum = 0, x2_sum = 0, y2_sum = 0, x_mean = 0, y_mean = 0, x_y_sum = 0;
	for (i = 0; i < 9; i++)
	{
		x_sum += x[i], y_sum += y[i];
		x2_sum += x[i] * x[i], y2_sum += y[i] * y[i];

	}
	x_mean = x_sum / 9.0;
	y_mean = y_sum / 9.0;
	for (i = 0; i < 9; i++)
		x_y_sum += y[i] * (x[i] - x_mean);

	w = x_y_sum / (x2_sum - (1.0 / 9)*x_sum*x_sum);
	b = y_mean - w * x_mean;

	
	return 0;


}

二.梯度下降法
在高中的时候,我们学过,函数在某一个区间内的导数大于零的话,函数值递增,否则递减。
只要我们每次利用当前的x减去这一点的导数值,就可以使得函数值减小。但为了更新后的x值不发生太大变化,往往还要给定一个学习率,来控制x的更新大小。
一个公式总结:new_x = x - 学习率 * ▽x

x = [1, 2, 3, 4, 5, 6, 7, 8, 9]  # 样本x
y = [1.1, 2.5, 3.2, 4.6, 5.1, 5.4, 6.7, 6.7, 8.1]  # 样本y
#   拟和方程为: y = 0.8*x + 0.8
w = 5    #随机初始化w
b = 3      #随机初始化b
loss = 0

for i in range(1000):    #更新w,b的次数
    w_D = 0
    b_D = 0
    loss = 0
    for a in range(len(x)):
        loss += (y[a] - (w*x[a]+b))**2    


        w_D -=(y[a]-(w*x[a]+b))*x[a]   #得到函数对w的偏导数值
        b_D +=w*x[a] + b - y[a]          #得到函数对b的偏导数值
    print('loss:%.2f'%loss)

    w = w - 0.002*w_D     #更新w   0.002为学习率
    b = b - 0.002*b_D     #更新b

    print('w:%.2f'%w)
    print('b:%.2f'%b)
  

在这里插入图片描述
三.在回归的基础上,实现分类任务,要用到sigmoid函数来实现特征映射,函数图如下。代码没有用到矩阵的内容,容易理解,,照顾新手。

在这里插入图片描述

import matplotlib.pyplot as plt                                                                
import math                                                                                    
                                                                                               
def sigmoid(x):                                                                                
                                                                                               
    a =1.0/(1+ math.exp(-x))                                                                   
    if a>0.5:                                                                                  
        return 1                                                                               
    else:                                                                                      
        return 0                                                                               
                                                                                               
def main():                                                                                    
    x = [0,1,2.1, 2,4.6, 3, 4, 5, 6, 7, 8, 9,10,12,14,15,16,17,21,22,23,24,25,26]  # 样本x       
                                                                                               
    y = [0,0, 0,0, 0,0, 0, 0, 1, 1, 1, 1,1,1,1,1,1,1,1,1,1,1,1,1]  # 样本y  表示类别                 
                                                                                               
    w = 5                           #初始化w,b,                                                   
    b = 3                                                                                      
    loss = 0                                                                                   
                                                                                               
    for i in range(1000):                                                                      
        w_D = 0                                                                                
        b_D = 0                                                                                
        loss = 0                                                                               
        for a in range(len(x)):                                                                
            loss += (y[a] - sigmoid(w*x[a]+b))**2                                              
            w_D += -1*(y[a] - sigmoid(w*x[a]+b)) *x[a]                                         
                                                                                               
            b_D +=  -1*(y[a] - sigmoid(w*x[a]+b))                                              
        print('loss:%.2f'%loss)                                                                
                                                                                               
        w = w - 0.2*(w_D)                                                                      
        b = b - 0.2*(b_D)                                                                      
        print(w_D)                                                                             
        print('w:%.2f'%w)                                                                      
        print('b:%.2f'%b)                                                                      
                                                                                               
    a = sigmoid(w *7+ b)                                                                       
    print("%.2f"%a)                                                                            
if __name__ == '__main__':                                                                     
    main()                                                                                     
                                                                                               

在这里相信大家对最小二乘法和梯度下降法来拟和一元回归和分类有了一定的了解。那么趁热打铁,多项式回归又改如何呢?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FPGA之旅

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值