景派HPC研究院丨oneAPI优化版scikit-learn与官方版对比测试
景派HPC研究院
由景派科技的技术团队组成,主要分享高性能计算领域的技术信息,与解答各位朋友在技术上遇到的问题和瓶颈,欢迎大家在文章下方的留言区讨论与提问。
Part1scikit-learn 简介
scikit-learn(曾称 scikit.learn,简称 sklearn),是 python 平台下免费开源的机器学习库。开源实现了机器学习中几乎所有常用的分类器、回归模型、聚类算法、降维算法、模型选择算法、数据预处理算法等 API。[1-2]
Fig 1~2 是截图自官网的简介。

Part2测试环境准备
从 oneAPI 官网中发现官方已经对 oneAPI 优化版 scikit-learn 进行了基准测试,如 Fig 3 所示。[3]

官方的基准测试是对比了 oneAPI 优化版 sklearn 在不同平台上的表现,而本文想要测试oneAPI优化版sklearn和官方版sklearn的性能差异
。因为 oneAPI 优化版 sklearn 使用的库大多是基于 Intel 环境优化过的,比如Intel Distribution for Python
,而官方版 sklearn 使用的库均为开源实现。为此,本文搭建了两个 Anaconda 环境,用于对比测试,如下表所示:
aikit-modin | jupyter-proj | |
---|---|---|
描述 | Intel® oneAPI AI Analytics Toolkit 提供的 Anaconda 环境,包含基于 Intel 底层库的 oneAPI 优化版 sklearn。 | 自己创建的 Anaconda 环境,包含基于开源 Python 环境的官方版 sklearn。 |
Python | Intel® Distribution for Python 3.7.9 | Python 3.7.9 |
sklearn | scikit-learn 0.24.1 prebuilt and accelerated with Intel® oneAPI Data Analytics Library (oneDAL), oneMKL, and oneTBB | scikit-learn 0.24.1 |
其他依赖 | 拉取自 Intel 官方 Anaconda 镜像仓库 | 拉取自 PyPi、conda-defaults |
Part3测试流程与代码实现
1导包
from sklearn.svm import SVC
from sklearn.decomposition import PCA
from sklearn.cluster import KMeans, DBSCAN
from sklearn import linear_model
import time
import numpy as np
import matplotlib.pyplot as plt
2设置随机数
统一随机数,使结果可复现
rand_val = 520
def set_rand(rand_val):
np.random.rand(rand_val)
set_rand(rand_val)
3实例化需要测试的算法
linear_reg = linear_model.LinearRegression() # 线性回归
logistic_reg_cla = linear_model.LogisticRegression(C=5) # 逻辑回归,实际上是分类模型
ridge_reg = linear_model.Ridge() # 岭回归
km1 = KMeans(n_clusters=1000) # K-Means聚类,聚为1000类
km2 = KMeans(n_clusters=5) # K-Means聚类,聚为5类
km3 = KMeans(n_clusters=20) # K-Means聚类,聚为20类
dbscan = DBSCAN() # DBSCAN聚类
pca = PCA() # 主成分分析
svc = SVC(C=2) # 支持向量机
elasnet_reg = linear_model.ElasticNet() # 弹性网络回归
4常见模型训练
在机器学习模型的应用过程中,训练往往花费巨大的时间,因此对于训练过程的优化是非常有必要的。接下来将会介绍常用的机器学习算法,并会使用随机数据进行测试。
K-Means 聚类
K-Means 算法通过把样本分离成 n 个具有相同方差的类的方式来聚集数据,最小化称为惯量(inertia) 或 簇内平方和(within-cluster sum-of-squares)的标准(criterion)。该算法需要指定簇的数量。它可以很好地扩展到大量样本(large number of samples),并已经被广泛应用于许多不同领域的应用领域。本文使用如下三个代码块对比测试 K-Means 算法在不同数据量、不同 K 值下的训练速度。
cla_x = np.random.random((20000, 20)) # 20K*20的数据
st = time.time()
km1.fit(cla_x) # K=1000
print(f'使用时间:{time.time()-st}')
cla_x = np.random.random((1000000, 50)) # 1M*50的数据
st = time.time()
km2.fit(cla_x) # K=5
print(f'使用时间:{time.time()-st}')
cla_x = np.random.random((100000, 50)) # 100K*50的数据
st = time.time()
km3.fit(cla_x) # K=20
print(f'使用时间:{time.time()-st}')
DBSCAN 聚类
DBSCAN 算法将簇视为被低密度区域分隔的高密度区域。由于这个相当普遍的观点,DBSCAN 发现的簇可以是任何形状的,与假设簇是凸的 K-Means 相反。DBSCAN 的核心概念是 core samples, 是指位于高密度区域的样本。因此一个簇是一组核心样本,每个核心样本彼此靠近(通过某个距离度量测量) 和一组接近核心样本的非核心样本(但本身不是核心样本)。算法中的两个参数, min_samples 和 eps,正式的定义了我们所说的 稠密(dense)。较高的 min_samples 或者较低的 eps 都表示形成簇所需的较高密度。本文使用如下代码块对比测试 DBSCAN 算法的训练速度。
cla_x = np.random.random((100000, 50)) # 100K*50的数据
st = time.time()
dbscan.fit(cla_x)
print(f'使用时间:{time.time()-st}')
PCA
主成分分析(PCA)用于对具有一组连续正交分量的多变量数据集进行方差最大化的分解。在 scikit-learn 中,PCA 被实现为一个变换器对象,通过 fit 方法可以拟合出 n 个成分,并且可以将新的数据投影到这些成分中。本文使用如下代码块对比测试 PCA 算法的训练的速度。
reg_x = np.random.random((9000000, 100)) # 9M*100
reg_y = np.random.random(9000000)
st = time.time()
linear_reg.fit(reg_x, reg_y)
print(f'使用时间:{time.time()-st}')
LinearRegression
普通最小二乘法(LinearRegression)拟合一个带有系数 的线性模型,使得数据集实际观测数据和预测数据(估计值)之间的残差平方和最小。其数学表达式为:
本文使用如下代码块对比测试 LinearRegression 算法的训练速度。
reg_x = np.random.random((30000000, 20)) # 30M*20
reg_y = np.random.random(30000000)
st = time.time()
linear_reg.fit(reg_x, reg_y)
print(f'使用时间:{time.time()-st}')
reg_x = np.random.random((4000000, 100)) # 4M*100
reg_y = np.random.random(4000000)
st = time.time()
linear_reg.fit(reg_x, reg_y)
print(f'使用时间:{time.time()-st}')
Ridge 回归
岭回归(Ridge) 回归通过对系数的大小施加惩罚来解决 普通最小二乘法 的一些问题。岭系数最小化的是带罚项的残差平方和,
其中, 是控制系数收缩量的复杂性参数: 的值越大,收缩量越大,模型对共线性的鲁棒性也更强。
本文使用如下代码块对比测试 Ridge 算法的训练速度。
reg_x = np.random.random((90000000, 20)) # 90M*20
reg_y = np.random.random(90000000)
st = time.time()
ridge_reg.fit(reg_x, reg_y)
print(f'使用时间:{time.time()-st}')
reg_x = np.random.random((9000000, 100)) # 9M*100
reg_y = np.random.random(9000000)
st = time.time()
ridge_reg.fit(reg_x, reg_y)
print(f'使用时间:{time.time()-st}')
logistic 回归
logistic 回归,虽然名字里有 “回归” 二字,但实际上是解决分类问题的一类线性模型。在某些文献中,logistic 回归又被称作 logit 回归,maximum-entropy classification(MaxEnt,最大熵分类),或 log-linear classifier(对数线性分类器)。该模型利用函数 logistic function 将单次试验(single trial)的可能结果输出为概率。本文使用如下代码块对比测试 logistic 回归算法的训练速度。
cla_x = np.random.random((10000000, 20)) # 10M*20
cla_y = np.random.randint(0, 5, 10000000)
st = time.time()
logistic_reg_cla.fit(cla_x, cla_y)
print(f'使用时间:{time.time()-st}')
cla_x = np.random.random((2000000, 100)) # 2M*100
cla_y = np.random.randint(0, 5, 2000000)
st = time.time()
logistic_reg_cla.fit(cla_x, cla_y)
print(f'使用时间:{time.time()-st}')
SVMs
支持向量机 (SVMs) 可用于以下监督学习算法: 分类, 回归 和 异常检测。支持向量机的优势在于:
在高维空间中非常高效。 即使在数据维度比样本数量大的情况下仍然有效。 在决策函数(称为支持向量)中使用训练集的子集,因此它也是高效利用内存的。 通用性: 不同的核函数 核函数 与特定的决策函数一一对应.常见的 kernel 已经提供,也可以指定定制的内核。
支持向量机的缺点包括:
如果特征数量比样本数量大得多,在选择核函数 核函数 时要避免过拟合, 而且正则化项是非常重要的。 支持向量机不直接提供概率估计,这些都是使用昂贵的五次交叉验算计算的。
本文使用如下两个代码块对比测试支持向量机在不同数据量下的训练速度。
cla_x = np.random.random((15300, 22)) # 15.3K*22
cla_y = np.random.randint(0, 5, 15300)
st = time.time()
svc.fit(cla_x, cla_y)
print(f'使用时间:{time.time()-st}')
cla_x = np.random.random((9900, 123)) # 9.9K*123
cla_y = np.random.randint(0, 5, 9900)
st = time.time()
svc.fit(cla_x, cla_y)
print(f'使用时间:{time.time()-st}')
ElasticNet
弹性网络(ElasticNet)是一种使用 L1, L2 范数作为先验正则项训练的线性回归模型。这种组合允许拟合到一个只有少量参数是非零稀疏的模型,就像 Lasso 一样,但是它仍然保持了一些类似于 Ridge 的正则性质。我们可利用 l1_ratio 参数控制 L1 和 L2 的凸组合。本文使用如下代码块对比测试弹性网络的训练速度。
reg_x = np.random.random((9630000, 90)) # 463K*100
reg_y = np.random.random(9630000)
st = time.time()
elasnet_reg.fit(reg_x, reg_y)
print(f'使用时间:{time.time()-st}')
Part4测试结果
在两个环境下分别运行测试脚本,得出运行时间,最终结果如下图所示:
结果表明,对于难以并行化实现的算法,oneAPI优化版sklearn和官方版的训练速度基本打平手(能是因为oneAPI优化版sklearn加入了众多并行化库导致一些开销,所以速度稍慢);而对于易于并行化实现的logistic 回归算法,oneAPI优化版sklearn
明显占优
,且数据量越大优势越明显
。
本文测试表明单节点下使用Intel® oneAPI AI Analytics Toolkit 提供的 Anaconda 环境中的sklearn进行训练在算法易于并行化、数据量大的情况下有明显的速度优势。oneAPI优化版sklearn获取方便,因此若是平时经常使用特定算法且训练数据量大的话可以考虑使用其进行加速。
Part5参考资料
[1] scikit-learn官网:https://scikit-learn.org
[2] scikit-learn (sklearn) 官方文档中文版:https://sklearn.apachecn.org/
[3] Intel® oneAPI AI Analytics Toolkit:https://software.intel.com/content/www/us/en/develop/tools/oneapi/ai-analytics-toolkit.html