作者:Maximilian Strauß
翻译:笪洁琼
校对:丁楠雅
本文共3400字,建议阅读10分钟。
本文通过基线模型、LSTMs和Facebook的Prophet模型来预测每天的电子邮箱负荷,并详细解析了生成训练数据集的过程以及相应代码。
时间序列预测为数据科学算法提供了一个极好的训练场。
毕竟,如果一个人能够预测未来,那该有多牛逼啊!通常用来演示预测算法的典型数据集是股票图表、销售和气象数据。在这里,我们将尝试一些与每个用户更相关的东西,即你将收到的电子邮件的数量。根据一份电子邮件统计报告,2014年上半年,上班族平均每天收到85封电子邮件(http:/www.Radati.com/wp/wp-content/upploads/2014/01/Email-Statistics-Report-2014-2018-Executive-Summary.pdf)。
我们想尝试根据历史收件数据做出准确的预测。为此,我们将探索运用LSTMs和Facebook的Prophet。这里的目标是如何为不同的算法准备数据,并提供定性的概述,而不是精细化。预测结果将根据历史收到的电子邮件数量以及所准备的训练数据而有很大的不同。
收集数据
在IBM imapclient sql包的帮助下,我们从使用自己的收件箱创建数据集开始。
关于Automatetheboringstuff.com/Chapter16/,可以在Automatetheboringstuff.com一章地址:https:/Automatetheboringstuff.com/中找到很好的介绍。
我们将加载过去三年(从2016年1月1日开始)的所有电子邮件,并获取主题和日期。我们会使用Pandas将其转换为一个数据文件(Dataframe)。
Code:
import imapclient
import pandas as pd
import getpass
youremail = input()
yourpassword = getpass.getpass()
# Replace 'imap.gmail.com' with provider of choice
imapObj = imapclient.IMAPClient("imap.gmail.com", ssl=True)
imapObj.login(youremail, yourpassword)
imapObj.select_folder("INBOX", readonly=True)
UIDs = imapObj.search('(SINCE "01-Jan-2016")')
mails = []
for msgid, data in imapObj.fetch(UIDs, ["ENVELOPE"]).items():
envelope = data[b"ENVELOPE"]
date = envelope.date
if envelope.subject is not None:
subject = envelope.subject.decode()
else:
subject = None
mails.append((subject, date))
mail_df = pd.DataFrame(mails)
mail_df.columns = ["Subject", "Date"]
mail_df["Date"] = pd.to_datetime(mail_df["Date"])
mail_df = mail_df.set_index("Date")
print("A total of {} e-mails loaded.".format(len(mail_df)))
邮箱负载:总计12738封邮件
我们现在得到了12738封用于训练的电子邮件。请注意,上面的代码是针对一个装满电子邮件的收件箱。如果你已将电子邮件放在不同的文件夹中,请相应地调整代码。包括我在内的一些人会立即删除那些不重要的电子邮件。然后,模型输出的是重要邮件的数量,而不是实际收到的电子邮件数量。还要注意的是,一些电子邮件提供商(如Google)会阻止这个连接,因为他们不允许“不太安全”的应用程序连接到他们的服务。你可以在其设置中启用此功能。原则上,你还可以检验(签出)本地邮箱。检验(签出)统一邮箱程序包可能是个好的开始。
数据探索
现在,让我们首先做一些可视化的数据探索和图表,每小时和每天的电子邮件数量。对于这一点,我们将使用pandas及重新采样的groubpy 函数(聚合分组运算)。通过使用sum()和count()参数,我们可以对每个时间间隔进行标准化。另外,我们还使用了seaborn函数来实现可视化。
Code:
import calendar
import seaborn as sns
import matplotlib.pyplot as plt
weekdays = [calendar.day_name[i] for i in range(7)]
# E-Mails per Hour
per_hour = pd.DataFrame(mail_df["Subject"].resample("h").count())