矩陣與矩陣乘積簡(jiǎn)介
點(diǎn)擊上方“小白學(xué)視覺(jué)”,選擇加"星標(biāo)"或“置頂”
重磅干貨,第一時(shí)間送達(dá)
【導(dǎo)讀】向量是存儲(chǔ)和操作數(shù)據(jù)的一種有用的方法??梢杂眉^或數(shù)字?jǐn)?shù)組來(lái)表示它們。然而,創(chuàng)建更復(fù)雜的數(shù)據(jù)結(jié)構(gòu)是有幫助的,而這正是需要引入矩陣的地方。
矩陣它們是正方形或矩形數(shù)組,包含按兩個(gè)維度:行和列。你可以把它們看作是一個(gè)電子表格。通常,你會(huì)在數(shù)學(xué)上下文中看到術(shù)語(yǔ)矩陣,在Numpy上下文中看到二維數(shù)組。
在矩陣的上下文中,術(shù)語(yǔ)維度不同于向量表示的維數(shù)(空間維數(shù))。當(dāng)我們說(shuō)矩陣是二維數(shù)組時(shí),意味著數(shù)組中有兩個(gè)方向:行和列。
矩陣表示如下:

矩陣A有兩行兩列,但你可以想象矩陣有任何形狀。更一般地說(shuō),如果矩陣有m行和n列,并且包含實(shí)值,可以用以下符號(hào)來(lái)刻畫(huà)它:「A」∈?(m×n)。
你可以使用不帶粗體的矩陣名稱引用矩陣中的元素,但是后面需要跟著行索引和列索引。例如,表示第一行和第二列中的元素。
按照慣例,第一個(gè)索引用于行,第二個(gè)索引用于列。例如,上面提到的例子位于矩陣A的第二行和第一列,因此它被表示為
矩陣分量可以寫(xiě)如下:

圖1:矩陣是二維數(shù)組。行數(shù)通常用m表示,列數(shù)用n表示。
數(shù)組的形狀給出了每個(gè)維度中元素的數(shù)量,如圖1所示。由于此矩陣是二維的(行和列),因此需要兩個(gè)值來(lái)描述形狀(按此順序排列的行數(shù)和列數(shù))。
讓我們先用這個(gè)方法np.array()創(chuàng)建一個(gè)2維numpy數(shù)組
A?=?np.array([[2.1,?7.9,?8.4],
??????????????[3.0,?4.5,?2.3],
??????????????[12.2,?6.6,?8.9],
??????????????[1.8,?1.,?8.2]])
注意,我們使用數(shù)組中的數(shù)組([[]])來(lái)創(chuàng)建二維數(shù)組。這與創(chuàng)建一維數(shù)組的不同之處在于所使用的方括號(hào)數(shù)。
與向量一樣,可以訪問(wèn)Numpy數(shù)組的shape屬性:
A.shape
你可以看到該形狀包含兩個(gè)數(shù)字:它們分別對(duì)應(yīng)于行數(shù)和列數(shù)。
要獲得矩陣元素,需要兩個(gè)索引:一個(gè)引用行索引,一個(gè)引用列索引。
使用Numpy,索引過(guò)程與向量的索引過(guò)程相同。你只需要指定兩個(gè)索引。我們?cè)賮?lái)看下面的矩陣A:
A?=?np.array([[2.1,?7.9,?8.4],
??????????????[3.0,?4.5,?2.3],
??????????????[12.2,?6.6,?8.9],
??????????????[1.8,?1.3,?8.2]])
可以使用以下語(yǔ)法獲取特定元素:
A[1,?2]
[1,2]返回行索引為1、列索引為2(以零為基礎(chǔ)的索引)的元素。
要獲得完整的列,可以使用冒號(hào):
A[:,?0]
array([?2.1,?3.?,?12.2,?1.8])
這將返回第一列(索引0),因?yàn)槊疤?hào)表示我們需要從第一行到最后一行的元素。同樣,要獲取特定行,可以執(zhí)行以下操作:
A[1,?:]
array([3.?,?4.5,?2.3])
能夠操縱包含數(shù)據(jù)的矩陣是數(shù)據(jù)科學(xué)家的一項(xiàng)基本技能。檢查數(shù)據(jù)的形狀對(duì)于確保數(shù)據(jù)的組織方式非常重要。了解使用Sklearn或Tensorflow等庫(kù)所需的數(shù)據(jù)形狀也很重要。
對(duì)于Numpy,如果數(shù)組是向量(1D Numpy數(shù)組),則shape是單個(gè)數(shù)字:
v?=?np.array([1,?2,?3])
v.shape
如果是矩陣,則形狀有兩個(gè)數(shù)字(行和列中的值的數(shù)目)。例如:
A?=?np.array([[2.1,?7.9,?8.4]])
A.shape
形狀的第一個(gè)數(shù)字是1。使用兩個(gè)方括號(hào)[[和]],可以創(chuàng)建一個(gè)二維數(shù)組(矩陣)。
矩陣乘積
你將在數(shù)據(jù)科學(xué)基礎(chǔ)數(shù)學(xué)中學(xué)習(xí)乘積。矩陣的等價(jià)運(yùn)算稱為矩陣乘積或矩陣乘法。它接受兩個(gè)矩陣并返回另一個(gè)矩陣。這是線性代數(shù)中的一個(gè)核心運(yùn)算。
矩陣乘積的更簡(jiǎn)單的情況是介于矩陣和向量之間(可以將其視為矩陣乘積,其中一個(gè)向量只有一列)。

