简体   繁体   中英

Numpy.dot dot product function for statsmodels

I am learning statsmodels.api module to use python for regression analysis. So I started from the simple OLS model.

In econometrics, the function is like: y = Xb + e where X is NxK dimension, b is Kx1, e is Nx1, so adding together y is Nx1. This is perfectly fine from linear algebra point of view.

But I followed the tutorial from Statsmodels as the following:

import numpy as np
nsample = 100 # total obs is 100
x = np.linspace(0, 10, 100) # using np.linspace(start, stop, number)

X = np.column_stack((x, x**2))
beta = np.array([1, 0.1, 10])

e = np.random.normal(size = nsample) # draw numbers from normal distribution 
default at mu = 0, and std.dev = 1, size = set by user
# e is n x 1
# Now, we add the constant/intercept term to X
X = sm.add_constant(X)
# Now, we compute the y
y = np.dot(X, beta) + e

So this generates the correct answer. But I have a question about the generation of beta = np.array([1,0.1,10]). This beta, if we use:

beta.shape
(3,)

It has a dimension of (3,), the same goes with y and e except X:

X.shape
(100,3)
e.shape
(100,)
y.shape
(100,)

So I guess initiating array using the following three ways

o = array([1,2,3])
o1 = array([[1],[2],[3]])
o2 = array([[1,2,3]])
print(o.shape)
print(o1.shape)
print(o2.shape)
----------------
(3,)
(3, 1)
(1, 3)

If I use beta = array([[1],[2],[3]]), which is a (3,1), and np.dot(X, beta) gets me a wrong answer, although the dimension seems to work. If I use array([[1,2,3]]), which is a row vector, the dimension doesn't match for dot product in numpy, neither in linear algebra.

So, I am wondering why for a NxK dot Kx1 numpy dot product, we have to use a (N,K) dot (K,) instead of (N,K) dot (K,1) matrices. What operation makes only np.array([1, 0.1, 10]) works for numpy.dot() while np.array([[1], [0.1], [10]]) doesn't.

Thank you very much.


Some update

Sorry about the confusion, the codes in Statsmodels are randomly generated so I tried to fix the X and get the following input:

f = array([[1,2,3],[4,5,6],[7,8,9],[10,11,12],[13,14,15]])
o = array([1,2,3])
o1 = array([[1],[2],[3]])
o2 = array([[1,2,3]])
print(o.shape)
print(o1.shape)
print(o2.shape)
print("---------")
print(np.dot(f,o))
print(np.dot(f,o1))
r1 = np.dot(f,o)
r2 = np.dot(f,o1)
type1 = type(np.dot(f,o))
type2 = type(np.dot(f,o1))
tf = type1 is type2
tf2 = type1 == type2
print(type1)
print(type2)
print(tf)
print(tf2)
-------------------------
(3,)
(3, 1)
(1, 3)
---------
[14 32 50 68 86]
[[14]
 [32]
 [50]
 [68]
 [86]]
<class 'numpy.ndarray'>
<class 'numpy.ndarray'>
True
True

Sorry again for the confusion and inconvenience, they worked fine.

python/numpy is not a matrix-based language as it is Matlab or Octave or Scilab. These follow the rules of matrix multplication strictly. So

np.dot(f,o)  ---------> f*o  in Matlab/Octave/Scilab
np.dot(f,o1) ---------> f*o1 does not work in Matlab/Octave/Scilab

python/numpy has the 'broadcasting' which are the rules how the different data types and operations give together a result. It's not obvious why np.dot(f,o1) even should work, but the broadcasting defines some usefull results. You will have to consult the docs for that.

In python/numpy the * is not a matrix operator. You can find out what the broadcasting gives for

print(f*o)
print(f*o1)
print(f*o2)

Rather recently python/numpy has introduced the matrix operator @ . You might find out what happens with

print(f@o)
print(f@o1)
print(f@o2)

Does this give some impressions ?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM