一元线性回归python代码

  • Post author:
  • Post category:python



目录


1.最小二乘法:


2.梯度下降法:


3.理论加实践:


4.python代码:


4.1梯度下降法:


4.2最小二乘法



学习引入:

机器学习中的参数模型(线性回归,逻辑回归)等。在这里我们只进行一元线性回归的学习,求一元线性回归有两种方法



梯度下降法,最小二乘法



梯度下降法


:通过建模找到一个最大程度拟合数据的模型,通过确定损失函数,最优化目标函数来进行学习

回归分析:


最下二乘法

:利用已知的数据(线性回归中需要找到一条直线)最大程度的拟合样本与输出标记,即产生拟合方程,从而对未知的数据进行估预测.

如何判断是否选用线性模型处理问题?

使用相关系数r衡量特征与标记之间的相关性强弱,判断是否适合用直线进行拟合,r为0到1的值,越接近1,相关性越强

如果x与y有较强的相关的模型,则有y

=ax+b

寻找合适的参数a,b,使得误差即损失最小



1.最小二乘法:


最小二乘法求解最小值:


2.梯度下降法:

一元线性回归公式:

求解的方法:首先构造损失函数,然后对损失函数进行求偏导,之后利用前面讲过的梯度下降进行更新迭代,求得最后的一元线性方程。下面有一些简单的模型


3.理论加实践:


下面通过分析pizza模型,分析披萨的直径与价格的线性关系,来预测任一直径的披萨的价格。

将上面的值在图像上以坐标点显示:

import matplotlib.pyplot as plt
def runplt():
    plt.figure()#自定义图像
    plt.title("Diameter and price")
    plt.xlabel("Diameter/inch")
    plt.ylabel("Cost/dollar")
    plt.axis([0, 25, 0, 30])#用来设置图像边框X到25,y到30
    plt.grid(True)
    return plt
plt = runplt()
X = [[6], [8], [10], [14], [18]]#x代表pizza的直径
y = [[7], [9], [13], [17.5], [18]]#代表pizza的价格
plt.plot(X, y, 'k.')#绘制点图,‘k,’的作用是画出点
# #plt.show()#用来显示图像

图形如下

可以看出pizza的价格与pizza的直径是有一定关系的,是随着直径增大而增大,但又不是线性关系,所以需要构建模型,下面会以梯度下降法和最小二乘法进行求解。


4.python代码:

4.1梯度下降法:

t1和t2是两组数据,代表着直径数据和价格数据,假设函数(def h(x))是首先进行一个初始赋值,通过梯度下降的方法不断对k和b进行更新,最后拟合出一元线性回归方程。

# 通过分析披萨的直径与价格的线性关系,来预测任一直径的披萨的价格。
# author gyh
# 一元线性回归
import matplotlib.pyplot as plt
import numpy as np
t1=np.array([6,8,10,14,18])#x代表pizza的直径
t2=np.array([7,9,13,17.5,18])#代表pizza的价格
#定义一个数组,用来存放损失值
result=list()
#初值
x_i0=np.ones(len(t1))
k,b=0,0
alpha=0.12
#假设函数
def h(x):
    return k*x+b
#损失函数
def error(x,y):
    return np.sum(np.power((h(x)-y),2))/10
#损失函数求导对b
def error_b(x,y):
    return alpha*np.sum((h(x)-y)*x_i0)/5
#损失函数求导对斜率k
def error_k(x,y):
    return alpha*np.sum((h(x)-y)*x)/5
#不断更新
cnt=0#循环次数限制
for i in range(5):
    b0=error_b(t1[i],t2[i])
    k0=error_k(t1[i],t2[i])
    b=b-b0
    k=k-k0
    errors=error(t1[i],t2[i])
    result.append(errors)
    cnt=cnt+1
    if(cnt>20 or errors <100):
        break
if __name__ == "__main__":
    plt.figure()
    plt.title("change")#标题
    plt.xlabel("price")#坐标x轴
    plt.ylabel("amount")#坐标y轴
    x = np.arange(6, 18, 0.001)  # 起点为1,终点为2.5,步长为0.01
    Y = k * x + b
    plt.plot(t1, t2, 'k.')  # 绘制点图,‘k,’的作用是画出点
    plt.plot(x,Y)
    plt.grid(linestyle='--')  # 画出网格线
    plt.show()
    print("h(x)=%f+%f * x" % (b, k))

代码运行的结果:

h(x)=0.840000+1.008000 * x

图示:

4.2最小二乘法

由最小二乘法的公式可得python代码如下:

# 通过分析披萨的直径与价格的线性关系,来预测任一直径的披萨的价格。
#最小二乘法
# author gyh
import matplotlib.pyplot as plt
import numpy as np

def runplt():
    plt.figure()#自定义图像
    plt.title("Diameter and price")
    plt.xlabel("Diameter/inch")
    plt.ylabel("Cost/dollar")
    plt.axis([0, 25, 0, 30])#用来设置图像边框X到25,y到30
    plt.grid(True)
    return plt
plt = runplt()
X1 =np.linspace(6, 18)
Y1 =np.linspace(7, 18)
X=[6,8,10,14,18]#x代表pizza的直径
y=[7,9,13,17.5,18]#代表pizza的价格
plt.plot(X, y, 'k.')#绘制点图,‘k,’的作用是画出点
plt.plot(X1,Y1)#画出直线
plt.show()#用来显示图像
sum1,sum2=0,0
for i in range(len(X)):
    sum1 +=X[i]
t1=sum1/len(X)#x求平均
print("直径的平均值为:",t1)
for i in range(len(y)):
    sum2 +=y[i]
t2=sum2/len(y)#y求平均
print("价格的平均值为:",t2)
lxx=0
for i in range(len(X)):
    lxx +=(X[i]-t1)*(X[i]-t1)
print("lxx= ",lxx)
lxy=0
for i in range(len(y)):
    lxy +=(X[i]-t1)*(y[i]-t2)
print("lxy= %.2f"%lxy)
#由最小二乘法b=Lxy/lxx得
b=lxy/lxx
print("一元线性方程的斜率b=%.2f"%b)
a=t2-b*t1
print("一元线性回归方程")
print("y=%.2f+"%a,'%.2fx'%b)

结果为:

直径的平均值为: 11.2
价格的平均值为: 12.9
lxx=  92.8
lxy= 90.60
一元线性方程的斜率b=0.98
一元线性回归方程
y=1.97+ 0.98x

图示:

说明:由于刚开始写的有点乱,现在又重新梳理了一下,会继续改进的。



版权声明:本文为weixin_54375830原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。