机器学习:鸢尾花数据集

机器学习:鸢尾花数据集#

如果你想在实时的 Python 内核中尝试这个笔记本,请使用 mybinder:

https://mybinder.org/badge_logo.svg

虽然 vaex.ml 尚未实现预测模型,但我们提供了对强大库(例如 Scikit-learn, xgboost)的封装,并使它们能够高效地与 vaex 协同工作。vaex.ml 实现了多种标准数据转换器(例如 PCA、数值缩放器、分类编码器)以及一个非常高效的 KMeans 算法,这些工具充分利用了 vaex 的优势。

以下是一个使用vaex.ml的简单示例。我们将使用著名的Iris数据集,并利用它来构建一个区分三种爱尔兰物种的模型(Iris setosa, Iris virginicaIris versicolor)。

让我们从导入常用库、加载并检查数据开始。

[1]:
import vaex
import vaex.ml

import matplotlib.pyplot as plt


df = vaex.datasets.iris()
df
[1]:
# 花萼长度 花萼宽度 花瓣长度 花瓣宽度 类别
0 5.9 3.0 4.2 1.5 1
1 6.1 3.0 4.6 1.4 1
2 6.6 2.9 4.6 1.3 1
3 6.7 3.3 5.7 2.1 2
4 5.5 4.2 1.4 0.2 0
... ... ... ... ... ...
1455.2 3.4 1.4 0.2 0
1465.1 3.8 1.6 0.2 0
1475.8 2.6 4.0 1.2 1
1485.7 3.8 1.7 0.3 0
1496.2 2.9 4.3 1.3 1

在数据上进行任何操作之前,应立即将数据分为训练测试步骤。vaex.ml包含一个train_test_split方法,该方法创建主DataFrame的浅拷贝,这意味着在定义训练和测试集时不会使用额外的内存。请注意,train_test_split方法对主DataFrame进行有序分割以创建这两个集。在某些情况下,可能需要打乱数据。

如果需要洗牌,我们建议以下内容:

df.shuffle().export("shuffled.hdf5")
df = vaex.open("shuffled.hdf5")
df_train, df_test = df.ml.train_test_split(test_size=0.2)

在当前情况下,数据集已经被打乱,因此我们可以直接进行分割。

[2]:
# Orderd split in train and test
df_train, df_test = df.ml.train_test_split(test_size=0.2)
/Users/jovan/PyLibrary/vaex/packages/vaex-core/vaex/ml/__init__.py:209: UserWarning: Make sure the DataFrame is shuffled
  warnings.warn('Make sure the DataFrame is shuffled')

由于这是一个非常简单的教程,我们将仅使用已提供的列作为训练模型的特征。

[3]:
features = df_train.column_names[:4]
features
[3]:
['sepal_length', 'sepal_width', 'petal_length', 'petal_width']

主成分分析#

vaex.ml 模块包含多个用于数据集转换的类,这些类通常用于在构建模型之前预处理数据。这些包括数值特征缩放器、类别编码器和PCA转换。我们采用了scikit-learn API,意味着所有转换器都有.fit.transform方法。

让我们在训练集上应用PCA变换。由于PCA也会对数据进行归一化,因此不需要事先缩放数据。

