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;
輕鬆求得預測結果。這裡我和數據集比對了一下,還是比較相近的,可信度高。
參考博客:
Andrew Ng機器學習week2(Linear Regression)編程習題Andrew Ng機器學習week2(Linear Regression)編程習題4.總結
到這裡,Week2的作業就詳解完畢了。
完整的代碼更新在我的Github上:nutllwhy/Machine-Learning
我是通過Coursera申請獎學金獲得的免費學習資源,包括視頻課,作業等,完成所有課程之後會頒發一個有一定認證力度的證書。
至於如何使用Coursera,我打算等全部學完之後,再寫一篇告知大家。
當然也可以加群來問我:
http://qm.qq.com/cgi-bin/qm/qr?k=gkmO4zpfyb1pogycjvmt1eexC6slldeL (二維碼自動識別)
歡迎討論。
推薦閱讀:
※我的機器學習計算資源
※譜聚類的consistency
※如何向普通人解釋機器學習、數據挖掘
※台灣李宏毅老師機器學習ML 第一課 回歸Regression
TAG:機器學習 |