美文网首页
利用人工智能构建简书资产排行榜预测模型

利用人工智能构建简书资产排行榜预测模型

作者: 初心不变_叶子 | 来源:发表于2022-02-04 21:26 被阅读0次

提到人工智能,大家会想到什么?

自动驾驶、大数据、图像识别、黑白照片上色、“换脸”......

巨大的算力需求、百万级的数据、长达数周的训练时长......

其实,人工智能的根本原理,就是模拟人类大脑的运作方式。

在实操之前,我想先跟大家聊聊 AI,和它背后的东西——神经网络。

神经元与神经网络

一句话解释:人类大脑中有 100 亿以上的神经元,它们以网状结构互相连接,就组成了神经网络。

通过计算机模拟的神经网络,通常叫做“人工神经网络”(Artificial Neural Network,ANN),有时也被简称为“神经网络”(Neural Network,NN)。

大脑中的神经元有树突和轴突,树突用于接收神经冲动,而轴突用于发送神经冲动。

神经网络中的神经元也有输入和输出,一个神经元通常有两个输入端和一个输出端。

每当两个数据传入,神经元就会将这两个数与对应的权重(Weight)相乘,将结果相加,然后输出。

举个例子,我们现在有一个神经元,输入端 x1 的权重为 0.3,输入端 x2 的权重为 0.5,现在 x1 = 2,x2 = 3,那么输出结果就是 0.3 * 2 + 0.5 * 3 = 2.1。

神经网络是分层的,最常用的神经层叫做“全连接层”,顾名思义,每个神经元都与它上一层和下一层的所有神经元相连接。

数据从神经网络的第一层输入,结果由最后一层输出。

神经网络的训练与预测原理

如果你要做一个识别猫和狗的 AI,你首先需要给它一些猫和狗的照片,让它学会怎么将两者区分开来。

这个让神经网络“学习”的过程,叫做训练。

未经训练的神经网络中,每个神经元的权重都是随机的。

我们通过一种神奇的方式,将猫和狗的图片转换成数据,然后输入神经网络。

(其实也不神奇,就是把图片转换为亮度的二维矩阵,然后展平成一维矩阵——如果看不懂可以略过)

神经网络给出了判定结果,一般是两个数,第一个代表图片为猫的概率,第二个代表图片为狗的概率。

当然,由于这个神经网络没有被训练,第一次的输出结果当然是不准确的。

这时,我们需要一个东西,准确来说,一个函数,来衡量神经网络的判定结果是否准确,这就是损失函数(loss)。

一般来说,损失函数的值越小,神经网络的预测结果越准确,这个模型就更像“人工智能”而不是“人工智障”。

loss 值有了,我们还需要一种方式,通过改变神经元的权重让神经网络的预测更准确,这就是优化器(optimizer)。

优化器会从最后一层开始,根据特定的规则更新每个神经元的权重,这一过程叫做神经网络的优化。

数据从输入层到输出层,这个过程是正向的,我们把它叫做“正向传播”。

相对应的,优化器反向更新权重的过程,叫做“反向传播”。

一次正向传播和一次反向传播,就是一次完整的训练过程。

当然,一个一个数据来训练未免有些慢了,我们可以一次输入多个数据,获取一批结果,针对这一批结果进行优化。

每批数据的个数,叫做批大小(batch_size),比如 batch_size = 64,就代表一次输入 64 个数据进行训练。

把所有数据分批输入之后,这轮训练就完成了。

我们把这里的“轮”叫做 Epoch。

哦对,神经网络的层数、每层的神经元个数、损失函数、优化器、批大小这些东西,统称为“超参数”。超参数在训练过程中保持不变。

而神经网络中的”参数“,指神经元的权重,是会在训练过程中不断改变的。

有了这些知识,我们就可以进入实战了。

开发环境与数据

本次使用的是简书用户资产排行榜数据,时间跨度从 2021 年 9 月 14 日到 2022 年 2 月 2 日,共 142 天。

数据集中包含每天资产排行榜前 1000 名用户的基础信息和简书钻、简书贝、总资产数据。

总数据量为 140840 条,存储在 SQLite 数据库中,大小为 10.8MB。

