本文是吳恩達《機器學習》影片筆記第29篇,對應第2周第11個影片。
“Octave Tutorial——Computing on data”
上一個影片學習瞭如何將資料裝入矩陣中,本次影片講解Octave對資料的基本運算方法。
初始化幾個待會要用到的矩陣定義3個矩陣,3×2的A和B、2×2的C
octave:1> A = [1 2; 3 4; 5 6]A = 1 2 3 4 5 6octave:2> B = [11 12; 13 14; 15 16]B = 11 12 13 14 15 16octave:3> C = [1 1; 2 2]C = 1 1 2 2
矩陣的運算矩陣乘法,m*n的矩陣和一個n*n的矩陣相乘。A*C
octave:4> A * Cans = 5 5 11 11 17 17
還有一種比較有意思的運算,將一個矩陣中的所有元素與另一個和它形狀相同的矩陣的每個元素對應相乘。用到的運算子號是“.*“,翻一番前面A和B的初識值,就知道這個是什麼意思了。
octave:5> A .* Bans = 11 24 39 56 75 96
需要注意的是:上面的這些計算其實都沒有改變運算子兩邊的矩陣的值,它們僅僅是進行了一個運算得到了一個結果,僅此而已,運算完之後A還是原來那個A、B還是原來的那個B。下面的運算也類似,當然你可以把這個結果賦給一個變數,把它儲存到記憶體中。
類似的,還可以使用“.^”運算將矩陣中的每個元素都求平方,如:
octave:7> A .^ 2ans = 1 4 9 16 25 36
再定義一個列向量,
octave:8> v= [1; 2; 3]v = 1 2 3
如果想要得到一個矩陣或向量中所有元素的倒陣列成的新的矩陣或者向量,方法類似。
octave:5> 1 ./ vans = 1.00000 0.50000 0.33333octave:6> 1 ./ Aans = 1.00000 0.50000 0.33333 0.25000 0.20000 0.16667
同樣的,像log()、exp()、abs()都可以往上招呼,都是對矩陣或向量的每個元素進行運算的。
還可以這樣:
octave:9> v + ones(length(v),1)ans = 2 3 4
更多的矩陣操作
轉置,就是加個單引號就行了:
octave:10> A'ans = 1 3 5 2 4 6octave:11> A''ans = 1 2 3 4 5 6
如果轉置兩次,就又轉回來了。
好,再定義一個行向量,帶小數點的:
octave:12> a=[1 15 2 0.5]a = 1.00000 15.00000 2.00000 0.50000
可以使用max函式獲取a的最大值、及最大值所在的位置。
octave:14> [val,in]=max(a)val = 15in = 2
如果把max函式作用在矩陣上,就會得到每一列上的最大值,及所在的位置。
octave:17> X = [1 3; 1 5; 2 2]X = 1 3 1 5 2 2octave:18> [val in]=max(X)val = 2 5in = 3 2
然後,看一下邏輯運算也比較好玩。
octave:19> aa = 1.00000 15.00000 2.00000 0.50000octave:20> a>3ans = 0 1 0 0
如果用“a>3"這樣的表示式,會把a的每一個元素和3比較,返回一個和a形狀一樣的行向量,對應的每個元素是邏輯表示式的結果。
還可以用這樣的邏輯表示式加上find函式,巧妙地查詢一些元素。
octave:23> aa = 1.00000 15.00000 2.00000 0.50000octave:24> find(a < 3)ans = 1 3 4
find(a<3)這行命令,找到了a中所有小於3的元素的標號。
magic函式magic函式比較有意思,它會生成一個每行、每列、兩個對角線上的元素的和都一樣的一個方陣。如:
octave:25> A = magic(3)A = 8 1 6 3 5 7 4 9 2
magic看著挺炫,實際上好像也沒啥用。
sum、prod、floor、ceil函式如果想求向量所有元素的和就可以用sum函式,如果想求所有元素的乘積呢?就可以用prod函式。
octave:26> aa = 1.00000 15.00000 2.00000 0.50000octave:27> sum(a)ans = 18.500octave:28> prod(a)ans = 15
還有地板求整和天花板求整:
octave:29> floor(a)ans = 1 15 2 0octave:30> ceil(a)ans = 1 15 2 1
值得注意的是,向下(地板)取整、向上(天花板)取整並不是四捨五入。
rand函式生成隨機數(矩陣)的函式
octave:33> rand(3)ans = 0.161875 0.332942 0.717015 0.518125 0.629254 0.128823 0.512882 0.966183 0.093146
max函式
一個矩陣,可以按列找出每一列的最大值組成一個行、也可以按行找出每行的最大值組成一個列。
octave:37> max(A,[],1)ans = 8 9 7octave:38> max(A,[],2)ans = 8 7 9
如果要想找整個矩陣的最大值怎麼辦呢?可以這樣:
octave:39> max(max(A))ans = 9octave:40> max(A(:))ans = 9
上面兩種方法都可行。
一個小技巧我們再來定義一個9*9的magic矩陣。
octave:41> A = magic(9)A = 47 58 69 80 1 12 23 34 45 57 68 79 9 11 22 33 44 46 67 78 8 10 21 32 43 54 56 77 7 18 20 31 42 53 55 66 6 17 19 30 41 52 63 65 76 16 27 29 40 51 62 64 75 5 26 28 39 50 61 72 74 4 15 36 38 49 60 71 73 3 14 25 37 48 59 70 81 2 13 24 35
那我們怎樣驗證magic的行、列、正負對角線的和都相同呢?
按列求和、按行求和比較簡單,分別用sum(A,1)、sum(A,2)
octave:42> sum(A,1)ans = 369 369 369 369 369 369 369 369 369octave:43> sum(A,2)ans = 369 369 369 369 369 369 369 369 369
那對角線求和該怎麼辦呢?
需要想辦法把矩陣的兩個對角線給提出來,需要先構造一個單位陣,然後想法把它點乘到A上,就可以把A的對角線拿出來。然後單位陣轉個90°,就可以把斜對角線也拿出來了,如:
我把過程拆細一點:
octave:44> eye(9)ans =Diagonal Matrix 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 1octave:45> A .* eye(9)ans = 47 0 0 0 0 0 0 0 0 0 68 0 0 0 0 0 0 0 0 0 8 0 0 0 0 0 0 0 0 0 20 0 0 0 0 0 0 0 0 0 41 0 0 0 0 0 0 0 0 0 62 0 0 0 0 0 0 0 0 0 74 0 0 0 0 0 0 0 0 0 14 0 0 0 0 0 0 0 0 0 35octave:46> sum(A .* eye(9))ans = 47 68 8 20 41 62 74 14 35octave:47> sum(sum(A .* eye(9)))ans = 369
類似的,把eye矩陣縱向翻轉之後再來計算A的斜對角線的和。
octave:48> flipud(eye(9))ans =Permutation Matrix 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0octave:49> sum(sum(A .* flipud(eye(9))))ans = 369octave:50>
求逆矩陣
這個比較簡單,用函式pinv即可,
octave:50> A = magic(3)A = 8 1 6 3 5 7 4 9 2octave:51> temp = pinv(A)temp = 0.147222 -0.144444 0.063889 -0.061111 0.022222 0.105556 -0.019444 0.188889 -0.102778octave:52> A * tempans = 1.00000 -0.00000 0.00000 0.00000 1.00000 -0.00000 -0.00000 0.00000 1.00000
關於資料運算就到這裡,下一個影片講解資料視覺化。