Joblib 基本使用方法简介

Joblib是一组在 Python 中提供轻量级pipeline的工具
在这里插入图片描述
以下是几个例子:

可以将joblib工具集成为ML管道,它有两个主要优点:

- Cache:使用缓存,避免重新计算
- Parallelization:并行化,充分利用CPU/GPU的所有核心。

1. Cache:使用缓存,避免重新计算

在这里插入图片描述

import time
import numpy as np

result = []

# 计算平方的函数:
def square_number(no):
    return (no*no)

# 连续计算平方:
def get_square_range(start_no, end_no):
    for i in np.arange(start_no, end_no):
        time.sleep(1)
        result.append(square_number(i))
    return result

start = time.time()
# 1到10的平方:
final_result = get_square_range(1, 21)
end = time.time()

# 总耗时
print('\n 计算总耗时{:.2f}s.'.format(end - start))
print(final_result)

在这里插入图片描述
现在使用joblib的Memory函数,新建一个文件夹来存储缓存,先需要新建一个文件夹在你指定的目录下,这里在当前目录下新建了一个名为cache_dir的文件夹:

'./cache_dir'
from joblib import Memory

# 定义存储缓存的位置
location = './cache_dir'
memory = Memory(location, verbose=0)

result = []

# 连续计算平方:
def get_square_range_cached(start_no, end_no):
    for i in np.arange(start_no, end_no):
        time.sleep(1)
        result.append(square_number(i))
    return result

get_square_range_cached = memory.cache(get_square_range_cached)

start = time.time()
# 1到10的平方:
final_result = get_square_range_cached(1, 11)
end = time.time()

# 总耗时
print('\n 计算总耗时{:.2f}s.'.format(end - start))
print(final_result)

在这里插入图片描述
在第一次计算时,结果与之前的10秒几乎相同,因为结果是第一次计算,然后存储到一个位置。我们再试一次运行:

start = time.time()
# 1到10的平方:
final_result = get_square_range_cached(1, 11)
end = time.time()
print('\n 计算总耗时{:.2f}s.'.format(end - start))
print(final_result)

在这里插入图片描述秒出结果,这主要是因为结果已经计算并存储在计算机的缓存中。
要清除缓存结果,可以使用以下直接命令:

# 清理缓存文件夹
memory.clear(warn=False)

但是,在使用此代码之前要注意的是,你可能会把最近计算得来的工作都清除了。

2. Parallelization:并行化,充分利用CPU/GPU的所有核心

以前是这样:
请添加图片描述
现在是这样:
请添加图片描述
顾名思义,我们可以使用“joblib.Parallel”并行计算任何指定的函数,即使有多个参数。在幕后,当使用多个jobs(如果指定)时,每个计算都不等待前一个作业完成,可以使用不同的处理器来完成任务。为了更好地理解,下面展示如何在缓存中运行并行作业。

创建一个(10000行,4列)的数组,我们计算每一列的平均值作为job

rng = np.random.RandomState(42)
data = rng.randn(int(1e4), 4)

在这里插入图片描述
下面是正常顺序处理的运行,其中只有在前一个计算完成后才开始新的计算。

def costly_compute(data, column):
    """通过休眠并返回一个列来模拟耗时的函数"""
    time.sleep(2)
    return data[column]

def data_processing_mean(data, column):
    """计算一列的均值"""
    return costly_compute(data, column).mean()

start = time.time()
results = [data_processing_mean(data, col) for col in range(data.shape[1])]
stop = time.time()

print('\n顺序处理')
print('整个处理所消耗的时间: {:.2f}s'
      .format(stop - start))

在这里插入图片描述
对于并行处理,我们将作业数设置为2。作业的数量受到CPU拥有或可用(空闲)核心数量的限制。

# 导入相应的 package
from joblib import Parallel, delayed
from joblib import Memory

location = './cache_dir'
memory = Memory(location, verbose=0)
costly_compute_cached = memory.cache(costly_compute)

def data_processing_mean_using_cache(data, column):
    """计算每一列的均值"""
    return costly_compute_cached(data, column).mean()

