python - 如何使用 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
抱歉,所有评论都是俄语)
解决方案
你有一个带有 CUDA 的 GPU 吗?那么您可以使用使用 NumPy 但在 GPU 上执行所有计算的 CuPy。这通常会导致性能提高 10 倍。当然,设置 CUDA 是一个痛苦的世界(尤其是如果你有旧硬件),但 CUDA 很受欢迎,而且非常高效和快速......
这是一个帮助您入门的链接:-
https://towardsdatascience.com/heres-how-to-use-cupy-to-make-numpy-700x-faster-4b920dda1f56
推荐阅读
- c# - 如何通过 Lambda 表达式创建 AutoCAD 对象并返回
- python - 逐像素二维辐射校准
- c# - 使用 ML.Net 在 C# 中进行图像分析
- git - 无法使用 Sourcetree 拉取或推送到 repo
- c# - EF Core - 连接字符串不能为空
- r - 图的两个方面的两个单独的 y 轴标题,同时使用 ggplot2 保留方面顶部条带标签
- php - 会话在 laravel 中过期并在提交表单后注销用户
- javascript - 原始 HTML 在 React 组件中的 DOM 上呈现
- django - '字段列表中的 Django CMS 未知列'djangocms_picture_picture.use_responsive_image'
- android - “单一活动架构” - 多个设备布局......我错过了什么?