標籤:

Andrew Ng機器學習week 2(Linear Regression)編程作業詳解

先介紹一下,編程作業分為兩部分,必做和選做。

必做部分通過ex1.m來作為主函數執行,選做部分通過ex1_multi.m作為主函數執行。

必做的部分包括提交練習,單參數的梯度優化實踐,全部做完 本周就算通過了,系統會給你的程序打分。選做部分是多參數的梯度優化實踐,正規方程實踐,做完了不會打分,只會顯示「Nice work!」

1.Simple Octave/MATLAB function

首先是一個簡單的示例,這個在視頻中有示範過。

在warmUpExercise.m文件中編輯:

A = eye(5);

保存之後,在Octave窗口中輸入「ex1」來執行文件。

輸出的一個是一個5*5的單位矩陣。(emmmm....不知道為什麼我的單位矩陣是歪的)

這步完成之後,可以根據視頻里的提交步驟嘗試進行第一次作業提交。

2.Linear regression with one variable

下一步,我們嘗試用Octave繪圖。

根據指導文件的提示,我們在plotData.m文件中寫上:

plot(x, y, rx, MarkerSize, 10); %Plot the dataylabel(Profit in $10,000s); %Set the y-axis labelxlabel(Population of City in 10,000s); %Set the x-axis label

plot是繪圖函數,因為這裡是單參數,所以X和y都是m維的向量,「rx」表示用紅色叉號符來標記數據,「MakerSize」指定標識符大小,繪製出離散的點。

保存,再回到Octave的命令窗口界面運行「ex1」,可以得到下圖:

把數據準備好了,我們要計算代價函數了,這裡主要用到了兩個公式:

這一步開始,指導文件中不會再給出代碼了,你要自己思考怎麼通過公式實現功能。

我們先通過computeCost.m來計算損失函數J(θ)

根據文件中給出的兩個條件,再結合已知的公式,還是很容易能推算出這一步的程序。在這個文件中,輸入以下代碼能過關:

J = (sum ((X * theta - y) .^ 2)) / (2*m)

注意運用括弧規定運算順序。

如果代價函數J沒算錯的話,

當θ取[0;0]的時候,J=32.073

當θ取[-1;2]的時候,J=54.242

代價函數算好,終於要來實踐梯度下降了。這裡我們用到了以下這個公式:

按這個式子的話,用以下這行代碼可以通關:

theta = theta - (alpha/m) * (X * (X * theta - y ));

但是我當初做的時候有點懵逼,主要是沒想通最後一個x到底是什麼,該怎麼乘上去。

我繞了點路,根據網上查到的做法反向推理,再結合自己的筆記,找到了這個式子:

用這個式子的話,就是以下這部分代碼:

temp_theta = theta; % Save the theta from the last iteration% Update theta0 theta(1) = temp_theta(1) - (alpha/m) * (sum(X * temp_theta - y));%Update theta1theta(2) = temp_theta(2) - (alpha/m) * (sum((X * temp_theta - y) .* X(:,2)));

Octave裡頭是從1開始計數的,所以是theta(1),theta(2),從我們CS學科的通用理解,其實就是θ(0)和θ(1)。但是要注意一下,這段代碼,只能在單因素的時候用,下一部分多因素假設,是不能用這段代碼求θ的。

這步完成,我們就能看到擬合出來的結果啦!

執行過程中我們可以觀察到J不斷下降,直至數值漸漸平穩。

接著我們就可以在屏幕上看到通過我們的程序,得到的預測結果:

預測結果

可以打開ex1data1.txt文件,掃一眼數值大小,還是可以看出我們的估計算是比較靠譜的。

接下來不用你動手改代碼,繼續執行ex1,會展示一個網格圖,這個圖是根據你剛剛編寫的computeCost函數,不斷迭代J的值得到的效果,繪圖函數寫在ex1.m里,可以找到。

在我沒搞清楚computeCost函數怎麼寫的時候,嘗試過執行到這一步,圖二的紅叉叉很明顯沒到中間的位置,只有現在這麼寫了,才會回到中間,也就意味著我得到局部最小值了。

