目录
学习引入:
机器学习中的参数模型(线性回归,逻辑回归)等。在这里我们只进行一元线性回归的学习,求一元线性回归有两种方法
:
梯度下降法,最小二乘法
梯度下降法
:通过建模找到一个最大程度拟合数据的模型,通过确定损失函数,最优化目标函数来进行学习
回归分析:
最下二乘法
:利用已知的数据(线性回归中需要找到一条直线)最大程度的拟合样本与输出标记,即产生拟合方程,从而对未知的数据进行估预测.
如何判断是否选用线性模型处理问题?
使用相关系数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
图示:
说明:由于刚开始写的有点乱,现在又重新梳理了一下,会继续改进的。