开发环境为 VS Code 与 Jupyter Notebook。

使用的第三方库如下:

tensorflow==2.7.0
keras==2.7.0
numpy==1.19.5
pandas==1.3.5
scikit-learn==0.24.2
matplotlib==3.4.3

训练在 CPU 上的运行时间不超过 10 分钟,可以不使用 GPU 进行训练。

如果需要使用 GPU,请参考 TensorFlow 官方文档进行环境配置。

注意:只支持 NVIDIA GPU,且 GPU 必须支持 CUDA。

我们使用 Keras 库进行模型构建与训练,它是 TensorFlow 的高层封装。

TensorFlow 是谷歌开发的深度学习框架,已被广泛用于商业级人工智能模型的训练与部署。

数据载入与预处理

创建一个名为模型训练.ipynb的文件,使用 VS Code 打开。

首先,载入第三方库:

import sqlite3
from pickle import dump as pkl_dump

import pandas as pd
from keras.callbacks import EarlyStopping, ModelCheckpoint
from keras.layers import Dense
from keras.models import Sequential
from matplotlib import pyplot as plt
from numpy import array
from sklearn.preprocessing import MinMaxScaler

我们首先需要对 Matplotlib 进行一些设置:

plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号
plt.rcParams["figure.figsize"] = (16, 8)  # 指定图表大小

接下来,使用 Python 内置库 sqlite3 创建数据库连接,并通过 Pandas 载入数据:

conn = sqlite3.connect("UserAssetsRankList.db")
df = pd.read_sql_query("SELECT * FROM assetsranklistdata", conn)
conn.close()

(这里的 SQL 语句含义为查询 assetsranklistdata 表中的所有数据)

查看数据概览:

数据概览

这里需要注意,data_id 作为数据库主键是不可能存在空值的,其它列的非空数据量与 data_id 列不同,意味着存在缺失数据。

使用以下代码,删除所有存在空数据的行:

df.dropna(inplace=True)

再次查看数据概览:

数据概览(去除空值后)

我们来输出前几条数据试试看:

数据样例

我们将使用资产量(assets)作为输入,排名(ranking)作为输出。

所以使用以下代码将这两列的数据提取出来,并转换为 Numpy Array:

x = array(df["assets"])
y = array(df["ranking"])

以防万一,我们需要看一眼数据维度:

数据维度(未调整)

输入神经网络的数据必须是 (数据量, 每条数据的变量个数) 这样的维度,否则进行训练时会因数据维度不匹配而报错。

所以我们需要对数据维度进行调整:

数据维度(调整后)

来看看前五条数据:

输入数据样例

输出是一个二维矩阵格式,外层为数据,内层为数据中的变量。

由于用户资产量差异巨大,如果直接作为输入提供给神经网络,会大大增加训练耗时,所以我们需要对数据进行标准化:

scaler = MinMaxScaler()
scaler = scaler.fit(x)
x = scaler.transform(x)

标准化后的数据是这样的:

输入数据样例(标准化后)

每条数据都是介于 0 和 1 之间的浮点数,其比例与原有数据的比例相同。

到这里,我们的输入数据就已经准备好了。

模型构建与训练

我们使用最简单的顺序模型:

model = Sequential()

然后向模型中添加层:

model.add(Dense(128, activation="relu", input_dim=1))
model.add(Dense(64, activation="relu"))
model.add(Dense(32, activation="relu"))
model.add(Dense(16, activation="relu"))
model.add(Dense(8, activation="relu"))
model.add(Dense(1, activation="linear"))

这里的 Dense 就是全连接层,参数 activation 则是激活函数,我们暂时不需要了解。

注意,第一层要指定输入数据的维度,也就是每条数据的变量个数,这里为 1。

最后一层的激活函数需要设置为 linear,激活函数的不同会影响最终输出的值。

查看一下模型结构:

模型结构

这是一个六层的顺序模型,共有 11265 个参数(权重)。

接下来对模型进行编译:

model.compile(loss="mse", optimizer="adam")

我们使用 MSE(均方误差)作为损失函数,Adam 作为优化器。

