机器学习-线性回归-一元线性回归-2020-3-9

​  线性回归: 

    简单案例  y = w*x + b   w: 权重   b: 偏置  

    w,b 都是向量

y:     标签 

x:     特征

"""

简单线性回归实例

    y = 3*x + 2  

人工制造数据集: 

    随机生成一个近似采样随机分布,使得w=3.0, b=2, 并加入一个噪声,噪声的最大振幅为0.4

  学习目标:   w =3 , b =2

"""

使用了4种方法:思路都是一样,实现条件不同。

    way 1:  概率估计 :w , b (完全按照书上堆公式,最大似然估计法)

    way 2:  机器学习:公式推导,自己写底层函数,求导,更新w,b

    way 3 : 机器学习: 求导,借助 梯度带 tf.GradientTape 求导 gradient

    way 4 : 机器学习 :   tf.optimizers 优化器更新w,b 求导tf.GradientTape)

把概率推导放在最后,其实挺简单,大致思路:最大似然估计->求偏导-> 解方程。

本机环境:编写环境(Jupyter)

1:数学公式推导 :估计未知参数:  a(对应公式中的 b), b (w)

"""简单线性回归实例    y = 3*x + 2  人工制造数据集:    随机生成一个近似采样随机分布,使得w=3.0, b=2, 并加入一个噪声,噪声的最大振幅为0.4""" import numpy as np import matplotlib.pyplot as pltimport tensorflow as tffrom time import time# 设置随机数种子np.random.seed(10)# np.linspace  生成等差数列在-(-1,5)之间 100个点x_data = np.linspace(-1,1,100)# *x_data.shape 将转成数字  标准正态分布。加入噪音0.4y_data = 3*x_data +2.0+np.random.randn(*x_data.shape)*0.4n = x_data.shape[0]  # 数据集的总数据个数# 一元线性回归的估计:公式具体参照《概率论与数理统计》 第4版 浙江大学p 248 页start_Time= time()s_xx = np.sum(np.square(x_data)) -(1/n)*np.square(np.sum(x_data))s_yy = np.sum(np.square(y_data)) -(1/n)*np.square(np.sum(y_data))s_xy = np.sum(x_data*y_data) - (1/n)*np.sum(x_data)*np.sum(y_data)b = s_xy / s_xxa = (1/n)*np.sum(y_data)-( 1/n*np.sum(x_data) )*bduration = time() -start_Timeprint("Train Finished take %5f "%(duration))print("根据公式可以估计 a,b 的值:")print("a =%f b=%f" %(a,b))# 绘制图#画出 随机生成数据集的散点图plt.plot(x_data, y_data, 'go', label='Original data')# 我们想要学习到的线性函数   y = 3*x + 2 plt.plot(x_data,3*x_data+2.0,color='black',label='aim: Linear')# 数学估计:回归直线plt.plot(x_data, a+b*x_data, color='r',label='studing:Linear regression')plt.legend()plt.show()# 利用模型进行预测x_test = 3.14predict = b * x_test +atarget = 3*x_test + 2.0print('当x_test = 3.14 时:预测值:%f 目标值:%f'%(predict,target))

    这里的 a: ->b     b->w

2: 机器学习:w ,b  自己写函数 

