欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

吴恩达 机器学习课程 coursera 第一次编程作业(Linear Regression Multi) python实现

程序员文章站 2022-07-13 08:52:35
...

本文是吴恩达老师的机器学习课程coursera的第一次编程作业的多变量部分。

 

源码和数据集下载:https://github.com/toanoyx/MachineLearning-AndrewNg-coursera-python/tree/master/ex1%20Linear%20Regression/ex1_multi

 

ex1_multi.py

import numpy as np
from feature_normalize import *
from gradient_descent_multi import *
from normal_eqn import *
import matplotlib.pyplot as plt

'''第1部分 特征缩放'''
print('Loading Data...')
data = np.loadtxt('ex1data2.txt', delimiter=',', dtype=np.int64)  # 加载txt格式数据集 每一行以','分隔
X = data[:, 0:2]  # 得到输入变量矩阵  每个输入变量有两个输入特征
y = data[:, 2]  # 输出变量
m = y.size  # 样本数

# 打印前10个训练样本
print('First 10 examples from the dataset: ')
for i in range(0, 10):
    print('x = {}, y = {}'.format(X[i], y[i]))

input('Program paused. Press ENTER to continue')

# 特征缩放  不同特征的取值范围差异很大  通过特征缩放 使其在一个相近的范围内
print('Normalizing Features ...')

X, mu, sigma = feature_normalize(X)
X = np.c_[np.ones(m), X]  # 得到缩放后的特征矩阵  前面加一列1  方便矩阵运算

'''第2部分 梯度下降法'''
print('Running gradient descent ...')

alpha = 0.03  # 学习率
num_iters = 400  # 迭代次数

theta = np.zeros(3).reshape(-1, 1)  # 初始化参数 转变为列向量 用2维数组表示 避免不必要的麻烦
theta, J_history = gradient_descent_multi(X, y, theta, alpha, num_iters)  # 梯度下降求解参数

# 绘制代价函数值随迭代次数的变化曲线
plt.figure()
plt.plot(np.arange(J_history.size), J_history)
plt.xlabel('Number of iterations')
plt.ylabel('Cost J')
plt.show()

# 打印求解的最优的参数
print('Theta computed from gradient descent : \n{}'.format(theta))

# 预测面积是1650 卧室数是3 的房子的价格

x1 = np.array([1650, 3]).reshape(1, -1)

x1 = (x1 - mu) / sigma  # 对预测样例进行特征缩放

x1 = np.c_[1, x1]  # 前面增加一个1
price = h(x1, theta)  # 带入假设函数 求解预测值

print('Predicted price of a 1650 sq-ft, 3 br house (using gradient descent) : {:0.3f}'.format(price.squeeze()))

'''第3部分 正规方程法求解多元线性回归'''
# 正规方程法不用进行特征缩放

print('Solving with normal equations ...')

# Load data
data = np.loadtxt('ex1data2.txt', delimiter=',', dtype=np.int64)
X = data[:, 0:2]
y = data[:, 2]
m = y.size

# 增加一列特征1
X = np.c_[np.ones(m), X]

theta = normal_eqn(X, y)  # 正规方程法

# 打印求解的最优参数
print('Theta computed from the normal equations : \n{}'.format(theta))

# 预测面积是1650 卧室数是3 的房子的价格

x2 = np.array([1, 1650, 3]).reshape(1, -1)
price = h(x2, theta)  # 带入假设函数 求解预测值

print('Predicted price of a 1650 sq-ft, 3 br house (using normal equations) : {:0.3f}'.format(price.squeeze()))

 

feature_normalize.py

def feature_normalize(X):
    mu = X.mean(axis=0)  # 每一列/特征的均值
    sigma = X.std(axis=0)  # 每一列/特征的标准差
    X_norm = (X - mu) / sigma  # 广播机制

    return X_norm, mu, sigma

 

gradient_descent_multi.py

import numpy as np
from compute_cost import *


def gradient_descent_multi(X, y, theta, alpha, num_iters):
    m = y.size  # 样本数
    J_history = np.zeros(num_iters)  # 每一次迭代都有一个代价函数值
    y = y.reshape(-1, 1)  # 用2维数组表示列向量 (m,1)

    for i in range(0, num_iters):  # num_iters次迭代优化
        theta = theta - (alpha / m) * X.T.dot(h(X, theta) - y)
        J_history[i] = compute_cost(X, y, theta)  # 用每一次迭代产生的参数 来计算代价函数值

    return theta, J_history

 

compute_cost.py

def h(X, theta):  # 线性回归假设函数
    return X.dot(theta)


def compute_cost(X, y, theta):
    m = y.size  # 样本数
    y = y.reshape(-1, 1)  # 转变为列向量 用二维数组表示(m,1)
    cost = 0  # 代价函数值
    myh = h(X, theta)  # 得到假设函数值  (m,1)

    cost = 1 / (2 * m) * (myh - y).T.dot(myh - y)  # [[]]

    return cost[0][0]

 

normal_eqn.py

from numpy.dual import pinv


def normal_eqn(X, y):
    y = y.reshape(-1, 1)
    # theta=inv(X.T.dot(X)).dot(X.T).dot(y)
    theta = pinv(X).dot(y)

    return theta