PyCaret 是 Python 中的一个开源、低代码机器学习库,它可以自动执行机器学习工作流。它是一种端到端的机器学习和模型管理工具,可成倍的提高您的工作效率。与其他开源机器学习库相比,PyCaret 是一个低代码的机器学习框架,可用于仅用几行代码替换数百行代码。这使得开发过程以指数方式快速和高效。PyCaret 本质上是几个机器学习库和框架的 Python 包装器,例如 scikit-learn、XGBoost、LightGBM、CatBoost、spaCy、Optuna、Hyperopt、Ray 等等。

PyCaret 中的模块

PyCaret 是一个模块化库,按模块排列,每个模块代表一个机器学习用例。当前Pycaret支持以下功能模块:分类、聚类、回归、时间序列、NLP、异常探测等。

安装Pycaret

安装 PyCaret 非常简单,可以使用以下的命令。但是强烈建议使用虚拟环境来避免与其他库的潜在冲突。

pip install pycaret

回归问题的pycaret的解决方案

Pycaret解决回归问题一般以下几个步骤:

  1. Getting Data:从 PyCaret 存储库导入模拟数据,或者也可以读取外部真实数据
  2. Setting up Environment:在 PyCaret 中设置算法环境并开始构建回归模型
  3. Compare Model: 比较所有内置的算法模型以评估性能。
  4. Create Model:创建模型、执行交叉验证和评估回归指标
  5. Tune Model:自动调优回归模型的超参数
  6. Plot Model:使用各种绘图分析模型性能
  7. Finalize Model:在模型训练结束时确定最佳模型
  8. Predict Model:对新的/看不见的数据进行预测
  9. Save / Load Model:保存/加载模型以供将来使用

1.加载并清洗数据

我们的数据来自于kaggle上的房屋价格数据,你可以从这里下载数据,关于数据字段的含义及其说明请参考kaggle上的相关说,这里不再说明。

df = pd.read_csv('./data/house/train.csv')
print(df.shape)
df.head()

  总共有1460条记录,共有81列,其中SalePrice是我们的目标变量,除去SalePrice和Id这两列以外,其余79个变量都是我们的特征变量,这些特征变量的含义在这我就不一一说明了(因为实在太多),大家可以查看kaggle中的Data Description。接下来我们要做数据清洗的工作,因为有很多字段有空值,我们必须要清洗掉这些数据,首先我们要查询一下数据中的空值情况:

(df.isnull().sum() / len(df)).sort_values(ascending=False)[:20]

 

我们查看了前20个包含空值最多的变量(字段),其中PoolQC、MiscFeature、Alley、Fence这4个变量所包含空值的比例都在90%和80%以上,它们包含了大量的空值。所以我们要删除这些变量,同时为了便于后续的分析,我们还要同时删除Id字段。

df.drop(['PoolQC', 'MiscFeature', 'Alley', 'Fence', 'Id'], axis=1, inplace=True)

 2.设置环境(setup)

在设置环境之前我们从整个数据集中随机抽取一小部分数据(如10%的数据),作为测试数据集(不参与模型训练),将剩余的数据(90%的数据)用来训练模型。

data = df.sample(frac=0.9, random_state=786)
data_unseen = df.drop(data.index)

data.reset_index(drop=True, inplace=True)
data_unseen.reset_index(drop=True, inplace=True)

print('Data for Modeling: ' + str(data.shape))
print('Unseen Data For Predictions: ' + str(data_unseen.shape))

 

接下来我们使用setup() 函数初始化 pycaret 中的环境,并创建转换管道以准备数据并进行建模和部署。 setup() 必须在执行 pycaret 中的任何其他函数之前调用。它需要两个强制性参数:pandas 的dataframe和目标列的名称。这里明确一下我们的目标列是“SalePrice”字段,其他所有其他参数都是可选的。

