Graduate Quantitative Economics and Datascience
This section uses the following packages:
A = np.array([[3, 1],
[1, 2]])
# A_eigs = np.real(eigvals(A)) # symmetric matrices have real eigenvalues
A_eigs = eigvalsh(A) # specialized for symmetric/hermitian matrices
print(A_eigs)
is_positive_definite = np.all(A_eigs > 0)
is_positive_semi_definite = np.all(A_eigs >= 0) # or eigvals(A) >= -eps
print(f"pos-def? {is_positive_definite}")
print(f"pos-semi-def? {is_positive_semi_definite}")
[1.38196601 3.61803399]
pos-def? True
pos-semi-def? True
A = np.array([[3, -0.1],
[-0.1, 2]])
# A_eigs = np.real(eigvals(A)) # symmetric matrices have real eigenvalues
A_eigs = eigvalsh(A) # specialized for symmetric/hermitian matrices
print(A_eigs)
is_positive_definite = np.all(A_eigs > 0)
is_positive_semi_definite = np.all(A_eigs >= 0) # or eigvals(A) >= -eps
print(f"pos-def? {is_positive_definite}")
print(f"pos-semi-def? {is_positive_semi_definite}")
[1.99009805 3.00990195]
pos-def? True
pos-semi-def? True
A_eigs = eigvalsh(np.array([[1, 0],
[0, 0]]))
print(A_eigs)
is_positive_definite = np.all(A_eigs > 0)
is_positive_semi_definite = np.all(A_eigs >= 0) # or eigvals(A) >= -eps
print(f"pos-def? {is_positive_definite}")
print(f"pos-semi-def? {is_positive_semi_definite}")
[0. 1.]
pos-def? False
pos-semi-def? True
A = -1 * np.array([[3, -0.1],
[-0.1, 2]])
A_eigs = eigvalsh(A)
print(A_eigs)
is_negative_definite = np.all(A_eigs < 0)
is_negative_semi_definite = np.all(A_eigs <= 0) # or eigvals(A) >= -eps
print(f"neg-def? {is_negative_definite}, neg-semi-def? {is_negative_semi_definite}")
[-3.00990195 -1.99009805]
neg-def? True, neg-semi-def? True
A = np.array([[-1, -1],
[-1, -1]])
A_eigs = eigvalsh(A)
print(A_eigs)
is_negative_definite = np.all(A_eigs < 0)
is_negative_semi_definite = np.all(A_eigs <= 0) # or eigvals(A) >= -eps
print(f"neg-def? {is_negative_definite}, neg-semi-def? {is_negative_semi_definite}")
[-2. 0.]
neg-def? False, neg-semi-def? True
eigs(A) = [-6.1925824 -0.8074176]
neg-def? True
eigs(A) = [-6.12310563 2.12310563]
Given a matrix \(X \in \mathbb{R}^{N \times M}\) and a vector \(y \in \mathbb{R}^N\), we want to find \(\beta \in \mathbb{R}^M\) such that \[ \begin{aligned} \min_{\beta} &||y - X \beta||^2, \text{ that is,}\\ \min_{\beta} &\sum_{n=1}^N \frac{1}{N}(y_n - X_n \cdot \beta)^2 \end{aligned} \]
Where \(X_n\) is n’th row. Take FOCS and rearrange to get
\[ (X^T X) \beta = X^T y \]
The \(X\) is often referred to as the “design matrix”. \(X^T X\) as the Gram matrix
Can form \(A = X^T X\) and \(b = X^T y\) and solve \(A \beta = b\).
\[ \beta = (X^T X)^{-1} X^T y \]
lstsq
better algorithms (more numerically stable, same “order”, possibly slightly slower)statsmodels
(integrates with pandas
and seaborn
)
N, M = 100, 5
X = np.random.randn(N, M)
beta = np.random.randn(M)
y = X @ beta + 0.05 * np.random.randn(N)
beta_hat, residuals, rank, s = scipy.linalg.lstsq(X, y)
print(f"beta =\n {beta}\nbeta_hat =\n{beta_hat}")
beta =
[-0.4342627 1.19270521 -0.4459076 -0.07885572 0.29519551]
beta_hat =
[-0.4276657 1.18800663 -0.43845695 -0.07074571 0.30388576]
Or we can solve it directly. Provide matrix structure (so it can use a Cholesky)
XX = X.T @ X
Xy = X.T @ y
beta_hat = solve(XX, Xy, assume_a="pos")
# beta_hat = solve(X.T @ X, X.T @ y, assume_a="pos")
print(f"beta =\n {beta}\nbeta_hat =\n{beta_hat}")
beta =
[-0.4342627 1.19270521 -0.4459076 -0.07885572 0.29519551]
beta_hat =
[-0.4276657 1.18800663 -0.43845695 -0.07074571 0.30388576]
cond(X) = 53.09739144854023, cond(X'*X)=2819.3329786399063, cond(X_col'*X_col)=1.2999933999712892e+16
lstsq
Solves it? Careful on Interpretation!solve(X.T@X, y)
lstsq
methods?lstsq
is giving\[ \min_{\beta} ||\beta||_2^2 \text{ s.t. } X \beta = y \]
eigenvalues of A: [2. 0.]
eigenvalues of A: [2.00001e+00 1.00000e-05]
lstsq
will return some solution even if not full rank.