ex I-代码实现

单变量线性回归

在本部分的练习中,您将使用一个变量实现线性回归,以预测食品卡车的利润。假设你是一家餐馆的首席执行官,正在考虑不同的城市开设一个新的分店。该连锁店已经在各个城市拥有卡车,而且你有来自城市的利润和人口数据。

您希望通过使用这些数据来帮助您扩展到下一个城市;

Step1: Prepare datasets

按照吴老师上课时候所说的来准备数据,取最后一列为目标向量,剩余列为输入矩阵X,最重要的是记得在第一列加入新的一列,数值全部为1

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

'''
单变量线性回归
1.Prepare datasets
'''
path = 'ex1data1.txt'
data = pd.read_csv(path, header=None, names=['Population', 'Profit'])   # names添加列名,header用指定的行来作为标题,若原无标题且指定标题则设为None
data.head()         # head()查看前5行,若为-1,则查看至倒数第二行
# print(data.head())
data.describe()     # describe快速统计汇总数据内容 
# print(data.describe())
# 展示散点图,可视化理解数据
# data.plot(kind='scatter', x='Population', y='Profit', figsize=(8, 5))
# plt.show()

data.insert(0, 'Ones', 1)       # 加入至第一列,全部数值为1
# print(data)

# 变量初始化:set X (training data) and y (target variable)
cols = data.shape[1]  # 列数
X = data.iloc[:, 0:cols - 1]        # iloc根据位置索引选取数据,先行后列,取前cols-1列作为输入向量
y = data.iloc[:, cols - 1:cols]     # 取最后一列作为目标向量
# print(X.head())
# print(y.head())

X = np.matrix(X.values)
y = np.matrix(y.values)
theta = np.matrix([0, 0])
print(X.shape, y.shape, theta.shape)  # 查看各自的行列数
Step2: Design model using Gradient Descent

首先, 我们将创建一个以参数吴恩达机器学习jupyter notebook代码 吴恩达 python_python为特征函数的代价函数
吴恩达机器学习jupyter notebook代码 吴恩达 python_人工智能_02
其中: 吴恩达机器学习jupyter notebook代码 吴恩达 python_python_03
计算代价函数 吴恩达机器学习jupyter notebook代码 吴恩达 python_人工智能_04

'''
2.Design model using Gradient Descent
'''
def computeCost(X, y, theta):
    '''
    作用:计算代价函数,向量化来计算参数
    :param X: 输入矩阵
    :param y: 输出目标
    :param theta: parameters
    :return:
    '''
    inner = np.power(((X * theta.T) - y), 2)
    # print(inner)
    return sum(inner) / (2 * len(X))


# testing
# computeCost(X, y, theta)  # 32.07273388

注意:这里我使用的是matix而不是array,两者基本通用。

但是matrix的优势就是相对简单的运算符号,比如两个矩阵相乘,就是用符号*,但是array相乘不能这么用,得用方法.dot()
array的优势就是不仅仅表示二维,还能表示3、4、5…维,而且在大部分Python程序里,array也是更常用的。

两者区别:

对应元素相乘:matrix可以用np.multiply(X2,X1),array直接X1X2
点乘:matrix直接X1
X2,array可以 X1@X2 或 X1.dot(X2) 或 np.dot(X1, X2)
代价函数是应该是numpy矩阵,所以我们需要转换X和Y,然后才能使用它们。 我们还需要初始化theta。

优化:
吴恩达机器学习jupyter notebook代码 吴恩达 python_数据_05
使用 vectorization同时更新所有的 吴恩达机器学习jupyter notebook代码 吴恩达 python_python, 可以大大提高效率