說(shuō)明了矩陣和向量之間乘積的步驟。讓我們考慮矩陣的第一行。在向量(值3和4)和考慮的行(值1和2)之間進(jìn)行點(diǎn)積。第一行的第一個(gè)值的與第一列的第一個(gè)值(1?3)和第一行第二個(gè)值與第一列的第二個(gè)值(2?4)。它給你計(jì)算的矩陣的第一個(gè)元素是(1?3 + 2?4 = 11)。
你可以看到矩陣乘積與點(diǎn)積相關(guān)。這就像把矩陣A分成三行并應(yīng)用點(diǎn)積(如數(shù)據(jù)科學(xué)的基本數(shù)學(xué))。
讓我們看看它是如何與numpy一起工作的。
A?=?np.array([
????[1,?2],
????[5,?6],
????[7,?8]
])
v?=?np.array([3,?4]).reshape(-1,?1)
A?@?v
array([[11],?[39],?[53]])
請(qǐng)注意,我們使用了reshape函數(shù)將向量重塑為一個(gè)2乘1的矩陣(-11告訴Numpy猜測(cè)剩余的數(shù)字)。如果沒(méi)有它,你將以一維數(shù)組結(jié)束,而不是這里的二維數(shù)組(只有一列的矩陣)。
還有另一種方法來(lái)考慮矩陣乘積。你可以考慮向量包含了對(duì)矩陣的每一列加權(quán)的值。它清楚地表明,向量的長(zhǎng)度需要等于應(yīng)用向量的矩陣的列數(shù)。
下圖可能有助于將這個(gè)概念形象化。可以將向量值(3和4)視為應(yīng)用于矩陣列的權(quán)重。前面看到的標(biāo)量乘法規(guī)則會(huì)產(chǎn)生與以前相同的結(jié)果。
使用最后一個(gè)示例,可以編寫(xiě)A和v之間的乘積,如下所示:

