自己在看课程时的的学习笔记,记下来,供以后复习。
线性回归
假设有下面这些房价数据,图表上的每个实例都是一次房屋交易
如下图,为房价和房屋面积的关系,横坐标为交易房屋的占地面积,纵坐标为房屋的交易价格。
但是现实生活中房价并不一定是仅仅与房屋面积相关,还有可能与其他因素相关,如下表所示:
这里我假设与房价相关的因素数目即特征数目为N,i表示第i个特征,总共有M组数据,j表示第j组数据。同时我假设h(x)作为我的预期的线性函数,x表示特征,y,表示房价。
假设 即
接下来就需要为我们的模型选择合适的参数(parameters) ,
…
使得我们的估计函数误差最小,这里选择最小二乘法作为我们的代价函数,至于选择最小二乘法的原因是我们假设所有特征都是独立同分布的情况下,可以使用高斯分布或者说正态分布来对误差函数建模,通过运算得到误差函数就是最小二乘法。
为了选择合适的使得
最小,这里我们选择梯度下降法。
梯度下降法
梯度下降是一个用来求函数最小值的算法,我们将使用梯度下降算法来求出代价函数J(θ0,θ1)的最小值。
梯度下降背后的思想是:开始时我们随机选择一个参数的组合( ,
…
),计算代价函数,然后我们寻找下一个能让代价函数值下降最多的参数组合。我们持续这么做直到到到一个局部最小值(local minimum),因为我们并没有尝试完所有的参数组合,所以不能确定我们得到的局部最小值是否便是全局最小值(global minimum),选择不同的初始参数组合,可能会找到不同的局部最小值。更新策略如下:
其中为步长,又叫学习率(learning rate)rate),它决定了我们沿着能让代价函数下降程度最大的方向向下迈出的步子有多大,。在上面得到代价函数为
所以
将上面的结果带到上面求导数的过程中,因为y项没有,而且x项中只有第i个
含有
所以就剩下
得到
在这种情况下,我们可以设置步长来使得误差函数尽快收敛,数据,代码如下所示:
100,4,9.3
50,3,4.8
100,4,8.9
100,2,6.5
50,2,4.2
80,2,6.2
75,3,7.4
65,4,6
90,3,7.6
90,2,6.1
#*****************************************************
#获取数据
#*****************************************************
def dataSet(filename):
data = np.genfromtxt(filename,delimiter = ',')
splitTrainingData = data[:,:-1]
trainingData = []
labelData = data[:,-1]
trainingArr = [1]
m,n = np.shape(splitTrainingData)
for i in range(m):
for j in range(n):
trainingArr.append(splitTrainingData[i,j])
trainingData.append(trainingArr)
trainingArr = [1]
return(trainingData,labelData)
#*****************************************************
#预测
#*****************************************************
def testaccuracy(parameters,testMatrix):
result = np.dot(testMatrix,parameters)
print(result)
#*****************************************************
#计算参数
#*****************************************************
def calculateParameters(trainingData,labelData):
trainingMatrix = np.array(trainingData)
lableMatrix = np.array(labelData)
m,n = np.shape(trainingMatrix)
parameters = np.ones((n,1))
step = 0.000005
errorlist = []
for arr in range(m):
error = 0.5*np.sum(np.dot(trainingMatrix,parameters)-lableMatrix)
trainArr = trainingMatrix[arr]
trainArr.shape = (n,1)
parameters = parameters - step * error * trainArr
errorlist.append(error)
return(parameters,errorlist)
filename = r'test.csv'
trainingData,labelData = dataSet(filename)
parameters,errorlist=calculateParameters(trainingData,labelData)
testMatrix = [1,102,6]
testMatrix = np.array(testMatrix)
testaccuracy(parameters,testMatrix)
#*****************************************************
#误差
#*****************************************************
x = range(np.shape(trainingData)[0])
y = errorlist
plt.figure(figsize = (8,4))
plt.plot(x,y,label="error",color = "red",linewidth = 2)
plt.show()
上面代码的参数还可以调整,误差收敛的效果也会有变化。用上面参数算出的预测值为10.52556946。
矩阵解释
我们假设X为训练样本矩阵。其中
,
…
分别为第1,2…M个训练样本,均为行向量。Y表示标签样本矩阵,
为待求得参数矩阵:
那么
计算代价函数
同理对矩阵求导
令代价函数最小即 所以由上式可以得到下面的结果
下面的代码是矩阵形式的实现
import numpy as np
import matplotlib.pyplot as plt
#*****************************************************
#获取数据
#*****************************************************
def dataSet(filename):
data = np.genfromtxt(filename,delimiter = ',')
splitTrainingData = data[:,:-1]
trainingData = []
labelData = data[:,-1]
trainingArr = [1]
m,n = np.shape(splitTrainingData)
for i in range(m):
for j in range(n):
trainingArr.append(splitTrainingData[i,j])
trainingData.append(trainingArr)
trainingArr = [1]
return(trainingData,labelData)
def calculateParameters(trainingData,labelData):
trainingMatrix = np.array(trainingData)
lableMatrix = np.array(labelData)
paramaters = np.dot(np.dot(np.linalg.inv(np.dot((trainingMatrix.T),trainingMatrix)),trainingMatrix.T) ,lableMatrix)
return paramaters
#*****************************************************
#预测
#*****************************************************
def testaccuracy(parameters,testMatrix):
result = np.dot(testMatrix,parameters)
print(result)
filename = r'test.csv'
trainingData,labelData = dataSet(filename)
parameters=calculateParameters(trainingData,labelData)
testMatrix = [1,102,6]
testMatrix = np.array(testMatrix)
testaccuracy(parameters,testMatrix)
计算得到的结果为10.9075798102
在接下来是用sklearn库进行检验的代码。
from numpy import genfromtxt
from sklearn import linear_model
datapath = r'C:\Users\ThinkCentre\Desktop\deep_learning\logistics\test.csv'
deliveryData = genfromtxt(datapath,delimiter = ',')
x = deliveryData[:,:-1]
y = deliveryData[:,-1]
regr = linear_model.LinearRegression()
regr.fit(x,y)
print("coefficients",regr.coef_)
print("intercept",regr.intercept_)
xPred = [102,6]
yPred = regr.predict(xPred)
print("predicted y",yPred)
上面代码的计算结果为10.90757981,发现三个结果还是很接近的。