天天看點

機器學習(三) 線性代數-矩陣機器學習(三) 線性代數-矩陣

機器學習(三) 線性代數-矩陣

矩陣

矩陣是一個二維的資料集合。我們将矩陣表示為清單的清單,每個内部清單的大小都一樣,表示矩陣的一行。如果A是一個矩陣,那麼

A[i][j]

就表示第i行第j列的元素。

按照數學表達的慣例,我們通常用大寫字母表示矩陣。例:

A = [[1,2,3], # A有2行3列
     [4,5,6]]
B = [[1,2],  # B有3行2列
     [3,4],
     [5,6]]
           

數學中,矩陣的第一行通常稱為"第一行",第一列通常稱為"第一列"。我們需要将矩陣的形式和python的清單統一:python中的清單從0開始索引,是以,我們将矩陣第一行通常稱為"第0行",第一列通常稱為"第0列"。

基于清單的清單這種表達形式,矩陣A具有len(A)和len(A[0])列,這種稱為形狀。

def shape(A):
    num_rows = len(A)
    num_cols = len(A[0]) if A else 0   #第一行中元素的個數
    return num_rows,num_cols
A = [[1,2], 
     [3,4],
     [5,6]]
shape(A)
           

如果一個矩陣有n行k列,則可以記為n x k矩陣。我們可以把這個n x k矩陣的每一行都當作一個長度為k的向量,把每一列都當作一個長度為n的向量。

def get_row(A,i):
    return A[i]   # A[i]是第i行
def get_column(A,j):
    return [A_i[j] for A_i in A]  #每個A_[i]行的第j個元素
get_row(A,2)
[5,6]
get_column(A,1)
[2,4,6]
           

我們也可以根據形狀和用來生成元素的函數來建立矩陣,這裡舉個建立機關矩陣(對角線元素是1,其他元素是0)的例子:

def entry_fn(i,j):
    return 1 if i==j else 0
  
def make_matrix(num_rows,num_cols,entry_fn):
    return [[entry_fn(i,j) for j in range(num_cols)]for i in range(num_rows)]
  
make_matrix(5,5,entry_fn)
           

結果如下:

[[1, 0, 0, 0, 0],
 [0, 1, 0, 0, 0],
 [0, 0, 1, 0, 0],
 [0, 0, 0, 1, 0],
 [0, 0, 0, 0, 1]]
           

矩陣很重要:

1.通過把每個向量看出是矩陣的一行,矩陣表示一個包含多元向量的資料集。

例如:有10萬人的身高、體重和年齡,就可以建立一個100000 x 3的矩陣,不會在markdown中輸入數學符号,點這裡:

​ [ 174 62 25 169 65 30 ⋮ ⋮ ⋮ 176 61 29 ] ​ \begin{bmatrix}174&62&25\\169&65&30\\\vdots&\vdots&\vdots\\176&61&29\end{bmatrix}​ ⎣⎢⎢⎢⎡​174169⋮176​6265⋮61​2530⋮29​⎦⎥⎥⎥⎤​​

2.可以用n x k矩陣表示一個線性函數,這個函數将一個k維的向量映射到一個n維的向量上。