def gradientDescent(X, y, theta, alpha, epoch):
    '''
    作用:获得最终梯度下降后的theta值以及cost
    :param X:
    :param y:
    :param theta:
    :param alpha:
    :param epoch:
    :return:
    '''
    # 变量初始化,储存数据
    temp = np.matrix(np.zeros(theta.shape))  # 初始化一个临时矩阵(1, 2)
    # flatten()即返回一个折叠成一维的数组。但是该函数只能适用于numpy对象,即array或者mat,普通的list列表是不行的。
    parameters = int(theta.flatten().shape[1])  # 参数theta的数量
    cost = np.zeros(epoch)  # 初始化一个ndarray, 包含每次训练后的cost
    counterTheta = np.zeros((epoch, 2))
    m = X.shape[0]  # 样本参数

    for i in range(epoch):
        '''
        使用 vectorization同时更新所有的θ,可以大大提高效率,此处都是相对应的进行计算
        X.shape, theta.shape, y.shape, X.shape[0]
        ((97, 2), (1, 2), (97, 1), 97)
        '''
        temp = theta - (alpha / m) * (X * theta.T - y).T * X

        # 以下是不用Vectorization求解梯度下降
        # error = (X * theta.T) - y  # (97, 1)
        # for j in range(parameters):
        #    term = np.multiply(error, X[:,j])  # (97, 1)
        #    temp[0,j] = theta[0,j] - ((alpha / m) * np.sum(term))  # (1,1)

        theta = temp
        counterTheta[i] = theta
        cost[i] = computeCost(X, y, theta)
        pass
    return counterTheta, theta, cost
Step3: Run model and Plot

最后一步就是将准备好的数据输入到相应的模型,得出两个图,第一个图是拟合数据图,第二个图是代价图

'''
3.Run model and Plot
'''

alpha = 0.01
epoch = 3800

counterTheta, final_theta, cost = gradientDescent(X, y, theta, alpha, epoch)
computeCost(X, y, final_theta)

x = np.linspace(data.Population.min(), data.Population.max(), 100)  # xlabel
f = final_theta[0, 0] + (final_theta[0, 1] * x)  # ylabel profit

fig1, ax = plt.subplots(figsize=(6, 4))
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')

fig2, ax = plt.subplots(figsize=(8, 4))
ax.plot(np.arange(epoch), cost, 'r')
ax.set_xlabel('Iteration')
ax.set_ylabel('Cost')
ax.set_title('Error vs. Training Epoch')
plt.show()

吴恩达机器学习jupyter notebook代码 吴恩达 python_代价函数_07

可以看出来拟合的相当不错

吴恩达机器学习jupyter notebook代码 吴恩达 python_机器学习_08

最后大概是收敛到4.47左右,如以下图

吴恩达机器学习jupyter notebook代码 吴恩达 python_机器学习_09

使用别的方法同样可以达到以上成果
1.normal equation(正规方程)

吴恩达机器学习jupyter notebook代码 吴恩达 python_人工智能_10

梯度下降与正规方程的比较:

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

正规方程:不需要选择学习率 吴恩达机器学习jupyter notebook代码 吴恩达 python_代价函数_11, 一次计算得出, 需要计算 吴恩达机器学习jupyter notebook代码 吴恩达 python_人工智能_12, 如果特征数量n较大则运算代 价大,因为矩阵逆的计算时间复杂度为 吴恩达机器学习jupyter notebook代码 吴恩达 python_代价函数_13, 通常来说当 吴恩达机器学习jupyter notebook代码 吴恩达 python_代价函数_14

def normalEqu(X, y):
    theta = np.linalg.inv(X.T@X)@X.T@y      # X.T@X等价于X.T.dot(X)
    return theta

final_theta2 = normalEqu(X, y)

x = np.linspace(data.Population.min(), data.Population.max(), 100)  # xlabel
f = final_theta[0, 0] + (final_theta[0, 1] * x)  # ylabel profit

fig3, ax = plt.subplots(figsize=(6, 4))
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()

吴恩达机器学习jupyter notebook代码 吴恩达 python_python_15

调用sklearn库来进行拟合

接着上面代码来

from sklearn import linear_model

'''
2.Design model using sklearn
'''
model = linear_model.LinearRegression()
model.fit(X, y)
# print(X)
# print(X[:, 1].A1.shape)
x = np.array(X[:, 1].A1)    # numpy.matrix[:, 1].A1-->取矩阵的第二列 转换成一维的
f = model.predict(X).flatten()  # 预测之后也转换成一维的