Adam 是 SGD(随机梯度下降)的优化版本,可以自动调整学习率,加快训练速度。

这里还可以指定 metrics(度量标准),比如在分类任务中,可以使用 Accuracy(准确率)作为度量标准,这样我们就可以更直观地看到模型训练的状态。度量标准的选择不会影响模型训练结果,它只是为模型的状态提供参考。

在开始训练之前,我们还需要设置 ModelCheckPoint 和 EarlyStopping。

callbacks = []
callbacks.append(ModelCheckpoint(filepath="checkpoint_{epoch:02d}_{val_loss:.4f}.h5", verbose=1, save_best_only=True))
callbacks.append(EarlyStopping(monitor="loss", patience=20, verbose=0))

ModelCheckPoint 可以按照一定规则自动将模型存入硬盘,防止训练中断导致进度丢失。

这里我们使用 val_loss 作为度量标准,每当训练集的 loss 值下降时,就会自动保存模型。

EarlyStopping 可以设置提前终止训练的条件,防止因训练次数过多出现过拟合。

过拟合是模型受到训练集上噪声的影响,导致在真实数据中表现反而更差的现象。

我们设置当 loss 连续 20 个 Epoch 没有下降时终止训练。

接下来,使用一行代码开始训练,参数含义如下:

  • x、y:输入和输出数据
  • epochs:训练轮数,这里我们设置为 500,但很有可能中途自动停止
  • batch_size:批大小,越大训练速度越快,同时也会占用越多的内存 / 显存,在不同数据量的情况下对模型性能也有一定影响
  • shuffle:每次训练前,打乱训练集的顺序(测试集不会打乱顺序)
  • callbacks:回调函数,如自动保存和提前停止规则
  • validation_split:训练集占比,0.2 代表 20%,测试数据会从数据集最后进行选取
history = model.fit(x, y, epochs=500, batch_size=1024, shuffle=True, callbacks=callbacks, validation_split=0.2)

注意:如果运行出现报错,并且错误信息中有 OOM(Out Of Memory,内存溢出)提示,请降低 batch_size,但一般不要小于 64,否则会大大延长训练时间。

训练输出如下:

训练输出

可以看到,输出内容包含每个 Epoch 的 batch 个数、预计剩余时间、单 batch 耗时,以及训练集与测试集的 loss 值。

在我的设备上(i5-6200U,GeForce 920MX),训练耗时 3 分 30 秒。

共训练了 130 个 Epoch,最终训练集 loss 为 8030.6338,测试集 loss 为 7508.0049。

注意,如果训练集 loss 明显低于测试集 loss,则代表模型可能存在过拟合。

训练结果可视化

我们刚才将训练数据保存到了 history 对象中,可以通过以下代码提取其中的信息,并绘制成 loss 趋势图:

plt.plot()
plt.title("loss & val_loss")
plt.plot(history.history["loss"], color="b", label="训练集 loss")
plt.plot(history.history["val_loss"], color="g", label="测试集 loss")
plt.legend()
plt.show()
loss 趋势图

可以看到,随着 Epoch 数的增加,loss 快速下降,随后趋于平缓并不再有大的波动。

之后我们通过以下代码,使用数据集中的前一万条数据进行批量预测,并将预测结果与实际值相比较:

result = model.predict(x[:10001])
plt.plot()
plt.title("ranking & assets")
plt.scatter(df["ranking"][:10001], df["assets"][:10001], label="实际", color="g", s=10)
plt.scatter(result, df["assets"][:10001], label="预测", color="b", s=10)
plt.legend()
plt.show()
预测值与实际值对比

预测结果(蓝色点)与实际值(绿色点)趋势基本一致,说明我们的模型较为准确。

模型保存

使用一行代码,将模型保存到硬盘:

model.save("user_assets_rank_model_20220203.h5")

.h5 是 HDF5 格式的扩展名,这是一种高效率的数据格式,常用于存储大量数据和模型权重信息。

神经网络模型分为两部分,结构与权重,save 方法可以将它们保存到同一个文件中,便于管理。

另外,我们还需要将用于数据标准化的 scaler 对象进行保存:

