機器學習 | 吳恩達機器學習第二週程式設計作業(Python版)
阿新 • • 發佈:2018-11-12
實驗指導書 下載密碼:hso0
本篇部落格主要講解,吳恩達機器學習第二週的程式設計作業,作業內容主要是實現單元/多元線性迴歸演算法。實驗的原始版本是用Matlab實現的,本篇部落格主要用Python來實現。
目錄
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