我正在学习statsmodels.api模块,以便使用python进行回归分析。所以我从简单的OLS模型开始。
在计量经济学中,函数如下:y=Xb+e其中X是NxK维度,b是Kx1,e是Nx1,所以y加在一起就是Nx1。从线性代数的角度来看,这是非常好的。
但我遵循了Statsmodels的教程如下:
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
所以这就产生了正确的答案。但是我有一个关于生成β=np.array([1,10,10])的问题。这个β,如果我们使用:
beta.shape
(3,)
它的维数为(3,),除了X:之外,y和e也是如此
X.shape
(100,3)
e.shape
(100,)
y.shape
(100,)
所以我想启动阵列使用以下三种方式
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)
如果我使用β=数组([[1],[2],[3]),这是一个(3,1),而np.dot(X,β)给了我一个错误的答案,尽管维度似乎有效。如果我使用数组([[1,2,3]]),这是一个行向量,那么在numpy中,维度与点积不匹配,在线性代数中也是如此。
所以,我想知道为什么对于NxK点Kx1 numpy点积,我们必须使用(N,K)点(K,)而不是(N,K)点(K,1)矩阵。什么操作使得只有np.array([1,0.1,10])适用于numpy.dot(),而np.arrays([[1],[0.1],[10]])不适用。
非常感谢。
一些更新
很抱歉造成混淆,Statsmodels中的代码是随机生成的,所以我试图修复X并获得以下输入:
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
再次对造成的混乱和不便表示歉意,他们工作得很好。
python/numpy不是一种基于矩阵的语言,因为它是Matlab、Octave或Scilab。这些严格遵循矩阵多重应用的规则。所以
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有"广播",这是不同数据类型和操作如何组合在一起产生结果的规则。np.dot(f,o1)
为什么应该工作还不清楚,但广播定义了一些有用的结果。你必须查阅相关文件。
在python/numpy中,*
不是矩阵运算符。你可以了解的广播效果
print(f*o)
print(f*o1)
print(f*o2)
最近python/numpy引入了矩阵运算符@
。你可能会发现会发生什么
print(f@o)
print(f@o1)
print(f@o2)
这会给人留下一些印象吗?