题目:房价预测
单变量线性回归
1. 进行数据可视化(散点图)
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
path="ex1data1.txt"
data= pd.read_csv(path,header=None,names=['Population','Profit'])
data.head()
data.describe()
#画出房价散点图
data.plot(kind='scatter',x='Population',y='Profit',figsize=(12,8))
plt.show()
Profit | Profit | ||
---|---|---|---|
0 | 6.1101 | 17.5920 | |
1 | 5.5277 | 9.1302 | |
2 | 8.5186 | 13.6620 | |
3 | 7.0032 | 11.8540 | |
4 | 5.8598 | 6.8233 |
2. 数据向量化
现在是得到一个散点图,是欠拟合的,所以接下来我们将用梯度下降算法来实现线性回归
现在我们把数据向量化,也就是在最前增加一列,且全为1作为x0
意思是loc(位置/索引)为0,name为ones,value为1
data.insert(0, 'Ones', 1)
3.首先,我们将创建一个以参数θ为特征函数的代价函数
def computeCost(X, Y, theta):
inner = np.power((X * theta.T) - Y, 2)
return np.sum(inner) / (2 * len(X))
- 变量初始化,X(训练集),y(目标变量)
cols=data.shape[1] #shape[],0代表行数,1代表列数,所以此时cols=3
# pandas,通过行号来取数据,也就是按数字索引
X=data.iloc[:,0:cols-1]# X抽取所有行,列抽取【0,2),左闭右开
y=data.iloc[:,cols-1:cols]# 也就是取第二列
分别得到两个变量数据
- 初始化theta
代价函数应该是numpy矩阵,所以我们需要转换X和y,然后才能使用它们。
同时我们还需要初始化theta,即把theta所有元素都设置为0(初始化)
X = np.matrix(X.values)
y = np.matrix(y.values)
theta = np.matrix(np.array([0,0]))
theta
# matrix([[0, 0]])
X.shape,theta.shape,y.shape
# ((97, 2), (1, 2), (97, 1))
- 计算代价函数
computeCost(X,y,theta)
# 32.072733877455676
4. 使用梯度下降
iters是需要迭代的次数,parameters表示参数个数(本题只有theta0和1两个参数)
# 梯度下降
def gradientDescent(X, Y, theta, alpha, iters):
temp = np.matrix(np.zeros(theta.shape)) #构建零值矩阵
parameters = int(theta.shape[1]) # 为2
cost = np.zeros(iters) # 也是一个矩阵,用来保存每次迭代的cost
for i in range(iters):
error = X * theta.T - Y
for j in range(parameters):# theta=0/1
term = np.multiply(error, X[:, j])
temp[0, j] = temp[0, j] - alpha / len(X) * np.sum(term)
theta = temp
cost[i] = computeCost(X, Y, theta)
return theta, cost
初始化一些变量,学习速率和迭代次数
alpha=0.01
iters=1000
现在让我们运行梯度下降算法来将我们的参数θ适合于训练集。
theta,cost=gradientDescent(X, y, theta, alpha, iters)
theta # 0和1的时候的值
# matrix([[-3.24041524, 1.12719506]])
利用了梯度算法得到thera0和1后,我们把它代入线性回归的代价函数,求误差
computeCost(X,y,theta)
# 4.516073179978322
现在我们来绘制线性模型以及数据,直观地看出它的拟合。
# 生成固定范围的数组
# np.linspace(左,右,生成个数),左闭右也闭,等距离(相除,每个数等距离)
x = np.linspace(data.Population.min(),data.Population.max(),100)
f = theta[0,0]+(theta[0,1]*x)
# ax 是一个 Axes 对象,通常由 plt.subplots() 或 fig, ax = plt.subplots() 返回
fig,ax=plt.subplots(figsize=(12,8))
# 折线图(红色)
ax.plot(x,f,'r',label='Prediction')
# 散点图(蓝色)
ax.scatter(data.Population,data.Profit,label='Traning Data')
# 显示图例,并设置位置
ax.legend(loc=4)
# x y轴坐标名和title
ax.set_xlabel('Population')
ax.set_ylabel('Profit')
ax.set_title('Predicted Profit vs Population Size')
plt.show()
画出cost图像
fig, ax = plt.subplots(figsize=(12,8))
ax.plot(np.arange(iters), cost, 'r')
ax.set_xlabel('Iterations')
ax.set_ylabel('Cost')
ax.set_title('Error vs. Training Epoch')
plt.show()
多变量线性回归
data2是一个房屋价格数据集,其中有2个变量(房子的大小,卧室的数量)和目标(房子的价格)
我们使用我们已经应用的技术来分析数据集
1. 导入数据
path = 'ex1data2.txt'
data = pd.read_csv(path, header=None, names=['Size', 'Bedrooms', 'Price'])
data.head()
Size | Bedrooms | Price | |
---|---|---|---|
0 | 2104 | 3 | 399900 |
1 | 1600 | 3 | 329900 |
2 | 2400 | 3 | 369000 |
3 | 1416 | 2 | 232000 |
4 | 3000 | 4 | 539900 |
2. 特征缩放
对于此任务,我们添加了另一个预处理步骤 - 特征归一化,也就是特征缩放
# 特征缩放
data = (data - data.mean()) / data.std()
data.head()
Size | Bedrooms | Price | |
0 | 0.130010 | -0.223675 | 0.475747 |
1 | -0.504190 | -0.223675 | -0.084074 |
2 | 0.502476 | -0.223675 | 0.228626 |
3 | -0.735723 | -1.537767 | -0.867025 |
4 | 1.257476 | 1.090417 | 1.595389 |
# add ones column
data.insert(0, 'Ones', 1)
cols = data.shape[1]
X = data.iloc[:, :cols-1]
Y = data.iloc[:, cols-1:cols]
X = np.matrix(X.values)
Y = np.matrix(Y.values)
theta = np.matrix(np.array([0, 0, 0]))
alpha = 0.01
iters = 1000
theta, cost = gradientDescent(X, Y, theta, alpha, iters)
computeCost(X, Y, theta)
# 0.13070336960771892
theta
# matrix([[-5.54461914e-17, 8.78503652e-01, -4.69166570e-02]])
# 画出cost图像
fig, ax = plt.subplots(figsize=(12, 8))
ax.plot(np.arange(iters), cost, 'r')
ax.set_xlabel('Iterations')
ax.set_ylabel('Cost')
ax.set_title('Error vs Training Epoch')
plt.show()
正规方程
正规方程是通过求解下面的方程来 找出—使得代价函数最小的参数
梯度下降与正规方程的比较:
梯度下降:需要选择学习率α,需要多次迭代,当特征数量n大时也能较好适用,适用于各种类型的模型
正规方程:不需要选择学习率α,一次计算得出,
通常来说当n小于10000 时还是可以接受的,只适用于线性模型,不适合逻辑回归模型等其他模型
def normalEqn(X,T):
theta = np.linalg.inv(X.T@X)@X.T@Y
return theta
final_theta2=normalEqn(X,Y)
final_theta2
matrix([[-5.55111512e-17],
[ 8.84765988e-01],
[-5.31788197e-02]])