灰太狼的數據世界(四)

  • 2019 年 10 月 6 日
  • 筆記

Scipy是

一個專門用於科學計算的庫

它與Numpy有著密切的關係

Numpy是Scipy的基礎

Scipy通過Numpy數據來進行科學計算

包含

統計

優化

整合

以及線性代數模組

傅里葉變換

訊號和影像圖例

常微分方差的求解等

給個表給你參考下?

怎麼樣?

是不是看上去就有一股很騷氣的味道?

那咱就繼續學下去唄!

首先

安裝

個人推薦pip直接全家桶

pip install -U numpy scipy scikit-learn

當然也有人推薦

Anaconda

因為用了它

一套環境全搞定

媽媽再也不用擔心我安裝問題了~

安裝完之後就是直接使用了

首先我們來談談

(這些函數其實都是numpy裡面的

它們也可以被scipy對象使用)

unique函數

之前在numpy裡面有說過

主要是用來除去重複元素

同樣的,這個方法適用numpy

也適用於sm這樣的一個對象

(類似於python裡面的set)

import numpy as np  import scipy.misc as sm  x = np.array([1, 3, 2, 1, 4, 2])  print(np.unique(x), "# unique(x)")
face = sm.face()  print(np.unique(face), "# unique(face)")

bincount函數

統計出數組裡的從0到數組最大值n

共n+1個自然數出現的次數

具體做法

先找出數組裡的最大值

統計0~最大值間的所有值出現的次數

import numpy as np  import scipy.misc as sm  ascent = sm.ascent()  print("max of array {} has {}"        .format(np.max(ascent[0]),                len(ascent[0])))  b =  np.bincount(ascent[0])  print("return array's length {}"        .format(len(b)))  print("result {}".format(b))

fromfunctiont函數

類似於python裡面的map函數

利用傳入的函數生成一個數組

import numpy as np  def func(x, y):      return (x + y) * 3  t = np.fromfunction(func, (3, 4),        dtype=np.uint8)print("t = {}".format(t))

除了上面這幾個

還有下面幾個函數

put函數

替換數組裡面的值

putmask函數

和put一樣,也是替換

………

剛剛說的這些

還是停留在Numpy的基礎上

都是Numpy自己的函數

下面我們來說點有用的

看看Scipy自己的函數吧~

Scipy有一些專門的類

可以用來創建

稀疏矩陣

coo_matrix

csc_matrix

csr_matrix

bsr_matrix

我們來瞧一個栗子

import numpy as np  import scipy.sparse as ss  a = np.zeros((3, 4))  a[1, 2] = 12  a[2, 2] = 22  print(a)  print(ss.csc_matrix(a))我們可以在創建的ndarry裡面找出不為零的值和他的位置,將這個數組直接轉化成稀疏矩陣

我們還可以利用

mat函數/bmat函數

來創建特殊的矩陣

np.mat函數可將數組轉為矩陣

np.bmat函數可以矩陣為參數創建陣列的矩陣

import numpy as np  a = np.mat(np.ones([3, 3]))  b = np.mat(np.zeros([3,3]))  print("a = {}".format(a))  print("b = {}".format(b))  c = np.bmat("a,b;b,a")  print("c = {}".format(c))

Tile函數

將第一個參數映射到第二個參數

import numpy as np  t = np.arange(9).reshape([3, 3])  print(t)  tm = np.tile(t, [3,2])  print(tm)

將t映射到【3,2】上

block_diag函數

block_diag函數可以創建一個

廣義「主對角線」非0的大矩陣

其參數是矩陣

用矩陣作為主對角線性的值

所以矩陣會很大~

import numpy as np  import scipy.linalg as sl  a = np.mat(np.ones([3, 3]))  b = np.mat(np.ones([4, 3]))  c = np.mat(np.ones([3, 4]))  print("a = {}".format(a))  print("b = {}".format(b))  print("c = {}".format(c))  d = sl.block_diag(a,b,c)  print("d = {}".format(d))

除了創建矩陣

scipy當然還有更多有趣的地方

例如

線性方程組求解

具體怎麼算的我也就不瞎說了

圖能看懂就看

高數沒學好的

推薦一個重新學的網址:

https://baike.baidu.com/item/lu%E5%88%86%E8%A7%A3/764245?fr=aladdin

我們有各種方法進行求解

例如:

LU分解

QR分解

SVD分解

Cholesky分解

先來了解一下LU分解~

將LU分解轉化成Scipy程式碼

SciPy里的

scipy.linalg.lu函數可以基本實現對Ax=b的LU分解

但scipy.linalg.lu函數的返回值有三個p'、l'、u'

所以矩陣分解變為(P'L')U' = A

from scipy.linalg import lu  import numpy as np  A = np.matrix([[2,3],[5,4]])  b = np.matrix([4,3])  p,l,u =  lu(A)  print("p = {}".format(p))  print("l = {}".format(l))  print("u = {}".format(u))  print("plu = {}".format(p.dot(l).dot(u)))  print("A = {}".format(A))

下面我們可以利用

