2012-08-25 29 views
7

Tôi đang cố gắng viết một thuật toán phân cụm phổ sử dụng NumPy/SciPy cho các hệ thống lớn hơn (nhưng vẫn có thể xử lý), sử dụng thư viện đại số tuyến tính thưa thớt của SciPy. Thật không may, tôi đang gặp sự cố về tính ổn định với eigsh().Scipy sparse eigsh() cho các giá trị riêng nhỏ của Scipy

Dưới đây là mã của tôi:

import numpy as np 
import scipy.sparse 
import scipy.sparse.linalg as SLA 
import sklearn.utils.graph as graph 

W = self._sparse_rbf_kernel(self.X_, self.datashape) 
D = scipy.sparse.csc_matrix(np.diag(np.array(W.sum(axis = 0))[0])) 
L = graph.graph_laplacian(W) # D - W 
vals, vects = SLA.eigsh(L, k = self.k, M = D, which = 'SM', sigma = 0, maxiter = 1000) 

Thư viện sklearn đề cập đến gói scikit-học, cụ thể this method để tính một Laplacian đồ thị từ một ma trận scipy thưa thớt.

_sparse_rbf_kernel là phương pháp tôi đã viết để tính toán các mối quan hệ theo cặp của các điểm dữ liệu. Nó hoạt động bằng cách tạo một ma trận ái lực thưa thớt từ dữ liệu hình ảnh, đặc biệt là chỉ tính toán các mối quan hệ theo cặp cho 8 vùng lân cận xung quanh mỗi pixel (thay vì theo cặp cho tất cả các pixel với phương thức rbf_kernel của scikit-learn).).

Vì laplacian là không chuẩn hóa, tôi đang tìm các giá trị riêng nhỏ nhất và các biến riêng của hệ thống. Tôi hiểu rằng ARPACK is ill-suited for finding small eigenvalues, nhưng tôi đang cố gắng sử dụng chuyển đổi đảo ngược để tìm các giá trị này và vẫn không có nhiều thành công.

Với những lập luận trên (đặc biệt là sigma = 0), tôi nhận được lỗi sau:

RuntimeError: Factor is exactly singular 

Với sigma = 0.001, tôi nhận được một lỗi khác nhau:

scipy.sparse.linalg.eigen.arpack.arpack.ArpackNoConvergence: ARPACK error -1: No convergence (1001 iterations, 0/5 eigenvectors converged) 

Tôi đã thử tất cả ba khác nhau giá trị cho mode với cùng một kết quả. Bất kỳ đề xuất nào về việc sử dụng thư viện thưa thớt SciPy để tìm các giá trị riêng nhỏ của một hệ thống lớn?

Trả lời

11

Bạn nên sử dụng which='LM': ở chế độ chuyển đổi ngược, tham số này đề cập đến các giá trị riêng được chuyển đổi. (Như được giải thích trong the documentation.)

+0

Phải, nhưng vấn đề là tôi muốn các giá trị riêng nhỏ nhất và các biến riêng của chúng, chứ không phải lớn nhất. Tài liệu giải thích rằng nếu các giá trị riêng nhỏ được mong muốn, chế độ chuyển đổi nghịch đảo nên được sử dụng để cải thiện hiệu suất, đó là những gì tôi đã cố gắng thực hiện bằng cách sử dụng 'sigma', không có kết quả. – Magsol

+3

Ở trên sẽ cung cấp cho bạn chính xác những gì bạn muốn. Lưu ý: với sigma = 0, các giá trị riêng được biến đổi là w '= 1/(w-sigma) = 1/w. Do đó, với 'which = 'LM'' bạn nhận được các giá trị riêng với lớn ** w' **, hay nói cách khác, các giá trị riêng nhỏ nhất của bài toán gốc. Nếu bạn sử dụng chế độ chuyển đổi nghịch đảo, bạn cũng cần điều chỉnh tham số 'which' cho phù hợp. –

+2

Chỉ muốn nói điều này cực kỳ hữu ích – YXD

Các vấn đề liên quan