用于金融的简单 Flask 应用程序。第2部分

用于金融的简单 Flask 应用程序。第2部分

Photo by 马库斯·温克勒 on 不飞溅

介绍

财务部门的职能之一是向管理层和股东提供定期报告,以便他们根据所提供的信息做出决策。财务专家通常会在复杂的电子表格中展示结果,其中包含冗长的公式和不友好的用户界面。但是,并非所有管理层和股东都毕业于金融专家,因此,他们需要的数据呈现难度较低。因此,在展示公司活动的结果时,可以考虑使用其他工具。

在这个项目中,我试图提出一种报告格式,管理层和股东可以通过公司网站轻松阅读和访问。我将使用的数据是虚拟数据,但可以用实际数字代替。

概述

在本节中,我将讨论应用程序的主要功能。它建立在 Flask 的后端和 HTML 的前端。您可以上传数据以进行进一步处理并将其存储在 AWS S3 中。存储后,可以随时以编程方式访问它。

该报告计算主要财务指标:给定时期的利润、收入、营销和开发费用。对于每个指标,都有一个单独的页面,用户可以使用交互式仪表板从不同的角度仔细查看数据。

该应用程序正在使用神经网络来生成利润预测。在 Make Predictions 页面上,用户可以选择一个项目并构建一个 LSTM(长期短期记忆)模型,然后将其保存到 AWS S3。保存的预测将显示在利润页面上。

现在我将详细说明上述功能。

将文件上传到 AWS S3

在后端:

创建了一个 FlaskForm 以允许将文件上传到应用程序。

Flask Form for uploading files to the app

我们只对上传带有我们选择的扩展名的文件感兴趣。有一个辅助函数可以验证文件的扩展名:

Helper function for extension validation

要将文件上传到 AWS S3,我们需要先建立连接并指定我们希望存储文件的存储桶。

Creating a connection to AWS S3 and specifying buckets

下面是负责将文件上传到 S3 的路由。首先,我们在前端选择一个文件,然后单击提交按钮,我们将文件传输到后端。下面的路由首先验证文件的扩展名、文件名,并将文件保存到上传文件夹。接下来,python 读取文件并检查列名是否符合预期。将来我们将需要连接这些文件,因此文件具有相同的结构会更好。预期的列名是:

将来,我计划对上传的 csv 文件的数据类型进行验证。

如果所有检查均通过,文件将上传到 S3 并从本地上传文件夹中删除。

Flask route for uploading files

上传文件后,我们就有了可使用的数据。现在我们转到指标页面。

利润

这是利润页面的样子:

Profit page filtered

利润页面有一个仪表板,底部有 4 个图表和一个表格。左上图按月显示利润,即产品在特定月份赚取了多少利润。右上图是未来的预测。我们将在本文后面讨论它。左下图是所选期间的累积利润。这些只是 x 轴上的日期和 y 轴上的运行总计。右下图显示了每个产品在整个期间的总利润。在页面底部,有一个表格,其中列出了每种产品的总利润。

在页面顶部,有一个过滤栏。您可以显示您希望的任何数据:指定特定的时间范围,并按公司、团队和产品进行过滤。此外,您可以从页面底部下载 xlsx 格式的表格。

我希望过滤器是依赖的​​,即以下选择取决于最后一个选择。我花了几个小时弄清楚如何做到这一点,但没有结果。我知道如何使用单选下拉菜单来做到这一点,但我们正在处理多选下拉菜单,这里的事情更加复杂。因此,如果您对如何解决问题有一些建议,我很乐意听取您的建议 😃

那么里面是什么?

数据来自 S3。 Flask 路由向 S3 发送一个获取请求并从那里获取数据。这是一个辅助函数,它遍历指定存储桶中的所有项目并返回一个熊猫数据框。

上述函数有一个限制:如果桶中没有任何内容,则会返回错误。这将在稍后修复。

数据上传到 S3 后,会对其进行预处理,以便用作图形的输入。 dataframes.py 文件中有一个单独的脚本。下面以其中一个函数为例:

数据经过预处理后,进入 plots.py 脚本。 Plots.py 包含项目的所有相关图表。这是一个示例要点:

然后在 Flask 路由中收集数据帧函数和绘图函数,并从那里将它们发送到前端:

在前端,jinja2 接受传递的变量,仅此而已。

上述顺序适用于以下页面:利润、收入、营销和发展。

收入、营销和开发页面的结构是相似的。让我们快速浏览一下收入页面。

Revenue page

顶部有两个图表:按月和类别划分的收入,显示公司每个月产生的收入金额,以及按国家/地区的收入,代表所选期间每个国家/地区的收入总额。

中间是三个甜甜圈图,分别显示了按类别划分的收入分布、交易对手的移动 IAP 和交易对手的广告收入分布。

