如何存储缩放参数供以后使用

How to store scaling parameters for later use

我想应用 scikit-learn 提供的缩放 sklearn.preprocessing.scale 模块来集中我将用来训练 svm 分类器的数据集。

然后我如何存储标准化参数,以便我也可以将它们应用于我想要分类的数据?

我知道我可以使用 standarScaler,但我能否以某种方式将它序列化到一个文件中,这样我就不必在每次想要 运行 分类器时都将它与我的数据相匹配?

我认为最好的方法是腌制它 post fit,因为这是最通用的选项。也许您稍后会创建一个由特征提取器和缩放器组成的管道。通过酸洗一个(可能是复合的)阶段,您可以使事情变得更通用。 sklearn documentation on model persistence 讨论了如何做到这一点。

话虽如此,您可以查询 sklearn.preprocessing.StandardScaler 的拟合参数:

scale_ : ndarray, shape (n_features,) Per feature relative scaling of the data. New in version 0.17: scale_ is recommended instead of deprecated std_. mean_ : array of floats with shape [n_features] The mean value for each feature in the training set.

以下简短片段说明了这一点:

from sklearn import preprocessing
import numpy as np

s = preprocessing.StandardScaler()
s.fit(np.array([[1., 2, 3, 4]]).T)
>>> s.mean_, s.scale_
(array([ 2.5]), array([ 1.11803399]))

Pickle 带来安全漏洞,允许攻击者在服务器上执行任意代码。条件是:

  • 可以用服务器上的另一个 pickle 文件替换 pickle 文件(如果没有执行 pickle 审计,即签名验证或哈希比较)

  • 相同,但在开发者 PC 上(攻击者破坏了一些开发者 PC

如果您的服务器端应用程序以 root 身份执行(或在 docker 容器中以 root 身份执行),那么这绝对值得您注意。

可能的解决方案:

  • 模型训练应该在安全的环境中进行

  • 经过训练的模型应该由来自另一个安全环境的密钥签名,该密钥不会加载到 gpg-agent(否则攻击者可以很容易地替换签名)

  • CI 应在隔离环境(隔离区)中测试模型

  • 使用 python3.8 或更高版本,其中添加了安全挂钩以防止代码注入技术

  • 或者避免泡菜:)

部分链接:

避免酸洗的可能方法:

# scaler is fitted instance of MinMaxScaler
scaler_data_ = np.array([scaler.data_min_, scaler.data_max_])
np.save("my_scaler.npy", allow_pickle=False, scaler_data_)

#some not scaled X
Xreal = np.array([1.9261148646249848, 0.7327923702472628, 118, 1083])

scaler_data_ = np.load("my_scaler.npy")
Xmin, Xmax = scaler_data_[0], scaler_data_[1]
Xscaled = (Xreal - Xmin) / (Xmax-Xmin)
Xscaled
# -> array([0.63062502, 0.35320565, 0.15144766, 0.69116555])

使用标准缩放器缩放

from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
scaler.fit(data)
scaled_data = scaler.transform(data)

保存 mean_ 和 var_ 以备后用

means = scaler.mean_ 
vars = scaler.var_    

(您可以使用 np.save 打印和复制粘贴方法和变量或保存到磁盘...)

以后使用保存的参数

def scale_data(array,means=means,stds=vars **0.5):
    return (array-means)/stds

scale_new_data = scale_data(new_data)

您可以使用 joblib 模块来存储缩放器的参数。

from joblib import dump
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
scaler.fit(data)
dump(scaler, 'scaler_filename.joblib')

稍后您可以加载定标器。

from joblib import load
scaler = load('scaler_filename.joblib')
transformed_data = scaler.transform(new_data)