start = time.time()
results = Parallel(n_jobs=2)(
    delayed(data_processing_mean_using_cache)(data, col)
    for col in range(data.shape[1]))

# Parallel(n_jobs=2)(delayed(data_processing_mean_using_cache)(data, col) for col in range(data.shape[1]))
# n_jobs=2 并行处理,作业数设置为2
# delayed(传入的job的方法(方法需要传入的参数1,方法需要传入的参数2,...))

stop = time.time()

print('总耗时: {:.2f}s'
      .format(stop - start))

在这里插入图片描述
在这里我们可以看到,使用Parallel方法的处理时间减少了2倍。

注意:如果用于计算量较少的函数,使用这种方法可能会导致性能下降。

3. Dump and Load 转存和加载

我们经常需要将数据集、模型、计算结果等存储和加载到计算机上的某个位置。Joblib提供了可以轻松转储和加载的函数:
转存
请添加图片描述

加载
请添加图片描述

from joblib import dump, load

start = time.time()

# 文件名称
joblib_file = 'train_features.joblib'

with open(path + joblib_file, 'wb') as f:
    dump(data, f)

# 计算总时间
simple_joblib_duration = time.time() - start
print("Dump 消耗的时间: %0.3fs" % simple_joblib_duration)
from joblib import dump, load

start = time.time()

# 文件名称
joblib_file = 'train_features.joblib'

with open(path + joblib_file, 'wb') as f:
    load(data, f)

# 计算总时间
simple_joblib_duration = time.time() - start
print("Load 消耗的时间: %0.3fs" % simple_joblib_duration)

4. Compression methods 压缩

请添加图片描述

当处理较大的数据集时,这些文件占用空间很大。对于特性工程,当我们添加更多的列时,文件的大小会变得更大。硬盘存储很大我们可以存在硬盘上。joblib提供了一些非常简单的压缩方法:

a. 简单的压缩:

最简单的方法就是上面所示的方法。它不提供任何压缩,但是存储任何文件的最快方法

start = time.time()

# 文件
pickle_file = '/train_features.pkl'

# 以正常格式Dumping文件
with open(path + pickle_file, 'wb') as f:
    dump(data, f)
    
simple_pickle_duration = time.time() - start

# dump 消耗的时间
print("dump 消耗的时间: %0.3fs" % simple_pickle_duration)

在这里插入图片描述

joblib_file = '/train_features.joblib'

# 文件的大小
raw_file_size = os.stat(path + joblib_file).st_size / 1e6

# 打印大小
print("文件大小是: %0.3fMB" % raw_file_size)

在这里插入图片描述

b. 使用Zlib压缩:

实现如下:

start = time.time()

# 文件
joblib_file = '/train_features.joblib'

# 以zlib压缩格式转储文件
with open(path + joblib_file, 'wb') as f:
    dump(data, f, compress='zlib')

simple_joblib_duration = time.time() - start

# dump 消耗的时间
print("dump 消耗的时间: %0.3fs" % simple_joblib_duration)

在这里插入图片描述

joblib_file = '/train_features.joblib'

# 文件的大小
zlib_file_size = os.stat(path + joblib_file).st_size / 1e6

# 打印大小
print("文件大小是: %0.3fMB" % zlib_file_size)

在这里插入图片描述

c. 使用lz4压缩:

这是另一种压缩方法,速度相比于Zlib更快,但压缩率略低于Zlib,在压缩大小和压缩率之间进行了很大的权衡。实现如下:

start = time.time()

# File
joblib_file = '/train_features.joblib'

# 以zl4压缩格式转储文件
with open(path + joblib_file, 'wb') as f:
    dump(data, f, compress='zl4')

simple_joblib_duration = time.time() - start

# dump 消耗的时间
print("dump 消耗的时间: %0.3fs" % simple_joblib_duration)

在这里插入图片描述

joblib_file = '/train_features.joblib'

# 文件的大小
zl4_file_size = os.stat(path + joblib_file).st_size / 1e6

# 打印大小
print("文件大小是: %0.3fMB" % zl4_file_size)

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值