结合python和c++;,或cython,以优化函数;最大似然示例;对c+知之甚少+; 我知道Python,但我不知道C++。我试图最大化一个需要很长时间才能计算的函数。我相信一个好的工作流程是编写C++中的函数的函数,并用SIPY.Opvest.Max最小化这个函数来找到最佳的。作为一个例子,假设我正在最大化一个可能性 import pandas as pd import numpy as np from scipy.optimize import minimize from scipy.stats import norm # simulating data means = np.array([10, 20, 30]) cov = np.diag([1, 4, 10]) N = 1000 df = pd.DataFrame(np.random.multivariate_normal(mean=means, cov=cov, size=N), columns=['a', 'b', 'c']) df[np.random.choice([True, False], size=(N, 3), p=[0.3, 0.7])] = np.nan # a function to print parameters used in likelihood function def print_params(params): print('Means: {}'.format(params[:3])) print('Variances: {}'.format(np.exp(params[3:])**2)) # defining likelihood def llf(params): logll = 0 for i in df.index: for j,col in enumerate(['a', 'b', 'c']): if not np.isnan(df.loc[i, col]): m = params[j] sd = np.exp(params[j+3]) logll += np.log(norm.pdf(df.loc[i, col], loc=m, scale=sd)) print_params(params) return -logll opt = minimize(llf, x0=np.array([0, 0, 0, 1, 1, 1]), options={'maxiter':30}) print_params(opt.x)

结合python和c++;,或cython,以优化函数;最大似然示例;对c+知之甚少+; 我知道Python,但我不知道C++。我试图最大化一个需要很长时间才能计算的函数。我相信一个好的工作流程是编写C++中的函数的函数,并用SIPY.Opvest.Max最小化这个函数来找到最佳的。作为一个例子,假设我正在最大化一个可能性 import pandas as pd import numpy as np from scipy.optimize import minimize from scipy.stats import norm # simulating data means = np.array([10, 20, 30]) cov = np.diag([1, 4, 10]) N = 1000 df = pd.DataFrame(np.random.multivariate_normal(mean=means, cov=cov, size=N), columns=['a', 'b', 'c']) df[np.random.choice([True, False], size=(N, 3), p=[0.3, 0.7])] = np.nan # a function to print parameters used in likelihood function def print_params(params): print('Means: {}'.format(params[:3])) print('Variances: {}'.format(np.exp(params[3:])**2)) # defining likelihood def llf(params): logll = 0 for i in df.index: for j,col in enumerate(['a', 'b', 'c']): if not np.isnan(df.loc[i, col]): m = params[j] sd = np.exp(params[j+3]) logll += np.log(norm.pdf(df.loc[i, col], loc=m, scale=sd)) print_params(params) return -logll opt = minimize(llf, x0=np.array([0, 0, 0, 1, 1, 1]), options={'maxiter':30}) print_params(opt.x),c++,python-3.x,scipy,cython,C++,Python 3.x,Scipy,Cython,用纯Python编写llf函数可能有更有效的方法,当然也有加速优化例程的方法(例如,通过选择适合问题的特定优化器,或通过提供衍生工具),但这不是这个问题的重点。我选择这个特定的例子是因为我有一个循环(我使用所有的数据,包括某些列缺少值的行)来评估可能性,这在纯python中需要花费很多时间,特别是如果我的样本量增加的话 如何在C++中编写似然函数并将其与Python最小化程序结合起来?请记住,我没有C++的经验,但我愿意学习。然而,许多可用的资源似乎都假定C++知识,例如参见。我在寻找一个知道P

用纯Python编写
llf
函数可能有更有效的方法,当然也有加速优化例程的方法(例如,通过选择适合问题的特定优化器,或通过提供衍生工具),但这不是这个问题的重点。我选择这个特定的例子是因为我有一个循环(我使用所有的数据,包括某些列缺少值的行)来评估可能性,这在纯python中需要花费很多时间,特别是如果我的样本量增加的话


如何在C++中编写似然函数并将其与Python最小化程序结合起来?请记住,我没有C++的经验,但我愿意学习。然而,许多可用的资源似乎都假定C++知识,例如参见。我在寻找一个知道Python的人的资源,但是完全不知道C++和Python与C++的结合方法。Eng>编辑:也许是使用我的例子来做这个的例子,或者关于组合Python和C++的可能收益的信息,这是有用的。由于我以前从未使用过Cython,因此我将完成用于实现Cython解决方案的步骤

首先,我安装了Cython。然后我编写了一个名为
fastlf.pyx
的文件,其中包含以下Cython代码:

#cython: boundscheck=False, wraparound=False, nonecheck=False

from libc.math cimport exp, sqrt, pi, log, isnan

cdef double SQ_PI = sqrt(2*pi)


cdef double norm_pdf(double x, double loc, double scale):
    return (1/(SQ_PI*scale))*exp(-(0.5)*((x - loc)**2)/(scale**2))