不過我的圖一顏色沒有引導文件里那麼豐富多彩,不清楚是為什麼,希望有執行出彩虹色的同學可以指正一下我的錯誤點。

以上,必做部分結束。

3.Linear regression with multiple variable

接下來是選做部分,我們要開始嘗試多因素的假設。

這裡用的示例數據和視頻課里比較接近,ex1data2.txt里是房屋的面積、房間數和房屋價格。

首先,根據視頻課的內容我們知道,如果要對多因素假設使用梯度下降,必須先對數據進行特徵縮放。

我們通過讓每個輸入值在大致相同的範圍內加速梯度下降。因為θ會在小範圍內迅速下降,在大範圍內緩慢下降。當變數非常不均勻的時候,θ會低效地下降到最佳值(可能要反覆迂迴才能達到局部最小)」

目的就是使偏移狀態減輕。縮小參數落在的區間。

這裡我們在featureNormalize.m函數中實現該功能,用到的公式如下:

根據提示,在Octave中可以使用mean函數求得平均值,使用std函數求得標準偏差。填入以下這段代碼可以通關:

len = length(X);mu = mean(X);sigma = std(X);X_norm = (X - ones(len, 1) * mu) ./ (ones(len, 1) * sigma);

保存後,執行ex1_multi.m文件,查看效果。

特徵縮放之前的數據

特徵縮放之後

然後我們可以去修改computeCostMulti.m和gradientDescentMulti.m這兩個函數了,如果在上一部分你填入的執行模塊是通用的話,在這段直接複製進來就好。

引導文件里多提了一句,在多因素假設下,損失函數也可以用下面這個矢量化形式得出:

那麼轉換成代碼,就是這樣表示:

J = (((X * theta) - y)) * ((X * theta) - y) / (2*m)

我試了一下,的確算出來一樣。

下一步,我們選擇最佳的學習率α。

在ex1_multi.m中,默認的α大小為0.01(在大概80幾行設置),我們可以通過調整這個值觀察不同學習率下圖像效果。引導文件中給了一個推薦的圖像,是迭代50次的效果圖。源代碼中設置的是迭代400次,我這裡也跟著教程修改了一下。

最後,學習率α調到0.13的時候,和引導文件給出的圖像比較相近。

接下來,我們要自己寫預測價格那一塊,要求預測1650公頃,3個房間的房子的價格。

仿照上一節中的代碼,可以輕鬆寫出代碼:

price = [1 1650 3] * theta; % You should change this

但是我發現了一個很大的問題,就是我得出的數據明顯比給出的示例圖要大個三次的數量級,最後預測出來的結果也異常的大。

這是我寫這篇詳解的動力所在。。。

希望實踐到這步的你們,能找出我的錯誤,在評論區或者私信聯繫我。

可以看到預測的數值明顯偏大

視頻中還提到另外一種方案,能夠一次性求解θ的最優值——正規方程(Normal Equation)。

這步直接給出了公式,轉換成代碼也很簡單,在normalEqn.m中增加如下代碼即可:

theta = (pinv(X * X)) * X * y;

輕鬆求得預測結果。這裡我和數據集比對了一下,還是比較相近的,可信度高。

Normal Equation的預測結果

參考博客:

Andrew Ng機器學習week2(Linear Regression)編程習題?

www.cnblogs.com

Andrew Ng機器學習week2(Linear Regression)編程習題?

www.voidcn.com

4.總結

到這裡,Week2的作業就詳解完畢了。

完整的代碼更新在我的Github上:nutllwhy/Machine-Learning

我是通過Coursera申請獎學金獲得的免費學習資源,包括視頻課,作業等,完成所有課程之後會頒發一個有一定認證力度的證書。

至於如何使用Coursera,我打算等全部學完之後,再寫一篇告知大家。

當然也可以加群來問我:

qm.qq.com/cgi-bin/qm/qr? (二維碼自動識別)

歡迎討論。

推薦閱讀:

我的機器學習計算資源
譜聚類的consistency
如何向普通人解釋機器學習、數據挖掘
台灣李宏毅老師機器學習ML 第一課 回歸Regression

TAG:機器學習 |