LU分解求方程組的解

分解過後的方程如下:

對應的結果也就是A

之後我們

求p、l、u

然後用pl和b求y

用u和y求x的值

from scipy.linalg import lu,solve  import numpy as np  A = np.array([[2,3],[5,4]])  b = np.array([4,3])  # 求的p l u  p,l,u =  lu(A)  print("p = {}".format(p))  print("l = {}".format(l))  print("u = {}".format(u))  # 求ply = b的y  y = solve(p.dot(l), b)  print("y = {}".format(y))  # 求ux = y的x  x = solve(u, y)  print("x = {}".format(x))

結果最後一行輸出的是x的值,

x=(x1,x2)=(−1,2)

Cholesky分解

要求解線性方程組Ax=b

其中為對稱正定矩陣

又叫平方根法

是求解對稱線性方程組常用的方法之一

那麼可通過下面步驟求解

(1)求的Cholesky分解,得到A=LLT

(2)求解Ly=b,得到y

(3)求解LTx=y,得到x

下面使用

scipy.linalg模組下的cholesky函數

來對係數矩陣進行求cholesky分解

from scipy.linalg import cholesky  import numpy as np  from scipy.linalg import lu,solve  A = np.array([[1,2,3],[2,8,8],[3,8,35]])  b = np.array([1,8,20])  l = cholesky(A, lower=True)  print("L = {}".format(l))  print("matmul = {}".format(np.matmul(l,l.T)))  print("dot = {}".format(l.dot(l.T)))  y = solve(l, b)  print(l.dot(y), b)  x = solve(l.T, y)  print("x = {}".format(x))  print(l.T.dot(x), y)  print("y = {}".format(y))

QR分解

QR分解法是三種將矩陣分解的方式之一

它把矩陣分解成:

一個正交矩陣與一個上三角矩陣的積

QR分解經常用來解線性最小二乘法問題

scipy.linalg模組下的qr函數

可以對矩陣進行QR分解操作

from scipy.linalg import qr  import numpy as np  aa = np.array([[0,3,1],[0,4,-2],[2,1,2]])  qq, rr = qr(aa)  print("Q = {}".format(qq))  print("R = {}".format(rr))  print("A = {}".format(aa))  print("QR = {}".format(qq.dot(rr)))

SVD奇異分解

svd是現在比較常見的演算法之一

也是數據挖掘工程師、演算法工程師

必備的技能之一

假設A是一個M×N的矩陣,

那麼通過矩陣分解將會得到

U,Σ,VT(V的轉置)三個矩陣

其中U是一個M×M的方陣

被稱為左奇異向量

方陣裡面的向量是正交的

Σ是一個M×N的對角矩陣

除了對角線的元素其他都是0

對角線上的值稱為奇異值

VT(V的轉置)是一個N×N的矩陣

被稱為右奇異向量

方陣裡面的向量也都是正交的

from scipy.linalg import qr,svd  import numpy as np  aa = np.array([[0,3,1],[0,4,-2],[2,1,2]])  u, e, v = svd(aa)  print("u = {}".format(u))  print("e = {}".format(e))  print("v = {}".format(v))

SVD的應用場景也比較明顯

典型的使用的場景:

訊號的降噪

影像的壓縮

我們這邊可以來看一個影像壓縮的例子:

import scipy.misc  from scipy.linalg import svd  import matplotlib.pyplot as plt  import numpy as np  import numpy  img = scipy.misc.face()[:,:,0]    print(img.shape,type(img))  img = np.matrix(img)  U,s,Vh=svd(img)  plt.gray()    plt.subplot(221,aspect='equal')  plt.title("orignal")  plt.imshow(img)  plt.imsave('org.png', img)    A = numpy.dot(U[:,0:10],numpy.dot(numpy.diag(s[0:10]),Vh[0:10,:]))  plt.subplot(222,aspect='equal')  plt.title(":10")  plt.imshow(A)  plt.imsave('a10.png', A)    A = numpy.dot(U[:,0:50],numpy.dot(numpy.diag(s[0:50]),Vh[0:50,:]))  plt.subplot(223,aspect='equal')  plt.title(":50")  plt.imshow(A)  plt.imsave('a50.png', A)    A = numpy.dot(U[:,0:100],numpy.dot(numpy.diag(s[0:100]),Vh[0:100,:]))  plt.subplot(224,aspect='equal')  plt.title(":100")  plt.imshow(A)  plt.imsave('a100.png', A)    plt.show()

壓縮原理如下:

總結

svd分解在

機器學習

深度學習

電腦視覺等領域

都有很多涉及

需明白基礎不牢靠

學習機器學習也就是浮於表面

這一期關於scipy使用的內容就到這裡了(主要是講的如何去使用scipy,但是具體的數學理論沒有特別去講,覺得以後有必要搞一期,談談線性代數,畢竟矩陣這個東西我們現在很常用)

下一期我們將接觸:

Scipy裡面的

范德蒙多項式逼近

最鄰近插值法

拉格朗日插值法

埃米爾特插值法

樣條插值

函數的求導和積分