[4]:
pca = vaex.ml.PCA(features=features, n_components=4)
df_train = pca.fit_transform(df_train)
df_train
[4]:
# 花萼长度 花萼宽度 花瓣长度 花瓣宽度 类别 PCA_0 PCA_1 PCA_2 PCA_3
0 5.4 3.0 4.5 1.5 1 -0.5819340944906611 -0.5192084328455534 -0.4079706950207428 -0.22843325658378022
1 4.8 3.4 1.6 0.2 0 2.628040487885542 -0.05578001049524599-0.09961452867004605-0.14960589756342935
2 6.9 3.1 4.9 1.5 1 -1.438496521671396 0.5307778852279289 0.32322065776316616 -0.0066478967991949744
3 4.4 3.2 1.3 0.2 0 3.00633586736142 -0.41909744036887703-0.17571839830952185-0.05420541515837107
4 5.6 2.8 4.9 2.0 2 -1.1948465297428466 -0.6200295372229213 -0.4751905348367903 0.08724845774327505
... ... ... ... ... ... ... ... ... ...
1155.2 3.4 1.4 0.2 0 2.6608856211270933 0.2619681501203415 0.12886483875694454 0.06429707648769989
1165.1 3.8 1.6 0.2 0 2.561545765055359 0.4288927940763031 -0.18633294617759266-0.20573646329612738
1175.8 2.6 4.0 1.2 1 -0.22075578997244774-0.401523366515551370.25417836518749715 0.04952191889168374
1185.7 3.8 1.7 0.3 0 2.23068249078231 0.826166758833374 0.07863720599424912 0.0004035597987264161
1196.2 2.9 4.3 1.3 1 -0.6256358184862005 0.0239304743336751680.21203674475657858 -0.0077954052328795265

pca .fit_transform 方法的结果是 DataFrame 的浅拷贝,其中包含转换的结果列,在这种情况下是 PCA 组件,作为虚拟列。这意味着转换后的 DataFrame 完全不占用内存!因此,虽然这个示例仅使用了 120 个样本,但即使对于数百万或数十亿个样本,这种方法也同样适用。

梯度提升树#

现在让我们训练一个梯度提升模型。虽然 vaex.ml 目前不包括这种类型的模型,但我们支持流行的提升树库 xgboost, lightgbm, 和 catboost。在本教程中,我们将使用 lightgbm 分类器。

[9]:
import lightgbm
import vaex.ml.sklearn

# Features on which to train the model
train_features = df_train.get_column_names(regex='PCA_.*')
# The target column
target = 'class_'

# Instantiate the LightGBM Classifier
booster = lightgbm.sklearn.LGBMClassifier(num_leaves=5,
                                          max_depth=5,
                                          n_estimators=100,
                                          random_state=42)

# Make it a vaex transformer (for the automagic pipeline and lazy predictions)
model = vaex.ml.sklearn.Predictor(features=train_features,
                                  target=target,
                                  model=booster,
                                  prediction_name='prediction')

# Train and predict
model.fit(df=df_train)
df_train = model.transform(df=df_train)

df_train
[9]:
# 花萼长度 花萼宽度 花瓣长度 花瓣宽度 类别 PCA_0 PCA_1 PCA_2 PCA_3 预测
0 5.4 3.0 4.5 1.5 1 -0.5819340944906611 -0.5192084328455534 -0.4079706950207428 -0.22843325658378022 1
1 4.8 3.4 1.6 0.2 0 2.628040487885542 -0.05578001049524599-0.09961452867004605-0.14960589756342935 0
2 6.9 3.1 4.9 1.5 1 -1.438496521671396 0.5307778852279289 0.32322065776316616 -0.00664789679919497441
3 4.4 3.2 1.3 0.2 0 3.00633586736142 -0.41909744036887703-0.17571839830952185-0.05420541515837107 0
4 5.6 2.8 4.9 2.0 2 -1.1948465297428466 -0.6200295372229213 -0.4751905348367903 0.08724845774327505 2
... ... ... ... ... ... ... ... ... ... ...
1155.2 3.4 1.4 0.2 0 2.6608856211270933 0.2619681501203415 0.12886483875694454 0.06429707648769989 0
1165.1 3.8 1.6 0.2 0 2.561545765055359 0.4288927940763031 -0.18633294617759266-0.20573646329612738 0
1175.8 2.6 4.0 1.2 1 -0.22075578997244774-0.401523366515551370.25417836518749715 0.04952191889168374 1
1185.7 3.8 1.7 0.3 0 2.23068249078231 0.826166758833374 0.07863720599424912 0.0004035597987264161 0
1196.2 2.9 4.3 1.3 1 -0.6256358184862005 0.0239304743336751680.21203674475657858 -0.00779540523287952651