执行 setup() 时,PyCaret 的内置推理算法将根据某些属性自动推断所有特征的数据类型。一般情况下能正确推断所有字段的数据类型,但有时候也会出错。为了解决这个问题,PyCaret 会在 setup() 执行后显示一个包含特征及其推断数据类型的表。如果所有的数据类型都被正确识别,可以按 Enter 键继续或键入 quit 键退出setup。确保数据类型正确在 PyCaret 中至关重要,因为它会自动执行一些预处理任务,这些任务对于任何机器学习算法都是必不可少的。对于每种数据类型,这些任务的执行方式不同,这意味着正确配置它们非常重要。在后面的教程中,我们将学习如何使用 setup() 中的 numeric_features 和 categorical_features 参数覆盖 PyCaret 的推断数据类型

from pycaret.regression import *
setup(data = data, target = 'SalePrice', session_id=123) 

 

成功执行setup()后,它会打印出一些和数据预处理有关的信息。下面我们说明一下这些信息中的一些主要信息的含义:

  1. session_id:一个伪随机数,作为种子分布在所有函数中,以供以后重现。如果没有传递 session_id,则会自动生成一个随机数,分发给所有函数。
  2. Original Data:显示数据集的原始形状。在这个本例中 (1168, 76) 表示 1168个样本和 76 个特征,包括目标列。
  3. Missing Values:当原始数据中存在缺失值时,则会显示为 True。在本例中,数据集中存在缺失值,故显示为True。
  4. Numeric Features:推断为数字类型的特征数量。在本例中,76个特征中有 18个被推断为数字类型特征。
  5. Categorical Features:推断为分类型的特征数量。在本例中,76 个特征中有 57 个被推断为分类特征。
  6. Transformed Train Set:表示经过转换后的训练集的形状,所谓转换后的训练集是指对分类型特征做了一些预处理的操作(如one-hot)后,特征数量会比原来有所增加,在本例中训练集的特征数量由原来的76个增加到了373个,Categorical 类字段经one-hot处理后数量增加了很多,训练集的维度为:(817, 373),其中817表示训练集的样本数量。
  7. Transformed Test Set:表示验证集经过转换后的形状,含义和上面的类似,只不过维度为:(351, 373)。

注意一些必须执行数据预处理步骤例如缺失值补全、分类编码(one-hot)等,setup()已经自动替你完成, 不需要任何人为操作,这大大节省了大家的开发时间。这里还要说明的是 setup() 中的参数是可选的,在本例中在setup()中除了两个必要的参数以外,其余参数我们都采用了默认参数,关于参数的详细说明请参阅pycaret官方文档。

3.比较模型(Compare Model)

在执行完setup()后,一般需要进行compare_models()操作,compare_models()的功能是比较模型库中所有模型以评估性能。(如果你明确知道哪个模型性能最好也可以不执行compare_mode,直接执行后续的create_model(),但通常情况大多数人都不会事先知道哪种模型性能最好。)。 compare_models()会训练模型库中的所有模型,并使用 k 折交叉验证对它们进行评分以进行度量评估。 并输出打印一个分数表格,评估指标包含: MAE、MSE、RMSE、R2、RMSLE 和 MAPE 以及训练时间。

best = compare_models()

 一句简单的代码,就完成了交叉验证训练和评估了 20 多个模型。 上面打印的分数表格显示了各个模型的各个评估指标的具体数值。 默认情况下使用 R2(从最高到最低)排序,可以通过传递排序参数来更改。 例如 compare_models(sort = 'RMSLE') 将按 RMSLE 对网格进行排序(数值从低到高,因为RMSLE越低越好)。 如果要将 fold 参数从默认值 10 更改为不同的值,则可以使用 fold 参数。 例如 compare_models(fold = 5) 将在 5 折交叉验证上比较所有模型。 减少交叉验证的折数(fold)将减少模型训练时间。 默认情况下, compare_models 根据默认排序顺序返回性能最佳的模型,但可用于通过使用 n_select 参数返回前 N 个模型的列表。在本例中compare_models()最后会返回一个最优的模型。

