吴恩达线性回归总结
数据集地址:
Hypothesis:
课后习题题目
1、制作一个5阶单位阵
2、假设你是一家餐厅的CEO,正在考虑开一家分店,根据城市人口预测其 利润,我们拥有不同城市的人口数据以及利润data1
3、假如你有一个房子需要出售,你想估算下你的房子值多少钱。我们拥有当地房子资料data1
一、吴恩达线性回归函数理解
回归问题中的一些标记:
m:代表训练集中实例的数量
x:代表特征/输入变量
y:代表目标变量/输出变量
(
x
,
y
)
\\{\rm{(x,y}})\,
(x,y):代表训练集中的实例
(
x
(
i
)
,
y
(
i
)
)
\\({x^{({\rm{i}})}},{y^{(i)}})\,
(x(i),y(i)):代表第i个观察实例
h:代表学习算法的解决方案或函数也称为假设函数(Hypothesis)
1.单变量线性回归
一种可能的表达方式为:
h
θ
(
x
)
=
θ
0
+
θ
1
x
\\{h_\theta }(x) = {\theta _0} + {\theta _1}{x} \,
hθ(x)=θ0+θ1x,因为只含有一个特征 /输入变量的问题叫作单变量线性回归问题。
1.1 假设函数(Hypothesis)
h
θ
(
x
)
=
θ
0
+
θ
1
x
\\{h_\theta }(x) = {\theta _0} + {\theta _1}{x} \,
hθ(x)=θ0+θ1x
说白了我们就是通过一系列回归运算,得出θ0与θ1的值,从而得到一条预测直线。
1.2 代价函数(Cost Function)
价函数的目的:通过梯度下降法或者BP算法来训练模型中的参数。
代价函数的意义:表征模型输出与标签值之间的差异。
代价函数的形式:是关于所有超参数w的函数。
代价函数选取的标准:
(1)可导。
(2)满足凸函数的条件,可以方便用梯度下降法求解最小值。
代价函数训练模型的方法:
通过使得代价函数取得最小值对应的超参数,即为模型最终的参数。
线性回归的代价函数为:
J
(
θ
)
=
1
2
m
∑
i
=
1
m
(
h
θ
(
x
(
i
)
)
−
y
(
i
)
)
2
\\J(\theta ) = \frac{{\rm{1}}}{{{\rm{2m}}}}\sum\limits_{i = 1}^m {{{({h_\theta }({x^{(i)}}) - {y^{(i)}})}^2}} \,
J(θ)=2m1i=1∑m(hθ(x(i))−y(i))2
我们的目标就是选择出合适的参数使得建模误差的平方和能够最小的参数模型。即使代价函数最小时的θ0与θ1。
最小化代价函数的方法:梯度下降法正规方程法
1.3 梯度下降(Gradient Descent)
根据上面的代价函数,为了拟合出参数,需要找出尽量让J(θ)取得最小值的参数θ。
梯度:
∂
J
(
θ
)
∂
θ
j
=
1
m
∑
i
=
1
m
(
h
θ
(
x
(
i
)
)
−
y
(
i
)
)
x
j
(
i
)
\\\frac{{\partial J(\theta )}}{{\partial {\theta _j}}} = \frac{{\rm{1}}}{{\rm{m}}}\sum\limits_{i = 1}^m {({h_\theta }({x^{(i)}}) - {y^{(i)}})} x_j^{(i)}\,
∂θj∂J(θ)=m1i=1∑m(hθ(x(i))−y(i))xj(i)
梯度下降:(沿梯度方向时下降最快的方向,j=0或j=1)
θ
j
:
=
θ
j
−
α
∂
J
(
θ
0
,
θ
1
)
∂
θ
j
\\{\theta _j}: = {\theta _j} - \alpha \frac{{\partial J({\theta _0},{\theta _1})}}{{\partial {\theta _j}}}\,
θj:=θj−α∂θj∂J(θ0,θ1)
α:学习率,不可过大,也不能太小
1.4 正规方程法(Normal Equation)
令:
∂
J
(
θ
0
,
θ
1
)
∂
θ
j
=
0
\\\frac{{\partial J({\theta _0},{\theta _1})}}{{\partial {\theta _j}}} = 0\,
∂θj∂J(θ0,θ1)=0
通过向量化表示:
θ
=
(
X
T
X
)
−
1
X
T
y
\\\theta = {({X^T}X)^{^{ - 1}}}{X^T}{\rm{y}}\,
θ=(XTX)−1XTy
2.多变量线性回归
2.1 特征缩放(特征归一化)
在我们面对多维特征问题的时候,我们需要保证这些特征值具有相近的尺度,这可以帮助我们更快的收敛。
特征归一化有两种方式:
方式一:Standardization
Standardization又称为Z-score normalization,量化后的特征将服从标准正态分布:
z
=
x
i
−
μ
δ
\\{\rm{z = }}\frac{{{x_i} - \mu }}{\delta }\,
z=δxi−μ
量化后特征值将分布在[-1,1]区间;
方式二:Min-Max Scaling
Min-Max Scaling又称为Min-Max Normalization,特征量化公式为:
z
=
x
i
−
min
(
x
i
)
max
(
x
i
)
−
min
(
x
i
)
\\{\rm{z = }}\frac{{{x_i} - \min ({x_i})}}{{\max ({x_i}) - \min ({x_i})}}\,
z=max(xi)−min(xi)xi−min(xi)
量化后特征值将分布在[0,1]区间。
二、代码演示
1.引入库
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
2.生成一个5阶单位阵
# 作一个五阶单位阵
A = np.eye(5) # 把一个5阶单位阵赋值给A
print(A) # 打印单位阵A
3.读取数据
path = 'K:\python\吴恩达机器学习python作业代码\code\ex1-linear regression/ex1data1.txt'
data1 = pd.read_csv(path,header = 0 ,names = ['Population','Profit'])
# header:整数,指定第几行作为列名(忽略注释行),如果没有指定名,默认header=0
# names:列表,指定列名
# sep:字符串,默认为','
# print(data1.head()) # data1.head(),默认查看前五个数据,括号填入前多少行
# print(data1.tail()) # data1.tail(),默认查看后五个数据,括号填入前多少行
# print(data1.describe()) # data1.describe(),查看数据基本参数
# print(data1.info()) # data1.info(),查看数据结构
# print("查看数据集data1:",data1)
4.数据可视化
fig, ax = plt.subplots(figsize=(9,6)) # 设置图片尺寸
ax.scatter(data1.Population, data1.Profit,s = 20,c = 'b',
marker = 'o',label = 'Training data') # s表示点的尺寸
ax.set_title("Datainit", fontsize=14) # 图名字,字号14
ax.set_xlabel("Population", fontsize=10) # x轴标签,字号10
ax.set_ylabel("Profit", fontsize=10) # y轴标签,字号10
ax.tick_params(axis = 'both', which = 'major', labelsize = 10)
# 主参数设置,其中指定的实参将影响x轴和y轴上的刻度(axis='both'),刻度标记的字号14
# 设置图例位置在右下角
ax.legend(loc='lower right') # 图例
#plt.grid(linestyle = '--', linewidth = 2.5) # 背景网格
fig.show()
数据可视化结果:
5.数据预处理
data1.insert(0, 'Ones', 1) # DataFram.insert(loc,column,value,allow_duplicates = False)
# loc: 插入的索引值
# column:插入的标签,字符串
# value:插入列的值
m = data1.shape[0] # 查看数据集的行数
n = data1.shape[1] # 查看数据集的列数
x = data1.iloc[:,1] # 提取数据集的第一列
y = data1.iloc[:,n-1:n] # y是data1最后一列
X = data1.iloc[:,:-1] # X是data1里的除最后列
# 切片:.iloc[:,start:end]
#print("查看m:",m)
#print("查看n:",n)
#print("查看x:",x)
#print('查看y:',y)
#print('查看X:',X)
X = np.matrix(X.values) # 将X转化成X矩阵(特征值)
y = np.matrix(y.values) # 将y转化成Y矩阵(目标值)
print'查看X的维数:',(X.shape)
print('查看y的维数:',y.shape)
#print('查看X:', X)
#print('查看y:', y)
6.计算J(Ѳ)
代码如下(示例):
def computeCost(X, y, theta):
inner = np.power(((X * theta.T) - y), 2) # matrix可以用*乘,array用@乘或者dot
# np.power(a,b),a的b次方
return np.sum(inner) / (2 * len(X))
计算J(Ѳ)的初始值:
theta = np.matrix(np.array([0,0])) # 初始化一个theta矩阵
# dataframe转化成ndarray:① df.values ② df.as.matrix() ③ np.array(df)
# print('查看theta的维数:',theta.shape)
# print('查看theta:', theta)
print('计算J(θ)的初始值:',computeCost(X, y, theta))
J(θ)的初始值:32.072733877455676
7.梯度下降函数计算theta(theta=g)
def gradientDescent(X, y, theta, alpha, iters):
temp = np.matrix(np.zeros(theta.shape)) # 初始化矩阵theta
parameters = int(theta.ravel().shape[1]) #
cost = np.zeros(iters)
for i in range(iters): # 当i在0-1500的范围内,执行下面的循环
e = (X * theta.T) - y # 定义中间函数(X * theta.T) - Y赋值给e
for j in range(parameters): # 当j分别为0、1时计算θ(j)
term = np.multiply(e, X[:, j])
temp[0, j] = theta[0, j] - ((alpha / len(X)) * np.sum(term)) # 计算θ(j)
theta = temp
cost[i] = computeCost(X, y, theta)
return theta, cost
计算theta(即g)
alpha = 0.01
iters = 1500
g, cost = gradientDescent(X, y, theta, alpha, iters)
print('查看theta:',g)
查看g: [[-3.63029144 1.16636235]]
8.正规方程法计算theta(theta=g)
def normalEquation(x,y):
result = np.linalg.inv(x.T@x)@x.T@y
return result
theta = normalEquation(X,y)
print('查看解析解theta:',theta)
查看解析解theta: [[-3.89578088]
[ 1.19303364]]
9.绘制预测图
fig, ax = plt.subplots(figsize=(9,6)) # 设置图片尺寸
z = np.linspace(data1.Population.min(), data1.Population.max(), 100)
f = g[0, 0] + (g[0, 1] * z) # 线性回归法法求出的theta结果
k = theta[0, 0] + (theta[1,0] * z) # 正规方程法求出的theta结果
ax.set_title("Prognostic Map", fontsize=14) # 图名字,字号14
ax.set_xlabel("Population", fontsize=10) # x轴标签,字号10
ax.set_ylabel("Profit", fontsize=10) # y轴标签,字号10
ax.tick_params(axis = 'both', which = 'major', labelsize = 10) # 主参数设置,刻度标记的字号10
ax.scatter(data1.Population,data1.Profit,s = 20,c='b',marker='o',label='Training data') # 绘制散点图
ax.plot(z,f,c='r',label='Linear Regression') # 绘制折线图
ax.plot(z,k,c='g',label='Normal Equation') # 绘制折线图
ax.legend(loc='lower right') # 设置图例位置在右下角
fig.show()
10.预测3.5万人和7万人口时盈利情况
predict1 = [1,3.5]*g.T # 预测3.5万人口的利润
print("predict1:",predict1)
predict2 = [1,7]*g.T # 预测7万人口的利润
print("predict2:",predict2)
predict1: [[0.45197679]]
predict2: [[4.53424501]]
11.绘制梯度下降法的误差迭代图
fig, ax = plt.subplots(figsize=(9,6)) # 设置图片尺寸
ax.set_title("Error vs. Training Epoch", fontsize=14) # 图名字,字号14
ax.set_xlabel("Iterations", fontsize=10) # x轴标签,字号10
ax.set_ylabel("Cost", fontsize=10) # y轴标签,字号10
ax.tick_params(axis = 'both', which = 'major', labelsize = 10) # 主参数设置,刻度标记的字号10
ax.plot(np.arange(iters),cost,c='r',label='Iteration Error') # 绘制折线图
ax.legend(loc='upper right') # 设置图例位置在右上角
fig.show()
12.损失函数可视化
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure()
ax = fig.gca(projection='3d') # 关键字绘图法
ax.set_title("Loss Function", fontsize=14) # 图名字,字号14
ax.set_xlabel("theta0", fontsize=10) # 设置x轴标签为theta0,字号10
ax.set_ylabel("theta1", fontsize=10) # 设置y轴标签为theta1,字号10
ax.set_zlabel("J_theta", fontsize=10) # 设置y轴标签为J_taeta,字号10
xx = np.linspace(-10,10,num = 100) # 从(-10,10)等距取100个点作为xx的取值
yy = np.linspace(-1,4,num = 100) # 从(-1,4)等距取100个点作为yy的取值
X_,Y_= np.meshgrid(xx,yy) # 将xx,yy绘制成100*100的数组
J = 0
for i in range(len(X)):
h = X_ + Y_*x[i]
J += np.power(h-y[i],2)
Z_ = J/(2*len(X))
ax.plot_surface(X_,Y_,Z_,rstride = 1, cstride = 1,cmap='rainbow') # 图片渲染
fig.show()
13.等高线图
fig, ax = plt.subplots(figsize=(9,6))
ax.set_title("Function of the theta0,theta1", fontsize=14) # 图名字,字号14
ax.set_xlabel("theta0", fontsize=10) # x轴标签,字号10
ax.set_ylabel("theta1", fontsize=10) # y轴标签,字号10
ax.contourf(X_, Y_, Z_,20,alpha=0.6,cmap='rainbow')
ax.plot(g[0,0],g[0,1],marker='o',markerSize=10, LineWidth=50,c='r') # 表示出(theta0,theta1)
ax.plot(theta[0,0],theta[1,0],marker='x',markerSize=10, LineWidth=50,c='g') # 表示出(theta0,theta1)
fig.show()
14.多变量线性回归
读取数据集:
path = 'K:\python\吴恩达机器学习python作业代码\code\ex1-linear regression/ex1data2.txt'
data2 = pd.read_csv(path,header=None,names=['Size', 'Bedrooms', 'Price'])
# 读取数据集data2
# print("查看数据集data2:",data2)
特征值归一化:
data2 = (data2 - data2.mean()) / data2.std() # 特征归一化(特征值减去方差再除去方差的方法)
# print("查看数据集data2:",data2)
数据预处理:
data2.insert(0,'x0',1) # 加一列常数项
cols = data2.shape[1]
# print(cols)
X = data2.iloc[:,0:cols-1] # X是data2除最后列
Y = data2.iloc[:,cols-1:cols] # Y是data2最后一列
X = np.matrix(X.values) # 将X转换成X矩阵
Y = np.matrix(Y.values) # 将Y转换成Y矩阵
theta = np.matrix(np.zeros(data2.shape[1]-1)) # 初始化矩阵theta
alpha = 0.01 # 学习率为0.01
iters = 1000 # 学习次数为1000
计算theta(theta=g):
g, cost = gradientDescent(X, Y, theta, alpha, iters) # 计算
print(g)
计算g:[[-1.10868761e-16 8.78503652e-01 -4.69166570e-02]]