with open("user_assets_rank_model_scaler_20220203.pkl", "wb") as f:
    pkl_dump(scaler, f)

这样,我们就可以通过模型对数据进行预测了。

模型使用

新建 模型使用.ipynb 文件。

导入必须的库:

from keras.models import load_model
from pickle import load as pkl_load

加载模型:

model = load_model("user_assets_rank_model_20220203.h5")

加载 scaler 对象:

with open("user_assets_rank_model_scaler_20220203.pkl", "rb") as f:
    scaler = pkl_load(f)

我们使用 2021 年 9 月 14 日排行榜第 501 - 505 名用户的数据进行测试:

测试数据

对数据进行预处理:

x = [34636.705, 33528.346, 32169.189, 32197.005, 32179.009]
x_to_perdict = [[item] for item in x]
x_to_perdict = scaler.transform(x_to_perdict)

进行预测:

result = model.predict(x_to_perdict)

输出结果:

for index, item in enumerate(result):
    print(f"{x[index]} => {item[0]}")

预测结果如下:

预测结果

预测值与实际值有约 100 名的差异,这是用户资产数据波动较大造成的。在较长的时间维度上,这一模型会有更好的表现。

总结

本篇教程带领大家从人工智能与神经网络开始,了解 AI 背后的运作原理。

同时,运用 Keras 完成了一个小型模型的构建、训练、评估与使用。

对人工智能与神经网络感兴趣的简友,可以自行探索以下内容:

  • 不同激活函数(activation)的图像,以及它对网络层的影响
  • 极高与极低 batch_size 对模型训练效果的影响
  • 不同损失函数与优化器对模型训练效果与训练速度的影响
  • 神经网络可视化工具 TensorBoard 的使用

如果大家在探索过程中做出了更加准确的模型,可以将模型结构和超参数发在评论区中。

深度学习是一个”炼丹“的过程,一点点微小的变动就可能对模型效果产生巨大的影响,我们能做的,只有不断地尝试,从而找到其中的规律。

人工智能离我们并不遥远,未来的路,就由我们一同探索吧。

相关文章

  • 利用人工智能构建简书资产排行榜预测模型

    提到人工智能,大家会想到什么? 自动驾驶、大数据、图像识别、黑白照片上色、“换脸”...... 巨大的算力需求、百...

  • 2020-09-04

    预测赔付金额 利用产险因子分险种预测赔付金额GBDT 构建残差模型 用集团共享标签去纠正

  • 昨天发文被封

    昨天发文被封,但是日更还是算的。 主要是讲简书资产排行榜的。 不让讲就不讲了。 总之大家注意下简书资产排行榜,看看...

  • 拥有2000简书钻贝在简书能排多少名

    简友们请注意,简书总资产排行榜是指简书钻和简书贝总和的排行榜。 此排行榜每日更新一次,约在凌晨两点左右更新昨日排行...

  • 从最和气被踩看国人之素质

    最和气乃旅英华人,著名畅销书作家,简书持巨钻首户,简书总资产约一百五十多万,荣居简书总资产排行榜第一名! 就是这样...

  • 简书资产排行榜

    简述资产排行榜。 可以看出来,第一名是权益小管家。 本来第二名是无穷。 现在他已经排到了第七名,并且名称变成了太傻...

  • 金融反欺诈项目

    构建信用卡反欺诈预测模型 本项目需解决的问题 本项目通过利用信用卡的历史交易数据,进行机器学习,构建信用卡反欺诈预...

  • 简书180天,资产10000,排名1000。

    文/乐德小老儿 到2020年5月24日根据简书官方的统计排行榜,我在简书的资产排行榜正好排名1000,一位不差,不...

  • 线性模型-线性回归

    线性模型 线性模型利用输入特征的线性函数(linear function)进行预测。 线性模型预测的一般公式如下:...

  • 快速了解临床预测模型的建立

    定义: 临床预测模型(又称临床预测规则、预测模型或者风险评分):指利用多因素模型估算患有某病的概率或者将来某结局发...

网友评论

      本文标题:利用人工智能构建简书资产排行榜预测模型

      本文链接:https://www.haomeiwen.com/subject/donskrtx.html