首先我们要确保已经知道了线性回归的基本知识,如果不知道的话,请看:机器学习_线性回归
数据下载:链接:https://pan.baidu.com/s/1H04W5R6asmwGisDkpDHTqA 密码:jgba
首先我们先看一下数据:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
def getDataSet():
path = 'ex1data1.txt'
data = pd.read_csv(path, header=None, names=['Population', 'Profit'])
data.plot(kind = 'scatter',x = 'Population',y = 'Profit',figsize = (8,6))
plt.show()
if __name__ == '__main__':
getDataSet()
然后我们就开始拟合直线
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
def getDataSet():
'''
函数说明:得到数据集
:return:
X:得到的X坐标
y:得到的y坐标
'''
path = 'ex1data1.txt'
data = pd.read_csv(path, header=None, names=['Population', 'Profit'])
data.insert(0,'Ones',1)
cols = data.shape[1] #得到数据集的列数
X = data.iloc[:,0:cols-1] #获得X坐标
y = data.iloc[:,cols-1:cols] #获得y坐标
return X,y
def getCost(X, y ,theta):
'''
函数说明:代价函数计算数值
:param X: 训练集
:param y: X对应的y值
:param theta: theta值
:return:
代价函数得到的数值
'''
inner = np.power((X*theta.T) - y,2)
return 1/(2*len(X)*sum(inner))
def gradientDescent(X, y ,theta, alpha, iters):
'''
函数说明:根据梯度下降,计算出最适应的theta值
:param X: 训练集
:param y: X对应的y值
:param theta: 需要更新的theta值
:param alpha: 学习速率
:param iters:循环更新次数
:return:
theta:最终更新好的theta值
cost:根据代价函数,求得的误差
'''
temp = np.mat(np.zeros(theta.shape)) #新建一个相同的theta对象,每次都先更新temp,然后再赋值
cost = np.zeros(iters)
parameters = int (theta.shape[1]) #得到theta的个数
for i in range(iters): #循环更新的次数
error = X*theta.T - y
for j in range(parameters): #每次更新一个theta值,这样更能体现出那样一个求和的过程
term = np.multiply(error,X[:,j])
temp[0,j] = theta[0,j] - alpha / len(X) * sum(term)
theta = temp
cost[i] = getCost(X,y,theta)
return theta,cost
if __name__ == '__main__':
X,y = getDataSet()
alpha = 0.01 #学习速率
theta = np.mat(np.array([0,0])) #将array转换为matrix,表示:theta
X = np.mat(X)
y = np.mat(y)
iters = 1000
theta,cost = gradientDescent(X,y,theta,alpha,iters)
x = np.linspace(X[:,1].min(),X[:,1].max(),100)
f = theta[0,0] + (theta[0,1] * x)
fig,ax = plt.subplots(figsize = (8,6))
ax.plot(x,f,'r',label = 'Prediction')
ax.scatter(np.array(X[:,1]),np.array(y[:,0]),label = 'Training Data')
ax.legend(loc = 'best')
ax.set_xlabel('Population')
ax.set_ylabel('Profit')
ax.set_title('Predicted Profit vs. Population Size')
plt.show()
我们也可以将代价函数的变化的图像画下来:
fig,ax = plt.subplots(figsize = (8,6))
ax.plot(np.arange(iters),cost,'r')
plt.show()
上面那种写法更容易被理解一些,但是我们如果直接用矩阵的乘法的话,可以省掉里面的那一层循环,更加便捷一些,因为矩阵相乘的过程就包含相加的过程。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
def getDataSet():
'''
函数说明:得到数据集
:return:
X:得到的X坐标
y:得到的y坐标
'''
path = 'ex1data1.txt'
data = pd.read_csv(path, header=None, names=['Population', 'Profit'])
data.insert(0,'Ones',1)
cols = data.shape[1] #得到数据集的列数
X = data.iloc[:,0:cols-1] #获得X坐标
y = data.iloc[:,cols-1:cols] #获得y坐标
return X,y
def getCost(X, y ,theta):
'''
函数说明:代价函数计算数值
:param X: 训练集
:param y: X对应的y值
:param theta: theta值
:return:
代价函数得到的数值
'''
inner = np.power(((X*theta.T) - y),2)
return np.sum(inner)/(2*len(X))
def gradientDescent(X, y ,theta, alpha, iters):
'''
函数说明:根据梯度下降,计算出最适应的theta值
:param X: 训练集
:param y: X对应的y值
:param theta: 需要更新的theta值
:param alpha: 学习速率
:param iters:循环更新次数
:return:
theta:最终更新好的theta值
cost:根据代价函数,求得的误差
'''
cost = np.zeros(iters)
parameters = int (theta.shape[1]) #得到theta的个数
for i in range(iters): #循环更新的次数
error = X*theta.T - y
theta =theta - (alpha * error.T * X)/len(X)
cost[i] = getCost(X,y,theta)
return theta,cost
if __name__ == '__main__':
X,y = getDataSet()
alpha = 0.01 #学习速率
theta = np.mat(np.array([0,0])) #将array转换为matrix,表示:theta
X = np.mat(X)
y = np.mat(y)
iters = 1000
theta,cost = gradientDescent(X,y,theta,alpha,iters)
x = np.linspace(X[:,1].min(),X[:,1].max(),100)
f = theta[0,0] + (theta[0,1] * x)
fig,ax = plt.subplots(figsize = (8,6))
ax.plot(x,f,'r',label = 'Prediction')
ax.scatter(np.array(X[:,1]),np.array(y[:,0]),label = 'Training Data')
ax.legend(loc = 'best')
ax.set_xlabel('Population')
ax.set_ylabel('Profit')
ax.set_title('Predicted Profit vs. Population Size2')
plt.show()
结果和上面的相同:
代价函数也是相同的