4.创建模型(create model)

执行完compare_models()后我们大致清楚那些模型的性能比较优秀,接下来我们可以使用create_model()方法来创建指定的算法模型,在创建指定的算法模型时任何会执行交叉验证来评估指定模型的性能,这里我们compare_model()的评估结果来创建一个性能最优的模型:lightgbm

lightgbm = create_model('lightgbm')

上面是经过默认的10折交叉验证后的评估结果,这个评估结果与 compare_models()结果中的第一条是完全一致的。同样我们也可以通过create_model()方法来创建其它的算法模型,比如create_model('rf'), create_model('svm'),create_model('dt')等,可以使用models()函数来展示所有的可创建的模型:

models()

 

 请注意,所有模型的平均分数与 compare_models() 中打印的分数是一致的。 这是因为在 compare_models() 的评估结果是所有交叉验证的的平均得分这和create_model()方法创建模型的方法是一致的,所以两者评估结果是一样的。 与 compare_models() 类似,如果要将交叉验证参数 fold 从默认值 10 更改为不同的值,则可以使用 fold 参数。 例如: create_model('dt', fold = 5) 使用 5 折交叉验证创建决策树模型。

5.模型调优(Tune Model)

当使用 create_model 函数创建模型时,它使用默认超参数来训练模型。 为了调整模型的超参数,我们需要使用了 tune_model 函数。 此函数使用随机网格搜索(Random Grid Search)在预定义的搜索空间上自动调整模型的超参数。 最后输出打印一个分数表格,按交叉验证的顺序显示 MAE、MSE、RMSE、R2、RMSLE 和 MAPE等评估指标的结果。 

tuned_lightgbm = tune_model(lightgbm)

 在默认情况下tune_model()方法的迭代次数为10次,这意味着最多需要 10 次迭代才能找到超参数的最佳值。 增加迭代次数可能会提高性能,但也会增加训练时间。可以在tune_model()方法中设置n_iter参数如:tune_model(lightgbm, n_iter = 50)。一般情况下经过超参数调优的模型性能要优于使用默认参数的模型。

这里还需要说明一点,在默认迭代次数下模型调优结果未必是最优的,有时候调优的结果会比默认参数的模型还要差,究其原因可能在迭代次数过少造成的,此时可以增加迭代次数后重新调试,但有时候为了避免模型调优时间过长,在调优模型性能比默认参数模型性能要差的情况下,优先选择默认参数模型。比如在本例中默认参数模型lightgbm的R2指标为0.8434,而经过参数调优的模型tuned_lightgbm的R2指标为0.8357(R2值越大越好,理想值为1),显然默认参数模型lightgbm的性能要优于调优模型tuned_lightgbm,因此在这里我们的后续操作仍然使用默认参数模型lightgbm,而放弃调优模型tuned_lightgbm。

6.模型可视化(Plot Model)

在模型最终确定之前,plot_model() 函数可用于分析训练集和验证集的不同方面的性能,例如残差图、预测误差、特征重要性等。

6.1 残差图

plot_model(lightgbm)

6.2 预测误差图 

plot_model(lightgbm, plot = 'error')

 

6.3 特征重要性图

plot_model(tuned_lightgbm, plot='feature')

 分析模型性能的另一种方法是使用 evaluate_model() 函数,该函数显示给定模型的所有可用图的用户界面。

evaluate_model(lightgbm)

 

 6.4 查看在验证集上的预测结果

在最终确定模型之前,建议通过预测验证集并查看评估指标来完成最终的模型检查步骤。 在前面setup()设置算法环境的时候,训练数据被按70%和30%的比例进行了拆分,其中70%的数据用来做交叉训练,另外30%的数据用来做验证。如果想改变训练集合验证集的比例,可以在执行setup时指定train_size参数,在本例中 30%(351 个样本)的数据已作为验证集样本分离出来。 我们在上面看到的所有评估指标都是仅基于训练集 (70%) 的交叉验证结果。 现在,使用已创建的lightgbm模型实例来预测验证集并评估模型性能。

