1. 程式人生 > >機器學習 | 吳恩達機器學習第二週程式設計作業(Python版)

機器學習 | 吳恩達機器學習第二週程式設計作業(Python版)

實驗指導書   下載密碼:hso0

本篇部落格主要講解,吳恩達機器學習第二週的程式設計作業,作業內容主要是實現單元/多元線性迴歸演算法。實驗的原始版本是用Matlab實現的,本篇部落格主要用Python來實現。

 

目錄

1.實驗包含的檔案

2.單元線性迴歸

3.單元線性迴歸完整專案程式碼

4.多元線性迴歸

5.多元線性迴歸完整專案程式碼


1.實驗包含的檔案

檔名稱 含義
ex1.py 單元線性迴歸的主程式
ex1_multi.py 多元線性迴歸主程式
ex1data1.txt 單變數線性迴歸資料集
ex1data2.txt 多變數線性迴歸資料集
plotData.py 視覺化資料集程式
computeCost.py 計算線性迴歸的代價函式程式
gradientDescent.py 梯度下降法程式
featureNormalize.py 特徵縮放程式
normalEqn.py
正規方程求解線性迴歸程式

實驗任務完成紅色部分程式的關鍵程式碼。

2.單元線性迴歸

  • 任務:預測快餐車的收益,輸入變數只有一個特徵是城市的人口,輸出變數是快餐車在該城市的收益。
  • 開啟單元線性迴歸主程式ex1.py
'''第1部分 視覺化訓練集'''
print('Plotting Data...')
data = np.loadtxt('ex1data1.txt', delimiter=',', usecols=(0, 1))#載入txt格式的資料集 每一行以","分隔
X = data[:, 0]   #輸入變數 第一列
y = data[:, 1]   #輸出變數 第二列
m = y.size     #樣本數

plt.ion()
plt.figure(0)
plot_data(X, y)  #視覺化資料集
  • 編寫視覺化程式plotData.py
def plot_data(x, y):
   
    plt.scatter(x,y,marker='o',s=50,cmap='Blues',alpha=0.3)  #繪製散點圖
    plt.xlabel('population')  #設定x軸標題
    plt.ylabel('profits')   #設定y軸標題 

    plt.show()
  • 視覺化效果

  • 使用梯度下降法求解單元線性迴歸

'''第2部分 梯度下降法'''
print('Running Gradient Descent...')

X = np.c_[np.ones(m), X]  # 輸入特徵矩陣 前面增加一列1 方便矩陣運算
theta = np.zeros(2)  # 初始化兩個引數為0  


iterations = 1500  #設定梯度下降迭代次數
alpha = 0.01      #設定學習率

# 計算最開始的代價函式值  並與期望值比較 驗證程式正確性
print('Initial cost : ' + str(compute_cost(X, y, theta)) + ' (This value should be about 32.07)')

#使用梯度下降法求解線性迴歸 返回最優引數 以及每一步迭代後的代價函式值
theta, J_history = gradient_descent(X, y, theta, alpha, iterations)

print('Theta found by gradient descent: ' + str(theta.reshape(2)))

# 在資料集上繪製出擬合的直線
plt.figure(0)
line1, = plt.plot(X[:, 1], np.dot(X, theta), label='Linear Regression')
plt.legend(handles=[line1])

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

# 用訓練好的引數 預測人口為3.5*1000時 收益為多少  並與期望值比較 驗證程式正確性
predict1 = np.dot(np.array([1, 3.5]), theta)
print('For population = 35,000, we predict a profit of {:0.3f} (This value should be about 4519.77)'.format(predict1*10000))
# 用訓練好的引數 預測人口為7*1000時 收益為多少  並與期望值比較 驗證程式正確性
predict2 = np.dot(np.array([1, 7]), theta)
print('For population = 70,000, we predict a profit of {:0.3f} (This value should be about 45342.45)'.format(predict2*10000))
  • 編寫計算線性迴歸代價函式的程式computeCost.py


def h(X,theta):  #線性迴歸假設函式
    return X.dot(theta)
    
def compute_cost(X, y, theta):
    
    m = y.size #樣本數
    cost = 0   #代價函式值
    myh=h(X,theta)  #得到假設函式值  (m,)
    
    cost=(myh-y).dot(myh-y)/(2*m)  #計算代價函式值

    return cost

與期望值進行比較,說明我們編寫的計算代價函式的程式碼是正確的。

  • 編寫梯度下降法程式gradientDescent.py


def gradient_descent(X, y, theta, alpha, num_iters):
    
    m = y.size #樣本數 
    J_history = np.zeros(num_iters)  #每一次迭代都有一個代價函式值

    for i in range(0, num_iters):   #num_iters次迭代優化
        theta=theta-(alpha/m)*(h(X,theta)-y).dot(X)
        J_history[i] = compute_cost(X, y, theta) #用每一次迭代產生的引數 來計算代價函式值

    return theta, J_history