cdef double llf_c(double[:, :] X, double[:] params):

    cdef double logll = 0
    cdef int N = X.shape[0]
    cdef int K = X.shape[1]
    cdef int i, j
    cdef double m, sd

    for i in range(N):
        for j in range(K):
            if not isnan(X[i, j]):
                m = params[j]
                sd = exp(params[j+K])

                logll += log(norm_pdf(X[i, j], m, sd))
    return -logll

def llf(double[:, :] X, double[:] params):
    return llf_c(X, params)
然后我创建了一个
setup.py
文件,其中包括以下内容:

from distutils.core import setup
from Cython.Build import cythonize

setup(name="fastllf", ext_modules=cythonize('fastllf.pyx'))
接下来,我在终端中使用以下命令编译了Cython代码

$ python3 setup.py build_ext --inplace
最后,我比较了我的旧的纯Python实现(稍微修改为使用数组而不是数据帧)和Cython实现之间的结果

import numpy as np
from scipy.stats import norm
import time
from fastllf import llf as cython_llf

# simulating data
means = np.array([10, 20, 30])
cov = np.diag([1, 4, 10])

N = 100000
np.random.seed(10)

X = np.random.multivariate_normal(mean=means, cov=cov, size=N)
X[np.random.choice([True, False], size=(N, 3), p=[0.3, 0.7])] = np.nan

def norm_pdf(x, loc, scale):
    return (1/(np.sqrt(2*np.pi)*scale))*np.exp(-(0.5)*((x-loc)**2)/(scale**2))

def llf(X, params):

    logll = 0
    N = X.shape[0]
    K = X.shape[1]

    for i in range(N):
        for j in range(K):
            if not np.isnan(X[i, j]):
                m = params[j]
                sd = np.exp(params[j+K])

                logll += np.log(norm_pdf(X[i, j], loc=m, scale=sd))    
    return -logll    

def timeit(fun, *args):
    start = time.time()
    rslt = fun(*args)
    end = time.time()
    print(rslt)
    print(end - start)

params = np.array([1.,1,1,1,1,1])
timeit(llf, X, params)
timeit(cython_llf, X, params)
我得到了以下结果:

Python Value: 6570173.7597125955
Python Time:  1.9558300971984863 seconds
Cython Value: 6570173.7597125955
Cython Time:  0.016242027282714844 seconds
这使得最大似然优化更可行,尤其是当我的问题变得更复杂时。唯一的问题是我需要找到数学和统计函数,我需要在Cython中编写
llf
函数,或者我需要编写自己的函数,就像我在上面的普通pdf中所做的那样


如对我的实施有任何意见,将不胜感激

如果你在寻找资源,你的问题是离题的,因为“要求我们推荐或查找书籍、工具、软件库、教程或其他离题资源的问题是离题的,因为它们往往会吸引自以为是的答案和垃圾邮件。”C++是一种非常复杂的语言,我怀疑在C++中编写循环真的会加快它的速度。如果你不知道C++,如果你的问题是关于C++和Python的桥接,那么你可能会发现Cython更容易接近。如果目标是更快的性能,我会在触发之前做很多分析——我怀疑Python在很多方面已经非常优秀了,并且有一些Python包可以做一些功能强大(而且性能很好)的数字处理。我的C++ C++ C++语言的解决方案是,C++/Python解决方案将远远不如性能——不是因为C++是慢的,而是桥接是开销,性能C++需要很多强大的C++知识。我认为这种模式是用python编写大部分代码,但用较低级别的语言编写性能关键的部分。您能解释一下为什么使用C++的Python不会在速度上产生大的增益吗?比如<代码> @ EJAAY < /COD> >说,性能瓶颈可能在桥接开销(从Python到C和Boad)。想象一下,有一辆停在车流中的快车。。。你是否能获得速度提升取决于你打了多少C电话,以及每次电话的持续时间。另外,最好先分析一下Python代码,看看哪一部分真正限制了性能。例如,我曾经注意到在pandas数据帧的元素上循环要比首先将数据帧转换为numpy然后执行循环慢得多。我不确定编译器是否预计算常量。例如,在Cython代码中,有常数项,如
sqrt(2*pi)
1/2.
。您可以预定义(在代码顶部)并手动替换为
SQ_PI=sqrt(2*PI)
0.5
。此外,如果将
sd
计算为
inv\u sd=exp(-params[j+k])
,则可以去掉
norm\u pdf
中的所有浮点除法。除法和平方根在计算上非常昂贵,所以尽可能用乘法代替它们。除此之外,我有点惊讶Cython比您的本地Python实现快1000倍以上。这种加速相当极端。是否
scipy.stats.norm.pdf()
函数有速率限制?您能否将自己的
norm\u pdf
函数实现到本地Python中,看看它是否有什么不同?我不确定如何将
sd
实现为
inv\u sd
,但我实现了您的其他建议。我还用Python编写了我自己的norm_pdf,并且非常惊讶地看到了不同之处。你知道为什么会这样吗?你必须检查
scipy.stats.norm.pdf()
的源代码,看看它到底在做什么,但是很明显,与你自己的实现相比,有各种背景检查或计算会使它慢4倍。Cython实现