import numpy as np import matplotlib.pyplot as pltfrom time import time### 人工生成数据集# np.linspace  生成等差数列在-(-1,1)之间 100个点x_data = np.linspace(-1,1,20)# *x_data.shape 将转成数字  标准正态分布。y_data = 3*x_data +2.0+np.random.randn(*x_data.shape)*0.4#plt.plot(x_data, y_data, 'go', label='Original data')  #画出数据集的图像data_num = x_data.shape[0]          # 获取数据集的大小x0= np.ones((data_num, 1))           #扩充矩阵 x0一列都等于1,便于矩阵运算x=x_data.reshape((data_num,1))x =np.hstack((x0,x))                 #按照列堆叠形成数组,其实就是 m*[x0,x1]样本数据 y=y_data.reshape((data_num,1)) ###  定义损失函数def loss_Function(theta,x,y,m):     """    theta: [ [θ1],[θ2] ] 待求参数   shape : 2*1   θ1 ->a θ2 ->b    x : 数据集  m *[x0,x1]          shape: m *2    x0 这一列全为1     y : 标签值                      shape: m *1    m : 数据集个数    """    # 均方差     Subtraction =np.dot(x,theta) -y    square = 1/(2*m)*np.dot(np.transpose(Subtraction) ,Subtraction)     return square###定义损失函数对应的梯度函数   def gradinet_Function(theta,x,y,m):    """    theta: [ [θ1],[θ2] ] 待求参数    shape : 2*1    x : 数据集  m *[x0,x1]           shape: m *2     y : 标签值                       shape: m *1    m : 数据集个数    """    #参照矩阵求导公式    diff = np.dot(x,theta)-y    square =1/m*np.dot(np.transpose(x),diff)     return square### 超参数learning_rate = 0.01traing_epochs = 3000### 训练参数初始化theta = np.array([1, 1]).reshape(2, 1) # 初始化theta ,默认为 1loss_history = [] # 保存损失### 开始训练start_Time= time()for epoch in range(traing_epochs+1):    gradient = gradinet_Function(theta,x,y,data_num) #计算梯度    theta = theta -learning_rate*gradient #更新theta     loss =loss_Function(theta,x,y,data_num)    loss_history.append(loss[0])    if epoch %1000 ==0:        print("第%d轮 loss= %f  a= %0.6f b=%0.6f"%(epoch,loss,theta[0],theta[1]))duration = time() -start_Timeprint("Train Finished take %5f "%(duration))print("最终得到 a= %0.6f b=%0.6f"%(theta[0],theta[1]))###数据可视化def plot_(theta,x,y):    ax = plt.subplot(111)     ax.scatter(x, y, s=10, marker="s",color='black')    plt.xlabel("X")    plt.ylabel("Y")    #目标直线    plt.plot(x_data,3*x_data+2.0, linewidth = '1',color='red',label='aim: Linear',marker='o')    #学习直线    y1 = theta[0] + theta[1]*x    ax.plot(x, y1,linewidth = '1',color='yellow',label="sty:Linear")    plt.legend(loc='upper left')    plt.show()plot_(theta,x[:,1],y)plt.plot(loss_history)

3 机器学习:梯度带 tf.GradientTape 求导 gradient

import numpy as np import matplotlib.pyplot as pltimport tensorflow as tffrom time import time# 设置随机数种子np.random.seed(10)# np.linspace  生成等差数列在-(-1,1)之间 100个点x_data = np.linspace(-1,1,100)# *x_data.shape 将转成数字  标准正态分布。加入噪音0.4y_data = 3*x_data +2.0+np.random.randn(*x_data.shape)*0.4#定义模型函数def model(x,w,b):    return w*x +b# 定义MSE损失函数def loss_Squared(y_estimate,y,n):    """     y_estimate : 是估计值 向量vector     y: 真实值 label       n: 数据集数据总数     loss = (y_estimate- y)^2  * 1/(2*n)    """    result = tf.reduce_sum(tf.pow(y_estimate - y,2) )      return result# 随机选择样本函数def data_iter(features, labels ,mini_batch):    """     数据迭代函数      Args:      - features: 特征矩阵 nxd 维      - labels: 样本,nx1 维      - mini_batch: 每次抽取的样本数   """    index =list(range(len(features)))     np.random.shuffle(index) #打乱顺序    for i in range(0,len(index),mini_batch):            # 增量 mini_batch        j = np.array(index[i:min(i+mini_batch,len(features))])         yield features[j] ,labels[j]   # 相当于一个断点 ,产生一个mini_batch小样本# 参数更新函数 def update_sgd(params, learning_rate,loss):      '''      计算梯度,并更新模型参数      Args:          - params: 模型参数,本例中为 [w, b]          - learning_rate: 学习率 learning rate    '''    for param in params: # 依次更新w ,b         param.assign_sub(learning_rate * tape.gradient(loss, param))#tensorflow 变量的生明 是tf.Variable 保存和更新参数  # 变量的初始值通常是随机数,常数,或者其他变量得到的# 训练参数w = tf.Variable(np.random.rand(),dtype=tf.float64)b = tf.Variable(np.random.rand(),dtype=tf.float64)#超参数traing_epoch = 300        #训练轮数learning_rate = 0.02 mini_batch = 10         #每次抽取的样本数   loss_history = []# 开始训练start_Time= time()for i  in range(traing_epoch+1):    for x,y in data_iter(x_data,y_data,mini_batch):         # 在内存中记录梯度过程        with tf.GradientTape(persistent=True) as tape :            tape.watch([w,b])            y_estim = model(x,w,b)            loss = loss_Squared(y_estim,y,mini_batch)              loss_history.append(loss)        #计算梯度,更新参数        update_sgd([w,b],learning_rate,loss)    #计算本次迭代的总误差    train_loss = loss_Squared(model(x_data,w,b),y_data,len(x_data))    if i%50 ==0:        print('epoch %d : loss: %f w:%f b:%f '  % (i , tf.reduce_mean(train_loss),w.numpy(),b.numpy()))duration =time() -start_Timeprint("Train Finished take %5f "%(duration))print('最后的结果  : loss: %f w:%f b:%f '  % ( tf.reduce_mean(train_loss),w.numpy(),b.numpy()))# 利用模型进行预测x_test = 3.14predict = model(w,x_test,b)target = 3*x_test + 2.0print('当x_test = 3.14 时:预测值:%f 目标值:%f'%(predict,target))###数据可视化def plot_(w,b):    ax = plt.subplot(111)     #画出 随机生成数据集的散点图    ax.plot(x_data, y_data, 'go', label='Original data')    plt.xlabel("X")    plt.ylabel("Y")    #目标直线    plt.plot(x_data,3*x_data+2.0, linewidth = '1',color='red',label='aim: Linear',marker='o')    #学习直线    y_prediction = np.array(w * x_data + b)    ax.plot(x_data, y_prediction,linewidth = '1',color='yellow',label="sty:Linear")    plt.legend(loc='upper left')    plt.show()plot_(w,b)plt.plot(loss_history)

