【问题标题】:Import the class Splitter from a *.pyd file in Cython从 Cython 中的 *.pyd 文件导入类 Splitter
【发布时间】:2017-11-18 18:47:32
【问题描述】:

我正在尝试编写 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

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

'Splitter' 不是类型名称

'SplitRecord' 不是类型标识符

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

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

我在互联网和这里搜索,发现了类似的问题,但其中的答案都没有帮助我...... 谁能帮帮我?

【问题讨论】:

    标签: scikit-learn cython


    【解决方案1】:

    需要cimport文件:

    from sklearn.tree._splitter cimport Splitter, SplitRecord
    

    import 在您的模块运行时发生,因此不会向 Cython 提供任何信息。它也不提供有关 Cython 需要的类的内部结构的信息。 cimport 在 Cython 编译模块时发生,因此让 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,而不是一个接一个地复制文件。

    【讨论】:

    • 但是当我尝试 cimport 类时,编译时出现以下错误:找不到 cimported module 'sklearn.tree._splitter''sklearn\ tree_splitter.pxd' not found(我真的没有 .pxd 文件,只有 .pyd 文件)。难道没有其他方法可以导入模块吗?
    • 我可能应该更仔细地阅读问题的结尾 - 你确实提到了 cimport.... 为什么你不能下载文件 github.com/scikit-learn/scikit-learn/blob/master/sklearn/tree/… ?真的没有其他方法 - Cython 需要这些信息来制作 cdef class
    • 嗯..我没想到。我会试试这个。我想过下载_spliter.pyx,但是_spliter.pyx cimport _criterion.Criterion,而_criterion 本身cimport 大约还有其他4 个模块,所以显得安静无止境。只下载 .pxd 文件就够了吗?
    • 编辑:好的,我试过了(我下载 _splitter.pxd 和 _criterion.pxd tp 与我的文件相同的目录,并在我的文件中导入它们并从 sklearn pakect 导入 _splitter.pyd) ,但现在它给了我错误 'sklearn\tree_splitter.pxd' not found 在行 from sklearn.tree._splitter import Splitter, SplitRecord...
    • 查看编辑。我认为您应该正确安装 sklearn 而不是一次下载一个文件
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-19
    • 1970-01-01
    • 2016-07-22
    • 1970-01-01
    • 2021-12-14
    • 1970-01-01
    相关资源
    最近更新 更多