這一點(diǎn)很重要,因?yàn)檎缒阍跀?shù)據(jù)科學(xué)基礎(chǔ)數(shù)學(xué)中看到的更多細(xì)節(jié),它表明Av是A的列的線性組合,系數(shù)是v的值。
另外,你可以看到矩陣的形狀和向量的形狀必須匹配才能得到乘積。
矩陣乘積類似于矩陣向量積,但應(yīng)用于第二個(gè)矩陣的每一列。
使用Numpy,可以精確地計(jì)算矩陣乘積:
A?=?np.array([
????[1,?2],
????[5,?6],
????[7,?8],
])
B?=?np.array([
????[3,?9],
????[4,?0]
])
A?@?B
array([[11,?9],?[39,?45],?[53,?63]])
與矩陣向量積一樣,第一個(gè)矩陣的列數(shù)必須與第二個(gè)矩陣的行數(shù)相匹配。
結(jié)果矩陣的行數(shù)與第一個(gè)矩陣的行數(shù)相同,列數(shù)與第二個(gè)矩陣的列數(shù)相同。
我們?cè)囋嚢伞?/p>
A?=?np.array([
????[1,?4],
????[2,?5],
????[3,?6],
])
B?=?np.array([
????[1,?4,?7],
????[2,?5,?2],
])
矩陣A和B有不同的形狀。讓我們計(jì)算他們的乘積:
A?@?B
array([[?9,?24,?15],?[12,?33,?24],?[15,?42,?33]])
你可以看到A?B的結(jié)果是一個(gè)3乘3的矩陣。這個(gè)形狀來(lái)自A(3)的行數(shù)和B(3)的列數(shù)。
可以使用矩陣與其轉(zhuǎn)置矩陣之間的乘積計(jì)算數(shù)據(jù)集的協(xié)方差矩陣。然后,除以觀測(cè)值(或貝塞爾修正值減去1)。但是你需要事先確保變量的中心在零附近(這可以通過(guò)減去平均值來(lái)實(shí)現(xiàn))。
讓我們模擬以下變量x、y和z:
x?=?np.random.normal(10,?2,?100)
y?=?x?*?1.5?+?np.random.normal(25,?5,?100)
z?=?x?*?2?+?np.random.normal(0,?1,?100)
使用Numpy,協(xié)方差矩陣為:
np.cov([x,?y,?z])
array([[?4.0387007?,?4.7760502?,?8.03240398],?[?4.7760502?,?32.90550824,?9.14610037],?[?8.03240398,?9.14610037,?16.99386265]])
現(xiàn)在,使用矩陣乘積,首先進(jìn)行堆疊:
X?=?np.vstack([x,?y,?z]).T
X.shape
你可以看到變量X是一個(gè)100×3的矩陣:100行對(duì)應(yīng)于觀察值,3列對(duì)應(yīng)于特征。然后,把這個(gè)矩陣減去均值:
X?=?X?-?X.mean(axis=0)
最后,計(jì)算協(xié)方差矩陣:
(X.T?@?X)?/?(X.shape[0]?-?1)
array([[?4.0387007?,?4.7760502?,?8.03240398],?[?4.7760502?,?32.90550824,?9.14610037],?[?8.03240398,?9.14610037,?16.99386265]])
你會(huì)得到一個(gè)協(xié)方差矩陣,與函數(shù)np.cov中得到的協(xié)方差矩陣相似,這一點(diǎn)很重要,要記住一個(gè)矩陣的轉(zhuǎn)置乘積對(duì)應(yīng)于協(xié)方差矩陣。
兩個(gè)矩陣之間乘積的轉(zhuǎn)置定義如下:

例如,取以下矩陣A和B:
A?=?np.array([
????[1,?4],
????[2,?5],
????[3,?6],
])
B?=?np.array([
????[1,?4,?7],
????[2,?5,?2],
])
你可以檢查(AB)^T和B^T A^T的結(jié)果:
(A?@?B).T
array([[?9,?12,?15],?[24,?33,?42],?[15,?24,?33]])
B.T?@?A.T
array([[?9,?12,?15],?[24,?33,?42],?[15,?24,?33]])
這可能是令人驚訝的首先,兩個(gè)向量或矩陣在括號(hào)中的順序必須改變,以滿足等價(jià)性。我們來(lái)看看操作的細(xì)節(jié)。
下圖顯示,如果改變向量和矩陣的順序,矩陣乘積的轉(zhuǎn)置等于轉(zhuǎn)置的乘積。
可以將此屬性應(yīng)用于兩個(gè)以上的矩陣或向量。例如,

交流群
歡迎加入公眾號(hào)讀者群一起和同行交流,目前有SLAM、三維視覺(jué)、傳感器、自動(dòng)駕駛、計(jì)算攝影、檢測(cè)、分割、識(shí)別、醫(yī)學(xué)影像、GAN、算法競(jìng)賽等微信群(以后會(huì)逐漸細(xì)分),請(qǐng)掃描下面微信號(hào)加群,備注:”昵稱+學(xué)校/公司+研究方向“,例如:”張三?+?上海交大?+?視覺(jué)SLAM“。請(qǐng)按照格式備注,否則不予通過(guò)。添加成功后會(huì)根據(jù)研究方向邀請(qǐng)進(jìn)入相關(guān)微信群。請(qǐng)勿在群內(nèi)發(fā)送廣告,否則會(huì)請(qǐng)出群,謝謝理解~

