机器学习作业 1 - 线性回归

机器学习作业 1 - 线性回归

  • 1.单变量线性回归
  • 2.batch gradient decent(批量梯度下降)
  • 3.多变量线性回归
  • normal equation(正规方程)(选做)

1.单变量线性回归

#导入需要使用的包
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

导入数据集。提醒大家:一定要把数据文件ex1data1.txt放在和程序同一个文件夹里,否则需要使用绝对路径访问文件 将csv文件读入并转化为数据框形式,路径,指定哪一行作为表头。默认设置为0(即第一行作为表头),如果没有表头的话,要修改参数,设置header=None, 指定列的名称,用列表表示。一般我们没有表头,即header=None时,这个用来添加列名 在默认情况下,head命令显示文件的头5行内

path =  'ex1data1.txt'
data = pd.read_csv(path, header=None, names=['Population', 'Profit'])
data.head()  #预览数据

机器学习作业 1 - 线性回归_第1张图片

data.describe()
#对于数值数据,结果的索引将包括计数,平均值,标准差,最小值,最大值以及较低的百分位数和50。默认情况下,较低的百分位数为25,较高的百分位数为75.50百分位数与中位数相同。

机器学习作业 1 - 线性回归_第2张图片

数据可视化,绘制散点图 kind: 取值为 line 或者 scatter, 后者为默认值 图像大小

data.plot(kind='scatter', x='Population', y='Profit', figsize=(12,8))  
plt.show()

机器学习作业 1 - 线性回归_第3张图片

现在让我们使用梯度下降来实现线性回归,以最小化成本函数。 以下代码示例中实现的方程在“练习”文件夹中的“ex1.pdf”中有详细说明。

首先,我们将创建一个以参数θ为特征函数的
代价函数
J ( θ 0 , θ 1 ) = 1 2 m ∑ i = 1 m ( h θ ( x ( i ) ) − y ( i ) ) 2 J \left( \theta_0, \theta_1 \right) = \frac{1}{2m}\sum\limits_{i=1}^m \left( h_{\theta}(x^{(i)})-y^{(i)} \right)^{2} J(θ0,θ1)=2m1i=1m(hθ(x(i))y(i))2最小。

其中:
h θ ( x ) = θ T X = θ 0 + θ 1 x 1 + θ 2 x 2 + . . . + θ n x n h_{\theta}\left( x \right)=\theta^{T}X={\theta_{0}}+{\theta_{1}}{x_{1}}+{\theta_{2}}{x_{2}}+...+{\theta_{n}}{x_{n}} hθ(x)=θTX=θ0+θ1x1+θ2x2+...+θnxn

np.power(x1,x2)数组的元素分别求n次方。x2可以是数字,也可以是数组,但是x1和x2的列数要相同。

def computeCost(X, y, theta):
    # your code here  (appro ~ 2 lines)
    inner = np.power(((X*theta.T)-y),2)
    return np.sum(inner)/(2*len(X))

让我们在训练集中添加一列,以便我们可以使用向量化的解决方案来计算代价和梯度。在训练集的左侧插入一列全为“1”的列,以便计算即x0=1 loc为0,name为ones,value为1.

data.insert(0, 'Ones', 1)

现在我们来做一些变量初始化。.shape[0] 为第一维的长度,shape[1] 为第二维的长度理解列.pandas中利用.iloc选取数据iloc’,’ 前的部分标明选取的行,‘,’后的部分标明选取的列 此时三列了

# set X (training data) and y (target variable)
cols = data.shape[1]      #shape0为行数,shape1为列数,此时cols等于3
X = data.iloc[:,0:cols-1] #iloc相当于从里面抽出某些行某些列,左闭右开,X是所有行,去掉最后一列
y = data.iloc[:,cols-1:cols]

观察下 X (训练集) and y (目标变量)是否正确.

X.head()#head()默认是观察前5行

机器学习作业 1 - 线性回归_第4张图片

y.head()

机器学习作业 1 - 线性回归_第5张图片

代价函数是应该是numpy矩阵,所以我们需要转换X和Y,然后才能使用它们。 我们还需要初始化theta,即把theta所有元素都设置为0.

X = np.matrix(X.values)
y = np.matrix(y.values)
# your code here  (appro ~ 1 lines)
theta = np.matrix(np.array([0,0]))

theta 是一个(1,2)矩阵

theta
#输出应该为matrix([[0, 0]])

看下维度

X.shape, theta.shape, y.shape
#((97, 2), (1, 2), (97, 1))

计算代价函数 (theta初始值为0).

computeCost(X, y, theta)
#32.072733877455676

2.batch gradient decent(批量梯度下降)

公式: θ j : = θ j − α ∂ ∂ θ j J ( θ ) {\theta_{j}}:={\theta_{j}}-\alpha \frac{\partial }{\partial {\theta_{j}}}J\left(\theta \right) θj:=θjαθjJ(θ)

def gradientDescent(X, y, theta, alpha, iters):
    temp = np.matrix(np.zeros(theta.shape)) #构建零值矩阵
    parameters = int(theta.ravel().shape[1])# ravel计算需要求解的参数个数 功能将多维数组降至一维
    cost = np.zeros(iters) #构建iters个0的数组
    
    for i in range(iters):
        # your code here  (appro ~ 1 lines)
        error = (X * theta.T) - y
        for j in range(parameters):
            # your code here  (appro ~ 2 lines)
            term = np.multiply(error, X[:,j])#计算两矩阵(hθ(x)-y)x
            temp[0,j] = theta[0,j] - ((alpha / len(X)) * np.sum(term))
            
        # your code here  (appro ~ 2 lines)    
        theta = temp
        cost[i] = computeCost(X, y, theta)
        
    return theta, cost