在底部,有一个可下载的表格。

作出预测

在此页面上,用户可以对未来 n 个月的时间序列进行预测。我为此任务尝试了 3 个模型:ARIMA、XGBoost 和 LSTM 神经网络。后者表现得比其他的更好,所以我在这个应用程序中使用了 LSTM。用户可以选择参数以使模型更准确。这是表单的样子:

Parameters for LSTM model

第一个字段是下拉菜单,用户可以在其中选择产品进行预测。

滞后是用于预测下一个值的过去观察的数量。

时期数是整个训练数据集通过模型的次数。在每个 epoch 中,模型的参数都会更新。

Months to be predicting 是要预测的月数

训练部分是训练集的观察百分比。

进行预测按钮有什么作用?

LSTM model

进行预测按钮对指定数量的提前期进行预测。这是一个时间序列问题。对于这类问题,理想情况下,时间序列应该是平稳的,简单来说,均值和方差应该随时间保持不变。在左上图,我们可以看到原始数据集表示一段时间内的利润。数据是非平稳的。我创建了一个新功能,它只是从一个观察到下一个观察的百分比变化。在右上图,我们可以看到所有的波动都接近于零,因此均值接近于零,然而,方差仍然是非平稳的。尽管存在非平稳方差,但我将进一步使用此功能。

接下来,使用表格中提供的百分比在训练集和测试集之间拆分数据集。使用 MinMaxScaler,使用从 0 到 1 的特征范围对特征进行归一化。然后使用 Keras TimeseriesGenerator 类生成目标变量。模型已定义。我选择均方误差作为损失函数,因为它是此类问题最流行的选项。

训练集通过模型n次(前面指定的Epochs数),每次更新模型的内部参数并计算均方误差。当均方误差较小时最好。我们可以看到在每个时期的损失图上训练模型的结果。该图显示,从第 70 个 epoch 开始,损失函数很低且恒定。

由于模型一次只预测一个值,我们需要使用前向验证过程。这是一个迭代过程,我们预测一个值并将该值附加到评估集。然后我们从原始评估集中删除第一个值,因此在每次迭代中,我们都有恒定数量的观察值,这等于表格中前面定义的滞后。

将测试集的实际值与预测值进行比较,并将其绘制在图表上。通常,图表可以更清晰地指示模型的执行情况。在左下图,实际数据用蓝线表示,预测数据用黄色表示。

此外,均方根误差作为评估指标提供。计算如下:我们在每次观察时取实际值与预测值之间的差,然后将每个差平方,使差为正,然后计算平方差的平均值,最后取平方结果均值的根。

RMSE formula

RMSE 值越低越好。但是,RMSE 是一个相对度量,应该通过考虑原始数据的规模进行分析。例如,上图中的 RMSE 为 0.09,这对于我们的案例来说是一个很好的指标,因为我们可以看到基础数据在 -0.2 到 0.2 之间变化,因此与这个范围相比,0.09 是一个相对较小的量。但是,如果基础数据在 -0.002 和 0.002 之间变化呢?在这种情况下,0.09 的 RMSE 很大。因此,考虑数据的规模非常重要。

以下是与模型相关的代码:

LSTM model

在模型经过训练和评估后,会生成前面表格中指定的时期的预测。

如果用户对生成的模型感到满意,他们可以按保存按钮,生成的预测将作为 CSV 文件上传到 S3。之后,预测将显示在利润页面上。

部署

我通常在 Heroku 上部署我的 Web 应用程序,但这次,在收到通知后,从 2022 年 11 月起他们不再为用户提供免费的 dyno,我决定尝试 AWS Elastic Beanstalk。部署过程非常简单,但是很难调试应用程序,老实说,还有一些错误需要修复。我稍后会这样做:)

结论

差不多就是这样。回顾一下,用户可以将交易列表上传到应用程序,应用程序将返回交互式仪表板,用户可以在其中监控公司的主要财务指标。使用flask,自定义内容非常容易,即添加或更改功能,因此应用程序可以根据用户的特定需求进行定制。在我看来,以这种格式提供的报告相对于具有长表格和复杂公式的 Excel 工作表来说更加专业和可靠。

您可以在我的 Github 仓库 .

可以使用此访问应用程序 关联 .

如果您将使用上面的链接使用该应用程序,请注意我在该应用程序版本中禁用了将文件上传到 S3。要访问具有完整功能的应用程序,请从 GitHub 克隆代码并在本地计算机上运行它。

请对您用于部署 Web 应用程序的框架发表评论。

就是这样,感谢您的阅读!

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明

本文链接:https://www.qanswer.top/1520/52232916

posted @ 2022-08-29 16:53  哈哈哈来了啊啊啊  阅读(58)  评论(0编辑  收藏  举报