首页 > 解决方案 > 如何使用 NumPy 在自定义 DecisionTreeClassifier 中加速方法“适合”?

问题描述

我正在做关于实现决策树分类器的作业,问题是我的算法有效,它产生的结果在准确性上并不比 sklearn 库中的树差,但它的工作时间要长得多。我在数据集“wine”上检查了它们,我的工作时间为 300 毫秒,而 sklearn 的工作时间为 1.5 毫秒,请告诉我应该如何只使用 numpy 库重写下面的代码,而不连接到 GPU 或类似的东西.

def __info(self, x, y, criterion):
    """
    Считаем меру неопределённости
    посредством критерия criterion
    по выборке (x, y)
    """
    y_len = y.shape[0]
    if y_len == 0:
        return 0.0

    prob_distr = np.bincount(y,\
                             minlength=self.num_class,\
                             weights=[1/y_len]*y_len)

    if   criterion == 'error':
        return 1 - prob_distr.max()

    elif criterion == 'gini':
        return 1 - np.power(prob_distr, 2).sum()

    elif criterion == 'entropy':
        return -(prob_distr * np.log2(prob_distr+1e-10)).sum() # 2 - в битах (e - натах).

    else:
        return 0.1
        # raise RuntimeError("No such criterion as \'{}\'!".format(criterion))


def __find_threshold(self, x, y):
    """
    Находим оптимальный признак и порог для сплита
    Здесь используемые разные impurity в зависимости от self.criterion
    """
    max_info_gain = -1
    if x.shape[0] == 0:
        raise RuntimeError("Received an empty sample!")

    for feature_id in range(x.shape[1]): # Использовать np.apply_along_axis()

        current_info = self.__info(x, y, self.criterion)

        tmp = np.unique(x[:,feature_id])
        if tmp.shape[0] < 2:
            thresholds = tmp
        else:
            thresholds = np.mean((tmp[:-1], np.roll(tmp, -1)[:-1]), axis=0)

        for threshold in thresholds: # Испо-ать np.apply_along_axis()

            x_left, x_right, y_left, y_right = self.__div_samples(x, y, feature_id, threshold)
            left_share = x_left.shape[0] / x.shape[0]

            left_info  = left_share       * self.__info(x_left,  y_left,  self.criterion)
            right_info = (1 - left_share) * self.__info(x_right, y_right, self.criterion)

            info_gain = current_info - left_info - right_info

            if info_gain > max_info_gain:

                max_info_gain = info_gain
                best_feature_id = feature_id
                best_threshold  = threshold


    x_left, x_right, y_left, y_right = self.__div_samples(x, y, best_feature_id, best_threshold) # ~о-мально!
    return best_feature_id, best_threshold, x_left, x_right, y_left, y_right

如果您愿意,可以在我的 github 中查看完整代码:https ://github.com/DaveMSU/msu_ml_spring_2020/blob/master/03/d.harazyan_hw3.ipynb

抱歉,所有评论都是俄语)

标签: pythonnumpymachine-learningscikit-learn

解决方案


你有一个带有 CUDA 的 GPU 吗?那么您可以使用使用 NumPy 但在 GPU 上执行所有计算的 CuPy。这通常会导致性能提高 10 倍。当然,设置 CUDA 是一个痛苦的世界(尤其是如果你有旧硬件),但 CUDA 很受欢迎,而且非常高效和快速......

这是一个帮助您入门的链接:-

https://towardsdatascience.com/heres-how-to-use-cupy-to-make-numpy-700x-faster-4b920dda1f56


推荐阅读