predict_model(lightgbm);

 这里我们在验证集中的R2值为0.8352,这与前面的残差图plot_model(lightgbm)中的评估指标是一致的。

7.确定最终模型(Finalize Model)

模型定型是建模的最后一步。 PyCaret 中的正常机器学习工作流程从 setup() 开始,然后使用 compare_models() 比较所有模型,并列出一些候选模型(基于感兴趣的指标)以执行多种建模技术,例如超参数调整、集成、堆叠等 . 此工作流程最终将引导您找到用于对新的和未见数据进行预测的最佳模型。 finalize_model() 函数将模型拟合到完整的数据集上,包括验证集(setup中拆分出来的30%数据)此功能的目的是在将模型部署到生产环境之前在完整数据集上训练模型。下面我们将执行finalize_model(),并打印出算法模型中使用的超参数:

final_lightgbm = finalize_model(lightgbm)
print(final_lightgbm)

注意: 在执行 finalize_model() 时包括训练集和验证集在内的整个数据集将用于训练。 因此,如果在使用 finalize_model() 后的模型用于对验证集的预测,则打印的出来的评估指标将具有误导性,因为您预测的数据是在训练模型时使用的数据由此产生的评估结果将由欺骗性。

下面我们来演示一下这种欺骗性,我们用final_lightgbm来预测验证集中的数据:

predict_model(final_lightgbm);

 预测了验证集后的评估指标R2,从之前的0.8352变成了0.9723,R2有了很大的提高,但这不是真实的,因为我们预测的是训练模型时使用的数据。

8.对未知数据的预测

predict_model() 函数也用于在未见过的数据集上进行预测。 与上面的唯一区别是,这次我们将传递 data参数,我们需要将未知数据传递给predict_model方法。 data_unseen 是在之前创建的变量,它包含从未暴露给 PyCaret 的原始数据集的 10%的数据(292 个样本)。

unseen_predictions = predict_model(final_lightgbm, data=data_unseen)
unseen_predictions.head()

 Label 列被添加到 data_unseen 集中。 Label是使用 final_lightgbm 模型的预测值。 如果要对预测进行四舍五入,可以在 predict_model() 中使用 round 参数。 下面我们来评估一下对未知数据预测的R2指标 :

from sklearn.metrics import r2_score

print('data_unseen r2 score: ', 
      r2_score(unseen_predictions.SalePrice.values,
               unseen_predictions.Label.values))

 9.保存/加载模型

我们可以使用save_model方法将我们最终模型保存在磁盘中,当有新的未知数据产生时,我们还可以使用load_model方法加载磁盘上的模型文件生成一个模型的实例来对未知数据进行预测。

save_model(final_lightgbm,'my_final_lightgbm')

my_final_lightgbm = load_model('my_final_lightgbm')

new_prediction = predict_model(my_final_lightgbm, data=data_unseen)


print('data_unseen r2 score: ', 
      r2_score(new_prediction.SalePrice.values,
               new_prediction.Label.values))

 总结

本教程涵盖了从数据预处理、模型训练、超参数调整、预测和保存模型以供以后使用的整个机器学习算法的过程。 我们在不到 10 个命令中完成了所有这些步骤,例如 create_model()、tune_model()、compare_models()。 在大多数机器学习类库中,如果不使用 PyCaret来实现机器学习算法,将至少需要 100 多行代码,尤其是在特征的选择和特征的预处理的过程会非常的繁琐。

在这里我们只介绍 pycaret.regression 的基础知识。 在接下来的教程中,我们将更深入地介绍高级预处理、集成、广义堆叠和其他技术。

参考资料

pycaret官方文档

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