梯度下降法求解的最優引數值:

利用訓練好的引數進行預測,與期望值進行比較,驗證我們的程式是正確的:

在資料集上視覺化擬合的直線:

  • 根據不同的引數取值,視覺化代價函式
'''第3部分 視覺化代價函式'''
print('Visualizing J(theta0, theta1) ...')

theta0_vals = np.linspace(-10, 10, 100)  #引數1的取值
theta1_vals = np.linspace(-1, 4, 100)    #引數2的取值

xs, ys = np.meshgrid(theta0_vals, theta1_vals)   #生成網格
J_vals = np.zeros(xs.shape)


for i in range(0, theta0_vals.size):
    for j in range(0, theta1_vals.size):
        t = np.array([theta0_vals[i], theta1_vals[j]])
        J_vals[i][j] = compute_cost(X, y, t)    #計算每個網格點的代價函式值

J_vals = np.transpose(J_vals)

fig1 = plt.figure(1)      #繪製3d圖形
ax = fig1.gca(projection='3d')
ax.plot_surface(xs, ys, J_vals)
plt.xlabel(r'$\theta_0$')
plt.ylabel(r'$\theta_1$')

#繪製等高線圖 相當於3d圖形的投影
plt.figure(2)
lvls = np.logspace(-2, 3, 20)
plt.contour(xs, ys, J_vals, levels=lvls, norm=LogNorm())
plt.plot(theta[0], theta[1], c='r', marker="x")

視覺化效果:

 

3.單元線性迴歸完整專案程式碼

下載連結   下載密碼:d8dd

4.多元線性迴歸

  • 任務:預測房價,輸入變數有兩個特徵,一是房子的面積,二是房子臥室的數量;輸出變數是房子的價格。
  • 開啟多元線性迴歸主程式ex1_multi.py

'''第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  方便矩陣運算
  • 編寫特徵縮放程式featureNormalize.py
def feature_normalize(X):
   
    n = X.shape[1]  # shape[1]返回特徵矩陣列數 即特徵數
    X_norm = X     #初始化特徵縮放後的特徵矩陣
    mu = np.zeros(n)  #初始化每一列特徵的均值
    sigma = np.zeros(n)  #初始化每一列特徵的標準差

    mu=np.mean(X,axis=0) #對每一列求均值
    sigma=np.std(axis=0) #對每一列求標準差
    X_norm=(X_norm-mu)/sig #廣播 每一列減去該列的均值/該列的標準差

    return X_norm, mu, sigma
  • 使用梯度下降法求解最優引數並進行預測,繪製代價函式隨迭代次數的變化曲線

'''第2部分 梯度下降法'''



print('Running gradient descent ...')


alpha = 0.03  #學習率
num_iters = 400 #迭代次數


theta = np.zeros(3)#初始化引數
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')

# 列印求解的最優的引數
print('Theta computed from gradient descent : \n{}'.format(theta))

# 預測面積是1650 臥室數是3 的房子的價格

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

x1=(x1-mu)/sigma  #對預測樣例進行特徵縮放
x1=np.r_[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))
  • 編寫計算線性迴歸代價函式的程式computeCost.py


def h(X,theta):  #線性迴歸假設函式
    return X.dot(theta)
    
def compute_cost(X, y, theta):
    
    m = y.size #樣本數
    cost = 0   #代價函式值
    myh=h(X,theta)  #得到假設函式值  (m,)
    
    cost=(myh-y).dot(myh-y)/(2*m)  #計算代價函式值

    return cost
  • 編寫梯度下降法程式gradientDescent.py


def gradient_descent_multi(X, y, theta, alpha, num_iters):
    
    m = y.size #樣本數 
    J_history = np.zeros(num_iters)  #每一次迭代都有一個代價函式值

    for i in range(0, num_iters):   #num_iters次迭代優化
        theta=theta-(alpha/m)*(h(X,theta)-y).dot(X)
        J_history[i] = compute_cost(X, y, theta) #用每一次迭代產生的引數 來計算代價函式值

    return theta, J_history

 

  • 梯度下降法求解的最優引數,樣例的預測價格以及代價函式隨迭代次數的變化曲線

  • 利用正規方程法求解多元線性迴歸,並預測樣例的房價
'''第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])
price = h(x2,theta) #帶入假設函式 求解預測值


# ==========================================================

print('Predicted price of a 1650 sq-ft, 3 br house (using normal equations) : {:0.3f}'.format(price))
  • 編寫正規方程法程式 normalEqn.py

def normal_eqn(X, y):
    theta = np.zeros((X.shape[1], 1))

    theta=inv(X.T.dot(X)).dot(X.T).dot(y)


    return theta
  • 正規方程法求解的最優引數,和預測樣例的房價

可以看到兩種方法預測的房價差不多。

5.多元線性迴歸完整專案程式碼

下載連結    下載密碼:cz04