本文簡要介紹 python 語言中 scipy.sparse.csgraph.laplacian
的用法。
用法:
scipy.sparse.csgraph.laplacian(csgraph, normed=False, return_diag=False, use_out_degree=False, *, copy=True, form='array', dtype=None, symmetrized=False)#
返回有向圖的拉普拉斯算子。
- csgraph: 數組 或稀疏矩陣,二維
compressed-sparse 圖形,形狀為 (N, N)。
- normed: 布爾型,可選
如果為 True,則計算對稱歸一化拉普拉斯算子。默認值:假。
- return_diag: 布爾型,可選
如果為 True,則還返回與頂點度數相關的數組。默認值:假。
- use_out_degree: 布爾型,可選
如果為 True,則使用出度而不是入度。僅當圖形不對稱時,這種區別才重要。默認值:假。
- copy: bool, optional:
如果為 False,則盡可能更改 csgraph,避免內存使用量加倍。默認值:True,用於向後兼容。
- form: ‘array’, or ‘function’, or ‘lo’:
確定輸出拉普拉斯算子的格式:
‘array’ 是一個 numpy 數組;
‘function’是評估Laplacian-vector或Laplacian-matrix產品的指針;
‘lo’ 結果采用 LinearOperator 的格式。
選擇‘function’ 或‘lo’ 始終避免內存使用加倍,忽略
copy
值。默認值:‘array’,用於向後兼容。- dtype: None or one of numeric numpy dtypes, optional:
輸出的數據類型。如果
dtype=None
,輸出的 dtype 與輸入 csgraph 的 dtype 匹配,但normed=True
和 integer-like csgraph 情況除外,其中輸出 dtype 為 ‘float’ 允許精確標準化,但會顯著增加內存使用。默認值:無,用於向後兼容。- symmetrized: bool, optional:
如果為 True,則輸出拉普拉斯算子是對稱/厄米算子。對稱化是通過以下方式完成的
csgraph + csgraph.T.conj
如果可能的話,在構造拉普拉斯算子之前不除以 2 以保留整數數據類型。對稱化將增加稀疏矩陣的內存占用,除非稀疏模式是對稱的或形式是‘function’ 或‘lo’。默認值:False,用於向後兼容。
- lap: ndarray,或稀疏矩陣,或LinearOperator
csgraph 的 N x N 拉普拉斯算子。如果輸入是密集的,則它將是 NumPy 數組(密集),否則將是稀疏矩陣,或者如果形式分別等於 ‘function’ 或 ‘lo’,則為函數格式或 LinearOperator。
- diag: ndarray,可選
拉普拉斯矩陣的 length-N 主對角線。對於歸一化拉普拉斯算子,這是頂點度數的平方根數組,如果度數為零,則為 1。
參數 ::
返回 ::
注意:
圖的拉普拉斯矩陣有時被稱為“Kirchhoff matrix”或隻是“Laplacian”,並且在譜圖理論的許多部分中都很有用。特別是,拉普拉斯算子的特征分解可以深入了解圖的許多屬性,例如,通常用於頻譜數據嵌入和聚類。
如果
copy=True
和form="array"
是默認值,則構造的拉普拉斯算子會使內存使用量加倍。除非form="array"
或矩陣以coo
格式稀疏或密集數組,否則選擇copy=False
無效,但normed=True
的整數輸入強製浮點輸出。如果
form="array"
,稀疏輸入將重新格式化為coo
,這是默認值。如果輸入鄰接矩陣不對稱,則拉普拉斯算子也是非對稱的,除非使用
symmetrized=True
。出於標準化目的,輸入鄰接矩陣的對角項將被忽略並替換為零,其中
normed=True
.歸一化使用輸入鄰接矩陣的 row-sums 的反平方根,因此如果 row-sums 包含負數或具有非零虛部值的複數,則可能會失敗。歸一化是對稱的,如果輸入 csgraph 是對稱的,則歸一化的拉普拉斯算子也是對稱的。
參考:
[1]例子:
>>> import numpy as np >>> from scipy.sparse import csgraph
我們的第一個插圖是對稱圖
>>> G = np.arange(4) * np.arange(4)[:, np.newaxis] >>> G array([[0, 0, 0, 0], [0, 1, 2, 3], [0, 2, 4, 6], [0, 3, 6, 9]])
及其對稱拉普拉斯矩陣
>>> csgraph.laplacian(G) array([[ 0, 0, 0, 0], [ 0, 5, -2, -3], [ 0, -2, 8, -6], [ 0, -3, -6, 9]])
非對稱圖
>>> G = np.arange(9).reshape(3, 3) >>> G array([[0, 1, 2], [3, 4, 5], [6, 7, 8]])
具有不同的行和列總和,從而產生兩種拉普拉斯矩陣,使用入度(默認值)
>>> L_in_degree = csgraph.laplacian(G) >>> L_in_degree array([[ 9, -1, -2], [-3, 8, -5], [-6, -7, 7]])
或者出度
>>> L_out_degree = csgraph.laplacian(G, use_out_degree=True) >>> L_out_degree array([[ 3, -1, -2], [-3, 8, -5], [-6, -7, 13]])
構造一個對稱拉普拉斯矩陣,可以將兩者相加為
>>> L_in_degree + L_out_degree.T array([[ 12, -4, -8], [ -4, 16, -12], [ -8, -12, 20]])
或使用
symmetrized=True
選項>>> csgraph.laplacian(G, symmetrized=True) array([[ 12, -4, -8], [ -4, 16, -12], [ -8, -12, 20]])
這相當於將原始圖對稱化
>>> csgraph.laplacian(G + G.T) array([[ 12, -4, -8], [ -4, 16, -12], [ -8, -12, 20]])
歸一化的目標是使拉普拉斯矩陣的非零對角線項全部為單位,同時相應地縮放非對角線項。標準化可以手動完成,例如,
>>> G = np.array([[0, 1, 1], [1, 0, 1], [1, 1, 0]]) >>> L, d = csgraph.laplacian(G, return_diag=True) >>> L array([[ 2, -1, -1], [-1, 2, -1], [-1, -1, 2]]) >>> d array([2, 2, 2]) >>> scaling = np.sqrt(d) >>> scaling array([1.41421356, 1.41421356, 1.41421356]) >>> (1/scaling)*L*(1/scaling) array([[ 1. , -0.5, -0.5], [-0.5, 1. , -0.5], [-0.5, -0.5, 1. ]])
或者使用
normed=True
選項>>> L, d = csgraph.laplacian(G, return_diag=True, normed=True) >>> L array([[ 1. , -0.5, -0.5], [-0.5, 1. , -0.5], [-0.5, -0.5, 1. ]])
現在返回縮放係數而不是對角線
>>> d array([1.41421356, 1.41421356, 1.41421356])
零縮放係數用 1 代替,因此縮放沒有影響,例如,
>>> G = np.array([[0, 0, 0], [0, 0, 1], [0, 1, 0]]) >>> G array([[0, 0, 0], [0, 0, 1], [0, 1, 0]]) >>> L, d = csgraph.laplacian(G, return_diag=True, normed=True) >>> L array([[ 0., -0., -0.], [-0., 1., -1.], [-0., -1., 1.]]) >>> d array([1., 1., 1.])
僅實現對稱歸一化,當且僅當其圖是對稱的並且具有所有非負度時,才會產生對稱拉普拉斯矩陣,如上麵的示例所示。
默認情況下,輸出拉普拉斯矩陣是密集數組或稀疏矩陣,從輸入圖矩陣推斷其形狀、格式和數據類型:
>>> G = np.array([[0, 1, 1], [1, 0, 1], [1, 1, 0]]).astype(np.float32) >>> G array([[0., 1., 1.], [1., 0., 1.], [1., 1., 0.]], dtype=float32) >>> csgraph.laplacian(G) array([[ 2., -1., -1.], [-1., 2., -1.], [-1., -1., 2.]], dtype=float32)
但也可以生成 matrix-free 作為 LinearOperator:
>>> L = csgraph.laplacian(G, form="lo") >>> L <3x3 _CustomLinearOperator with dtype=float32> >>> L(np.eye(3)) array([[ 2., -1., -1.], [-1., 2., -1.], [-1., -1., 2.]])
或作為lambda-function:
>>> L = csgraph.laplacian(G, form="function") >>> L <function _laplace.<locals>.<lambda> at 0x0000012AE6F5A598> >>> L(np.eye(3)) array([[ 2., -1., -1.], [-1., 2., -1.], [-1., -1., 2.]])
拉普拉斯矩陣用於頻譜數據聚類和嵌入以及頻譜圖劃分。我們的最後一個示例說明了噪聲有向線性圖的後者。
>>> from scipy.sparse import diags, random >>> from scipy.sparse.linalg import lobpcg
使用稀疏鄰接矩陣
G
創建具有N=35
頂點的有向線性圖:>>> N = 35 >>> G = diags(np.ones(N-1), 1, format="csr")
修複隨機種子
rng
並向圖G
添加隨機稀疏噪聲:>>> rng = np.random.default_rng() >>> G += 1e-2 * random(N, N, density=0.1, random_state=rng)
設置特征向量的初始近似值:
>>> X = rng.random((N, 2))
常數向量始終是要濾除的非歸一化拉普拉斯算子的平凡特征向量:
>>> Y = np.ones((N, 1))
交替 (1) 圖權重的符號允許在單個循環中確定譜最大和最小切割的標簽。由於該圖是無向的,因此在構造拉普拉斯算子時必須使用選項
symmetrized=True
。選項normed=True
不能在 (2) 中用於此處的負權重,因為對稱歸一化計算平方根。 (2) 中的選項form="lo"
是 matrix-free,即保證固定的內存占用和對圖的隻讀訪問。調用特征值求解器lobpcg
(3) 計算 Fiedler 向量,該向量將標簽確定為 (5) 中其分量的符號。由於特征向量中的符號不是確定性的並且可以翻轉,因此我們將 (4) 中第一個分量的符號固定為始終 +1。>>> for cut in ["max", "min"]: ... G = -G # 1. ... L = csgraph.laplacian(G, symmetrized=True, form="lo") # 2. ... _, eves = lobpcg(L, X, Y=Y, largest=False, tol=1e-3) # 3. ... eves *= np.sign(eves[0, 0]) # 4. ... print(cut + "-cut labels:\n", 1 * (eves[:, 0]>0)) # 5. max-cut labels: [1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1] min-cut labels: [1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
正如對(稍微有噪音的)線性圖的預期,max-cut 剝離圖的所有邊,將所有奇數頂點著色為一種顏色,將所有偶數頂點著色為另一種顏色,而平衡的 min-cut 將圖在中間劃分為刪除單個邊。兩個確定的分區都是最優的。
相關用法
- Python SciPy csgraph.csgraph_to_dense用法及代碼示例
- Python SciPy csgraph.min_weight_full_bipartite_matching用法及代碼示例
- Python SciPy csgraph.minimum_spanning_tree用法及代碼示例
- Python SciPy csgraph.breadth_first_order用法及代碼示例
- Python SciPy csgraph.connected_components用法及代碼示例
- Python SciPy csgraph.dijkstra用法及代碼示例
- Python SciPy csgraph.breadth_first_tree用法及代碼示例
- Python SciPy csgraph.csgraph_from_dense用法及代碼示例
- Python SciPy csgraph.floyd_warshall用法及代碼示例
- Python SciPy csgraph.bellman_ford用法及代碼示例
- Python SciPy csgraph.csgraph_to_masked用法及代碼示例
- Python SciPy csgraph.maximum_flow用法及代碼示例
- Python SciPy csgraph.csgraph_masked_from_dense用法及代碼示例
- Python SciPy csgraph.shortest_path用法及代碼示例
- Python SciPy csgraph.reconstruct_path用法及代碼示例
- Python SciPy csgraph.johnson用法及代碼示例
- Python SciPy csgraph.maximum_bipartite_matching用法及代碼示例
- Python SciPy csgraph.depth_first_order用法及代碼示例
- Python SciPy csgraph.csgraph_from_masked用法及代碼示例
- Python SciPy csgraph.construct_dist_matrix用法及代碼示例
- Python SciPy csgraph.reverse_cuthill_mckee用法及代碼示例
- Python SciPy csgraph.depth_first_tree用法及代碼示例
- Python SciPy csgraph.structural_rank用法及代碼示例
- Python SciPy csc_array.diagonal用法及代碼示例
- Python SciPy csc_matrix.nonzero用法及代碼示例
注:本文由純淨天空篩選整理自scipy.org大神的英文原創作品 scipy.sparse.csgraph.laplacian。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。