Функция точечного произведения Numpy.dot для statsmodels - PullRequest
0 голосов
/ 18 января 2019

Я изучаю модуль 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

Так что это дает правильный ответ. Но у меня есть вопрос о генерации beta = np.array ([1,0.1,10]). Эта бета, если мы используем:

beta.shape
(3,)

Он имеет размерность (3,), то же самое относится к y и e, за исключением X:

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)

Если я использую beta = array ([[1], [2], [3]]), который является (3,1), и np.dot (X, beta) дает мне неправильный ответ, хотя измерение, кажется, работает. Если я использую массив ([[1,2,3]]), который является вектором строки, размерность не совпадает для точечного произведения ни в numpy, ни в линейной алгебре.

Итак, мне интересно, почему для произведения NxK dot Kx1 numpy dot мы должны использовать (N, K) dot (K,) вместо (N, K) dot (K, 1) матриц. То, что делает только np.array ([1, 0.1, 10]), работает для numpy.dot (), а np.array ([[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

Еще раз извините за сумбур и неудобства, они работали нормально.

1 Ответ

0 голосов
/ 18 января 2019

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)

Это дает какие-то впечатления?

...