2012-09-06 38 views
18

Tôi muốn viết một hàm bình thường hóa các hàng của một ma trận thưa thớt lớn (như vậy chúng tổng hợp thành một).Cách hiệu quả để chuẩn hóa một Ma trận thưa thớt Scipy

from pylab import * 
import scipy.sparse as sp 

def normalize(W): 
    z = W.sum(0) 
    z[z < 1e-6] = 1e-6 
    return W/z[None,:] 

w = (rand(10,10)<0.1)*rand(10,10) 
w = sp.csr_matrix(w) 
w = normalize(w) 

Tuy nhiên này cung cấp cho các ngoại lệ sau đây:

File "/usr/lib/python2.6/dist-packages/scipy/sparse/base.py", line 325, in __div__ 
    return self.__truediv__(other) 
File "/usr/lib/python2.6/dist-packages/scipy/sparse/compressed.py", line 230, in __truediv__ 
    raise NotImplementedError 

Có bất kỳ giải pháp hợp lý đơn giản? Tôi đã xem this, nhưng vẫn chưa rõ cách thực sự làm việc phân chia.

+3

Về cơ bản, đây là bản sao của: http: //stackoverflow.c om/questions/12237954/multiplying-elements-in-a-sparse-array-với-rows-in-matrix vì nó không quan trọng nếu một hàng của nó theo phép nhân hoặc phép chia theo phần tử. Tất nhiên nếu ai đó có một câu trả lời tốt hơn, tuyệt vời :) – seberg

+0

Tuyệt vời - cảm ơn! – sterne

+0

Tôi không đồng ý, đây là một vấn đề khác. Bản sao bạn đã chỉ định nhân nhân tố khôn ngoan, trong khi câu hỏi này dường như muốn chia từng hàng theo một giá trị khác (chứ không phải tất cả các phần tử khác không bằng cùng một giá trị). Giải pháp của Aaron McDaid dưới đây sẽ hoạt động hiệu quả (và không yêu cầu sao chép dữ liệu). – conradlee

Trả lời

29

Điều này đã được triển khai trong scikit-learn sklearn.preprocessing.normalize.

from sklearn.preprocessing import normalize 
w_normalized = normalize(w, norm='l1', axis=1) 

axis=1 nên bình thường hóa theo hàng, axis=0 để chuẩn hóa theo cột. Sử dụng đối số tùy chọn copy=False để sửa đổi ma trận tại chỗ.

+2

Lưu ý rằng nếu bạn chuẩn hóa theo các tính năng (trục = 0) thì ma trận được trả lại thuộc loại 'csc' ngay cả khi w là một 'csr'. Điều này có thể khó chịu nếu bạn được tính là 'csr' – Leo

3

đây là giải pháp của tôi.

  • transpose Một tổng
  • tính toán của mỗi col
  • dạng đường chéo ma trận B với đối ứng của tổng
  • A * B bằng bình thường
  • transpose C

    import scipy.sparse as sp 
    import numpy as np 
    import math 
    
    minf = 0.0001 
    
    A = sp.lil_matrix((5,5)) 
    b = np.arange(0,5) 
    A.setdiag(b[:-1], k=1) 
    A.setdiag(b) 
    print A.todense() 
    A = A.T 
    print A.todense() 
    
    sum_of_col = A.sum(0).tolist() 
    print sum_of_col 
    c = [] 
    for i in sum_of_col: 
        for j in i: 
         if math.fabs(j)<minf: 
          c.append(0) 
         else: 
          c.append(1/j) 
    
    print c 
    
    B = sp.lil_matrix((5,5)) 
    B.setdiag(c) 
    print B.todense() 
    
    C = A*B 
    print C.todense() 
    C = C.T 
    print C.todense() 
    
Các vấn đề liên quan