4:借用tensorlfow 实现

import tensorflow as tf import numpy as npimport matplotlib.pyplot as pltimport randomfrom time import time# np.linspace  生成等差数列在-(-1,1)之间 100个点x_data = np.linspace(-1,1,10)# *x_data.shape 将转成数字  标准正态分布。y_data = 3*x_data +2.0+np.random.randn(*x_data.shape)*0.4data_num = x_data.shape[0]# arguments : learning_rate = 0.01training_epoch=1500loss_history = []# 随机初始化权重,偏置w = tf.Variable(0.0,name='weights')b = tf.Variable(np.random.randn(),name='bias')# 线性回归 w*x + bdef linear_regression(x,w,b):    return tf.multiply(w,x) + b# 损失函数def mean_square(y_pred ,y_true):    return tf.reduce_sum(tf.pow(y_pred-y_true,2)) /(2.0*data_num)# 梯度下降 optimizer = tf.optimizers.SGD(learning_rate)#训练参数start_Time =time()for epoch in range(training_epoch+1):    with tf.GradientTape() as tape:        tape.watch([w,b])        pred = linear_regression(x_data,w,b)        loss = mean_square(pred,y_data)        loss_history.append(loss)    # 计算梯度    gradients  =  tape.gradient(loss,[w,b])    optimizer.apply_gradients(zip(gradients,[w,b])) #自动更新 w b    if epoch % 200 ==0:        print('epoch: %i ,loss: %f, w: %f b=%f ' %(epoch,loss,w.numpy(),b.numpy()))duration =time() -start_Timeprint("Train Finished take %5f "%(duration))print('最后的结果: w: %f b: %f '  % (w.numpy(),b.numpy()))# 利用模型进行预测x_test = 3.14predict = linear_regression(w,x_test,b)target = 3*x_test + 2.0print('当x_test = 3.14 时: 预测值:%f 目标值:%f'%(predict,target))#数据可视化化def plot_(w,b):    ax = plt.subplot(111)     #画出 随机生成数据集的散点图    ax.plot(x_data, y_data, 'go', label='Original data')    plt.xlabel("X")    plt.ylabel("Y")    #目标直线    plt.plot(x_data,3*x_data+2.0, linewidth = '1',color='red',label='aim: Linear',marker='o')    #学习直线    y_prediction = np.array(w * x_data + b)    ax.plot(x_data, y_prediction,linewidth = '1',color='yellow',label="sty:Linear")    plt.legend(loc='upper left')    plt.show()plot_(w,b)plt.plot(loss_history)

 

一元线性回归:(推导)

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值