使用工具:jupyter notebook Python3.8
数据集来源:https://www.kesci.com/home/project/5da16a37037db3002d441810/code
导入库:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
单变量线性回归:
问题背景:根据城市人口数量,预测开小吃店的利润,数据集文件为ex1data1.txt,位于桌面上,第一列数据为人口Population,第二列数据为该城市小吃店利润Profit
1.1Plotting the Data
读入输入,然后展示数据
path = 'C:/Users/96108/Desktop/ex1data1.txt'
data = pd.read_csv(path, header=None, names=['Population', 'Profit'])
data.head()
输出:
绘图: scatter表示散点图
data.plot(kind='scatter', x='Population', y='Profit', figsize=(12,8))
plt.show()
1.2.1 梯度下降
在现有数据集的基础上,训练线性回归的参数θ)
约定公式:J(θ)为代价函数 h(θ)(x)为线性回归给出的结果,采用向量化的形式进行计算以优化计算速度
def computeCost(X, y, theta):
inner = np.power(((X * theta.T) - y), 2)
return np.sum(inner) / (2 * len(X))
#这个部分计算J(Ѳ),X是矩阵
1.2.2 实现
数据前面已经读入,现在要加入一列x,用于更新theta0,然后我们将theta初始化为0,学习率初始化为0.01,迭代次数为1500次
data.insert(0,'Ones',1)
然后做一些变量初始化:
cols=data.shape[1] #列数
X = data.iloc[:,0:cols-1]#X是所有行,去掉最后一列
y = data.iloc[:,cols-1:cols]#y是所有行,只取最后一列
观察下 X (训练集) and y (目标变量)是否正确.
代价函数是应该是numpy矩阵,所以我们需要转换X和Y,然后才能使用它们。 我们还需要初始化theta。
X = np.matrix(X.values)
y = np.matrix(y.values)
theta = np.matrix(np.array([0,0]))
看下维度:
1.2.3 计算代价函数
1.2.4 梯度下降
J(θ)的变量是θ,而不是X和y,意思是说,我们变化θ的值来使J(θ)变化,而不是变化X和y的值。 一个检查梯度下降是不是在正常运作的方式,是打印出每一步J(θ)的值,看他是不是一直都在减小,并且最后收敛至一个稳定的值。 θ最后的结果会用来预测小吃店在35000及70000人城市规模的利润。
def gradientDescent(X, y, theta, alpha, iters):
temp = np.matrix(np.zeros(theta.shape))
parameters = int(theta.ravel().shape[1])
cost = np.zeros(iters)#预定义iter个损失值,初始化为0
#每循环一次,计算一次损失值,并赋值
for i in range(iters):
error = (X * theta.T) - y #误差矩阵
#更新参数值,统一全部更新
for j in range(parameters):
term = np.multiply(error, X[:,j])
temp[0,j] = theta[0,j] - ((alpha / len(X)) * np.sum(term))
theta = temp
cost[i] = computeCost(X, y, theta) #计算损失值并保存
return theta, cost
#这个部分实现了theta的更新
初始化一些附加变量 - 学习速率α和要执行的迭代次数
alpha = 0.01
iters = 1500
运行梯度下降算法来使参数theta适合于训练集:
g, cost = gradientDescent(X, y, theta, alpha, iters)
g
predict1 = [1,3.5]*g.T
print("predict1:",predict1)
predict2 = [1,7]*g.T
print("predict2:",predict2)
#预测35000和70000城市规模的小吃摊利润
绘制一下拟合情况
x = np.linspace(data.Population.min(),data.Population.max(),100)
f = g[0,0] + (g[0,1] * x)
fig, ax=plt.subplots(figsize=(12,8))
ax.plot(x, f, 'r', label='Prediction')
ax.scatter(data.Population, data.Profit, label='Training Data')
ax.legend(loc=2)
ax.set_xlabel('Population')
ax.set_ylabel('Profit')
ax.set_title('Predicted Profit vs. Population Size')
plt.show()
1.3 多变量线性回归
ex1data2.txt里的数据,第一列是房屋大小,第二列是卧室数量,第三列是房屋售价 根据已有数据,建立模型,预测房屋的售价
path = 'C:/Users/96108/Desktop/ex1data2.txt'
data2 = pd.read_csv(path, header=None, names=['Size', 'Bedrooms', 'Price'])
data2.head()
1.4 特征归一法
观察数据发现,size变量是bedrooms变量的1000倍大小,统一量级会让梯度下降收敛的更快。做法就是,将每类特征减去他的平均值后除以标准差
data2 = (data2 - data2.mean()) / data2.std()
data2.head()
1.5 梯度下降
# 加一列常数项
data2.insert(0, 'Ones', 1)
# 初始化X和y
cols = data2.shape[1]
X2 = data2.iloc[:,0:cols-1]
y2 = data2.iloc[:,cols-1:cols]
# 转换成matrix格式,初始化theta
X2 = np.matrix(X2.values)
y2 = np.matrix(y2.values)
theta2 = np.matrix(np.array([0,0,0]))
# 运行梯度下降算法
g2, cost2 = gradientDescent(X2, y2, theta2, alpha, iters)
g2