请注意,在训练模型后,我们使用.transform方法来获取包含模型预测的DataFrame的浅拷贝,以虚拟列的形式存在。这使得评估模型变得容易,并且可以轻松创建各种诊断图。如果需要,可以调用.predict方法,这将生成一个内存中的numpy.array,其中包含预测结果。

自动管道#

假设我们对模型的性能感到满意,我们可以继续并将我们的转换和模型应用到测试集上。与其他库不同,我们不需要显式地创建一个管道来传播这些转换。实际上,使用vaexvaex.ml,管道会在数据探索过程中自动创建。每个vaex DataFrame包含一个状态,这是一个(可序列化的)对象,包含了应用于DataFrame的所有转换信息(过滤、创建新的虚拟列、转换)。

回想一下,PCA转换和增强模型的输出实际上是虚拟列,因此存储在df_train的状态中。我们需要做的就是将此状态应用于另一个类似的DataFrame(例如测试集),所有的更改都将被传播。

[6]:
state = df_train.state_get()
df_test.state_set(state)

df_test
[6]:
# 花萼长度 花萼宽度 花瓣长度 花瓣宽度 类别 PCA_0 PCA_1 PCA_2 PCA_3 预测
0 5.9 3.0 4.2 1.5 1 -0.4978687101343986 -0.11289245880584761-0.119626012060696370.0625954090178564 1
1 6.1 3.0 4.6 1.4 1 -0.8754765898560835 -0.039024021195735940.022944044447894815-0.14143773065379384 1
2 6.6 2.9 4.6 1.3 1 -1.0228803632878913 0.2503709022470443 0.4130613754204865 -0.0303919115590032821
3 6.7 3.3 5.7 2.1 2 -2.2544508624315838 0.3431374410700749 -0.28908707579214765-0.07059175451207655 2
4 5.5 4.2 1.4 0.2 0 2.632289228948536 1.020394958612415 -0.20769510079946696-0.13744144140286718 0
... ... ... ... ... ... ... ... ... ... ...
255.5 2.5 4.0 1.3 1 -0.16189655085432594-0.6871827581512436 0.09773053160021669 0.07093166682594204 1
265.8 2.7 3.9 1.2 1 -0.12526327170089271-0.3148233189949767 0.19720893202789733 0.060419826927667064 1
274.4 2.9 1.4 0.2 0 2.8918941837640526 -0.6426744898497139 0.0061717958745104440.007700652884580328 0
284.5 2.3 1.3 0.3 0 2.850207707200544 -0.9710397723109179 0.38501428492268475 0.377723418991853 0
296.9 3.2 5.7 2.3 2 -2.405639277483925 0.4027072938482219 -0.229448178035409730.17443211711742812 2

生产#

现在 df_test 包含了我们在训练集 (df_train) 上应用的所有转换,包括模型预测。将状态从一个 DataFrame 转移到另一个 DataFrame 对于将模型投入生产可能非常有价值。

性能#

最后,让我们检查模型的性能。

[7]:
from sklearn.metrics import accuracy_score

acc = accuracy_score(y_true=df_test.class_.values, y_pred=df_test.prediction.values)
acc *= 100.
print(f'Test set accuracy: {acc}%')
Test set accuracy: 100.0%

模型获得了100%的完美准确率。这并不令人惊讶,因为这个问题相当简单:对特征进行PCA变换可以很好地分离出3种花卉物种。绘制前两个PCA轴,并根据样本的类别进行着色,已经显示出几乎完美的分离。

[8]:
plt.figure(figsize=(8, 4))
df_test.scatter(df_test.PCA_0, df_test.PCA_1, c_expr=df_test.class_, s=50)
plt.show()
../_images/guides_ml_iris_16_0.png