Numpy中矩阵乘法的正确语法?

Correct syntax for matrix multiplication in Numpy?

提问人:Andres Mallcott 提问时间:9/30/2023 最后编辑:Andres Mallcott 更新时间:10/2/2023 访问量:84

问:

我想使用 Numpy 将以下公式转换为 Python 代码。请注意,mu 是 3x1 向量,sigma 是使用协方差矩阵的 3x3 矩阵。

enter image description here

u = np.array([0.0493, 0.0770, 0.0886])
cov_matrix = ([[0.0017, -0.0017, -0.0021],
               [-0.0017, 0.0396, 0.0309],
               [-0.0021, 0.0309, 0.0392]])

def hyperbola(u):
    k = u * np.linalg.inv(cov_matrix)                       
    l = u * np.linalg.inv(cov_matrix) * u[:, np.newaxis]    
    m = np.linalg.inv(cov_matrix)                           

    g = (l * np.linalg.inv(cov_matrix) - k * np.linalg.inv(cov_matrix) * u[:, np.newaxis]) / (l*m - k**2)
    h = (m * np.linalg.inv(cov_matrix) * u[:, np.newaxis] - k * np.linalg.inv(cov_matrix)) / (l*m - k**2)
    
    a = h * cov_matrix * h[:, np.newaxis]
    b = 2 * g * cov_matrix * h[:, np.newaxis]
    c = g * cov_matrix * g[:, np.newaxis]

    return np.sqrt(a * u**2 + b*u + c)


efficient_frontier = hyperbola(u)

我构造了上面的内容,但是,生成的双曲线是 3x3x3。我到底做错了什么?我确实在转置 mu 向量时遇到了一些问题,也许与此有关?

提前致谢!

编辑:我现在已经创建了下面的代码,它似乎产生了正确的代码结构,但没有产生预期的曲线形状。

def hyperbola(u):
    k = u @ np.linalg.inv(cov_matrix) @ np.ones_like(u)                  
    l = u @ np.linalg.inv(cov_matrix) @ u
    m = np.ones_like(u) @ np.linalg.inv(cov_matrix) @ np.ones_like(u)

    g = (l * np.linalg.inv(cov_matrix) @ np.ones_like(u) - k * np.linalg.inv(cov_matrix) @ u) / (l*m - k**2)
    h = (m * np.linalg.inv(cov_matrix) @ u - k * np.linalg.inv(cov_matrix) @ np.ones_like(u)) / (l*m - k**2)
    
    a = h @ cov_matrix @ h
    b = 2 * g @ cov_matrix @ h
    c = g @ cov_matrix @ g

    return np.sqrt(a * u**2 + b*u + c)

efficient_frontier = hyperbola(u)

plt.plot(u, efficient_frontier)
plt.xlabel('Volatility')
plt.ylabel('Mean Return')
plt.grid(True)

预期曲线应类似于下面的红色曲线。为什么我得到不同的结果?我已经多次浏览了所有变量,但找不到差异。

enter image description here

Python 数学 矩阵 向量

评论

7赞 Michael Cao 9/30/2023
乘法符号用于元素乘法,而不是矩阵乘法。对于 numpy,您希望使用 .您还可以用于矩阵/向量的转置。*@h.T
0赞 Andres Mallcott 9/30/2023
这很简单。有道理,谢谢。至于使用 .T,我注意到这对向量不起作用,因为它们只是保持相同的形式。到目前为止,该方法是我发现的唯一一种方法。h[:, np.newaxis]
1赞 Stef 9/30/2023
请参阅转置 1d numpy 数组?。如果向量被存储为一维 numpy 数组,您可能根本不需要转置它们。不要使用 nor .如果向量被存储为 numpy 2d 数组,则只需要显式转置它们。您的向量存储为 shape 的一维数组,而不是 shape 或 的二维数组,因此您不需要显式转置它们。只需用于乘法,numpy 就会知道如何处理向量。.T[:, np.newaxis]3(3, 1)(1, 3)@
1赞 Stef 9/30/2023
顺便说一句,在stackoverflow上,如果你在你的问题中包含代码,那么让它“可重现”,或者换句话说,自包含被认为是很好的风格。这里没有人可以运行你的代码,因为它在没有定义变量的情况下调用。因此,在您向我们展示的代码中添加显式或类似内容将是一个很好的风格。hyperbola(u)uu = np.array([1, 2, 3])
0赞 Andres Mallcott 9/30/2023
我明白了,谢谢你的解释!

答: 暂无答案