机器学习作业 1 - 线性回归_第6张图片

初始化一些附加变量 - 学习速率α和要执行的迭代次数。

alpha = 0.01
iters = 1000

现在让我们运行梯度下降算法来将我们的参数θ适合于训练集。

g, cost = gradientDescent(X, y, theta, alpha, iters)
g
# matrix([[-3.24140214,  1.1272942 ]])

最后,我们可以使用我们拟合的参数计算训练模型的代价函数(误差)。

computeCost(X, y, g)
#4.515955503078912

现在我们来绘制线性模型以及数据,直观地看出它的拟合。fig代表整个图像,ax代表实例

x = np.linspace(data.Population.min(), data.Population.max(), 100)#抽100个样本
f = g[0, 0] + (g[0, 1] * x)#g[0,0] 代表theta0 , g[0,1] 代表theta1

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)#显示标签位置
ax.set_xlabel('Population')
ax.set_ylabel('Profit')
ax.set_title('Predicted Profit vs. Population Size')
plt.show()

机器学习作业 1 - 线性回归_第7张图片

由于梯度方程式函数也在每个训练迭代中输出一个代价的向量,所以我们也可以绘制。 请注意,代价总是降低 - 这是凸优化问题的一个例子。

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()

机器学习作业 1 - 线性回归_第8张图片
机器学习作业 1 - 线性回归_第9张图片

3.多变量线性回归

练习1还包括一个房屋价格数据集,其中有2个变量(房子的大小,卧室的数量)和目标(房子的价格)。 我们使用我们已经应用的技术来分析数据集。

path =  'ex1data2.txt'
data2 = pd.read_csv(path, header=None, names=['Size', 'Bedrooms', 'Price'])
data2.head()

机器学习作业 1 - 线性回归_第10张图片

对于此任务,我们添加了另一个预处理步骤 - 特征归一化。 这个对于pandas来说很简单

如果这个房子价格不归一化,它的数量级和你输入值规一化数量级差别太大,几十万的数量级和个位小数做回归,就不能保证收敛了 预测的y和实际上y几十万差的太多了

data2 = (data2 - data2.mean()) / data2.std()
data2.head()

机器学习作业 1 - 线性回归_第11张图片

现在我们重复第1部分的预处理步骤,并对新数据集运行线性回归程序。

# add ones column
data2.insert(0, 'Ones', 1)

# set X (training data) and y (target variable)
cols = data2.shape[1]
X2 = data2.iloc[:,0:cols-1]
y2 = data2.iloc[:,cols-1:cols]

# convert to matrices and initialize theta
X2 = np.matrix(X2.values)
y2 = np.matrix(y2.values)
theta2 = np.matrix(np.array([0,0,0]))

# perform linear regression on the data set
g2, cost2 = gradientDescent(X2, y2, theta2, alpha, iters)

# get the cost (error) of the model
computeCost(X2, y2, g2)

我们也可以快速查看这一个的训练进程。

fig, ax = plt.subplots(figsize=(12,8))
ax.plot(np.arange(iters), cost2, 'r')
ax.set_xlabel('Iterations')
ax.set_ylabel('Cost')
ax.set_title('Error vs. Training Epoch')
plt.show()

机器学习作业 1 - 线性回归_第12张图片
机器学习作业 1 - 线性回归_第13张图片

normal equation(正规方程)(选做)

正规方程是通过求解下面的方程来找出使得代价函数最小的参数的: ∂ ∂ θ j J ( θ j ) = 0 \frac{\partial}{\partial{\theta_{j}}}J\left( {\theta_{j}} \right)=0 θjJ(θj)=0 。假设我们的训练集特征矩阵为 X X X(包含了 x 0 = 1 {{x}_{0}}=1 x0=1)并且我们的训练集结果为向量 y y y,则利用正规方程解出向量 θ = ( X T X ) − 1 X T y \theta ={{\left( {X^T}X \right)}^{-1}}{X^{T}}y θ=(XTX)1XTy 。 上标T代表矩阵转置,上标-1 代表矩阵的逆。设矩阵 A = X T X A={X^{T}}X A=XTX,则: ( X T X ) − 1 = A − 1 {{\left( {X^T}X \right)}^{-1}}={A^{-1}} (XTX)1=A1
梯度下降与正规方程的比较:

梯度下降:需要选择学习率α,需要多次迭代,当特征数量n大时也能较好适用,适用于各种类型的模型

正规方程:不需要选择学习率α,一次计算得出,需要计算 ( ( X T X ) − 1 {{\left( {X^T}X \right)}^{-1}} (XTX)1 ,如果特征数量n较大则运算代价大,因为矩阵逆的计算时间复杂度为 (3) ,通常来说当 小于10000 时还是可以接受的,只适用于线性模型,不适合逻辑回归模型等其他模型

np.linalg.inv求逆操作 @相当于dot() ,dot函数可以通过numpy库调用,也可以由数组实例对象进行调用。a.dot(b) 与 np.dot(a,b)效果相同。

# 正规方程
def normalEqn(X, y):
    # your code here  (appro ~ 1 lines)
    theta = np.linalg.inv(X.T@X)@X.T@y
    return theta
final_theta2=normalEqn(X, y)#感觉和批量梯度下降的theta的值有点差距
final_theta2

梯度下降得到的结果是matrix([[-3.24140214, 1.1272942 ]])

数据集与代码已上传:链接:https://pan.baidu.com/s/1W6zfvhhTzGOo0ShM5yQaAg
提取码:eavl

你可能感兴趣的:(吴恩达机器学习作业记录,机器学习,python,深度学习,人工智能,数据分析)