fig, ax = plt.subplots(figsize=(8, 5))
ax.plot(x, f, 'r', label='Prediction')
ax.scatter(data.Population, data.Profit, label='Traning Data')
ax.legend(loc=2)
ax.set_xlabel('Population')
ax.set_ylabel('Profit')
ax.set_title('Predicted Profit vs. Population Size')
plt.show()

吴恩达机器学习jupyter notebook代码 吴恩达 python_机器学习_16

多向量线性回归

这是ex1中另外一组数据,是多维的数据,其中包括房子的大小,以及卧室的多少,这个时候可以运用到一个小技巧就是特征值归一化

具体的不多说,看代码和图,可直接复制并且运行.

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

'''
多变量线性回归
1.Prepare datasets
'''
path = 'ex1data2.txt'
data = pd.read_csv(path, header=None, names=['Size', 'Bedroom', 'Price'])   # names添加列名,header用指定的行来作为标题,若原无标题且指定标题则设为None
data.head()         # head()查看前5行,若为-1,则查看至倒数第二行
# print(data.head)
# 预处理-特征值归一化
data = (data - data.mean())/data.std()      # std为标准差
data.head()
# print(data.head)
# add ones column
data.insert(0, 'Ones', 1)

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

# convert to matrices and initialize theta
X = np.matrix(X.values)
y = np.matrix(y.values)
theta = np.matrix(np.array([0, 0, 0]))

'''
2.Design model using Gradient Descent
'''


def computeCost(X, y, theta):
    '''
    作用:计算代价函数,向量化来计算参数
    :param X: 输入矩阵
    :param y: 输出目标
    :param theta: parameters
    :return:
    '''
    inner = np.power(((X * theta.T) - y), 2)
    # print(inner)
    return sum(inner) / (2 * len(X))


# testing
# computeCost(X, y, theta)  # 32.07273388


def gradientDescent(X, y, theta, alpha, epoch):
    '''
    作用:获得最终梯度下降后的theta值以及cost
    :param X:
    :param y:
    :param theta:
    :param alpha:
    :param epoch:
    :return:
    '''
    # 变量初始化,储存数据
    temp = np.matrix(np.zeros(theta.shape))  # 初始化一个临时矩阵(1, 2)
    # flatten()即返回一个折叠成一维的数组。但是该函数只能适用于numpy对象,即array或者mat,普通的list列表是不行的。
    parameters = int(theta.flatten().shape[1])  # 参数theta的数量
    cost = np.zeros(epoch)  # 初始化一个ndarray, 包含每次训练后的cost
    counterTheta = np.zeros((epoch, 3))
    m = X.shape[0]  # 样本参数

    for i in range(epoch):
        '''
        使用 vectorization同时更新所有的θ,可以大大提高效率,此处都是相对应的进行计算
        X.shape, theta.shape, y.shape, X.shape[0]
        ((97, 2), (1, 2), (97, 1), 97)
        '''
        temp = theta - (alpha / m) * (X * theta.T - y).T * X

        # 以下是不用Vectorization求解梯度下降
        # error = (X * theta.T) - y  # (97, 1)
        # for j in range(parameters):
        #    term = np.multiply(error, X[:,j])  # (97, 1)
        #    temp[0,j] = theta[0,j] - ((alpha / m) * np.sum(term))  # (1,1)

        theta = temp
        counterTheta[i] = theta
        cost[i] = computeCost(X, y, theta)
        pass
    return counterTheta, theta, cost


'''
3.Run model and Plot
'''

alpha = 0.01
epoch = 3800

counterTheta, final_theta, cost = gradientDescent(X, y, theta, alpha, epoch)
computeCost(X, y, final_theta)

fig2, ax = plt.subplots(figsize=(8, 4))
ax.plot(np.arange(epoch), cost, 'r')
ax.set_xlabel('Iteration')
ax.set_ylabel('Cost')
ax.set_title('Error vs. Training Epoch')
plt.show()

吴恩达机器学习jupyter notebook代码 吴恩达 python_人工智能_17