2012-02-10 23 views
13

Tôi vừa mới bắt đầu học SciPy và đang đấu tranh với các tính năng cơ bản nhất.Sản phẩm Dot của một vector trong SciPy/NumPy (nhận ValueError: đối tượng không được căn chỉnh)

Hãy xem xét các vector theo tiêu chuẩn:

In [6]: W=array([[1],[2]]) 

In [7]: print W 
[[1] 
[2]] 

Nếu tôi hiểu nó một cách chính xác, điều này sẽ là đại diện scipy của một 2x1 vector toán học tiêu chuẩn, như thế này:

(1)  
(2) 

Dấu chấm sản phẩm của vector này chỉ đơn giản là 1*1+2*2=5. Tuy nhiên, điều này không hoạt động trong SciPy:

In [16]: dot(W, W) 
--------------------------------------------------------------------------- 
ValueError        Traceback (most recent call last) 
/home/ingo/<ipython-input-16-961b62a82495> in <module>() 
----> 1 dot(W, W) 

ValueError: objects are not aligned 

Lưu ý rằng các công việc sau đây. Đây phải là một vectơ có dạng (1 2) nếu tôi không nhầm.

In [9]: V=array([1,2]) 

In [10]: print V 
[1 2] 

In [11]: dot(V, V) 
Out[11]: 5 

Quan niệm sai lầm của tôi là gì? Tôi đang làm gì sai?

+0

Bạn có thể quên "hàng" và "cột" khi sử dụng * mảng *. Lưu ý rằng bạn cần nó khi sử dụng * ma trận *. – astrojuanlu

Trả lời

11

Điều quan trọng ở đây là việc xếp gọn hình dạng mảng khi tính toán các sản phẩm chấm. Nhìn vào ví dụ đầu tiên của bạn, W là một mảng 2x1:

In [7]: W=array([[1],[2]]) 

In [8]: print W.shape 
------> print(W.shape) 
(2, 1) 

nó là, do đó, cần thiết để sử dụng toán tử chuyển vị để tính toán dấu chấm (bên trong) Sản phẩm của W với chính nó:

In [9]: print dot(W.T,W) 
------> print(dot(W.T,W)) 
[[5]] 

In [10]: print np.asscalar(dot(W.T,W)) 
-------> print(np.asscalar(dot(W.T,W))) 
5 
0

Đó là một mảng gồm hai mảng, không phải là mảng của hai giá trị. Người đầu tiên có thể được coi là ma trận: hai hàng với một cột mỗi cột.

Điều thứ hai là chính xác; nó cung cấp cho bạn đúng sản phẩm dấu chấm là tốt. Tin vào mắt bạn; sử dụng thứ hai.

+0

Ok, do đó, 'V = mảng ([1,2])' một vectơ có hai hàng và một cột, hoặc một cột và hai hàng? – Ingo

+0

@Có, đó là một véc tơ có một hàng và không có cột nào. Đó là véc tơ 1 chiều. 'numpy' phân biệt giữa các mảng và ma trận của hình dạng' (2,) 'và hình dạng' (2, 1) 'hoặc hình dạng' (1, 2) '. – senderle

+0

Đó là vectơ hàng: 1 hàng, 2 cột. HOẶC một vector cột: 2 hàng, 1 cột. Phụ thuộc vào cách nó được sử dụng. đó là điều nhà toán học nói – duffymo

0

Trong ví dụ đầu tiên, W là một mảng 2 chiều, trong khi ở cuối cùng (mảng hoạt động), bạn chỉ có 1 mờ.

Yon có thể chắc chắn cách thứ 2 là cách phù hợp để thực hiện việc này.

4

Trong trường hợp đầu tiên, bạn tạo ra vectơ là một mảng hai chiều, về cơ bản là ma trận 2-by-1. Trong trường hợp đó, không thể lấy sản phẩm dấu chấm vì ma trận m-by-n chỉ có thể được rải rác bằng ma trận n-by-k. Giải pháp là sử dụng:

dot(W.T,W) 

Điều này giống như cách x.x đôi khi được viết x^T x.

Trong trường hợp thứ hai, để tạo thuận tiện cho việc tạo ra mảng một chiều thay vì ma trận, do đó, sản phẩm chấm có định nghĩa đơn giản. Nếu bạn tạo một ma trận 1-by-2 bằng cách sử dụng

W = np.array([[1,2]]) 

thì bạn sẽ có được hành vi tương tự như trong trường hợp đầu tiên.

3

Bạn đang nhầm lẫn về hình dạng của mảng bạn vượt qua trong:

>>> W = np.array([[1], [2]]) 
>>> W.shape 
(2, 1) 
>>> W = np.array([1, 2]) 
>>> W.shape 
(2,) 

Như bạn đã quan sát, sử dụng np.dot vào định nghĩa thứ hai của W công trình như mong đợi.Để chấm một 2-d ma trận với chính nó, khi nó không phải là hình vuông, bạn phải transpose:

>>> W = np.array([[1], [2]]) 
>>> np.dot(W, W.transpose()) 
array([[1, 2], 
     [2, 4]]) 

Một shortcut cho transposeW.T

Lưu ý rằng hình dạng của các đầu ra khác nhau tùy vào việc bạn bắt đầu với chuyển vị hoặc bản gốc, như mong đợi:

>>> np.dot(W.T, W) 
array([[5]]) 
>>> np.dot(W.T, W).shape 
(1, 1) 

Xem tài liệu numpy để biết thêm.

9

Bạn nên sử dụng vdot: "Trả lại sản phẩm chấm của hai vectơ". Hàm này làm phẳng các đối số đầu vào và cho kết quả bạn mong đợi. Ví dụ:

>>> W = np.array([[1], [2]]) 
>>> np.vdot(W, W) 
5 
>>> 
Các vấn đề liên quan