机器学习中的Numpy库基础——向量、矩阵和数组
1.Numpy簡介
Numpy是Python機器學習技術棧的基礎。
Numpy可以對機器學習中常用的數據結構——向量(vector)、矩陣(matrice)、張量(tensor)——進行高效的操作。
Numpy是很多庫的基礎,比如Scipy、Matplotlib、OpenCV、scikit-learn等,非常重要。
之前寫過一篇博文,對其中的操作進行了梳理 → Here
本文對其中的內容進行整理和補充,希望能更好地指引初學者的腳步。
2.創建一個向量
向量可以表示為一維數組。
# 加載numpy庫 import numpy as np# 創建一個一維數組表示一個行向量 vector_row = np.array([1, 2, 3])# 創建一個一維數組表示一個列向量 vector_column = np.array([[1], [2], [3]])3.創建一個矩陣
矩陣可以表示為一個二維數組。
表示的時候注意[[, ], [, ], [, ]]這樣的格式,不要漏外括號。
當然,在Numpy中,可以用專門的矩陣數據結構來表示矩陣。
但并不推薦——Reasons:
- 數組才是Numpy標準的數據結構。
- 絕大多數Numpy操作返回的是數組而不是矩陣對象。
4.創建一個稀疏矩陣
我們在學習數據結構時學習了稀疏矩陣的知識。
機器學習中,數據集十分龐大且其中大部分元素是0的情況很常見,如果正常存儲十分浪費空間;但按照稀疏矩陣存儲,能節省空間、降低計算成本。
總結:稀疏矩陣能高效地表示只有零星非零值的數據。
我們可以查看稀疏矩陣:
# 查看稀疏矩陣 print(matrix2_sparse)我們再看一看更大的矩陣吧:
# 創建一個更大的矩陣 matrix_large = np.array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],[0, 1, 0, 0, 0, 0, 0, 0, 0, 0],[3, 0, 0, 0, 0, 0, 0, 0, 0, 0]])# 創建一個CSR矩陣 matrix_large_sparse = sparse.csr_matrix(matrix_large)# 查看原先的稀疏矩陣 print(matrix2_sparse)# 查看更大的稀疏矩陣 print(matrix_large_sparse)稀疏矩陣的類型很多,比如,壓縮的稀疏列、表中表以及鍵值對字典,我們應該學會在合適的場景運用合適的類型。
5.選擇元素
我們可以利用索引,在向量或矩陣中選擇一個或多個元素。
注意索引都是從0開始的呀!
另外,負數索引是倒著來的,這點也要注意哈!
眾所周知,Python的列表和元組就有索引和切片,那么這里其實也有的:
# 選取一個向量的所有元素 print(vector[:])# 選取從0開始一直到第3個(包含第3個)元素 print(vector[:3])# 選取第3個元素之后的全部元素 print(vector[3:])# 選取最后一個元素 print(vector[-1])# 選取矩陣的第1行和第2行以及所有列 print(matrix_vector[:2, :])# 選取所有行以及第2列 print(matrix_vector[:, 1:2])# 選取所有行以及第2列并轉換成一個新的行向量 print(matrix_vector[:, 1])6.展示一個矩陣的屬性
有時候,在某一步操作之前,我們可能想確認一下矩陣的形狀、大小和維數,這可能是簡單的,也可能很重要。
接下來我們分別利用shape查看矩陣的形狀、利用size查看矩陣的大小、利用ndim查看矩陣的維數:
7.對多個元素同時應用某個操作
我們有時候可能想要對一個數組中的多個元素同時應用某個函數,而Numpy中的vertorize類可以將一個函數轉成另一個函數,這個函數能把某個操作應用的數組的全部元素或者一個切片上。
需要明確的是,vertorize本質上是在對數組選中的所有元素循環的執行某種操作,所以并不會提升性能。
此外,使用Numpy的數組,我們可以對兩個維度不同的數組執行操作(這是一種叫做廣播的方法):
matrix_vector + 1008.找到最大值和最小值
計算一個數組的最大值或者最小值可能是重要的。
# 加載numpy庫 import numpy as np# 創建矩陣 matrix_vector = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])# 返回最大的元素 print(np.max(matrix_vector))# 返回最小元素 print(np.min(matrix_vector))如上所述,求一個數組或者一個數組的子集中元素的最大值和最小值是很常見的需求,使用max和min方法易于實現。而使用axis參數可以對一個特定的坐標軸應用此操作:
# 找到每一列的最大元素 print(np.max(matrix_vector, axis=0))# 找到每一行最大的元素 print(np.max(matrix_vector, axis=1))9.計算平均值、方差和標準差
如果我們還記得學過的概率論與數理統計的內容的話,就會知道一些重要的描述性統計值,如數學期望、方差和標準差等,這里我們可以利用Numpy的mean、var和std求解:
# 加載numpy庫 import numpy as np# 創建矩陣 matrix_vector = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])# 返回平均值 print(np.mean(matrix_vector))# 返回方差 print(np.var(matrix_vector))# 返回標準差 print(np.std(matrix_vector))我們當然可以容易的求出整個矩陣或者其中一個坐標軸的描述性統計值:
# 求每一列的平均值 print(np.mean(matrix_vector, axis=0))# 求每一行的方差 print(np.var(matrix_vector, axis=1))10.矩陣變形
有時候,我們可能會想在不改變元素值的前提下,改變一個數組的形狀(行數和列數),Numpy的reshape可以實現這種要求。
reshape可以重構一個數組,維持該數組原來的數據不變,只改變行數和列數。但要求原矩陣和新矩陣包含的元素個數必須相同(大小相同)。比如,2 × 6 矩陣可以換成 3 × 4 矩陣,元素個數都是12個。
reshape能傳入參數-1,這時意味著可以“根據需要填充元素”。
# reshape時傳入參數-1意味著可以根據需要填充元素 print(matrix3.reshape(1, -1))只提供一個整數作為參數也是可以的,會返回一個長度為該整數的一維數組:
# reshape如果提供一個整數,那么reshape會返回一個長度為該整數值的一維數組 print(matrix3.reshape(12))11.轉置向量或矩陣
學過線性代數之后我們都知道,轉置是常見的操作,它將矩陣的每個元素的行坐標、列坐標互換。
# 加載numpy庫 import numpy as np# 創建矩陣 matrix_vector = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])# 轉置matrix_vector矩陣 print(matrix_vector.T)實際上,在線性代數里面,向量是不能被轉置的。
我們如果想“轉置向量”,就需要把向量純粹的當做1×N或者N×1的矩陣處理(即用[[, ]]而不是[, ]):
12.展開一個矩陣
所謂“展開”矩陣,不過是將一個矩陣轉換成一個一維數組,Numpy中的flatten可以幫助我們實現:
# 加載numpy庫 import numpy as np# 創建矩陣 matrix_vector = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])# 將matrix_vector矩陣展開 print(matrix_vector.flatten())我們才看過的reshape顯然也能完成這種小任務:
# 將矩陣展開的另一種策略是利用reshape創建一個行向量 print(matrix_vector.reshape(1, -1))13.計算矩陣的秩
線性代數里面,矩陣的秩也是重要的概念。為了便于理解,我們這里就不提什么向量組的極大無關組那些,我們可以認為矩陣的秩就是按照其行或者列展開的向量空間的維數,神圣的Numpy提供了matrix_rank,我們利用它可以輕松求解:
# 加載numpy庫 import numpy as np# 創建用于求秩的新矩陣 matrix5 = np.array([[1, 1, 1], [1, 1, 10], [1, 1, 15]])# 計算矩陣matrix5的秩 print(np.linalg.matrix_rank(matrix5))14.計算行列式
我在學線性代數的時候,行列式是最早學的Part了,行列式只是一個數而已,但矩陣的行列式是很有用的。
簡而言之,矩陣的[ ]換成| |就是矩陣的行列式的表示(手寫版),只是從一個數表變成了一個數。
求解行列式可能是復雜的,但Numpy的det幫助我們解決了這個問題:
15.獲取矩陣的對角線元素
有時候,我們可能想要獲取矩陣的對角線元素,Numpy的diagonal能幫到我們:
# 加載numpy庫 import numpy as np# 創建用于行列式求解的新矩陣 matrix6 = np.array([[1, 2, 3], [2, 4, 6], [3, 8, 9]])# 返回矩陣的對角線元素 print(matrix6.diagonal())我們還可以使用offset參數在主對角線上下偏移,獲取偏移后的對角線方向上的元素:
# 返回主對角線向上偏移量為1的對角線元素 print(matrix6.diagonal(offset=1))# 返回主對角線向下偏移量為1的對角線元素 print(matrix6.diagonal(offset=-1))16.計算矩陣的跡
線性代數里提到了矩陣的跡,指矩陣對角線元素之和,常被用在機器學習方法的底層計算中,Numpy的trace可以加以求解:
# 加載numpy庫 import numpy as np# 創建用于行列式求解的新矩陣 matrix6 = np.array([[1, 2, 3], [2, 4, 6], [3, 8, 9]])# 返回矩陣的跡 print(matrix6.trace())當然,也可以麻煩一些,利用對矩陣對角線元素求和的方式求解:
# 求跡的另外的方法(返回對角線元素并求和) print(sum(matrix6.diagonal()))17.計算特征值和特征向量
線性代數中,矩陣的特征值和特征向量特別重要,我學習的時候這是矩陣相似對角化的重要基礎。另外,假設線性變換是以矩陣A的形式給出的,則當應用此線性變換的時候,特征向量只會改變大小(不改變方向)。
Aν = λν(A為方陣,λ是特征值,ν是特征向量)
Numpy的eig可以幫助我們求解(想我當年學線代,這倆東西算起來也是頗為麻煩的):
18.計算點積
向量的點積其實在高中就學習了,在線性代數和空間解析幾何中也是重要內容。可以這樣定義:
Numpy的dot可以完成這個任務:
Python 3.5+版本可以利用@求解向量點積:
# Python 3.5+ 版本可以這樣求解點積 print(vector_a @ vector_b)19.計算矩陣的相加或相減
所謂矩陣加法或者減法,無非是在兩個形狀大小完全一致的矩陣上,對每個元素逐一進行加減法,Numpy的add和subtract可以分別實現矩陣加減法:
# 加載numpy庫 import numpy as np# 構造兩個可用于加減的矩陣 matrix_a = np.array([[1, 1, 1], [1, 1, 1], [1, 1, 2]]) matrix_b = np.array([[1, 3, 1], [1, 3, 1], [1, 3, 8]])# 兩矩陣相加 print(np.add(matrix_a, matrix_b))# 兩矩陣相減 print(np.subtract(matrix_a, matrix_b))直接利用運算符運算也是被支持的:
# 直接用+/-也可以做矩陣加減 print(matrix_a + matrix_b) print(matrix_a - matrix_b)20.矩陣的乘法
矩陣乘法的實現類似向量乘法,可以用Numpy的dot:
# 加載numpy庫 import numpy as np# 構造兩個可用于乘法的小矩陣 matrix_c = np.array([[1, 1], [1, 2]]) matrix_d = np.array([[1, 3], [1, 2]])# 兩矩陣相乘 print(np.dot(matrix_c, matrix_d))Python 3.5+版本可以利用@求解矩陣乘法:
# Python 3.5+ 版本可以這樣求解矩陣乘法 print(matrix_c @ matrix_d)只是把矩陣對應元素相乘,可以用*求解:
# 我們也可以把兩矩陣對應元素相乘,而非矩陣乘法 print(matrix_c * matrix_d)21.計算矩陣的逆
如果逆矩陣存在,則可以用Numpy的linalg.inv來計算:
# 加載numpy庫 import numpy as np# 創建一個用于求逆的矩陣 matrix8 = np.array([[1, 4], [2, 5]])# 計算矩陣的逆 print(np.linalg.inv(matrix8))如果逆矩陣存在,矩陣本身和逆矩陣相乘得到單位矩陣:
# 驗證一個矩陣和它的逆矩陣相乘等于I(單位矩陣) print(matrix8 @ np.linalg.inv(matrix8))22.生成隨機數
偽隨機數是很重要的,值得一提的是,其生成器中有“種子”。
# 加載numpy庫 import numpy as np# 設置隨機數種子 np.random.seed(0)# 生成3個0.0~1.0之間的浮點隨機數 print(np.random.random(3))我們繼續看看吧:
# 生成3個1~10之間的隨機整數 print(np.random.randint(0, 11, 3))# 從平均值是0.0,標準差是1.0的正態分布中抽取3個數 print(np.random.normal(0.0, 1.0, 3))# 從平均值是0.0,散布程度是1.0的logistic分布中抽取3個數 print(np.random.logistic(0.0, 1.0, 3))# 從大于等于1.0,小于2.0的范圍內抽取3個數 print(np.random.uniform(1.0, 2.0, 3))總結
Numpy有豐富的內容,本文舉一些經典的應用加以闡釋,還望對讀者有所幫助。
總結
以上是生活随笔為你收集整理的机器学习中的Numpy库基础——向量、矩阵和数组的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【面向对象】面向对象程序设计测试题7-对
- 下一篇: 【计算机科学基础】ASCII码表知识总结