{ Y 1 = β 1 X 11 + β 2 X 21 + β 3 X 31 + ⋯ + β k X k 1 Y 2 = β 1 X 12 + β 2 X 22 + β 3 X 32 + ⋯ + β k X k 2 ⋯ ⋯ ⋯ ⋯ ⋯ ⋯ ⋯ ⋯ ⋯ ⋯ ⋯ ⋯ ⋯ ⋯ Y n = β 1 X 1 n + β 2 X 2 n + β 3 X 3 n + ⋯ + β k X k n ​ \begin{cases}Y_1=\beta_1X_{11}+\beta_2X_{21}+\beta_3X_{31}+\cdots+\beta_kX_{k1}\\Y_2=\beta_1X_{12}+\beta_2X_{22}+\beta_3X_{32}+\cdots+\beta_kX_{k2}\\\cdots\cdots\cdots\cdots\cdots\cdots\cdots\cdots\cdots\cdots\cdots\cdots\cdots\cdots\\Y_n=\beta_1X_{1n}+\beta_2X_{2n}+\beta_3X_{3n}+\cdots+\beta_kX_{kn}\end{cases}​ ⎩⎪⎪⎪⎨⎪⎪⎪⎧​Y1​=β1​X11​+β2​X21​+β3​X31​+⋯+βk​Xk1​Y2​=β1​X12​+β2​X22​+β3​X32​+⋯+βk​Xk2​⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯Yn​=β1​X1n​+β2​X2n​+β3​X3n​+⋯+βk​Xkn​​​

用矩陣表示為:

[ Y 1 Y 2 ⋮ Y n ] \begin{bmatrix}Y_1\\Y_2\\\vdots\\Y_n\end{bmatrix} ⎣⎢⎢⎢⎡​Y1​Y2​⋮Yn​​⎦⎥⎥⎥⎤​= [ X 11 X 21 X 31 ⋯ X k 1 X 12 X 22 X 32 ⋯ X k 2 ⋮ ⋮ ⋮ ⋱ ⋮ X 1 n X 2 n X 3 n ⋯ X k n ] \begin{bmatrix}X_{11}&X_{21}&X_{31}&\cdots&X_{k1}\\X_{12}&X_{22}&X_{32}&\cdots&X_{k2}\\\vdots&\vdots&\vdots&\ddots&\vdots\\X_{1n}&X_{2n}&X_{3n}&\cdots&X_{kn}\end{bmatrix} ⎣⎢⎢⎢⎡​X11​X12​⋮X1n​​X21​X22​⋮X2n​​X31​X32​⋮X3n​​⋯⋯⋱⋯​Xk1​Xk2​⋮Xkn​​⎦⎥⎥⎥⎤​ [ β 1 β 2 ⋮ β n ] ​ \begin{bmatrix}\beta_1\\\beta_2\\\vdots\\\beta_n\end{bmatrix}​ ⎣⎢⎢⎢⎡​β1​β2​⋮βn​​⎦⎥⎥⎥⎤​​

簡化寫為:

Y = X β \beta β

3.可以用矩陣表示二維關系。

某個社交網站中會員的好友關系就可以用矩陣A來表示,如果會員i和會員j有關系,則用

A[i][j]=1

來表示,若會員i和會員j沒有關系,則用

A[i][j]=0

來表示。

使用者0到使用者9一共10位會員之間的關系:

之間的關系:

#使用者 0 1 2 3 4 5 6 7 8 9
friendships = [[0,1,1,0,0,0,0,0,0,0], #使用者0
               [1,0,1,1,0,0,0,0,0,0], #使用者1
               [1,1,0,1,0,0,0,0,0,0], #使用者2
               [0,1,1,0,1,0,0,0,0,0], #使用者3
               [0,0,0,1,0,1,0,0,0,0], #使用者4
               [0,0,0,0,1,0,1,1,0,0], #使用者5
               [0,0,0,0,0,1,0,0,1,0], #使用者6
               [0,0,0,0,0,1,0,0,1,0], #使用者7
               [0,0,0,0,0,0,1,1,0,1], #使用者8
               [0,0,0,0,0,0,0,0,1,0]] #使用者9
           

通過矩陣形式再現:

​ [ 0 1 1 0 0 0 0 0 0 0 1 0 1 1 0 0 0 0 0 0 1 1 0 1 0 0 0 0 0 0 0 1 1 0 1 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 0 1 0 1 1 0 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 1 1 0 1 0 0 0 0 0 0 0 0 1 0 ] ​ \begin{bmatrix}0&1&1&0&0&0&0&0&0&0\\1&0&1&1&0&0&0&0&0&0\\1&1&0&1&0&0&0&0&0&0\\0&1&1&0&1&0&0&0&0&0\\0&0&0&1&0&1&0&0&0&0\\0&0&0&0&1&0&1&1&0&0\\0&0&0&0&0&1&0&0&1&0\\0&0&0&0&0&1&0&0&1&0\\0&0&0&0&0&0&1&1&0&1\\0&0&0&0&0&0&0&0&1&0\\\end{bmatrix}​ ⎣⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎡​0110000000​1011000000​1101000000​0110100000​0001010000​0000101100​0000010010​0000010010​0000001101​0000000010​⎦⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎤​​

如果關系很少,這種表示形式的效率就會很低,因為必須存儲很多零。但是通過矩陣可以快速地查找确認某2個節點是否連結(有關系),不用周遊每條邊。

friendships[0][2] == 1  #傳回True,使用者0和使用者2是朋友
friendships[0][8] == 1  #傳回False,使用者0和使用者8不是朋友
           

如果想找到一個使用者的所有朋友即找到一個節點的所有連接配接,隻要檢查這個節點所在的列或者行即可。

舉例,檢視使用者3的所有朋友:

fried_of_three = [i for i,is_friend in enumerate(friendships[3]) if is_friend]
fried_of_three
           

繼續閱讀