从Cython中的* .pyd文件导入类Splitter

时间:2017-11-18 18:47:33

标签: scikit-learn cython

我正在尝试编写sklearn的类sklearn.tree._splitter.Splitter的子类。 我在cython中编写了以下子类:

from libc.string cimport memcpy 
import numpy as np
cimport numpy as np
np.import_array()

from sklearn.tree._splitter import Splitter, SplitRecord

from ._utils import rand_int

cdef double INFINITY = np.inf

cdef class StochasticSplitter(Splitter):
    """Splitter for finding a split stochastically."""
    def __reduce__(self):
        return (StochasticSplitter, (self.criterion,
                                     self.max_features,
                                     self.min_samples_leaf,
                                     self.min_weight_leaf,
                                     self.random_state,
                                     self.presort), self.__getstate__())

    cdef int node_split(self, double impurity, SplitRecord* split,
                        SIZE_t* n_constant_features) nogil except -1:
        """ Find the best split on node samples[start:end]
        Returns -1 in case of failure to allocate memory (and raise MemoryError)
        or 0 otherwise.
        """
        " My Logic...."

        # Return values
        split[0] = chosen_split
        n_constant_features[0] = n_total_constants
        return 0

但是当我尝试编译文件时,出现了以下错误:

  

'分配器'不是类型名称

  

' SplitRecord'不是类型标识符

为什么会这样? 我如何导入Splitter和SplitRecord以便我可以在cdef类中使用它们?

注意: - 我没有_splitter模块的.pyx和.pxd,所以我不能进行这些类的操作。我只有.pyd文件。 - 我想把这个类定义为cdef类(而不是常规的pythonic类),因为函数node_split使用指针(我不知道如何在python中使用指针)

我在网上和这里搜索过,发现了一些熟悉的问题,但是这些问题都没有帮助我...... 有谁可以帮助我?

1 个答案:

答案 0 :(得分:0)

需要cimport个文件:

from sklearn.tree._splitter cimport Splitter, SplitRecord

import在模块运行时发生,因此不向Cython提供任何信息。它也没有提供有关Cython所需的类的内部结构的信息。当Cython编译模块时会发生cimport,所以让Cython知道Splittercdef class,因此你应该能够继承它。

Cython所需的信息在编译的.pyd文件中确实不可用。您必须拥有.pxd文件。它还需要安装正确的路径,以便Cython找到它(即在名为sklearn\tree\的目录中和Python路径上)。

鉴于sklearn是开源的,所以没有理由不拥有必要的文件。见http://scikit-learn.org/stable/install.html。如果您的问题是由于您没有管理员权限而无法完全安装sklearn,那么您可以将其安装到用户目录目录中:

pip install --user -U sklearn

最好安装sklearn,而不是逐个复制文件。