优化这段代码:def oprobit(theta): beta=theta[0] BX = x*beta mu1=theta[1] mu2=theta[2] mu3=theta[3] mu4=theta[4] output=np.copy(y) part0=(np.log(stats.norm.cdf(mu1-BX[y==0])-stats.norm.cdf(-np.inf-BX[y==0]))) part1=(np.log(stats.norm.cdf(mu2-BX[y==1])-stats.norm.cdf(mu1-BX[y==1]))) part2=(np.log(stats.norm.cdf(mu3-BX[y==2])-stats.norm.cdf(mu2-BX[y==2]))) part3=(np.log(stats.norm.cdf(mu4-BX[y==3])-stats.norm.cdf(mu3-BX[y==3]))) part4=(np.log(stats.norm.cdf(np.inf-BX[y==4])-stats.norm.cdf(mu4-BX[y==4]))) return -(part0.sum()+part1.sum()+part2.sum()+part3.sum()+part4.sum())
时间: 2024-02-18 22:03:40 浏览: 31
可以尝试使用向量化计算,减少循环和重复计算。具体地,可以将 `part0`, `part1`, `part2`, `part3`, `part4` 的计算用向量表示,如下所示:
```
cdfs = stats.norm.cdf(np.array([mu1, mu2, mu3, mu4, np.inf]) - BX)
part0 = np.log(cdfs[0, y == 0] - stats.norm.cdf(-np.inf - BX[y == 0]))
part1 = np.log(cdfs[1, y == 1] - cdfs[0, y == 1])
part2 = np.log(cdfs[2, y == 2] - cdfs[1, y == 2])
part3 = np.log(cdfs[3, y == 3] - cdfs[2, y == 3])
part4 = np.log(stats.norm.cdf(np.inf - BX[y == 4]) - cdfs[3, y == 4])
```
其中,`cdfs` 是一个 $5 \times n$ 的数组,第 $i$ 行表示 $N(\mu_i, 1)$ 的累积分布函数值,$n$ 是样本数量。这样,代码的运行速度将得到显著提升。
相关问题
如何将下面的代码写成一个class:def oprobit(theta): beta=theta[0] BX = x*beta mu1=theta[1] mu2=theta[2] mu3=theta[3] mu4=theta[4] output=np.copy(y) part0=(np.log(stats.norm.cdf(mu1-BX[y==0])-stats.norm.cdf(-np.inf-BX[y==0]))) part1=(np.log(stats.norm.cdf(mu2-BX[y==1])-stats.norm.cdf(mu1-BX[y==1]))) part2=(np.log(stats.norm.cdf(mu3-BX[y==2])-stats.norm.cdf(mu2-BX[y==2]))) part3=(np.log(stats.norm.cdf(mu4-BX[y==3])-stats.norm.cdf(mu3-BX[y==3]))) part4=(np.log(stats.norm.cdf(np.inf-BX[y==4])-stats.norm.cdf(mu4-BX[y==4]))) return -(part0.sum()+part1.sum()+part2.sum()+part3.sum()+part4.sum()) minimize(oprobit, x0=np.array([0.8,4,5,6,7]))
可以将代码写成如下的class:
```python
import numpy as np
from scipy import stats
from scipy.optimize import minimize
class Oprobit:
def __init__(self, x, y):
self.x = x
self.y = y
def __call__(self, theta):
beta = theta[0]
BX = self.x * beta
mu1 = theta[1]
mu2 = theta[2]
mu3 = theta[3]
mu4 = theta[4]
output = np.copy(self.y)
part0 = (np.log(stats.norm.cdf(mu1 - BX[self.y == 0]) - stats.norm.cdf(-np.inf - BX[self.y == 0])))
part1 = (np.log(stats.norm.cdf(mu2 - BX[self.y == 1]) - stats.norm.cdf(mu1 - BX[self.y == 1])))
part2 = (np.log(stats.norm.cdf(mu3 - BX[self.y == 2]) - stats.norm.cdf(mu2 - BX[self.y == 2])))
part3 = (np.log(stats.norm.cdf(mu4 - BX[self.y == 3]) - stats.norm.cdf(mu3 - BX[self.y == 3])))
part4 = (np.log(stats.norm.cdf(np.inf - BX[self.y == 4]) - stats.norm.cdf(mu4 - BX[self.y == 4])))
return -(part0.sum() + part1.sum() + part2.sum() + part3.sum() + part4.sum())
```
然后可以通过如下方式调用:
```python
model = Oprobit(x, y)
result = minimize(model, x0=np.array([0.8, 4, 5, 6, 7]))
```
def oprobit(theta): beta=theta[0] BX = x*beta mu1=theta[1] mu2=theta[2] mu3=theta[3] mu4=theta[4] output=np.copy(y) part0=(np.log(stats.norm.cdf(mu1-BX[y==0])-stats.norm.cdf(-np.inf-BX[y==0]))) part1=(np.log(stats.norm.cdf(mu2-BX[y==1])-stats.norm.cdf(mu1-BX[y==1]))) part2=(np.log(stats.norm.cdf(mu3-BX[y==2])-stats.norm.cdf(mu2-BX[y==2]))) part3=(np.log(stats.norm.cdf(mu4-BX[y==3])-stats.norm.cdf(mu3-BX[y==3]))) part4=(np.log(stats.norm.cdf(np.inf-BX[y==4])-stats.norm.cdf(mu4-BX[y==4]))) return -(part0.sum()+part1.sum()+part2.sum()+part3.sum()+part4.sum())如何优化这个代码
可以考虑使用向量化操作来优化这段代码。具体来说,可以将条件语句和循环语句转化为矩阵运算,从而提高代码的效率。以下是一种可能的优化方案:
```
def oprobit(theta):
beta = theta[0]
BX = x.dot(beta)
mu = np.concatenate(([theta[1]], theta[2:]))
cdf1 = stats.norm.cdf(mu - BX)
cdf2 = np.concatenate(([0], cdf1[:-1]))
output = np.copy(y)
output[y == 0] = np.log(cdf1[y == 0] - cdf2[y == 0])
for i in range(1, 5):
output[y == i] = np.log(cdf1[y == i] - cdf1[y == i - 1])
return -output.sum()
```
在这个优化方案中,首先使用矩阵乘法计算出 $BX$,然后将 $\mu$ 向量化。接着使用 `stats.norm.cdf` 函数计算出 $P(Y \leq j | X = x_i)$,其中 $j$ 是 $0,1,2,3,4$ 中的一个数。注意到 $P(Y \leq 0 | X = x_i) = 0$,因此需要在 $cdf2$ 中添加一个 $0$。最后,使用循环语句对 $output$ 进行赋值。这样做可以避免重复计算 $P(Y \leq j | X = x_i)$,提高代码的效率。
相关推荐
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)