原文towardsdatascience.com/real-world-use-cases-forecasting-service-utilization-using-tabnet-and-optuna-26308db615c3?sourcecollection_archive---------8-----------------------#2024-08-15https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/316bd735324a679d8146caf7b72e8144.png图片由 Dall-e 生成数据科学在实际应用中最为出色。我打算分享一些我参与的各种生产化项目中的见解。https://medium.com/hampusg?sourcepost_page---byline--26308db615c3--------------------------------https://towardsdatascience.com/?sourcepost_page---byline--26308db615c3-------------------------------- Hampus Gustavsson·发表于 Towards Data Science ·阅读时间7 分钟·2024 年 8 月 15 日–在我作为数据科学家的这些年里我遇到了许多有兴趣成为数据科学家的学生或者是刚毕业的新手。开始数据科学的职业生涯像任何领域一样都需要经历一个陡峭的学习曲线。我经常被问到一个非常好的问题我已经学到了很多数据科学的理论知识但现实世界中的例子是什么样的呢我希望分享一些小的工作片段来自我整个职业生涯中参与的不同项目。虽然其中一些可能已有几年历史但我只会写我仍然认为有价值的主题。我会尽量保持整体画面清晰简洁让有志的同行能了解接下来可能会遇到的内容。但我也希望停下来深入探讨细节期望有经验的开发者能从中获得一些启示。商业案例现在让我们深入探讨推动这一项目的具体业务案例。团队包括项目经理、客户利益相关者和我本人。客户需要一种方法来预测特定服务的使用情况。这样做的原因是为了服务的资源分配和动态定价。关于服务使用行为的经验主要由经验丰富的同事掌握而这个应用程序旨在增强对他们退休和相关知识流失的抵御能力。此外使用这种工具可以使新员工的入职过程变得更加简便。数据和分析设置数据包含了很多特征包括分类特征和数值特征。在此用例中需要预测具有动态时间范围的使用情况即需要对未来不同时间段的使用情况进行预测。还需要预测许多相关和不相关的值。这些多变量时间序列使得关注点主要集中在基于时间序列的模型实验上。但最终Tabnet 被采纳为处理表格数据的模型。Tabnet 架构中有几个有趣的特性。本文不会深入探讨模型细节但我建议进行一些相关的理论研究。如果找不到合适的资源我认为这篇文章是一个很好的概述或者可以参考这篇论文进行更深入的探索。作为超参数调优框架使用了 Optuna。虽然 Python 中还有其他框架可供选择但我至今没有找到不使用 Optuna 的理由。Optuna 被用作贝叶斯超参数调优并保存到磁盘。其他功能包括提前停止和热启动。提前停止用于节省资源防止没有前景的实验运行过长时间。热启动则是从先前的实验开始调整。我觉得当新数据到来时这一点非常有用可以避免从头开始调优。初始参数宽度将根据Tabnet 文档中的建议或Tabnet 论文中讨论的参数范围进行设置。为了表达残差的异方差性采用了 Tabnet 作为分位回归模型。为此或者说为了以这种方式实现任何模型使用了弹球损失函数并设置了适当的上下分位点。该损失函数具有偏斜性根据误差是正值还是负值不平等地惩罚误差。代码演示这些代码片段所用的要求如下。pytorch-tabnet4.1.0optuna3.6.1pandas2.1.4定义模型的代码。importosfrompytorch_tabnet.tab_modelimportTabNetRegressorimportpandasaspdimportnumpyasnpfromutilsimportCostumPinballLossclassmediumTabnetModel:def__init__(self,model_file_name,dependent_variablesNone,independent_variablesNone,batch_size16_000,n_a8,n_steps3,n_independent2,n_shared2,cat_idxs[],cat_dims[],quantileNone):self.model_file_namemodel_file_name self.quantilequantile self.clfTabNetRegressor(n_dn_a,n_an_a,cat_idxscat_idxs,cat_dimscat_dims,n_stepsn_steps,n_independentn_independent,n_sharedn_shared)self.batch_sizebatch_size self.independent_variablesindependent_variables self.dependent_variablesdependent_variables self.cat_idxscat_idxs# Indexes for categorical values.self.cat_dimscat_dims# Dimensions for categorical values.self.ram_dataNonedeffit(self,training_dir,train_date_split):ifself.ram_dataisNone:data_pathos.path.join(training_dir,self.training_data_file)dfpd.read_parquet(data_path)df_traindf[df[dates]train_date_split]df_valdf[df[dates]train_date_split]x_traindf_train[self.independent_variables].values.astype(np.int16)y_traindf_train[self.dependent_variables].values.astype(np.int32)x_validdf_val[self.independent_variables].values.astype(np.int16)y_validdf_val[self.dependent_variables].values.astype(np.int32)self.ram_data{x_train:x_train,y_train:y_train,x_val:x_valid,y_val:y_valid}self.clf.fit(self.ram_data[x_train],self.ram_data[y_train],eval_set[(self.ram_data[x_val],self.ram_data[y_val])],batch_sizeself.batch_size,drop_lastTrue,loss_fnCostumPinballLoss(quantileself.quantile),eval_metric[CostumPinballLoss(quantileself.quantile)],patience3)feat_scoredict(zip(self.independent_variables,self.clf.feature_importances_))feat_scoredict(sorted(feat_score.items(),keylambdaitem:item[1]))self.feature_importances_dictfeat_score# Dict of feature importance and importance score, ordered.作为数据处理框架使用了 Pandas。我还推荐使用 Polars它是一个更高效的框架。Tabnet 实现包含了预构建的局部和全局特征重要性属性已附加到拟合模型中。这方面的内部工作可以在之前发布的文章中进行研究但就商业用例而言这有两个目的Sanity check — 客户可以验证模型。商业洞察 — 该模型可以为客户提供关于业务的新洞察。与主题专家一起。在最终应用中解释性被包括进来以便展示给用户。由于数据匿名化本篇文章不会深入探讨解释性而是保留在能够讨论和展示模型中真实特征的案例中再进行说明。拟合和搜索步骤的代码。importoptunaimportnumpyasnpdefdefine_model(trial):n_sharedtrial.suggest_int(n_shared,1,7)logging.info(fn_shared:{n_shared})n_independenttrial.suggest_int(n_independent,1,16)logging.info(fn_independent:{n_independent})n_stepstrial.suggest_int(n_steps,2,8)logging.info(fn_steps:{n_steps})n_atrial.suggest_int(n_a,4,32)logging.info(fn_a:{n_a})batch_sizetrial.suggest_int(batch_size,256,18000)logging.info(fbatch_size:{batch_size})clfmediumTabnetModel(model_file_namemodel_file_name,dependent_variablesy_ls,independent_variablesx_ls,n_an_a,cat_idxscat_idxs,cat_dimscat_dims,n_stepsn_steps,n_independentn_independent,n_sharedn_shared,batch_sizebatch_size,training_data_filetraining_data_file)returnclfdefobjective(trial):clfdefine_model(trial)clf.fit(os.path.join(args.training_data_directory,args.dataset),df[int(len(df)*split_test)])y_predclf.predict(predict_data)y_truenp.array(predict_data[y_ls].values).astype(np.int32)metric_valuecall_metrics(y_true,y_pred)returnmetric_value studyoptuna.create_study(directionminimize,storagesqlite:///db.sqlite3,study_namemodel_name,load_if_existsTrue)study.optimize(objective,n_trials50)数据正在被分割为训练集、验证集和测试集。不同数据集的用途如下训练集。是模型学习的基准数据集。本项目中占数据的 80%。验证集。是 Optuna 计算其指标的数据集因此该指标是优化的目标。本项目中占数据的 10%。测试集。这个数据集用于确定模型的真实表现。如果该指标不够好可能值得回去调查其他模型。这个数据集还用于决定何时停止超参数调优。KPI 的推导以及与利益相关者共享的可视化图表也是基于这个数据集。最后需要注意的是为了尽可能模拟模型部署时的行为数据集是按时间分割的。这意味着周期的前 80%的数据用于训练部分接下来的 10%用于验证最近的 10%用于测试。https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/457c9b60de76deafea9d022d15c28ab4.png时间序列数据分割的示意图。图表由作者创建。对于这里展示的例子试验结果被保存到磁盘。更常见的方法是将其保存到云存储中以便更好地访问和更容易维护。Optuna 还附带了一个可视化的 UI可以通过在终端中运行以下命令启动pip install optuna-dashboard cd/path/to/directory_with-db.sqlite3/optuna-dashboard sqlite:///db.sqlite3用于 sanity check 的手动任务是查看最优参数与采样限制的接近程度。如果它们距离设置的边界合理地远则无需进一步拓展搜索空间。对于调优中显示的内容的深入分析请查看这里。这里是一些结果的可视化。https://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/2aa2d5280c0f9aebe258635ec2917aba.pnghttps://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/fa264aa50a22d3afb54580c6f7c987a0.pnghttps://github.com/OpenDocCN/towardsdatascience-blog-zh-2024/raw/master/docs/img/5a099d16c8bb0be766afb92ee9ce6adf.png模型表现的可视化。图表由作者创建。结论和客户反馈。图表显示随着预测服务使用情况的时间延长预测的不确定性增加。这是预期中的情况客户也确认了这一点。如所注意到的模型在识别不寻常的峰值时遇到了困难。在实际使用案例中努力的重点是寻找更多的数据源看看模型是否能够更好地预测这些异常值。在最终产品中还引入了对预测数据点的新颖性评分使用了 Deepchecks 库。这是在与客户的讨论中提出的目的是检测数据漂移并为用户提供数据的见解。在另一篇文章中会深入探讨如何开发这一功能。感谢阅读希望你觉得这篇文章有用和/或启发。如果你有任何评论或问题请随时联系我你也可以在LinkedIn上与我联系。