用决策树模型预测二氧化碳排放增长
基于化石/核能/可再生能源消费增长的二氧化碳增长预测
Python ETL 脚本、Tableau 探索性数据分析和 scikit-learn 决策树
二氧化碳排放量的增长是导致气候变化速度加快的一个主要因素。为了减少二氧化碳排放,各国必须发挥积极作用,遏制与排放增长最相关的能源消费活动。在当前的能源消费形势下,可再生能源(例如:风能、太阳能)的消费也越来越受到重视。为了优先考虑对减少二氧化碳排放影响最大的举措,各国必须配备高性能的未来排放预测工具。
拟议解决方案
在这个项目中,我们旨在提供这样一种工具,它使用决策树机器学习算法,根据一个州的能源消耗状况的理论变化来预测该州的排放量增长。
该工具使用 Python 脚本来提取、标准化和创建基于六个独立数据集的模型,这些数据集与州排放、经济和能源消耗概况相关。这里使用的主要 Python 库是:requests、pandas 和 scikit-learn。
该项目基于 2019 年秋季南加州大学维特比工程学院应用数据科学硕士项目 INF 550“大规模数据科学”课程的一项任务,由金善浩教授提供建议。我的搭档哈维尔布兰东也为这个项目做出了巨大贡献。
概念验证(POC)现已在我的 Github 页面-> 此处 上提供了用户友好的指南。
假设问题
我们希望为本项目提供指导的两个主要假设问题是:
- 国家能源消耗或生产与排放有更高的关系吗?
- 给定一个州的能源消耗增长,我们能很有把握地预测排放量是否会增长吗?
我们将使用清理数据集上的 Tableau 散点图来回答第一个问题。我们将使用 Python scikit-learn 处理转换后的数据来回答第二个问题。
ETL 和建模应用程序的结构
为了对 python 脚本和结果数据文件进行组织,我用两个子文件夹构建了存储库:
- src —保存用于生成数据库的所有脚本,包括:驱动程序文件、python 模块需求、表格清理、线性回归和决策树脚本。这个驱动文件叫做**‘Emissions _ data analysis . py’。**应该从终端调用这个驱动程序,以运行所有的清理和建模脚本。
- 数据 —保存已清洗的。csv 文件、线性回归和决策树可视化输出
src 文件夹的组织——驱动程序、清理和建模脚本位于此处
步骤 1:数据采集
该分析考虑了各州的历史排放、能源生产、能源消耗和经济数据。这些数据是从两个美国机构的网站上获得的——能源信息署 (EIA) 和经济分析局 (BEA) 。从这些 web 资源中,提取了六个表,并使用各自的 python 脚本对每个表进行了规范化。EIA 提供了涵盖 2000 年至 2016 年的国家排放、部门排放、能源生产和能源消费的数据集。这些数据发表在。该机构网站上的 csv 格式。
提取后,数据表被规范化并存储在本地。csv 文件
每个表都通过一个’-cleaning.py '脚本进行提取、转换和存储。x4 EIA 清理脚本指向。csv 文件,而 x2 BEA 脚本利用 BEA API 工具提取数据。
步骤 1:数据转换
为了实现排放、经济、能源生产和能源消耗表的连接,在写入之前,使用 python pandas 在内存中对数据进行了规范化。csv 文件到磁盘。这些数据集覆盖了不同的年份,并在不同的维度上扩展。一些数据集的属性是行,状态是列,而另一些则相反。每个脚本都必须适合数据源的原始格式,这样才能完成正确的转换。
标准化表格格式的过程是一个不可避免的障碍。然而,这一步是探索性数据分析(Tableau)和机器学习模型创建(Python)的基本先决条件。有了规范化的表格,现在可以将数据连接在一起,研究经济和环境指标之间的关系。
步骤 2:关系表的存储
清理完成后,每个数据集都作为存储库中的. csv 文件写入磁盘。我们使用的数据集相对较小,因此我们可以管理其中的存储。csv 文件在用户的机器上足够容易。
如果数据集非常大(千兆字节或兆兆字节),我们将在远程机器上实现已清理数据的存储。我们还希望使用分布式方法实现 python 数据清理,将工作分配给几个工人。
在应用程序的“数据”文件夹中存储已清理的数据文件
步骤 3:数据探索过程
在连接这些表之后, Tableau 用于探索针对假设问题的连接数据集的可视化。与假设一致,目标是揭示经济活动、能源消耗和排放之间的可预测关系。
双变量分析 —在此步骤中,探索了两个变量的许多组合,试图揭示预测关系。Tableau 用于快速构建二元可视化。在此步骤中,重点还在于回答与初始假设相关的两个问题:
每个观察代表 2016 年的一个州
1。能源生产或消费与排放的相关性更大吗? —为了探索这个问题,我们分析了 2016 年的数据,并构建了一个散点图矩阵,将生产和消费设为自变量,将源排放量(总&运输)设为因变量。这一形象化的分析清楚地表明了消费和排放之间存在着更强的联系。因为消费有很强的相关性,所以在分析的后面会对消费类型(化石燃料、核能、可再生能源)进行更深入的探讨。
“排放运输”关系中的噪音更少
2。哪些经济因素可以用来预测排放量?— 为了理解这个问题,我们选择了 2016 年的数据来创建另一个散点图矩阵,希望观察到线性关系。该散点图使用经济指标(实际国内生产总值、人口、个人收入、能源消耗)作为自变量,源排放量(总量、电力、交通)作为因变量。每个观察值反映了 2016 年的一个特定状态。为了保持这种关系,剔除了异常值,包括必须单独研究的较大状态。这些州异常值是加利福尼亚州、佛罗里达州、洛杉矶、纽约州和德克萨斯州。
从这个可视化结果来看,与运输排放的关联分数最为明显。由于强线性关系,这表明运输排放可能是使用线性回归线进行预测的强有力候选。
步骤 4:模型创建-线性回归
在观察到经济变量和运输排放之间的强线性关系后,正式定义了二元线性回归关系。这些回归使用了 2016 年的数据,并再次删除了必须单独研究的州异常值(加利福尼亚州、纽约州、德克萨斯州)。Python 脚本连接到了。csv 表并用于构建回归模型。Python 包 pandas、pyplot、matplotlib 和 scikit learn 用于模型和可视化。
每条回归线的 R 平方得分至少为 0.8659,这意味着这些线将解释因变量中至少 0.8659 的变异。如果没有行业标准的领域知识,很难相信这个度量的质量。然而,回归模型为预测运输排放提供了相对准确的工具。
从’ emissions_regressions.py 创建的回归输出
步骤 5:模型创建—决策树
在确定了总排放量和能源消耗之间的关系后,工作重点转向进一步发展这种关系,寻找与排放量增加最相关的能源消耗类型(化石、核能、可再生能源)和化石燃料消耗类型(煤、天然气、石油)。Python pandas 用于数据转换,scikit-learn 用于算法和可视化。
决策树需要的数据转换,在’decision tree _ emis _ foster fuels . py
作为该分析的先决条件,必须转换数据以符合决策树分类输入要求。在此分析中,类别设置为排放量,属性设置为煤炭、天然气和石油消耗。然后,计算从 1990 年到 2016 年每个类别和属性的逐年增长。最后,每个增长指标被分类编码为 0 —减少,1 —无变化,2 —增加。对数据进行编码后,三个不同的决策树根据 1990 年至 2015 年的数据进行了训练(行数= 1250),并将增长限制在三个节点,以避免过度拟合。然后用 2015-2016 年的数据(行= 50)测试每棵树,并分析结果。
每个决策树的测试结果
在 python scikit-learn 包中, DecisionTreeClassifier 对象用于增长树并使用基尼不纯指数对数据节点进行分区。基尼系数显示了随机选择的元素被错误标记的频率。类似于使用最高信息增益的节点分裂,最小的 gini 杂质用于分裂树。此外,对于进一步的节点,DecisionTreeClassifier 对象考虑同一属性的较小分区的 gini 杂质,以最大化分类的准确性。
我们有最高的测试精度(0.94%),模型设置为预测“燃料类型”(化石、核能、可再生能源)的“所有排放”。在所述决策树(如下)中,第一个节点表明化石燃料消耗的增加对排放增加的影响最大。即使考虑到核能和可再生能源消费的增长(第二和第三节点),排放量增长预测主要反映了化石燃料的增长状况。这一观察结果反映出化石燃料的消耗与排放密切相关。然而,包括第二和第三节点(核能和可再生能源)增加了模型预测的准确性。
最高性能决策树的输出,来自’[decision tree _ emis _ all fuels . py【T1]'](https://github.com/mann-brinson/CO2Emissions_Predictive_Analysis/blob/master/src/decisiontree_emis_allfuels.py)
结论
这项研究证明:1)可以使用人口、国内生产总值和消费**【线性回归】来预测州交通排放;2)减少化石燃料比可再生能源消费【决策树】**对排放的影响更大。
这些都是重要的见解,因为它们为特定的行动过程提供了数据驱动的基础。例如,希望减少总体排放量的国家可以考虑鼓励减少化石燃料的消耗,而不是太阳能电池板等可再生能源的消耗。这个话题开启了关于设计减少国家二氧化碳排放的最有效途径的对话。
用模糊逻辑预测新冠肺炎感染
如何利用模糊时间序列预测冠状病毒感染病例
约翰·利博特在 Unsplash 上的照片
介绍
使用时间序列预测方法是分析疫情感染率的常用方法。这将有助于我们创建更好的决策支持系统。我在这里所写的,是我在伊斯法罕科技大学 J-Asgari 教授的模糊系统课程中学到的一部分。所以我们先从时间序列的定义说起。
时间序列是在连续的、在大多数情况下是等距的时间周期/时间点对一个个体或集体现象的数量特征进行的一组有规律的时序观察[ 更确切地说是 ]。时间序列数据有两种主要的预测方法:
1-统计工具:阿玛 SARIMA 萨里玛[ 更多 ]
2-基于神经网络的智能工具,如 RNN 和 LSTM [ 更多
数据探索
我们已经查看了从这里下载的欧洲数据。此外,所有数据文件、源代码和笔记本都已上传到这个 Colab 笔记本上。让我们快速浏览一下数据集:
import pandas as pd
import warnings
import matplotlib.pylab as plt
%pylab inlinedf = pd.read_excel('COVID-19.xlsx')
df.head()
如上所示,我们必须按“continentExp”和“countriesAndTerritories”汇总数据:
#Aggregate by continentExp
continentExp = pd.pivot_table(df, values='cases', index=['dateRep'],columns=['continentExp'], aggfunc=np.sum, fill_value=0)#Aggregate by countriesAndTerritories
countriesAndTerritories = pd.pivot_table(df, values='cases', index=['dateRep'],columns=['countriesAndTerritories'], aggfunc=np.sum, fill_value=0)
按 continentExp 汇总
continentExp["Europe"].plot(figsize=(15,5), color=["green"], title='Europe')plt.show()
模糊时间序列预测
1965 年,扎德提出了模糊集的概念,作为检验未知隶属度的工具。许多模糊研究试图将这种方法作为理论框架,并广泛应用于自然科学和社会科学的研究领域,取得了良好的研究成果。模糊时间序列也是从模糊集概念中衍生出来的一种分析方法。由扎德提出的模糊集有许多表现形式,如模糊集、模糊决策分析和模糊时间序列。【1。
pyFTS 库是什么?
这个软件包是为学生,研究人员,数据科学家,或谁想要利用模糊时间序列方法。这些方法提供了简单,易于使用,计算成本低,人类可读的模型,适用于统计外行专家。 Github 。
#install pyFTS
!pip install pyFTSCollecting pyFTS Downloading [https://files.pythonhosted.org/packages/41/3a/c5ef1879b33fdf07dc5678e8484d9ea637924afd6c66f14d65001cb1cddf/pyFTS-1.6-py3-none-any.whl](https://files.pythonhosted.org/packages/41/3a/c5ef1879b33fdf07dc5678e8484d9ea637924afd6c66f14d65001cb1cddf/pyFTS-1.6-py3-none-any.whl) (175kB) |████████████████████████████████| 184kB 3.3MB/s Installing collected packages: pyFTS Successfully installed pyFTS-1.6
定义语言变量
对于语言变量,我们指的是其值为自然或人工语言中的单词或句子的变量。例如,年龄是一个语言变量,如果它的值是语言的而不是数字的,即年轻、不年轻、非常年轻、非常年轻、老、不太老和不太年轻[ 2 ]。
我们定义了 10 个变量“A0 — A9”,其中 A0 的感染度最低,A9 的感染度最高。然后进行模糊化,即通过最大化方法将每条记录集合成一个模糊集。
from pyFTS.partitioners import Griddata = data.valuesfs = Grid.GridPartitioner(data=data,npart=15)fig, ax = plt.subplots(nrows=1, ncols=1, figsize=[15,5])fs.plot(ax)
fuzzyfied = fs.fuzzyfy(data, method='maximum', mode='sets')pd.DataFrame(fuzzyfied).assign(values = list(data)).tail()
时间模式
这部分描述了考虑先例→结果逻辑已经生成的规则,例如,在 A0 先例之后,我们移动到 A0 和下一个时间步(t+1) A1。所以这里我们有:
from pyFTS.common import FLRpatterns = FLR.generate_non_recurrent_flrs(fuzzyfied)print([str(k) for k in patterns])output: 'A0 -> A0', 'A0 -> A1', 'A1 -> A1', 'A1 -> A2', 'A2 -> A2', 'A2 -> A3', 'A3 -> A3' ... ,'
规则生成
在生成模糊规则时,需要解决类之间的重叠。有两种解决重叠的方法:一种是在不考虑重叠的情况下生成模糊规则,然后通过调整模糊规则来解决重叠;另一种是在生成模糊规则的同时解决重叠。我们把前者的静态模糊规则生成和后者的动态模糊规则生成[ 更称为 ]。
根据我们上面讨论的模式,可以生成时间步长移动的规则。
from pyFTS.models import chenmodel = chen.ConventionalFTS(partitioner=fs)model.fit(data)print(model)
上述规则显示了每个语言变量的先例和后果,并生成规则。也就是说,在 A0 中发生的任何数据都有 A0 和 A1 的结果,这意味着在 A0 之后没有 A2 的数据。
模糊化和建模
模糊化就是将模糊域中的连续量分成几个层次,根据需要,每一个层次都可以看作一个模糊变量,并对应一个模糊子集或一个隶属函数[ more ]。
fuzzyfied = fs.fuzzyfy(18876, method='maximum', mode='sets')fig, ax = plt.subplots(nrows=1, ncols=1, figsize=[15,5])forecasts = model.predict(data)forecasts.insert(0,None)orig, = plot(data, label="Original data")pred, = plot(forecasts, label="fuzzified forecast")legend(handles=[orig, pred])
结论
ARIMA 时间序列预测中的方法可以预测平均误差。利用模糊时间序列中的公式,我们可以求出平均误差。模糊时间序列的误差值小于 ARIMA 时间序列的误差值。因此可以得出结论,模糊时间序列比其他时间序列模型有更好的结果。
参考
使用 Prophet 和 SARIMA 模型预测新冠肺炎的推文量
使用邻域聚类预测德里的新冠肺炎密集区
对位置进行分析和分组,以制定最佳位置缓解策略
https://news.un.org/en/story/2020/02/1056562
编者注: 走向数据科学 是一份以研究数据科学和机器学习为主的中型刊物。我们不是健康专家或流行病学家,本文的观点不应被解释为专业建议。想了解更多关于疫情冠状病毒的信息,可以点击 这里 。
1.介绍
1.1 背景
新冠肺炎是一种传染性疾病,它扰乱了地球上每个平民的日常生活,给现代世界带来了巨大灾难。该病毒主要影响肺部,全球已有 4,543,390 人感染,303,711 人因此丧生(截至 2020 年 5 月 15 日)。疫情迫使世界各国领导人采取严厉措施,如全国范围的封锁,以遏制病毒的传播。但是封锁阻碍了平民的工作和谋生,其影响不仅困扰着穷人,也困扰着社会的每一个部分,甚至政府本身。在这种情况下,经济下滑,国家可能走向衰退,人们可能被迫离开,与病毒一起工作和生活。这给像印度这样人口密度巨大的国家带来了巨大的风险。
1.2 问题
为了预见解除封锁的影响,我的研究和这本笔记本将帮助人们了解哪些社区可能会出现新冠肺炎病例激增。我将使用人口密度数据和热门地点(如热门市场)的位置数据来估计在特定地点发生的交互。这些社区将被分组,这样就可以建立共同有效的策略来处理类似的地方。我将主要关注我所在城市(印度首都德里)的预测。
1.3 利息
借此,我希望读者能够更好地了解潜在的危险区域,当局可以采取措施,事先对这些区域进行限制,以减少病毒的传播,从而减少平民生活的痛苦。
我希望并祈祷读到这封信的人平安无事。
2.数据
为了解决上述问题,我利用了以下数据:
德里的邻近地区(及其分割的基础)
德里有 9 个区,居民区都集中在其中一个区。
链接—https://en.wikipedia.org/wiki/Neighbourhoods_of_Delhi
请注意,这一数据是根据 2011 年人口普查得出的,根据目前的情况,人口普查公布了 9 个区,而不是 11 个区。因此,我将在南德里下增加东南德里的地方,在东德里下增加沙达拉的地方。
当我在地图上绘制结果时,这些数据将用于定义邻域。我借助谷歌地图中的“搜索”选项,计算出每个街区的大致坐标,并创建了自己的数据集。
热门地点的位置数据——由 Foursquare API 提供
Foursquare API 提供了与特定地点不同地点出现频率相关的数据。我将使用位置数据来识别人流密集的场所(如市场)附近的集群。这些区域将被识别为热点区域。
值得注意的是,Foursquare API 没有太多关于德里场馆的细节,因此这只是真实世界的一个大概图片。但我们可以肯定地说,这是一个很好的近似值,将满足我们的需要。
各地区的人口密度——2011 年人口普查数据
由于生活条件高度接近,人口密度数据将用于标记具有潜在高社区传播风险的地区。
链接—https://www . census 2011 . co . in/census/state/district list/Delhi . html
地区边界数据
我自己创建了一个数据集,里面有德里每个区的多边形坐标。我利用两个网站——http://nominatim.openstreetmap.org/和http://polygons.openstreetmap.fr/index.py首先提取地图上一个地方的位置,然后分别提取其坐标。
3.方法学
为了预测德里的 COVID 密集区,我们将执行以下步骤:
- 查找每个街区的热门场地类别
- 使用 KMeans 聚类,根据流行的场所类别形成邻域的聚类。
- 叠加一层每个地区人口密度的 choropleth 图,以正确预测可能情况的严重性
最初,我开始想象社区和每个社区的活动场所。
根据社区对场地进行分组,我们看到只有 161 个社区被返回。这意味着在 177 个社区中,有 16 个没有场地结果。
现在,我创建了一个表,其中包含了在每个社区中找到的前两个场所类别。
根据找到的顶级场所,我使用 KMeans 聚类对相似的社区进行分组。我利用剪影分数比较来寻找 K 的最佳值(即聚类数)。
K 的最佳值为 6,然后用 K 均值聚类法将邻域分成 6 类。然后将结果合并到一个数据框中。
4.结果
在使用地区人口密度数据创建一个 Choropleth 地图时,我得到了这个。
此后,我将邻近区域的聚类添加到该地图上,这样我们就可以根据该地点的聚类属性和人口密度来了解邻近区域的聚类以及对它们的关注程度。
图例:
- 最令人担忧的——红色、黄色
- 适度关注—紫色、蓝色
- 最不值得关注的——绿松石
- 无关—绿色
邻域聚类属性有:
- 主要有“快餐店”和其他社交活动场所的社区。(最受关注)—黄色标记
- 有住宅区和日常平民活动区的社区。(中度相关)—蓝色标记
- 有许多日常生活相关场所的社区。(中度相关)—紫色标记
- 以“印度餐馆”为主的街区。(最受关注)—红色标记
- 只有基本需求场所的社区。(最不相关)—绿松石标记
- 场馆很少的街区。(无关)—绿色标记
5.讨论
在最终地图的帮助下,我们可以看到哪些地区容易受到病毒传播的影响,以及每个地区的哪些社区需要特别注意。
如果不及时采取措施,红色和黄色标记的地方(最受关注区域)尤其是像东北德里、北德里和中央这样的地区会使情况恶化。德里西南部和德里北部是人口稀少的地区,应该是德里最不受关注的地区。
在今后的研究中,可以进行以下改进:
- 如前所述,Foursquare API 在用于收集关于德里的数据时并不提供非常详细的结果。在进一步的研究中,可以利用其他位置数据提供者来获得更高的准确性。
- 此外,如果能够利用邻域边界并提取边界内的所有地点,而不是使用邻域的坐标,将会产生近乎完美的结果。
- 该项目使用了 2011 年人口普查数据。今年是 2020 年,这意味着统计数据可能会发生很大变化。因此,根据最新的人口普查数据,当它发布时,可能会使结果更好。
6.结论
新冠肺炎在全球造成了严重破坏,现在地球上几乎一半的人都在抗击疫情。有了更好的战略和更有效的制度,我们应该能够以更好的方式解决这个问题,以便尽快解决这个问题,这不仅是为了全体人民的福利,也是为了保护经济。我希望我的这个项目有助于缓解战略的形成,以便我们都能赢得这场战斗,并尽早恢复正常生活。
我要感谢 Coursera、IBM 和所有参与数据科学专业证书课程的教师,他们向我介绍了数据科学,并使我具备了分析手头问题并得出结果所需的所有技能。最后但同样重要的是,我希望并祈祷我的读者们平安无事。
感谢您花费宝贵的时间阅读我的作品。
预测农作物产量:机器学习纳米级顶点项目
印度田间的农民— @nandhukumarndd
一.定义
简介、问题陈述和指标
训练机器来学习和产生未来预测模型的科学被广泛使用,这并不是没有意义的。农业在全球经济中发挥着至关重要的作用。随着人口的持续增长,了解世界范围内的作物产量对于应对粮食安全挑战和减少气候变化的影响至关重要。
作物产量预测是一个重要的农业问题。农业产量主要取决于天气条件(雨水、温度等)、杀虫剂。关于作物产量历史的准确信息对于做出与农业风险管理和未来预测相关的决策非常重要。
世界各地的烹饪有很大差异,但维持人类生存的基本成分非常相似。我们吃大量的玉米、小麦、大米和其他简单的农作物。在这个项目中,利用粮农组织和世界数据库的公开数据,机器学习方法被用于预测 10 种消费最多的作物。
回归分析是一种预测建模技术,调查因变量(目标)和自变量(预测值)之间的关系。用于本项目的回归模型:
- 梯度推进回归器
- 随机森林回归量
- SVM
- 决策树回归器
sk learn . metrics . R2 _ score函数计算 **R(决定系数);**它是可从自变量预测的因变量中方差的比例,它是一种介于 0 和 1 之间的统计度量,用于计算回归线与其拟合的数据的相似程度。如果是 1,模型 100%预测数据方差;如果它是 0,模型预测没有方差。
评估指标将是 R 分数,它将代表回归模型中项目(作物)方差的比例。默认的 SciKit-Learn 梯度推进回归器和随机森林回归器将用作基准。然后将探索几个模型来改进基准,包括决策树回归器和支持向量机(SVM)。
二。分析
收集和清理数据
数据收集是收集和测量相关变量信息的过程。粮农统计数据库提供了 300 多万个与粮食和农业有关的时序和跨部门数据。粮农组织的数据可以在 csv 格式(万岁!)。粮农统计数据库的核心数据集中包含 200 个国家和 200 多种初级产品和投入的数据。它提供国家和国际的食品和农业统计数据。首先要得到的是每个国家的农作物产量。
现在数据看起来整洁有序,但是删除了一些列,如区号、域、商品代码等,这些对分析没有任何用处。此外,将值重命名为 hg/ha_yield ,以便更容易识别这是我们的作物产量产值。最终结果是一个四列的数据框架,包括:国家,项目,年份和作物产量。
使用 describe() 函数,很少能弄清楚数据框架,它从 1961 年开始,到 2016 年结束,这是粮农组织所有可用的最新数据。
气候因素包括湿度、阳光和涉及气候的因素。环境因素是指土壤条件。在这个模型中,选择了两个气候因素和一个环境因素,雨和温度。除了影响植物生长和发育的杀虫剂。
雨水对农业有着巨大的影响,除了每个国家的平均温度外,本项目的年降雨量信息也是从世界数据库中收集的。
平均降雨量的最终数据框架包括:国家、年份和年平均降雨量。数据框从 1985 年到 2017 年,另一方面,平均温度数据框包括国家、年份和平均记录温度。温度数据帧开始于 1743,结束于 2013。年份的变化会对收集的数据造成一定的影响,因为必须统一一个年份范围以不包含任何空值。
农药的数据是从粮农组织收集的,它从 1990 年开始,到 2016 年结束。将这些数据框架合并在一起,预计年份范围将从 1990 年开始,到 2013 年结束,这是 23 年的数据。
最终数据帧
上图描述了模型应用的最终数据框架和选定的特征。
正如预期的那样,数据框架从 1990 年开始,到 2013 年结束。确保没有空实体,我可以进入下一步。最后要注意的是,每一列的值的高方差,稍后我将说明这一点。
数据探索
按国家和项目分组,以便更好地理解数据集。数据框架中有 101 个国家,其中印度的农作物产量最高。此外,印度是木薯和土豆产量最高的国家。马铃薯似乎是数据集中的主要作物,在 4 个国家中最高。
现在,探索数据帧的列之间的关系,快速检查列之间的相关性的一个好方法是将相关性矩阵可视化为热图。从下面的热图可以明显看出,所有变量都是相互独立的,没有相关性。
数据帧中特征的相关热图
三。方法学
数据预处理
数据预处理是一种用于将原始数据转换成干净数据集的技术。换句话说,无论何时从不同来源收集数据,都是以原始格式收集的,这对于分析是不可行的。
在最终的数据帧中有两个分类列,分类数据是包含标签值而不是数值的变量。可能值的数量通常限于一个固定的集合,就像本例中的 items 和 countries 值。许多机器学习算法不能直接对标签数据进行操作,它们要求所有输入变量和输出变量都是数字。
这意味着分类数据必须转换成数字形式。一个热编码是一个过程,通过该过程,分类变量被转换成可以提供给 ML 算法的形式,以在预测中做得更好。为此,将使用一键编码将这两列转换为一键数字数组。
分类值表示数据集中条目的数值。这种编码将为每个类别创建一个二进制列,并返回一个包含结果的矩阵。
dataframe 的特征将类似于上面的 115 列。看一下上面的数据集,它包含的要素在量级、单位和范围上有很大差异。与低量值的要素相比,高量值的要素在距离计算中的权重要大得多。为了抑制这种效应,我们需要将所有的特征置于相同的量级。这可以通过用最小最大缩放器进行缩放来实现。
数据预处理的最后一步是训练和测试数据。数据集将被分成两个数据集,即训练数据集和测试数据集。数据通常倾向于拆分不等式,因为训练模型通常需要尽可能多的数据点。对于培训/测试,常见的拆分是 70/30 或 80/20。
训练数据集是用于训练 ML 算法以学习和产生正确预测的初始数据集。(70%的数据集是训练数据集)
型号比较和选择
在决定使用哪种算法之前,首先我们需要评估、比较并选择最适合这个特定数据集的算法。
通常,当使用给定的数据集处理机器学习问题时,我们会尝试不同的模型和技术来解决优化问题,并拟合最合适的模型,该模型既不会过拟合也不会欠拟合。
评估指标是基于 **R(决定系数)**回归得分函数设置的,它将代表回归模型中项目(作物)方差的比例。 R 分数显示了术语(数据点)与曲线或直线的拟合程度。
四款车型的研发结果
从上面的结果来看,决策树回归器的 R 值最高,为的 96% ,GradientBoostingRegressor次之,为的 89%。
我还将计算调整后的 R ,其中它也表示术语与曲线或直线的拟合程度,但会根据模型中的术语数量进行调整。如果你在一个模型中加入越来越多的无用变量,调整后的 r 平方将会减少。如果你增加更多有用的变量,调整后的 r 平方将会增加。调整后的 R 将始终小于或等于 R 。
R 和调整后的 R 结果。
四。结果
模型结果和结论
对 R 最常见的解释是回归模型与观测数据的拟合程度。对于示例,60%的 R 表明 60%的数据符合回归模型。通常,较高的 R 表示更适合该模型。从获得的结果来看,很明显,该模型与数据的吻合度达到了 96%。
特征重要性通过到达该节点的概率加权的节点杂质的减少来计算。节点概率可以通过到达节点的样本数除以样本总数来计算。该值越高,越重要,特性越重要。获得模型的 7 大重要特性:
特征重要性条形图
土豆这种作物在模型决策中具有最高的重要性,它是数据集中最高的作物。木薯也是如此,正如我们所料,我们看到了杀虫剂的影响,这是第三个最重要的特征,如果作物是红薯,我们会看到一些在数据集中特征重要性最高的作物。
如果作物生长在印度,这是有意义的,因为印度在数据集中有最大的作物总和。然后是降雨量和温度。关于这些特征的第一个假设是正确的,它们都显著影响模型中的预期作物产量。
下面的箱线图显示了每个项目的产量。土豆最高,木薯,红薯,山药。
动词 (verb 的缩写)结论和最终想法
上图包含了颠倒的决策树的图形,根在顶部,在这个例子中,根是条目 potatoes,因为它是顶部的特征。特征的重要性一目了然,关系也易于查看。
决策树算法已经成为 Kaggle 等竞赛以及商业环境中使用最多的机器学习算法之一。决策树既可以用于分类问题,也可以用于回归问题。
决策树通常从单个节点开始,分支成可能的结果。这些结果中的每一个都会导致额外的节点,这些节点又分支成其他的可能性。由正方形表示的决策节点显示要做出的决策,而结束节点显示决策路径的最终结果。一个节点代表一个输入变量(X)和该变量上的一个分割点,假设该变量是数值型的。树的叶节点(也称为终端节点)包含用于进行预测的输出变量(y)。
决策树通过对数据提出一系列问题来得出一个估计值,每个问题都会缩小我们的可能值,直到模型有足够的信心做出一个预测。问题的顺序及其内容由模型决定。另外,问的问题都是真/假的形式。决策树回归使用均方误差 (MSE)来决定将一个节点分割成两个或多个子节点。
根节点是 item potato,这是它在模型中最重要的特性。该模型会询问它是否是马铃薯,然后根据它的真假来跟踪分支。该算法首先选取一个值,并将数据分成两个子集。对于每个子集,它将分别计算 MSE。该树选择导致最小 MSE 值的值,直到它到达叶节点。
既然对分类项进行了编码,那么答案要么是 0,要么是 1,要么是,要么不是,那么深度为 1 的两个内部节点,如果遵循真分支,“是项木薯?< = 0.5”。另一个节点,会问“农药 _ 公吨< = 0.005 ”,跟随决策树到更深一层等等。
上图显示了预测的拟合优度,显示为一条线。可以看出 R 成绩优秀。这意味着我们已经找到了一个很好的拟合模型来预测某个国家的作物产量值。增加更多功能,如气候数据;风和污染,特定国家的经济状况等等可能会增强模型的预测。
那么,纳米学位值得吗?
嗯,某些部分,肯定是!如果部署部分更侧重于使用 Flask 而不是 Amazon SageMaker,我会更喜欢。
我设法在三周内完成了纳米学位,通过每个项目后的自律和满足感绝对值得。此外,可爱的升级项目专家徽章也值得你额外努力去完成每一件事。#UdacityLevelUp
(链接代码: 机器学习-顶点-项目)
参考
sci kit-learn 和 Spark 中决策树、随机森林和特征重要性的数学运算
联合国粮食及农业组织
预测电信行业的客户流失
使用特征重要性通过降维来简化问题,并为不平衡分类移动阈值。
授权 Leo Siu-Yin 通过 Shutterstock 获取图像
为什么要预测客户流失?
获得新客户比留住现有客户要昂贵得多。一些研究表明,获得一个新客户的成本是保持一个现有客户的六到七倍。
据 BeyondPhilosophy.com:
忠诚的客户会降低与消费者教育和营销相关的成本,尤其是当他们成为你组织的净推广者时
因此,能够主动确定最有可能离开的客户并通过了解他们的需求和提供积极的客户体验来采取预防措施非常重要。
Sharon McCutcheon 在 Unsplash 上拍摄的照片
方法论
该项目分为 3 个阶段:
- 数据清理和探索性数据分析。
- 模型选择和阈值调整。
- 结果解释。
数据清理和探索性数据分析
数据来自 Kaggle,IBM 数据集。数据集有些不平衡,流失率为 26.5%。
首先检查数据的唯一客户 ID。空格被替换为 0,列在适用时被更改为数字类型。
进行 EDA 是为了理解数据。像性别这样的特征对流失影响不大,会被去掉。
使用热图绘制要素间的相关性,并丢弃彼此高度相关的要素(如下所示,相关性> 0.6)。
然后对分类特征进行一次热编码。并且通过使用算法的特征重要性属性的随机森林分类来选择前 11 个特征。
减少输入要素的数量将简化正在建模的问题并加快建模过程。
模型选择和阈值调整
使用四种模型对最终数据进行建模:逻辑回归、C-支持向量分类、K 近邻分类器和随机森林分类器。
GridSearchCV 用于调整超参数,并为每个模型找到最佳超参数。
基于阈值 0.5 的 1 类分类,发现逻辑回归模型具有最高的 ROC-AUC 得分、最低的对数损失、最高的 F1 得分和最高的回忆得分。因此,选择逻辑回归模型作为最终模型来进一步微调阈值,以提高我们数据的召回分数。
ROC-AUC 评分
原木损失
F1 分数
精确
回忆
精度是相关实例在检索到的实例中所占的比例,召回(也称为敏感度)是实际检索到的相关实例总数的比例。
在预测客户流失时,较高的召回率优于较高的精确度,因为能够预测哪些客户流失的风险较高是最理想的。然而,调整阈值以获得更高的召回率是以降低精确度为代价的。因此,需要实现平衡。在这个项目中,我选择使用 F1 分数作为衡量标准来选择我的阈值。
分类算法的工作原理是在概率被映射到类别标签之前预测概率。这是通过使用诸如 0.5 的阈值来实现的,其中等于或大于阈值的所有值被映射到一个类,而所有其他值被映射到另一个类。
由于数据具有类别不平衡,默认阈值会导致较差的分类。因此,调整用于将概率映射到分类标签的阈值非常重要。
在默认阈值为 0.5 时,逻辑回归模型给出的 F1 值为 0.58。基于 0.62 的最大 F1 分数,阈值结果是 0.36。这个新的阈值将回忆分数从 0.55 提高到 0.78。
结果解读
基于逻辑回归模型,电信公司可以专注于前两项功能,并通过以下方式减少客户流失:
- 与客户签订长期合同。
- 提高客户的在线安全性。
这里有一个链接到我的 GitHub,你可以在那里找到我的代码和演示幻灯片。也可以通过 LinkedIn 联系我。
使用逻辑回归预测客户流失
我第一次接触逻辑回归算法
在 Unsplash 上由 Austin Distel 拍摄的照片
什么是客户流失?
流失率,也称为损耗率或客户流失率,是客户停止与实体做生意的比率。它通常表示为在给定时间段内停止订购的服务用户的百分比。高客户流失率表明公司正在以惊人的速度流失客户。客户流失可归因于无数原因,公司需要通过客户数据中的模式和趋势来发现这些原因。
现代企业如今采用复杂的算法来预测最有可能流失的客户,即离开公司的客户。通过使用这种算法,公司可以提前知道最有可能放弃公司服务的客户,并因此提出客户保留策略来减轻公司可能面临的损失。
问题陈述
在前面的段落中描述客户流失的原因是因为我的下一个机器学习项目的目标是开发一种算法,可以准确预测最有可能流失的客户。
作为一个额外的挑战,我试图发现客户流失的趋势,并确定客户决定终止合同时的主要因素。在我所掌握的各种可视化库的帮助下,我能够找出控制客户流失决策的可能参数。这些因素将在本博客的后续章节中讨论。
工作流程
电信行业客户流失预测是一个机器学习问题。因此,为这个项目获取数据非常简单。我从 Kaggle 下载了数据集,并将其加载到我的 jupyter 笔记本上。此外,我还导入了完成这个项目所必需的库。现在需要的唯一任务是分析数据,清理数据,并使用清理后的数据集训练 ML 模型。
数据探索和数据工程
步骤 1:检查缺失值。
探索数据集时最重要的步骤之一是搜索缺失值。缺失值能够阻碍 ML 算法的训练过程,并影响训练模型的准确性。在数据集上使用 pandas 的 isnull()函数后,我发现数据集中没有缺失值。因此,我进入了数据探索步骤。
要素列表以及缺失值的计数。(图片由作者提供)
第二步:数据探索。
因为我现在确信我的数据集中没有丢失的值,所以我可以将注意力转向研究手头的数据。数据探索是至关重要的一步,因为它使我能够熟悉数据集中存在的不同特征以及每个特征列包含的值的类型。下面列出了我在数据探索阶段发现的数据要点。
- 总共有 17 个分类特征和 4 个连续特征。
- 除了“老年人”、“任期”和“每月费用”,所有其他特征都是数据类型对象。
- 最后,数据集包含 1,869 条有过交易的客户记录和 5,163 条没有交易的客户记录。
步骤 3:数据可视化
数据可视化是任何机器学习或数据科学项目的一个关键方面。可视化通常提供数据的鸟瞰图,允许数据科学家或 ML 工程师从手头的数据中辨别趋势和模式。我使用 seaborn library 的 countplot 函数来绘制分类特征,然后试图发现客户流失的趋势。上述可视化任务的输出可以在下图中看到。
(图片由作者提供)
从上面的图片中,我能够挑出一些有趣的点,这些点在流失的客户中很普遍。以下列出了相同的内容:
- 男性和女性的流失率几乎相当。
- 老年人的流失率很低。
- 拥有电话服务的客户流失率更高。
- 有合作伙伴和家属的客户的流失率低于没有合作伙伴和家属的客户。
- 与其他支付方式相比,使用电子支付方式的客户流失率更高。
- 没有互联网服务的客户流失率较低。
- 光纤互联网服务的流失率要高得多。
这种可视化通常有助于公司发现客户流失的可能原因。例如,以电子方式付款的客户更有可能流失,这可能是因为他们在进行电子付款时面临一些不便,公司可以对此进行调查,或者选择光纤互联网服务的客户对公司的流失率有很大影响,这可能暗示客户对公司提供的光纤互联网服务不满意,公司可以调查此事并尽早解决问题。数据可视化是重要的一步,因为它提供了可操作的见解,并帮助公司做出明智的决策。
步骤 4:数据工程
由于数据探索阶段现在已经完成,并且我对数据集有了很好的理解,所以我继续进行项目的数据工程部分。首先,我去掉了“*客户 Id”*列,因为它不会影响我们的 ML 模型的预测能力。接下来,我将所有分类特征转换成一次性编码特征。最后,数据集被分成训练和测试数据,以促进 ML 模型的训练。
机器学习模型创建和评估
第一步:训练一个机器学习模型。
随着数据探索和工程阶段的完成,我继续训练我的机器学习模型。客户流失预测是一个分类问题,因此,我使用逻辑回归算法来训练我的机器学习模型。在我看来,逻辑回归是一个相当容易实现、解释和训练非常有效的算法。此外,它在数字数据上工作得非常好。最后,可以通过逻辑回归实现的*【L1】和【L2】*正则化技术防止模型过度拟合。
我从 sklearn 库中导入了逻辑回归模型,并对训练数据使用了*“fit”*函数。拟合操作一完成,我就进入下一步,评估我的 ML 模型的性能。
步骤 2:评估模型性能。
这是我的机器学习项目的最后一步,就是测试我的 ML 模型的性能。这一步至关重要,因为我可以根据看不见的客户数据来衡量我的 ML 模型的准确性。为了确定我的 ML 模型的性能,我使用了测试数据,并计算了预测标签的准确度分数以及混淆矩阵。逻辑回归模型的准确度得分为 *81.5%。*共有 1148 个标签被准确预测,而 259 个标签被错误预测。
结论
这个关于客户流失预测的机器学习项目给我提供了一个新的学习体验。它允许我使用各种可视化库,并让我意识到数据可视化的重要性。这也让我有机会使用一种新的 ML 算法,即逻辑回归。这个项目是机器学习在现实世界中的一个主要例子,在这个项目中工作帮助了我,磨练了我在机器学习领域的技能。
我为这个项目遵循的工作流程可以在我的Github个人资料中找到。我希望你喜欢看我的博客。
使用逻辑回归预测客户流失
第 2 部分:构建模型
在我之前的帖子中,我们完成了一个客户流失分析数据集的探索性数据分析过程。我们的数据来源于 Kaggle,以客户流失率为中心,商业客户将离开他们目前是电信公司 Telco 的(付费)客户的商业平台。现在 EDA 流程已经完成,我们对数据在处理前告诉我们的东西有了很好的认识,我们可以继续构建一个逻辑回归分类模型,它将允许我们预测客户是否有从电信平台流失的风险。
完整的 GitHub 知识库和笔记本以及数据浏览可以在这里找到。
由 Austin Distel 在 Unsplash 上拍摄的照片
逻辑回归
当处理我们累积到二元分离的数据时,我们希望将我们的观察结果分类为客户“会流失”或“不会流失”平台。逻辑回归模型将试图猜测属于一个或另一个群体的概率。逻辑回归本质上是线性回归的扩展,只有预测的结果值在[0,1]之间。该模型将确定我们的目标特征、流失和我们的剩余特征之间的关系,以应用概率计算来确定客户应该属于哪个类别。我们将使用 Python 中的“ScikitLearn”包。
概括数据
提醒一下,在我们的数据集中,我们有 7043 行(每行代表一个唯一的客户)和 21 列:19 个特征,1 个目标特征(客户流失)。数据由数字和分类特征组成,因此我们需要分别处理每种数据类型。
目标:
- 客户流失—客户是否流失(是,否)
数字特征:
- 任期——客户在公司工作的月数
- 月度费用—每月向客户收取的费用
- 总费用——向客户收取的总费用
分类特征:
- CustomerID
- 性别—男/女
- 老年人—客户是否是老年人(1,0)
- 合作伙伴—客户是否有合作伙伴(是,否)
- 受抚养人——客户是否有受抚养人(是,否)
- 电话服务—客户是否有电话服务(是,否)
- 多条线路—客户是否有多条线路(是,否,无电话服务)
- 互联网服务—客户的互联网服务类型(DSL、光纤、无)
- 在线安全—客户是否有在线安全插件(是、否、无互联网服务)
- OnlineBackup —客户是否有在线备份插件(是、否、无互联网服务)
- 设备保护—客户是否有设备保护附件(是、否、无互联网服务)
- 技术支持—客户是否有技术支持附加服务(是、否、无互联网服务)
- 流媒体电视—客户是否有流媒体电视(是,否,无互联网服务)
- 流媒体电影—客户是否有流媒体电影(是,否,无互联网服务)
- 合同—客户合同的期限(每月、1 年、2 年)
- 无纸账单—客户是否有无纸账单(是,否)
- 支付方式—客户的支付方式(电子支票、邮寄支票、银行转账(自动)、信用卡(自动))
为建模预处理我们的数据
在 EDA 过程中,我们移动了一些数据,但是预处理主要是为了便于使用和消化,而不是为了模型的功能。为了进行逻辑回归,我们必须以不同的方式对数据进行预处理,特别是为了适应数据中的分类特征。让我们再看一下我们的数据信息,了解一下我们正在做什么。
我们没有任何丢失的数据,我们的数据类型是有序的。请注意,我们的大部分数据是“对象”类型,即我们的分类数据。这将是我们在预处理步骤中关注的主要领域。在数据的顶部,我们看到两个不必要的列,“未命名:0”和“客户 id”。这两列与我们的数据无关,因为前者没有任何重要的值,而后者是客户的唯一标识符,这是我们不想要的。我们通过快速熊猫切片从数据帧中快速删除这些特征:
df2 = df.iloc[:,2:]
下一步是解决我们的目标变量,流失。目前,该特性的值为“是”和“否”。这是一个二元结果,这是我们想要的,但我们的模型将无法以其当前的字符串形式有意义地解释这一点。相反,我们希望用数字二进制值替换这些变量:
df2.churn.replace({"Yes":1, "No":0}, inplace = True)
接下来,我们必须处理剩余的分类变量。虚拟变量是将名义变量作为二进制值合并到回归中的一种方式。这些变量允许计算机将分类变量的值解释为高分(1)或低分(0)。因为变量现在是数字,模型可以评估变量的方向性和重要性,而不是试图找出“是”或“否”的意思。当添加虚拟变量时,将添加新的二进制特征,其值为[0,1],我们的计算机现在可以解释。Pandas 有一个简单的函数来执行这一步。
dummy_df = pd.get_dummies(df2)
**注意:**当分类变量有多于二进制值时,注意“drop_first”参数是非常重要的。我们不能使用分类变量的所有值作为特征,因为这将引发多重共线性问题(计算机将对冗余信息赋予错误的意义)并破坏模型。我们必须留下一个类别作为参考类别。
我们新的数据框架特征如上,现在包括虚拟变量。
分割我们的数据
我们现在必须将数据分为目标特征和预测特征。
# Establish target feature, churn
y = dummy_df.churn.values# Drop the target feature from remaining features
X = dummy_df.drop('churn', axis = 1)# Save dataframe column titles to list, we will need them in next stepcols = X.columns
特征缩放
我们的数据几乎完全经过预处理,但还有一个更突出的问题需要解决,即缩放。我们的数据现在全是数值型数据,但是都是不同的单位。将“streamingtv_Yes”的二进制值 1 与“monthlycharges”的连续价格值进行比较不会给出任何相关信息,因为它们具有不同的单位。这些变量对模型的贡献是不一样的。为了解决这个问题,我们将通过重新调整原始变量来标准化我们的数据值,使其与其余变量具有相同的范围和方差。出于我们的目的,我们将使用最小-最大缩放 [0,1],因为标准化值将位于二进制范围内。
# Import the necessary sklearn method
from sklearn.preprocessing import MinMaxScaler# Instantiate a Min-Max scaling object
mm = MinMaxScaler()# Fit and transform our feature data into a pandas dataframe
X = pd.DataFrame(mm.fit_transform(X))
训练-测试-分离
我们现在进行标准的训练测试分割,将我们的数据分成训练集和测试集。
from sklearn.model_selection import train_test_splitX_train, X_test, y_train, y_test = train_test_split(X, y, test_size = .25, random_state = 33)
构建模型
现在可以相对快速地建立模型,我们选择一些参数:
from sklearn.linear_model import LogisticRegression# Instantiate a logistic regression model without an intercept, arbitrarily large C value will offset the lack of interceptlogreg = LogisticRegression(fit_intercept = False, C = 1e12, solver
= 'liblinear')# Fit the model to our X and y training sets
logreg.fit(X_train, y_train)
既然我们的模型已经建立,我们必须预测我们的未来值。
y_hat_train = logreg.predict(X_train)
y_hat_test = logreg.predict(X_test)
此时,我们的模型实际上已经完全构建好了,尽管我们没有看到输出。让我们来看看评估我们的表现。
评估模型性能
分类器在训练集上正确的次数是多少?
因为我们试图预测一个客户是否会离开,有什么比看看它多长时间是正确的更好的方法来检查我们的模型性能!为此,我们将采用实际训练数据和预测训练数据之间的剩余距离,以及实际测试数据和预测测试数据之间的剩余距离。
# Find residual differences between train data and predicted train data
resiudals = np.abs(y_train, y_hat_train)# Print the number of times our model was correct ('0') and incorrect ('1')
print(pd.Series(residuals).value_counts()# Print normalized amount of times our model was correct (percentage)
print(pd.Series(residuals).value_counts(normalize = True)
非标准化训练结果:
- 正确:4270
- 不正确:1012
归一化训练结果:
- 正确:. 8084
- 不正确:1916
这挺好的!在我们的第一次测试中,80%的正确率是一个很大的数字。请记住,100%的准确性实际上会是一个问题,因为我们的模型会完全超出我们的数据。让我们检查我们的测试数据(执行与上面相同的代码块,使用 y_test 和 y_hat_test 作为剩余参数。
非标准化测试结果:
- 正确:1409
- 不正确:352
归一化测试结果
- 正确:. 8001
- 不正确:1999 年
再次,积极的结果!我们的测试集和训练集大小不同,因此归一化的结果在这里更有意义。事实上,我们的模型在我们的训练和测试集上表现得差不多,这是一个积极的迹象,表明我们的模型表现良好。
混淆矩阵
混淆矩阵是评估我们的分类器性能的一个非常强的方法。混淆矩阵是一种直观表示,它告诉我们四个重要分类指标的程度:
- 真阳性(TP): 模型预测客户会流失(1)并且他们确实会流失(1)的观察次数
- 真否定(TN): 模型预测客户不会流失(0),而他们实际上没有流失(0)的观察次数。
- 误报(FP): 模型预测客户会流失的观察次数(1),但在现实生活中他们不会流失(0)。
- 假阴性(FN): 模型预测客户不会流失的观察次数(0),但在现实生活中他们会流失(1)。
混淆矩阵的一个轴将代表真实值,而另一个轴将代表预测值。在这一步,拥有业务领域知识是非常重要的。某些度量对我们的模型来说更普遍。例如,如果我们对一个病人是否患有疾病进行建模,那么大量的假阴性会比大量的假阳性更糟糕。如果有许多假阳性,那么这仅仅意味着一些患者需要进行一些不必要的测试,可能还需要一两次烦人的医生检查。但是,高假阴性意味着许多患者实际上已经患病并被诊断为健康,这可能会产生可怕的后果。为了达到客户流失的目的,当客户实际流失时,预测客户不会流失对我们来说更糟糕,这意味着我们的假阴性更值得关注。
from sklearn.metrics import confusion_matrix# Pass actual test and predicted target test outcomes to function
cnf_matrix = confusion_matrix(y_test, y_hat_test)
混淆矩阵:
我们在 1761 次观察中有 224 次是假阴性。这比我们想要的略大,但仍然是一个有希望的数字。为了从混淆矩阵中获得真正的意义,我们必须使用这四个指标来产生更具描述性的指标:
- 精确度:预测的精确度
- 精度= TP/PP
- “在模型预测客户会流失的所有次数中,客户实际流失了多少次”
2。Recall: 表示我们感兴趣的类实际上被模型捕获的百分比
- 召回= TP/(TP + FN)
- “在我们看到的所有实际流失的客户中,我们的模型正确识别为‘将会流失’的客户占多少比例
**3。准确性:**度量模型获得正确预测的总数,包括真阳性和真阴性
- 准确度= (TP + TN)/(TP + FP + TN + FN)
- “在所有的预测中,有百分之多少是正确的?”
**4。F1 得分:**精确度和召回率的调和平均值—精确度和召回率的一个强有力的指标(在没有强有力的模型支持的情况下,不可能有高的 F1 得分)
- F1 = 2(精度*召回)/(精度+召回)
- 如果模型偏向于精确或召回,则严重惩罚模型
- 通常最常用的模型性能指标
这些指标可以通过更长的路径手工计算,但对我们来说幸运的是,Sklearn 有一些模块可以为我们计算这些指标。我们要做的就是传递我们的目标数据集和我们预测的目标数据集。
from sklearn.metrics import precision_sore, recall_score, accuracy_score, f1_scoreprecision_train = precision_score(y_train, y_hat_train)
precision_test = precisoin_score(y_test, y_hat_test)recall_train = recall_score(y_train, y_hat_train)
recall_test = recall_score(y_test, y_hat_test)accuracy_train = accuracy_score(y_train, y_hat_train)
accuracy_test = accuracy_score(y_test, y_hat_test)f1_train = f1_score(y_train, y_hat_train)
f1_test = f1_score(y_test, y_hat_test)
精度:
- 火车:0.6615
- 测试:0.6666
回忆:
- 火车:0.5558
- 测试:0.5333
精度:
- 火车:0.8084
- 测试:0.8001
F1 得分:
- 火车:0.6041
- 测试:0.5926
我们的结果令人鼓舞,但并不完全令人满意。我们的查全率和查准率分数比我们预期的要低一点,但是我们的查准率分数是最强的指标,也是一个非常好的标志,尤其是在第一次尝试的时候。请记住,构建模型是一个迭代过程,因此第一次的高分是令人鼓舞的!
ROC 曲线和 AUC
另一种评估我们模型性能的综合方法和混淆矩阵的替代方法是 AUC 度量和 ROC 曲线图。
ROC 曲线——受试者操作者特征曲线
这个直观的图表将说明我们的分类器的真阳性率(召回率— TPR)与假阳性率(FPR)。表现最好的模型将有一个 ROC 曲线,它紧挨着图表的左上角。这意味着我们对积极因素的正确分类要比错误分类多得多。下图中的蓝色虚线表示 1:1 的线性关系,代表一个坏的分类器,因为模型每猜对一个就猜错一个,这比扔硬币好不了多少!
AUC —曲线下面积
AUC 将为我们提供一个单一的数字指标进行比较,而不是直观的表示。AUC = 1 表示完美的分类器,AUC = 0.5 表示只有 50%精度的分类器。这一指标量化了我们的分类器模型的总体准确性。
获取指标的编码如下:
from sklearn.metrics import roc_curve, auc# Calculate probability score of each point in training set
y_train_score = model.decision_function(X_train)# Calculate false positive rate(fpr), true pos. rate (tpr), and thresholds for train set
train_fpr, train_tpr, train_thresholds = roc_curve(y_train, y_hat_train)# Calculate probability score of each point in test set
y_test_score = model.decision_function(X_test)# Calculate fpr, tpr, and thresholds for test set
test_fpr, test_tpr, test_thresholds = roc_curve(y_test, y_hat_test)
绘制 ROC 曲线的代码:
# Plot the training FPR and TPR
plt.plot(train_fpr, train_tpr, label = 'ROC Curve')# Plot positive sloped 1:1 line for reference
plt.plot([0,1],[0,1])
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.05])
plt.xticks([i/20.0 for i in range(21)])
plt.yticks([i/20.0 for i in range(21)])
- 训练 AUC = 0.8517
- 测试 AUC = 0.8388
这些指标看起来很棒!请注意,我们的测试和训练曲线都紧挨着左上角,并且具有非常强的 AUC 值。有了这样强大的模型,我们现在可以将目光转向调整一些模型参数/超参数来慢慢提升我们的分数。
结论
我们为第一轮建造了一个非常坚固的模型。构建任何机器学习模型都是一个迭代的过程,分类建模本身就有几种类型的模型。在接下来的一些帖子中,我将探索这些其他方法,如随机森林、支持向量建模和 XGboost,看看我们是否可以改进这个客户流失模型!
用 PySpark 预测客户流失
Sparkify 是一种虚构的流行数字音乐服务,类似于 Spotify 或 Pandora。使用 Sparkify,许多用户可以通过这项服务播放他们最喜欢的歌曲,并可以通过在歌曲之间放置广告的免费层或使用高级订阅模式来这样做。用户可以随时升级、降级或取消他们的服务,所以确保用户喜欢这项服务非常重要。
每当用户与该服务进行交互时,无论他们是在播放歌曲、注销、竖起大拇指喜欢一首歌、听广告还是降低服务等级,它都会生成数据。所有这些数据都包含了让用户满意和帮助企业发展的关键见解。
通过 Udacity 的 Nanodegree 项目提供的这个项目,我将利用这些数据来预测哪些用户有流失的风险,要么降低他们的服务级别,要么完全取消服务。通过能够在用户离开服务之前准确识别用户,Sparkify 可能会提供折扣和激励措施,并可能为企业节省数百万美元的收入。
下面是我在这个项目中采取的一些步骤,以探索数据集,并为预测客户流失的机器学习模型做准备。
正在加载火花数据
作为任何项目的第一步,我首先需要将我的项目加载到我的环境中。我将 128MB 的数据集读入一个 spark 数据帧,首先检查我的数据集包含多少行和列以及模式。
正如您在下图中看到的,我的数据集包含 286,500 行和 18 列。大多数列被表示为 string 类型,只有少数列被表示为 long 类型。
现在让我们看看实际数据是什么样的:
通过查看数据,我可以开始了解在我的探索性数据分析步骤中哪些列可能是相关的。
清理火花数据
当我开始探索我的数据时,我知道我需要清理我的数据,以便它可以准备好构建机器学习模型。
下面我提供了一个我为这个项目经历的清洁步骤的快速总结。
- 检查缺少用户标识的记录
- 检查 sessionId 为空的记录
- 检查缺少性别输入的记录
- 检查列的分布,以删除任何可能没有变化的列(单值列)
- 将 ts 列转换为正确的时间戳格式
- 将注册转换为正确的时间戳格式
- 将“位置”列拆分为两个新列——用户城市和用户州
- 删除用户代理、方法、位置列,因为它们似乎与我的分析无关
需要注意的一点是,我当然可以采取更多的步骤来进一步清理我的数据,但是这取决于每个数据科学家决定他们何时认为他们的数据足够干净。执行完这些步骤后,我得到了比原始数据集更清晰的数据集。
现在我的数据比以前干净了,我可以开始进一步研究我的数据了。
探索性数据分析
当我开始研究我的数据时,我知道我想要找出那些正在搅动的用户。我意识到目前的数据不能直接为我提供这个答案,所以我需要首先提取这个答案,这样我就可以进一步探索我的数据。
在上一步中,我查看了数据中的每一列,并打印出了列中每个值的计数。
对于页面列,我能够找到我正在寻找的确切细节,用户在那里进入取消确认页面,用户在那里点击以便实际取消他们的会员资格。在下面我可以找到所有用户所在的页面。
现在,我已经找到了我要寻找的细节,以找出哪些用户正在翻腾,我可以把它变成自己的列
提取客户流失信息后,我可以进一步探索我的数据。
让我们根据播放的歌曲来探索 Sparkify 的整体活动。
总的来说,许多用户与这项服务互动很多,听了很多歌曲!看起来 ID 为 39 的用户总共听了大约 8000 首歌!
我知道我的数据集有相同用户的各种数据点,所以我将确保现在只查看每个唯一用户的数据。我将从客户流失列开始,了解我的数据集中有多少用户流失了。
看起来在这个包含 225 个用户的数据集中,大约有 52 个用户受到了影响。
被搅动的用户如何因他们来自哪里而不同?总的来说,我不认为这是完全相关的,但它肯定可以用来理解国家在某一时期是如何参与的。(也许在冬季,来自美国北部各州的用户听更多的音乐,因为他们可能更经常在家,并且喜欢播放音乐来娱乐,等等)
就目前而言,这并不太令人惊讶,因为加州、纽约州和佛罗里达州的人口往往更密集,我们通常可以预期更高的流失率和更高的整体参与度。由于我只有 Sparkify 数据的一个子集,我也许可以通过完整的数据集确定更多。
让我们来看看被搅动的用户在他们的订阅账户级别和性别方面是如何变化的。
对于帐户级别,它肯定表明免费层用户可能比付费订阅用户更容易流失。此外,付费用户可以简单地将他们的帐户降级为免费,而不是完全取消他们的订阅。一些可以用完整数据集进一步探索的东西。
那么,当只看被搅动的用户时,与之前可视化中的总量相比,他们听了多少首歌?
正如你所看到的,ID 为 29 的用户听了最多的歌曲,总共有 3028 首!
总的来说,数据集无疑告诉了我们很多关于通过免费或付费订阅选项订阅 Sparkify 的用户的信息。我们当然可以进一步探索数据,但对于这个项目,我已经有了下一步该做什么的想法。
数据建模
因此,我最终想用这个数据集建立各种模型来预测客户流失,但我不确定哪种预测模型最好。
对于这个项目,我将测试 2 个不同的模型。逻辑回归模型和梯度推进树分类器模型。对于建立的每个模型,我将基于准确性和 F1 分数对它们进行评估。
以下是每个型号的结果。
逻辑回归模型
梯度增强树分类器模型
比较基本型号时,我得到以下结果:
从上面训练的模型来看,看起来 GBT 分类器在准确性和 F1 分数之间有更多的平衡。此外,对于我的下一步调整,GBT 分类器有几个选项供我调整,并可能比逻辑回归模型更多地增加我的指标。
调整我的模型
我已经选择调整 GBT 分类器模型。这些是我将调整和评估的参数:
maxIter (10,20,30)
maxDepth (3,5,10,20)
minInfoGain(0)
minInstancesPerNode(1)
通过调整超参数,我能够改进 GBT 分类器模型!这花了几个小时,但我能够改进我的模型的指标,并实现了大约 0.73 的精确度和大约 0.68 的 F-1 分数。
这些是调优后最适合我的 GBT 分类器的参数。
maxIter(20)
max depth(3)
minInfoGain(0)
minInstancesPerNode(1)
现在我有了一个已经建立和调整的模型,可以用来评估未来的用户是否会在 Sparkify 服务上流失。
结论
在这个项目中,我能够实现一个 python 笔记本,它可以加载、探索和清理客户数据,然后用于构建一个可以预测客户流失的机器学习模型。在用于预测模型的数据集中,我有 9 个特征(不包括流失特征和用户 Id)。
我能够建立两个机器学习模型。逻辑回归模型和 2。GBT 分类器模型。在比较了每个模型的准确性和 F1 值后,我确定 GBT 分类器模型是预测客户流失的最佳平衡模型。
丰富
我认为这个实现肯定可以做一些改进。在这个特定的项目中,我只使用了数据的子集(12MB)。完整的数据集为 12GB,这肯定会产生巨大的差异,并使我能够更好地了解哪些功能值得认真研究,哪些功能在创建预测模型时可能更重要。虽然 12MB 的数据肯定足以满足这个初始模型,但可能会有一些可能被忽略的不准确之处。此外,在我创建的模型中,我只是使用了一些我认为与我的模型相关的特定特征,尽管我肯定可以在最终的数据集中使用更多或所有的特征,并可能获得更好的模型。我还可以对模型的超参数进行更多的调整,尽管这会花费更多的时间和计算能力。
反射
我喜欢完成这个项目,因为它反映了一个非常真实的例子。这肯定是所有类型的客户都会经历的事情,他们希望确保他们能够真正更好地了解他们的客户,并能够在客户离开时采取主动的方法,而不是被动的方法。正如在 Udacity Nanodegree 项目之前的课程中所解释的那样,该项目以及任何其他具有大量数据的项目最重要的方面是探索和预处理数据。为了真正拥有在现实世界示例中有用的模型,需要对如何预处理数据进行大量思考,以确保您可以创建一个可用于训练模型的数据集。如果预处理不好,创建的模型可能不会像您希望的那样有效。
Github 项目
你可以在下面找到与这篇博文相关的 github 项目。
https://github . com/lrod rig-IBM/uda city-Capstone-spark ify-Project
致谢
感谢 Udacity 提供基于真实世界经验的相关数据集和数据科学纳米学位项目
预测危机期间的需求
在不确定的世界中做出更好的需求计划决策
Fikri Rasyid 在 Unsplash 上拍摄的照片
鉴于我们全球供应链的脆弱状态,预测制造什么、运输什么、储存什么在今天比在最近的记忆中更重要。鉴于过去三周我们看到的购买行为的转变,确保消费者能够在当地杂货店找到他们需要的产品极其困难:
- 新冠肺炎封锁彻底改变了我们生活的方方面面,包括我们购物的内容、方式、地点、时间和原因
- 经过十多年的持续增长后,我们正在进入衰退
- 许多人做出购买决定是出于恐惧而不是需求
随着供应链重新成为焦点,许多企业都在努力理解为什么他们的需求计划流程不起作用,以及他们可以做些什么来修复它们。以下是我和别人谈过这个问题后的看法。
短期内,预测应该退居二线
在封闭的世界中,消费者需求有着根本的不同:历史数据和基于这些数据的建模基础设施不再代表我们今天生活的世界。某些产品类别将比其他类别更能感受到这种转变的影响,但我们可以假设 2020 年 2 月之前大多数产品商店的观察是有偏差的。许多人问,其他危机事件是否可以代表我们当前的情况(例如,飓风或暴风雪使人们在室内呆了一周;12 月/1 月来自中国的早期观察),但这些事件和今天持续的全球封锁之间有太多的差异,我们无法相信这是事实。
不幸的是,留给我们的代表性数据样本非常少。集合模型(如 XGBoost)在如此小的样本量下可能会欠拟合,而时间序列模型(如 ARIMA)在零售商过去两周观察到的极端销售差异下会过拟合。在这种情况下能做些什么?
鉴于我们的观测数据如此之少,而形势发展如此之快,我们不应指望在短期内可靠地预测未来。这个疫情带来的文化和经济挑战才刚刚开始:我们现在开发的任何点估计都将非常不准确。即使我们在建模阶段很幸运,我们也没有足够的观测值来可靠地测量样本外误差。在我们有足够的数据来验证我们的预测方法之前,我们最好把时间花在别的地方。
在不确定性中做出明智的决策
鉴于我们无法再做出准确的预测,问题就变成了“在一个不确定的世界里,我们如何做出更好的供应链决策?”。
首先,我们应该强调未来几周我们将做出的许多艰难决定没有“正确”的答案。“完美是好的敌人”当然适用于这种情况:减少偏见,保持开放的心态,保持敏捷比在这个阶段纠结于数据更重要。
第二,我们应该有目的地调整我们的心智模式来进行需求规划。历史数据和稳定的预测应该打折扣,以利于新近加权模型、实时分析和已经在管理层得到验证的明智假设。我们衡量成功的方式可能必须改变,以 a)保持货架上关键消费品的可用性,b)避免可能影响我们核心业务的现金流问题。像这样的选择需要权衡,嵌入式数据科学团队非常适合就每个决策的相关风险提出建议。
最后,我们可以建立专家系统和 ML 基础设施来提醒我们何时应该重新考虑我们的假设。特别是像[帕累托/NBD 和帕累托/GGG](http://Resample your data) 这样的生成模型,可以讲述看似不稳定的购买行为背后丰富的故事。通过可视化它们随时间的后验分布,并观察它们的移动和形状变化,我们可以观察需求的转折点,并推断美国各地商店的真实情况。这些概率模型也不会给我们精确的点估计,但没关系:查看概率分布将有助于规划者自信地约束他们的决策。所有型号都是错的,但是我们的还可以用。
随着封锁解除,我们的生活变得更加确定,我们可以用短期贝叶斯预测、定制损失函数和新冠状病毒相关特征来改进我们的集合模型。在那之前,我们会做出明智的决定,将破产的风险降到最低。
预测全球难民署关注人员的人口趋势
利用回归模型设计更好的社会支持系统
保加利亚的难民营|图片来源:论坛报达卡
介绍
在过去的十年里,难民和流离失所者的数量激增,使我们陷入了有史以来最大的难民危机。与此同时,像美国这样的国家正在接受数量少得可怜的 T2 难民,同时大力发展机构服务和支持网络。我们必须立即纠正这些侵犯人权的行为,并对我们已经看到的大规模移民进行更好的规划。
尽管数据科学和机器学习技术在历史上一直被用来对付边缘化群体,而不是增强他们的能力(只需看看凯西·奥尼尔的数学毁灭武器,如果使用正确,它们也可以用来帮助实现公平。在流离失所的背景下,我们可以开始实现预测人口迁移趋势的崇高目标。通过不仅从总人口规模的角度来看人们来自哪里,而且从人口本身的构成来看,政府和组织可以在搬迁过程中将自己置于支持流离失所者的最佳位置。显然,知道一个群体中有 70%是 4 岁以下的儿童,比不得不假设各年龄层之间的分布相等要好。
联合国难民署(UNHCR)在被归类为关注人群的个人中收集人口统计数据。这可以作为一个示例数据集来构建一个用于预测全球近期人口趋势的框架。具体来说,该工具将使用回归技术来预测八个人口统计桶中的总人数。请注意,使用这种方法可以而且应该用于更具体的人口统计数据集(按年龄、非二元性别身份等)。
方法学
*预处理:*就本项目而言,难民署的数据需要在国家一级进行标准化和汇总,因此可以采用一些简单的数据清理步骤,如去除星号、按国家分组、合并不总是被视为单独类别的人口统计数据,以及重命名国家,以便从中提取纬度和经度。我们也不能对只有一年数据的国家进行回归,所以这些值必须被删除。
*机器学习:*主模型利用简单线性回归进行预测。构建函数是为了在数据集中指定一个国家,并为特定的人口统计创建线性回归对象。然后在 test_train_split sklearn 功能中对多个测试规模应用回归,以通过 R 最大化线性回归。对于所有国家和人口统计数据,线性回归对象被转换为数据框架,以便在预测分析中轻松计算。
可视化: 用两种不同的可视化来检验预测的数据。第一幅图清楚地展示了特定年份的历史数据、回归拟合和预测值,而第二幅图则提供了以对数色标绘制的地理点地图。
支架开发
我不会在本文中讨论数据清理,但是如果你对细节感兴趣的话,可以看看我的 github。对于这个框架,我创建了三个函数,指定一个国家来获取数据,创建回归模型,并通过在 train/test/split 中迭代不同的测试规模来最大化基于 R 的回归。在这里,线性回归函数可以用其他回归模型来代替,如果它们能产生更好的拟合的话。
对柬埔寨人口统计“女性 5-17 岁”进行测试,我们得到:
现在,可以在清理后的数据集中对每个国家和人口进行迭代。显然,一些 R 值比其他值更好。稍后会详细介绍。
形象化
如上所述,该工具的可视化有两种形式——国家级和全球级。第一个是给定人口统计和国家的简单线性回归图,包括历史数据、相关回归线(R 最大化)和图表上显示所选年份预测值的特定点。第二个可视化显示了一个对数彩色比例的世界地理图,蓝色代表极少数流离失所者(0-10),红色代表特定人口和年份的大量流离失所者(1,000,000-10,000,000)。有了这个图,你可以点击任何数值,得到那个国家的预测。
可视化开发如下所示。注意,第二个函数获取输入地址的纬度和经度。
可视化示例如下所示:
结果和讨论
建立这一模型是为了更好地预测总人口中流离失所者的具体人口数量,以便更好地准备必要的服务来支持受关注的人,但结果显然缺乏统计刚性。
这项研究最大的败笔是对大量公开数据的预测能力。每个国家最多有 18 个数据点,自 2001 年以来每年一个。有了这么少量的数据和流离失所的难以置信的不稳定性,这个工具的实际预测可行性非常低-如果有的话,它只能提供方向性的答案,即我们将在哪里看到特定人口的流离失所。每次回归运行时,R 会根据国家的不同而有很大的变化,尽管是最大化的。这在人口流离失所率低的国家尤其普遍。有了更长时间的数据收集和更具体的指标,算法支架会更成功。
该工具预测能力的一个改进领域是根据趋势不可变的特定因果数据进行映射。例如,利用围绕气候变化所做的大量预测工作是有意义的,气候变化已经迫使个人流离失所,而不是试图预测特定的战争是否会爆发。这并不是说后者更重要或更不重要,而是说如果模型除了完全基于总人口流动的历史趋势进行预测之外,还智能地引入因果因素,它将得到更好的装备。本质上,流离失所趋势是复杂的,因此获得有用的信息需要引入因果数据,并利用更先进的回归模型。然而,这可以为加载、清理和转换复杂的数据集提供一个支架,以构建和分析必要的学习算法。
尽管所使用的数据集存在统计学上的缺陷,但我们还是可以收集到一些推论。基于详细描述流离失所者预测人数的对数图,我们得到了基于历史趋势的预期结果。具体来说,预计最大的人口通常来自撒哈拉以南非洲、中东、中美洲和东南亚部分地区。
一些意想不到的国家出现了我们原本没有预料到的高数据,比如德国。然而,研究通常会指出这些数字存在的原因。例如,不仅有许多流离失所者前往德国,而且政府还驱逐了其中的许多人。由于靠近许多正在经历难民危机的地区,人数不幸变得相当多。
同样显而易见的是,即使在同一个国家,人口趋势也有很大差异——如果你自己摆弄数据,你会发现一些人口随着时间的推移在下降,而另一些人口则在上升(例如,阿富汗的老年男性与年轻男性)。
有关如何利用数据科学为难民创造更加公平的环境的更多信息,请参见 Bansak、 et al. (2018)。
如有任何想法或问题,请随时联系我们,完整代码请参见 my Github 。非常感谢 Madeline Hardt 为这个项目提供咨询。
马尼拉奎松市 Barangay 预测登革热
登革热是菲律宾的一个长期问题。由于热带气候和漫长的雨季,菲律宾成为携带病毒的蚊子的良好滋生地。不幸的是,登革热是无法治愈的,对于少数不幸被严重病毒感染的人来说,这可能是致命的。
预测病例数本身有助于为可能即将爆发的疫情做准备。然而,一个地方政府特别感兴趣的问题可能是:哪里我们确切地预计会有大量病例?通过定位登革热热点,官员们可以优先考虑进行蚊子存在测试和死水检查的地区,这将有助于降低爆发的可能性。
语境
一个镇是菲律宾最小的地理单位——大致相当于美国的一个县。初级卫生服务(据推测)是由每个镇的卫生站提供的,而镇很小,足以提供一个很好的图片,以准确地指导登革热干预措施。
换句话说,我回答了“我们在哪里预测登革热的爆发?”,通过回答“我们预测登革热在哪个镇爆发?”
方法
登革热数据来自 2016-2018 年 PhilHealth 从 Wilson Chua 先生和蚊子实时普查跟踪项目获得的记录(查看!).使用 Google API 对地址进行地理标记,然后映射到从 PhilGIS 获得的 barangay shapefiles。
特性
【NDWI】
水通常是蚊子的良好滋生地——这可能使它成为一个很好的预测器。这是使用 NDWI 量化的,它使用光吸收和反射的波长之间的差异来绘制高浓度和低浓度水的区域。使用谷歌地球引擎和 Sentinel-2 数据,对每个镇的 NDWI 值进行平均,并计算 2016 年至 2018 年期间每个月的 NDWI 值。
被吸收的光合有效辐射的分数【FAPAR】
像水一样,植被也是蚊子的良好滋生地——这可以使用 FAPAR 进行量化。它使用与 NDWI 相同的原理工作,但具有水反射和吸收的其他光谱带。还从谷歌地球引擎和 Sentinel-2 获得并处理了数据。
人口和密度
人口和人口密度值由 barangay 使用 PSA 的 2015 年数据获得。
日期变量
月份和年份用作模型的输入特征。
目标变量
利用菲律宾健康中心的数据,我们统计了每个镇每月的登革热病例数。生成了三个二元目标变量:
- 低风险:当月,镇上至少有 1 例登革热病例
- 中等风险:当月,镇上至少有 10 例登革热病例
- **高风险:**当月,镇上至少有 20 例登革热病例
这些值是任意的,选择这些值是为了探索模型对不同目标的预测准确性。
型号
对数据的初步扫描显示,登革热的发生相对异常——在 4825 份记录中,25%至少有 1 例登革热病例,12%至少有 10 例,4.4%至少有 20 例。
考虑到这一点,使用 SMOTE 平衡数据集,SMOTE 通过取当前数据的中点来生成新数据。这产生了一个数据集,其中一半的行是登革热阳性,一半的行是阴性。通过平衡数据,我们训练的模型不会偏向于预测一种结果而不是另一种结果。
然后,我们实施了梯度推进——一种机器学习模型,它迭代地重新加权输入,以便调整模型来分类模型以前无法分类的行。这使得它可以集中于最初可能无法正确分类的异常数据,并对这些条目进行加权,从而将模型调整到能够正确分类先前错误分类的镇的程度。
我们研究了梯度增强的三种变体:正常梯度增强、XGBoost 和轻型 GBM。
结果
这些模型在预测出现登革热病例的高风险地区时表现最佳。在三个模型中,LGBM 在预测高风险区域(97.47%的准确率)方面表现最好,而 XGBoost 在预测中等(93.67%)和低风险(80.84%)区域方面表现更好。将这些结果与纯粹的随机猜测(50.00%)进行对比——表明模型的表现并不太差。
为什么模型在高危情况下表现更好?
没有登革热病例的镇和有 1 例登革热病例的镇之间的 NDWI 或人口密度可能没有明显差异,这使得模型更难将一个镇分类为低风险或无风险。然而,一个没有病例的乡镇和 20 个病例的乡镇之间可能存在更大的差异——这使得模型更容易预测高风险地区,所达到的更高准确性就是证明。
但是,值得注意的是,大量数据被估算(实际上是创建)以创建平衡的数据集,尤其是在中高风险区域。因为这些数据是生成的,所以它遵循现有数据的模式,并且不包含来自真实世界数据的噪声——这反过来可能会使模型更容易生成更好的预测。这对我们来说意味着,虽然高风险模型在我们生成的数据上表现良好,但我们不确定它在未来的真实世界数据上表现如何。
哪些变量对将一个镇归类为有(或没有)登革热风险的影响最大?
使用 SHAP 图,我们可以看到哪些变量对模型的决策过程贡献最大,从而将镇划分为有登革热风险的镇。SHAP 值表示某个变量将模型的预测转变为支持或反对将某个镇归类为登革热阳性的程度。
**读图:**变量的分布表明它对模型预测的影响范围。价差越大,一个变量的影响就越大。如果红点在右边,蓝色值在左边,这意味着该变量与更高的登革热发病率正相关。右边的蓝点和左边的红点表示该变量与登革热呈负相关。
由于我们使用了二元指标(0 表示没有登革热,1 表示有登革热),一个镇的人口变量的 SHAP 值为 0.50,表明该镇的人口发生登革热的预测概率增加了 50%。
具有 XGBoost 的中等风险登革热模型的 SHAP 值
**结果:**人口对一个镇的登革热风险评分影响最大。正如所料,这是正相关的:人越多,患登革热的风险就越高。月份变量(从 1 到 12,每个月)也显示出正相关,这与雨季的趋势一致。一年中较早的月份相对干燥,因此“低”月份值(2 月至 5 月,标记为 2 至 5)与登革热的低风险相关,而潮湿和“高”月份值(7 月至 10 月,标记为 7 至 10)与登革热的高风险相关。
**评论:**结果相当令人惊讶——我预计 FAPAR、NDWI 和人口密度会产生最大的影响,因为它们直接量化了降雨量、植被和人口密度,而这些都与蚊子的繁殖和生长直接相关。然而,事实证明人口和月份的影响要大得多。这可能与 FAPAR、NDWI 或 density 的数据质量问题有关,或者它们可能不像我想象的那样具有预测性!
那又怎样?
在这个项目中,我们着眼于使用一个镇的信息来预测其发生至少 1 例登革热病例、10 例以上登革热病例和 20 例以上登革热病例的概率。然后我们发现人口多的镇在一年的后几个月最容易患登革热。对于奎松市来说,这意味着在选择实施登革热缓解计划的地方时,他们应该优先考虑人口最多的镇,并在雨季开始时这样做。
代码和谢谢
查看这里的代码:https://github.com/ljyflores/Dengue-Prediction.git
非常感谢 Wilson Chua 先生的指导和指引,以及耶鲁大学科学和社会科学信息中心的 Miriam Olivares 和 TC Chakraborty 对特征工程的帮助。
机器学习如何预测你想要购买的钻石的价格
使用基本测量指标预测钻石价格。
由 Unsplash 上的 chuttersnap 拍摄
介绍
我想一有足够的钱就给我妈妈买一枚钻石戒指。前几天,我在谷歌上搜索了它的价格,但我不知道是什么指标推动了这些价格。因此,我决定应用一些机器学习技术来找出是什么推动了一枚完美无瑕的钻石戒指的价格!
目标
构建一个 web 应用程序,用户可以在其中查找他们想要的钻石的预测价格。
数据
对于这个项目,我使用了 GitHub 上 pycaret 的 dataset 文件夹中的一个数据集,执行了数据预处理转换,并建立了一个回归模型,以使用基本的钻石测量指标来预测钻石的价格(326 美元至 18,823 美元)。数据集中的每颗钻石都有一个价格。钻石的价格由 7 个输入变量决定:
- 克拉重量:0.2 千克-5.01 千克
- 切割:一般、良好、非常好、优质、理想
- 颜色:从 J(最差)到 D(最好)
- 清晰度 : I1(最差)、SI2、SI1、VS2、VS1、VVS2、VVS1、IF(最好)
- 波兰 : ID(理想)、EX(优秀)、G(良好)、VG(非常好)
- 对称性 : ID(理想),EX(优秀),G(良好),VG(非常好)
- 报告 : AGSL(美国宝石协会实验室)、GIA(美国宝石学院)
👉任务
- **模型训练和验证:**使用 Python ( PyCaret )训练、验证模型,并开发用于部署的机器学习管道。
- **前端 Web 应用:**构建一个基本的 HTML 前端,带有自变量(克拉重量、切工、颜色、净度、抛光度、对称性、报告)的输入表单。
- **后端 Web 应用:**使用烧瓶 框架。
- **部署 web 应用程序:**使用 Heroku ,一旦部署,它将公开可用,并且可以通过 Web URL 访问。
💻项目工作流程
机器学习工作流程(从培训到 PaaS 部署)
任务 1 —模型训练和验证
使用 PyCaret 在 Python (Jupyter 笔记本)中进行模型训练和验证,以开发机器学习管道并训练回归模型。我使用 PyCaret 中的默认预处理设置。
from **pycaret.regression import** *s2 = setup(data, target = 'Price', session_id = 123,
normalize = **True**,
polynomial_features = **True**, trigonometry_features = **True**, feature_interaction=**True**,
bin_numeric_features= ['Carat Weight']
数据集中转换的比较
这改变了数据集,减少到 65 个用于训练的特征,而原始数据集中只有 8 个特征。
PyCaret 中的模型训练和验证:
# Model Training and Validation
lr = **create_model**('lr')
线性回归模型的 10 倍交叉验证
在这里,均方根误差( RMSE )和平均绝对百分比误差( MAPE )受到了显著影响。
# plot the trained modelplot_model(lr)
线性回归模型的残差图
构建模型后,我将它保存为一个文件,该文件可以传输到其他应用程序并供其使用:
# save transformation pipeline and model
save_model(lr, 'deployment_28042020')
保存模型会根据在 setup() 函数中定义的配置创建整个转换管道,并且会考虑到相互依赖关系。整个机器学习管道和线性回归模型现在保存在 save_model() 函数中。
任务 2 — 前端 Web 应用
CSS 样式表 CSS(层叠样式表)描述了用 HTML 编写的文档的呈现方式。它保存诸如颜色、字体大小、边距等信息。它被保存为链接到 HTML 代码的. css 文件。
<head>
<meta charset="UTF-8">
<title>Predict Diamond Price</title>
<link href='[https://fonts.googleapis.com/css?family=Pacifico'](https://fonts.googleapis.com/css?family=Pacifico') rel='stylesheet' type='text/css'>
<link href='[https://fonts.googleapis.com/css?family=Arimo'](https://fonts.googleapis.com/css?family=Arimo') rel='stylesheet' type='text/css'>
<link href='[https://fonts.googleapis.com/css?family=Hind:300'](https://fonts.googleapis.com/css?family=Hind:300') rel='stylesheet' type='text/css'>
<link href='[https://fonts.googleapis.com/css?family=Open+Sans+Condensed:300'](https://fonts.googleapis.com/css?family=Open+Sans+Condensed:300') rel='stylesheet' type='text/css'>
<link type="text/css" rel="stylesheet" href="{{ url_for('static', filename='./style.css') }}">
</head>
对于前端 web 应用程序,我使用了一个简单的 HTML 模板和一个 CSS 样式表来设计输入表单。下面是我们的 web 应用程序前端页面的 HTML 代码片段。
<body>
<div class="login">
<h1>Predict Diamond Price</h1><!-- Form to enter new data for predictions -->
<form action="{{ url_for('predict')}}"method="POST">
<input type="text" name="Carat Weight" placeholder="Carat Weight" required="required" /><br>
<input type="text" name="Cut" placeholder="Cut" required="required" /><br>
<input type="text" name="Color" placeholder="Color" required="required" /><br>
<input type="text" name="Clarity" placeholder="Clarity" required="required" /><br>
<input type="text" name="Polish" placeholder="Polish" required="required" /><br>
<input type="text" name="Symmetry" placeholder="Symmetry" required="required" /><br>
<input type="text" name="Report" placeholder="Report" required="required" /><br>
<button type="submit" class="btn btn-primary btn-block btn-large">Predict</button>
</form><br>
<br>
</div>
{{pred}}</body>
任务 3—后端 Web 应用程序
我使用 Flask 框架来构建后端 web 应用程序。下面是后端应用程序的 Flask 代码片段。
from flask import Flask,request, url_for, redirect, render_template, jsonify
from pycaret.regression import *
import pandas as pd
import pickle
import numpy as npapp = Flask(__name__)model = load_model('deployment_28042020')
cols = ['Carat Weight', 'Cut', 'Color', 'Clarity', 'Polish', 'Symmetry', 'Report'][@app](http://twitter.com/app).route('/')
def home():
return render_template("home.html")[@app](http://twitter.com/app).route('/predict',methods=['POST'])
def predict():
int_features = [x for x in request.form.values()]
final = np.array(int_features)
data_unseen = pd.DataFrame([final], columns = cols)
prediction = predict_model(model, data=data_unseen, round = 0)
prediction = int(prediction.Label[0])
return render_template('home.html',pred='Price of the Diamond is ${}'.format(prediction))[@app](http://twitter.com/app).route('/predict_api',methods=['POST'])
def predict_api():
data = request.get_json(force=True)
data_unseen = pd.DataFrame([data])
prediction = predict_model(model, data=data_unseen)
output = prediction.Label[0]
return jsonify(output)if __name__ == '__main__':
app.run(debug=True)
任务 4— 部署网络应用
在训练了模型,建立了机器学习管道之后,我在 Heroku 上部署了 web 应用程序。我链接了一个 GitHub 库到 Heroku。这个项目的代码可以在我的 GitHub 库这里找到。
github.com/dhrumilpatel02/diamond-price-prediction
接下来,我在 Heroku 上部署了 web 应用程序,该应用程序发布在 URL:
https://diamond-price-prediction.herokuapp.com/
感谢 PyCaret 的创始人和主要作者, Moez Ali 。这个项目的过程灵感来自于他最近在的帖子。
感谢阅读!
您可以通过以下方式联系到我:
用随机森林回归预测电子商务销售额
使用真实生活数据的基础教程
rupixen.com在 Unsplash 上拍照
数据集
为了演示随机森林回归,将使用流行的在线零售商 Wish 的电子商务销售数据集。这些数据来自 Kaggle ,并且只展示了夏季服装的销售信息。这些属性包括产品描述、评级、是否使用了广告宣传、产品列表中是否添加了紧急文本以及售出的数量等。
为了显示随机森林回归的威力,将预测售出的单位数。不仅对于需要估计订购或生产多少产品的库存计划人员来说,而且对于需要了解产品在电子商务环境中如何移动的销售人员来说,做出良好、准确的预测都是非常宝贵的。
导入和清理数据
所有的数据导入和操作都将通过 python 以及 pandas 和 numpy 库来完成。
import pandas as pd
import numpy as np# import the data saved as a csv
df = pd.read_csv("Summer_Sales_08.2020.csv")
前两行只是导入 pandas 和 numpy 库。最后一行读取先前保存并重命名为“Summer_Sales_08.2020”的 CSV 文件,并创建一个数据框。
df["has_urgency_banner"] = df["has_urgency_banner"].fillna(0)df["discount"] = (df["retail_price"] - df["price"])/df["retail_price"]
查看数据时,“has_urgency_banner”列编码不正确,该列指示是否对产品列表应用了紧急横幅。当横幅没有被使用时,它只是留下空白,而不是使用 1 和 0。第一行代码用 0 填充这些空白。
第二行创建一个名为“discount”的新列,它计算产品相对于列出的零售价格的折扣。
df["rating_five_percent"] = df["rating_five_count"]/df["rating_count"]
df["rating_four_percent"] = df["rating_four_count"]/df["rating_count"]
df["rating_three_percent"] = df["rating_three_count"]/df["rating_count"]
df["rating_two_percent"] = df["rating_two_count"]/df["rating_count"]
df["rating_one_percent"] = df["rating_one_count"]/df["rating_count"]
原始数据集包括几个专用于产品评级的列。除了平均评级,它还包括评级总数以及五星、四星、三星、二星和一星评论的数量。因为已经考虑了评论的总数,所以最好将星级作为总评分的百分比来看,这样可以在产品之间进行直接比较。
上面几行简单地创建了五个新列,给出了数据集中每个产品的五星、四星、三星、二星和一星评论的百分比。
ratings = [
"rating_five_percent",
"rating_four_percent",
"rating_three_percent",
"rating_two_percent",
"rating_one_percent"
]for rating in ratings:
df[rating] = df[rating].apply(lambda x: x if x>= 0 and x<= 1 else 0)
虽然 pandas 在除以 0 时不会抛出错误,但在试图分析数据时会产生问题。在这种情况下,评分为 0 的产品在上一步计算时会产生问题。
上面的代码片段遍历所有新生成的列,并检查输入的值是否在 0 和 1 之间,包括 0 和 1。如果不是,它们会被替换为 0,这是一个合适的替代。
数据探索
import seaborn as sns# Distribution plot on price
sns.distplot(df['price'])
价格分布图。图由作者制作。
上面的代码生成了数据集中所有产品的价格分布图。最明显也是最有趣的发现是,没有任何产品花费€10 英镑。这可能是商家为了让他们的产品出现在“€10 岁及以下”名单上而故意做出的努力。
sns.jointplot(x = "rating", y = "units_sold", data = df, kind = "scatter")
收视率和销售量之间的散点图。图由作者制作。
上图显示,绝大多数销售都是在三星和四星半之间。它还显示,大多数产品的销量不到 2 万件,少数产品的销量分别为 6 万件和 10 万件。
作为一个旁白,散点图组织成线的趋势表明,销售单位更可能是一个估计,而不是硬数字。
sns.jointplot(x = "rating_count", y = "units_sold", data = df, kind = "reg")
收视率和销售量之间的散点图。图由作者制作。
这张图表展示了评级的另一面。评级的数量和产品销售的可能性之间有一种松散但积极的关系。这可能是因为消费者在考虑购买时会同时考虑总体评分和评分数量,或者是因为高销量的产品自然会产生更多的评分。
如果没有关于购买时间和评级发布时间的额外数据,如果没有额外的领域知识,很难辨别相关性的原因。
什么是随机森林回归?
简而言之,随机森林回归是一系列决策树的平均结果。决策树就像一个流程图,它提出一系列问题,并根据这些问题的答案做出预测。例如,试图预测网球运动员是否会去球场的决策树可能会问:正在下雨吗?如果是,球场在室内吗?如果没有,玩家能找到伴侣吗?
一个简单的决策树。图由作者制作。
决策树将在做出预测之前回答每一个问题。虽然容易理解,而且根据一些专家的说法,比其他机器学习技术更好地模拟实际的人类行为,但它们经常过度拟合数据,这意味着它们经常可以在类似的数据集上给出非常不同的结果。
为了解决这个问题,从相同的数据集中取出多个决策树,打包,并返回结果的平均值。这就是所谓的随机森林回归。
一个简单的随机森林。图由作者制作。
它的主要优势是对高度非线性的数据做出准确的预测。在愿望数据集中,在评级中可以看到非线性关系。没有一个很好的,容易看到的相关性,但低于三颗星和高于四颗半的截止点是显而易见的。随机森林回归可以识别这种模式,并将其纳入结果中。然而,在一个更传统的线性回归中,它只会混淆它的预测。
此外,随机森林分类器是高效的,可以处理许多输入变量,并且通常做出准确的预测。这是一个非常强大的工具,并且不需要太多代码来实现。
实现随机森林回归
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestRegressor# Divide the data between units sold and influencing factors
X = df.filter([
"price",
"discount",
"uses_ad_boosts",
"rating",
"rating_count",
"rating_five_percent",
"rating_four_percent",
"rating_three_percent",
"rating_two_percent",
"rating_one_percent",
"has_urgency_banner",
"merchant_rating",
"merchant_rating_count",
"merchant_has_profile_picture"
])Y = df["units_sold"]# Split the data into training and testing sets
X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.33, random_state = 42)
在运行任何模型之前,前两行导入相关的库。下一组行创建两个变量 X 和 Y,然后将它们分成训练和测试数据。测试大小为 0.33,这确保了大约三分之二的数据将用于训练数据,三分之一将用于测试数据的准确性。
# Set up and run the model
RFRegressor = RandomForestRegressor(n_estimators = 20)
RFRegressor.fit(X_train, Y_train)
接下来,模型实际上被初始化并运行。注意,参数 n_estimators 表示要使用的决策树的数量。
predictions = RFRegressor.predict(X_test)
error = Y_test - predictions
最后,新拟合的随机森林回归被应用于测试数据,并且取差来产生误差阵列。这就是全部了!
结论
Wish 数据集提供了一个数字游戏场,可用于解决现实世界的问题。通过最少的数据操作,随机森林回归被证明是分析这些数据并提供实际结果的无价工具。
用 Keras 和 Python 预测停电
知道你所在的城市什么时候、什么地方会停电,会停电多长时间
在本文中,我们将探索我和我的团队开发一个 web 应用程序来预测班加罗尔停电的概率的过程。只要能收集到足够的数据,结果可以在任何城市重现。
第 1 部分:整合数据
我们从 BESCOM 的网站上找到了公开的非计划停电数据。虽然这不是一个优雅的解决方案,但由于网站一次加载所有 50,000+行,一个简单的 Ctrl+A,Ctrl+C 和 Ctrl+V 到一个 excel 表中,使我们免于编写复杂的废弃代码。
显示从 BESCOM 网站“复制”的数据的 Excel 表格
将它加载到我们的 python 代码中相当简单。我们的文件被保存为BESCOM-electricity-data-orange . xlsx .
Sl. No. ... Updated By
0 1.0 ... Sushma
1 2.0 ... Sushma
2 3.0 ... Sushma
3 4.0 ... SUSHMA
4 5.0 ... Devaraj R[5 rows x 12 columns]
为了查看所有单独的列,我们使用
array(['Sl. No.', 'Circle', 'Division', 'Subdivision', 'Substation',
'From', 'To', 'LC Duration', 'Feeders', 'Areas Affected',
'Reason For LC', 'Updated By'], dtype=object)
由于这些属性中的大多数并没有为我们的理解增加很多信息,为了使我们的任务更简单和更容易可视化,我们将只保留列 Sl。号,分割,从和 LC 持续时间。
Division From LC Duration
0 HSR Division 2019-11-06 21:07:00 0 days 1 hours
1 HSR Division 2019-11-06 16:00:00 0 days 2 hours
2 Koramangala Division 2019-11-06 14:00:00 0 days 2 hours
3 HSR Division 2019-11-06 14:29:00 0 days 1 hours
4 Indiranagar 2019-11-06 13:00:00 0 days 2 hours
接下来,我们需要添加关于某一天是否是假日的数据。直觉告诉我们,节假日的用电量会增加,因此停电的可能性更大。为此,我们首先找到数据集中包含的最早和最早的日期。
Timestamp('2019-11-06 21:07:00')
Timestamp('2014-05-05 02:40:00')
现在,我们找到该范围内的所有公共假日,并将它们添加到单独的 excel 表 holidayData.xlsx.
所有假期的列表
下一步是将这些假期映射到我们现有的数据集中。为此,我们在数据集中创建另一个名为 Holiday 的列,并将所有行赋值为零。查看日期,我们将列更新为“1 ”,即出现在 holidayData.xlsx 中的日期。
Holiday Division From LC Duration Date
0.0 16136 16179 16179 16179
1.0 1116 1117 1117 1117
接下来,我们将绘制各个分区的人口图,人口越多的分区理论上遭受停电的几率就越高。
首先,我们找到独特的部门列表
array(['HSR Division', 'Koramangala Division', 'Indiranagar',
'Shivajinagar', 'Hebbal', 'Whitefield', 'Malleshwaram',
'Rajaji Nagara Division', 'Jayanagar', 'Jalahalli',
'Kengeri Division', 'R R NAGAR', 'Vidhanasoudha',
'Peenya Division', nan], dtype=object)
我们现在找到了这些地区的估计人口。这项任务的准确性因数据是否公开而异。在我们的例子中,上一次人口普查是在 2011 年进行的,所以我们必须推断人口数来反映班加罗尔当前的总人口。由于只有 14 个区域,我们将在字典中输入这些值,而不是将这些数据添加到另一个 excel 文件中。然后,我们在数据集中创建另一个名为人口的列,并为其分配与部门相同的值。然后我们使用 python 中的替换函数,用 div_pop_dict 中的值替换 Population 中的键。
0 105265.0
1 105265.0
2 63987.0
3 105265.0
4 58830.0
Name: Population, dtype: float64
接下来,我们发现了之前提到的日期范围内的每日最低和最高温度。这些数据存储在 **weather_data_max_min.xlsx 中。**我们将加载数据集并将 datetime 值更改为日期。
Date Max Temp Min Temp
0 2014-01-01 18.7 14.8
1 2014-01-02 27.3 15.4
2 2014-01-03 27.7 13.1
3 2014-01-04 29.5 12.0
4 2014-01-05 29.6 14.1
现在,我们遵循与人口数据集相同的流程,即创建一个包含日期和温度值的字典,并用最低/最高温度替换断电日期。
Max Temp Min Temp
0 34.3 15.3
1 34.3 15.3
2 34.3 15.3
3 34.3 15.3
4 34.3 15.3
这些都是我们将在这个例子中使用的特性。
现在,我们需要为分类创建标签。现在我们已经详细了解了产生和中断的特征组合。然而,我们需要将关于哪些条件不会导致断电的数据输入到模型中,以便正确理解区别并相应地制定规则。
我们将如何处理这个特殊的问题是通过选择每一行,其中我们有断电发生的时间和地点的日期和时间,并将其标记为断电的日期和时间。对于所有其他持续时间,除了时间之外的完全相同的特征组合的标签被标记为**‘0’表示不停机。为了进一步说明这一点,我们举一个例子:**
假设选择了下面的行:
然后将断电标记为**‘1】,如下所示:**
请注意,这一特定停机发生的时间大致在2100-2200 小时之间。因此,我们可以得出结论,在**0000–2100 和 2200–0000 之间的持续时间内可能没有断电。因此,我们可以复制具有这些持续时间的行,并将它们标记为‘0’表示不中断。**获取:
作为训练前的最后一步,我们需要将一键编码的值。这意味着,划分(英迪拉那加,科拉曼加拉,HSR 布局……)对计算机来说毫无意义。因此,我们为这些划分中的每一个划分形成单独的列,每行可以有 0/1。例如,假设为 Indirangar 的分部形成了一行,行中的值 0 将意味着该特定行没有 Indiranagar 作为其分部,而值 1 将表明它是。这让计算机用自己的术语理解数据,并形成更好的模式。为了更深入地理解一键编码,你可以阅读这篇文章。
这给出了下面的列,我们可以注意到,在每一行中,只有一列的值为“1 ”,表示分部。
一个热编码分区
第 2 部分:训练数据
在训练数据之前,我们需要对其进行缩放。*这意味着不同的特征具有不同的取值范围,而神经网络通常工作得最好的是作为其输入的值在 **-1 到+1 或 0 到 1 的范围内。*因此,我们在单个特征自身的尺度上对其进行缩放,以降低给定范围内的所有值,同时保持其内在差异。
这通过找到列的平均值和标准偏差,然后转换列,使缩放器适合数据。当另一个数据集需要被缩放以提供给神经网络进行预测时,我们应该不要再次拟合缩放器,而只是将其转换并馈入神经网络。
缩放数据
接下来,我们需要将数据集分割成一个训练和测试集。训练集用于训练模型,测试集用于评估模型的准确性。
现在是我们定义神经网络模型的时候了。我们为我们的工作选择了一个具有 3 个隐藏层的序列模型。
定义模型后,我们的艰苦工作就完成了,现在是时候满意地观看我们的模型火车了:
*Epoch 1/20
81987/81987 [==============================] - 3s 35us/step - loss: 0.4935 - accuracy: 0.7443
Epoch 2/20
81987/81987 [==============================] - 3s 33us/step - loss: 0.4333 - accuracy: 0.7874
Epoch 3/20
81987/81987 [==============================] - 3s 33us/step - loss: 0.4259 - accuracy: 0.7900
Epoch 4/20
81987/81987 [==============================] - 3s 31us/step - loss: 0.4186 - accuracy: 0.7923
Epoch 5/20
81987/81987 [==============================] - 3s 32us/step - loss: 0.4147 - accuracy: 0.7949
Epoch 6/20
81987/81987 [==============================] - 3s 31us/step - loss: 0.4121 - accuracy: 0.7977
Epoch 7/20
81987/81987 [==============================] - 3s 32us/step - loss: 0.4097 - accuracy: 0.7983
Epoch 8/20
81987/81987 [==============================] - 3s 31us/step - loss: 0.4080 - accuracy: 0.7988
Epoch 9/20
81987/81987 [==============================] - 3s 32us/step - loss: 0.4058 - accuracy: 0.8007
Epoch 10/20
81987/81987 [==============================] - 3s 31us/step - loss: 0.4041 - accuracy: 0.8015
Epoch 11/20
81987/81987 [==============================] - 3s 31us/step - loss: 0.4039 - accuracy: 0.8020
Epoch 12/20
81987/81987 [==============================] - 3s 32us/step - loss: 0.4020 - accuracy: 0.8024
Epoch 13/20
81987/81987 [==============================] - 3s 32us/step - loss: 0.4004 - accuracy: 0.8043
Epoch 14/20
81987/81987 [==============================] - 3s 31us/step - loss: 0.3989 - accuracy: 0.8046
Epoch 15/20
81987/81987 [==============================] - 3s 32us/step - loss: 0.3984 - accuracy: 0.8056
Epoch 16/20
81987/81987 [==============================] - 3s 31us/step - loss: 0.3974 - accuracy: 0.8057
Epoch 17/20
81987/81987 [==============================] - 3s 31us/step - loss: 0.3964 - accuracy: 0.8062
Epoch 18/20
81987/81987 [==============================] - 3s 31us/step - loss: 0.3952 - accuracy: 0.8067
Epoch 19/20
81987/81987 [==============================] - 3s 32us/step - loss: 0.3944 - accuracy: 0.8075
Epoch 20/20
81987/81987 [==============================] - 3s 31us/step - loss: 0.3934 - accuracy: 0.8080*
测试训练好的模型:
*20497/20497 [==============================] - 1s 34us/step
Out[80]: [0.38760558974482917, 0.7936800527572632]*
我们已经实现了大约 80%的训练准确率和大约 79%的测试准确率。这可以通过调整神经网络架构来改善。
这篇文章就到这里吧各位!感谢您的阅读,如果您觉得这对您有用,请发表评论。这也是我的第一篇中型文章,所以任何关于我无意中出错的事情的指点都是非常感谢的!
你可以在 GitHub 上找到完整的项目。在 Linkedin 上与我联系,或者查看我的网站。
我是一名 20 岁的信息科学与工程专业的学生,是一名有抱负的软件开发人员,住在班加罗尔…
卡尔潘.代码](https://kalpan.codes)
别忘了给我你的👏!
*
预测能源产量
使用深度学习神经网络模型
作为为 AI4IMPACT 的深度学习 Datathon 2020 创建的,团队默认创建了一个基于神经网络的深度学习模型,用于预测法国的能源生产需求。该模型是使用 Smojo 在 AI4IMPACT 创新的基于云的学习和模型部署系统上创建的。
我们的模型能够达到 0.131 的测试损失,这大大超过了 0.485 的持续性损失。
一些背景
随着全球能源市场变得越来越自由化,自由开放的市场已经看到了优化能源需求的上升和重要性。新的和现有的进入者转向数据和各种方法来预测能源消耗,希望能够获得利润。
这对于寻求转换和采用清洁/可再生能源发电以减少碳足迹、满足监管标准或干脆不投资碳捕获技术的国家尤其重要。因为太阳不会整天照耀,风也不会吹,所以预测能源需求比以往任何时候都更有助于防止短缺和停电。
随着人工智能(AI)和机器学习的出现,零售商和贸易商已经利用人工神经网络的潜力来优化能源需求,从而优化产量。
照片由 Unsplash 上的khaméo Vilaysing拍摄
任务
我们项目的目标是使用神经网络深度学习模型为我们的客户最大化利润,该模型预测未来 18 小时的能源需求。
该模型将于 7 月 21 日至 7 月 29 日实时运行,在此期间,利润和排行榜排名将被实时跟踪。该模型将建立在 AI4IMPACT 开发的 AI 开发工具 Autocaffe 上。
我们的目标是获得 T+18 小时的能量预测,每小时**。目标是利用你的能源产量预测和给定的交易算法为你的客户实现利润最大化。**
以下参数起作用:
- 你的客户每向电网出售一千瓦时可获得 10 欧分。你只能向电网出售你对该日期的预测。
- 如果实际发电量超过预测,超出部分将被电网吸收,但您的客户不会因此得到补偿。
- 如果实际发电量低于预测,您必须从现货市场购买能源(每千瓦时 20 欧分)供应给电网。
前 18 个小时(称为“热身”)不进行任何交易。每小时预热后,您需要生成一个 T+18 小时的能源产量预测。这就是所谓的“交易期”。交易在周末和公共假日继续,24x7。交易在评估期结束时结束。
开始时你会得到 10,000,000 欧元的现金。您需要在评估期结束时返还该金额。剩下的是你的客户的利润,这是你的工作最大化。****
数据
使用了 2 个数据集:风能产量和风速
风能生产的来源来自法国能源传输管理局。
近实时风能实际值来自 RTE 的在线数据库,我们将其平均并标准化为 1 小时的时基。
- 提供了从 2020 年 1 月 1 日到 2020 年 7 月 19 日每天和每小时的数据。
- 发电量值以千瓦时为单位。
- 数据集被标准化为 1 小时的值
初步分析(季节性/趋势)
总体趋势
以每日分辨率查看整个日期范围,我们可以拟合一条简单的递增多项式阶 2 线,并观察能量需求随时间的逐渐增加。
总体趋势
月度趋势
按季度分析数据,我们发现不同的季度有不同的能源需求。趋势似乎是,它在第一季度(1 月、2 月和 3 月)达到最大值,并在其余月份持续下降,直到从第三季度开始增加到第二年的第一季度。
每月趋势
每周趋势
以每周一次的分辨率检查数据,我们观察到了几周内能源需求的差异。通过计算一天的平均能量产出,我们注意到能量产出往往在周一最高,周二最低。
似乎趋势是能源需求在周二开始处于低位,周三增加,周六减少,然后在周日和周一增加。
每周趋势
数据预处理
从下面的数据集可以看出,这些值具有季节性趋势,每年 11 月至 3 月期间产生的能量更多。此外,根据风电场信息,2017 年 8 月和 2019 年 7 月新增风电场。为了确保我们能够以最小的漂移获得足够大的数据集,我们决定从 2019 年 1 月 1 日到现在获取数据集。
随着时间推移产生的能量
我们只考虑从 2019 年 1 月 1 日开始的发电量数据的 3 位小数作为我们的第一列数据,并获取不同位置的风速值,计算风速的平均值作为我们的第二列数据。
smojo 配置
下图显示了从 2019 年 1 月 1 日开始的能源和风速图表。这两个变量之间有明显的密切相关性。可以作出的进一步推论是,在增加新的生产者之后,通常能量生产率更高。风向对发电量也没有太大的贡献,因此被忽略。
一段时间内的发电量和风速
使用 autocaffe,我们计算了所考虑的两个变量的统计数据。以下数据是用于两个变量标准化的值。我们还发现持续性值为 0.485,在开发我们的交易模型时,我们必须打破这个值。
数据集统计
训练/测试分割
数据集的 70:30 训练/测试分割用于确保足够的训练。趋向于比率平衡的比率可能导致测试和进一步的新数据的欠拟合。
利润基准
为了找出可获得的最大利润,我们采用了从 2019 年 1 月 1 日到现在产生的能量总和 x10 美分 x 0.3 来说明训练/测试分割。基准测试的原因将允许我们测试利润。我们在整个期间能够获得的最大利润将是 9.972E+08 美分。
特征选择和模型构建流程
下面是团队为得出最终模型所经历的迭代过程的总结。下面详细介绍了各个迭代
模型迭代摘要
#1 幼稚网络
击败比分: 485 /击败利润:9.972E+08 欧分
型号#1 配置
模型#1 结果
首先,我们从一个简单的网络开始,用数据来测试我们的第一轮结果。该能量窗口包括从 T-24 到 T-0 小时平均值和标准偏差值的特征。风速窗口仅包括 T-0 到 T+18 小时的数据。我们的神经网络有 3 种不同的大小,分别是 32、64 和 128 个节点。我们选择的求解器类型是 Adam,在神经网络中有 3 个隐藏层。第一次运行将不包括超参数调整。
下面我们从第一次测试运行中获得的结果表明,我们的最佳测试损失是 0.388224。我们这次的利润总计为 3.354E8 欧分,这只是可获得的最大利润的 33.6%。我们的实际与测试预测图也非常分散,这很糟糕,因为这表明我们的模型不可靠且不准确。滞后峰值也在 18,这很糟糕。
#2 更多功能
预期得分:0.38824 /预期利润:3.354E8 欧分
型号#2 配置
模型#2 结果
我们得出结论,可以向我们的模型中添加更多的特征,以确保更好的结果和准确性。因此,我们添加了更详细的特征,包括 T-24 至 T-0 小时的平均值和标准差、最小值和最大值、偏斜度、差异值以及更多来自能量的过去数据,如 T-168 至 T-0 小时和 T-336 至 T-0 小时的平均值、标准差和偏斜度值。
至于风速数据,我们包括了从 T+15 到 T+18 小时的未来值。到目前为止,网络还没有其他变化。记住之前最好的测试亏损 0.38824,盈利 3.354E8 欧分。运行新的模型,我们获得了更好的测试损失 0.137427,以及利润新高 6.514E8 美分,这是我们最大可能利润的 65.3%。至于我们的实际与测试预测图,我们可以看到 2 个值之间有更好的相关性,我们的滞后峰值为 0,这是一个好迹象,表明我们的模型正在改善。
#3 超参数
预期得分:0.137427 /预期利润:6.514E8 欧分
型号#3 配置
模型#3 结果
基于上一个实验的知识,更多的隐藏层被添加到模型中。具体来说,添加了 0.01、0.001、0.0001 的辍学率,以减少训练数据集的过度拟合。类似地,添加 0.01、0.001 和 0.0001 的权重衰减值以减少过拟合。L2 正则化被包括以减少训练期间神经网络权重的量值。
获得的最佳测试损失为 0.135409,利润为 6.467E8,比之前的更差。我们注意到,实际数据和测试预测变得更加相关,滞后相关峰值略高。性能最好的设置是 NN-size = 256,dropout = 0.0001,decay = 0.001。
#4 使用 2019 年 7 月的数据
预期得分:0.135409 /预期利润:6.514E8 欧分
模型#4 结果
接下来,我们重复了相同的神经网络配置,但仅使用 2019 年 7 月的数据,结果如下图所示。运行该模型使我们获得了更好的测试损失,为 0.100719,超过了我们从 2019 年 1 月开始的数据集的测试损失。然而,我们从这款更新更近的车型中获得的利润仅为 2.439E8 欧分,仅为我们应实现的 8.016E8 欧分预期利润的 30.4%。****
#5 扩展
预期得分:0.100719 /预期利润:6.467E8 欧分
动量和力损失的预测结果
最后,我们测试了在模型上添加动量、力损失和自动编码器的概念。在附加动量和力损失的情况下,获得的最佳试验损失为 0.158881,利润为 6.157E8。我们观察到预测中的噪声增加,导致预测不太准确。
启用自动编码器的预测结果
在自动编码器下,最佳测试损失为 0.129414,利润为 6.647E8。这使得模型的训练时间明显延长,导致测试结果更加多样化。
最终模型
我们的最终模型是一个简单的模型,它使用设置#3,重复 20 次,并采用最佳设置。
使用的特征包括 3 个时间框架的平均值、标准差、偏斜度和差异:T-24、T-168 和 T-336。此外,我们使用过去的数据来预测从 T-0 小时(T-0 到 T-18 小时)的未来 18 小时,并使用值对来表示从 T-(-24)到 T-0 的 18 个差异。这导致模型中总共有 14 个独立的特征。
该模型具有以下特点:
最终模型配置
决赛成绩
最终模型的最终测试损失为 0.132 欧元,利润为 6.501 欧分。作为对比,持续性损失= 0.485,盈利基准= 9.972E+08。模型的训练和测试损失、实际和测试预测以及滞后相关图如下所示。
最终模型结果
进一步的潜在改进
- 利用额外特征,如风向
虽然我们试图保持输入的准确性并符合我们的直觉,但将风向作为额外输入的潜力可能会被证明是有用的。
2.配置
测试了进一步的改进,并偏离了之前的配置;当观察到一个普遍趋势时,团队就去追求它,而不考虑另一个完全不同的设置。
类似于神经元权重的“随机初始化”的想法,该团队可以“初始化”一个新的起点,这可以提供前所未有的洞察力。
3.附加原始数据
如果对 2019 年之前最初被忽略的数据进行进一步清理和归一化,以符合 2019 年及以后的数据的相同归一化范围,则可以利用这些数据。有了更多的数据,模型会学得更好。
总结和回顾
该团队认为,复杂的模型不一定等同于更好的结果,因为它可能倾向于陷入次优解决方案。因此,我们的方法从一个直观的简单模型开始,并通过分析趋势和试错法建立在它的基础上。毕竟,一个我们可以理解的模型是可以客观而非盲目改进的。
凭借目前良好的结果,我们满怀信心地进入现场测试阶段。
认识团队:)
**[## 许伟文-企业联络主任-南洋理工大学学生会
目前就读于南洋理工大学(NTU),攻读机械工程学士学位,辅修…
www.linkedin.com](https://www.linkedin.com/in/koh-wei-wen-927044120/)** **[## Anders Choo -新加坡南洋理工大学| LinkedIn
在全球最大的职业社区 LinkedIn 上查看安德斯·周的个人资料。安德斯的教育列在…
www.linkedin.com](https://www.linkedin.com/in/anders-choo/)** ** [## Gabriel Tan -新加坡国立大学学生大使| LinkedIn
查看 Gabriel Tan 在全球最大的职业社区 LinkedIn 上的个人资料。加布里埃尔有 4 份工作列在他们的…
linkedin.com](http://linkedin.com/in/gabriel-tan-223a631a0) [## 韩德-大数据实习生-雷蛇公司| LinkedIn
在世界上最大的职业社区 LinkedIn 上查看韩德·c 的个人资料。韩德有一份工作列在他们的…
www.linkedin.com](https://www.linkedin.com/in/dehan-c-948045177/)
这里还有一篇文章给你!
使用 scikit 的自然语言处理基础-学习
towardsdatascience.com](/create-a-sms-spam-classifier-in-python-b4b015f7404b)**
预测虚假招聘信息—第 1 部分(探索性分析)
当心这种虚假的“现在招聘”标志
由于新冠肺炎·疫情对各大洲的经济造成损害,我们正生活在一个前所未有的时代。失业率每天都在增加,据美国报道,约有 2600 万人申请失业救济,这是其漫长历史上的最高记录,英国有数百万人被解雇,世界各地有数千人被解雇。以下是联合国副秘书长阿米娜·穆罕默德的一句话,用一句话概括了当前的形势。
正当世界全力应对疫情新冠肺炎冠状病毒前所未有的影响时,我们正面临一场前所未有的人道主义危机,我们的社会结构和凝聚力正面临压力。
在这个绝望的时代,成千上万的人在寻找工作,这为网络骗子利用他们的绝望情绪提供了一个绝佳的机会。我们看到这些虚假的招聘信息每天都在增加,这些信息看起来很合理,通常这些公司也会有一个网站,他们的招聘流程与业内其他公司相似。
如果一个人足够努力,他们可以发现这些假帖子和真帖子之间的差异。大多数情况下,这些帖子上没有公司的标志,公司的第一反应是来自一个非官方的电子邮件帐户,或者在面试中,他们可能会要求您提供个人机密信息,如您的信用卡信息,说他们需要这些信息进行人员验证。在正常的经济条件下,所有这些都是公司可疑之处的明显暗示,但这不是正常的经济条件。这是我们一生中见过的最糟糕的时期,在这个时候,绝望的人只需要一份工作,这样,这些人就直接落入了这些骗子的手中。以下是丹尼尔·林斯基的一段话,他是波士顿警察局的前局长
警察部门没有调查这些事件的资源,在联邦当局介入之前,这必须是一个数百万美元的诈骗,所以骗子们只能继续逍遥法外。
通过这两部分的系列媒体文章,我希望让求职者意识到这一问题的严重性,以及如何通过机器学习模型来预测一个职位发布是否具有欺诈性。在本系列的第 1 部分,我将探索这些数据,并深入了解哪些行业受到的影响更大,以及哪些关键的危险信号会泄露这些虚假帖子。在第二部分,我将应用机器学习模型来预测我们如何检测这些伪造的帖子。
我将在分析中使用的数据是由爱琴海大学信息与通信系统安全实验室(http://emscad.samos.aegean.gr/)编制的 18000 份工作描述的数据集。这个数据集包含 800 个虚假的职位描述。
数据集具有以下变量:
- 标题:招聘广告条目的标题。
- 位置:招聘广告的地理位置。
- 部门:法人部门。
- 薪金 _ 范围:指示性薪金范围。
- Company_profile:简要的公司描述。
- 描述:招聘广告的详细内容。
- 要求:空缺职务的登记要求。
- 福利:由雇主提供的福利。
- 远程办公:适用于远程办公的职位。
- Has_company_logo:如果公司徽标存在,则为 True。
- Has_questions:如果存在筛选问题,则为 True。
- 就业 _ 类型:全职、兼职、合同等。
- 要求 _ 经验:高管、入门级、实习生等。
- 要求 _ 学历:博士、硕士、学士等。
- 行业:汽车、IT、医疗保健、房地产等。
- 职能:咨询、工程、研究、销售等。
- 欺诈性的(目标变量):如果是假的,则为 1,否则为 0。
数据清理
我在我的系统上导入了 Jupyter 笔记本上的数据,并在 Python 3 上工作。由于我希望这一部分更多的是关于洞察力而不是代码,所以我没有在这里附上任何代码要点,但是任何对查看数据清理代码感兴趣的人都可以随意查看我的 GitHub 库—【https://github.com/sharad18/Fake_Job_Posting
最初的数据集包含 18,000 个帖子。清理后,新数据有大约 11,000 个帖子。在本系列的第 2 部分,我将研究机器学习模型来预测哪些帖子可能是假的。我将干净的数据导入到 Tableau 中进行探索性分析,这将在下一节中详细描述。
探索性分析
目标变量的分布
我们首先需要看的是数据的分布,这是非常不平衡的,只有 249 个虚假发布,涉及 11,023 个良好的职位发布,这是预计会出现这样的问题。欺诈性的广告张贴很普遍,但数量上超过了真正的广告。这些招聘广告已经发布在 LinkedIn、Glassdoor 和其他求职网站上,这些网站都有其欺诈检测团队。该数据集通过这些网站的高精度算法发现隐藏得很好的虚假网站。
非常不平衡的目标变量
数据集中其他变量的分布
在下图中,我们看到了要求的教育程度、就业类型和要求的经验等变量的分布。对于第一个变量,我们可以看到数据中的大多数代表是高中毕业生和大学毕业生,这在当前每个公司都在削减成本的情况下是可以理解的。最残忍的方法是解雇比大多数人挣得多的人,用级别较低的人取代他们。从这里,我们可以得到一个年龄组的估计,可能在 20 岁到 35 岁之间。此外,研究生级别的工作和博士级别的工作数量较少,这表明求职者受教育程度越高,他们对某个角色的要求就越复杂,因此与受教育程度较低的人相比,为他们创建工作岗位具有挑战性。
中高级职位在数据集中最常见。
第二幅图更符合一个共识,即在任何时候,对全职职位的需求总是比临时职位多,因为对公司来说,长期投资于个人仍是更好的投资。
在不止一个场景中,最后一个情节与第一个情节相矛盾。要求学历是大专学历,但要求经验是中高级水平。这表明,对于任何角色来说,过去在特定行业或企业界的技能都比教育更受重视。一个典型的刻板印象是,对于高级职能来说,研究生学位是必须的,但数据并不同意这一点。大多数高管都是通过网络招聘的,这一数据与此相符,因为这是发布招聘广告最不需要的经历。
工作职能和行业分布
接下来,我们将看看哪些工作职能和行业最容易受到骗子的攻击。在下图中,我们看到像信息技术和工程这样的技术功能位于顶部,随后是销售和客户服务。由于大部分招聘信息都围绕这些工作职能,他们最容易受到虚假招聘信息的影响。随着我们往下看,我们看到功能变得越来越具体,因此,欺骗这些人变得越来越困难,因为这些功能对他们的行业来说是如此的特殊。
信息技术和工程主宰了招聘信息。
在接下来的情节中,我们可以看到前面结果的延续。像 IT、计算机软件和互联网这样的技术行业在招聘信息中占主导地位。这两个数字清楚地表明,专业工作最容易受到这种虚假职位的影响,因为目前这些人的需求很大。即使有这么多的招聘信息,供应仍然少于市场,这就创造了一个完美的局面,骗子可以介入并剥削这些求职者。
排名前三的行业都是技术性的。
虚假招聘信息分析
在接下来的章节中,我们将深入分析这些虚假招聘广告的一些特殊特征,这些特征将它们与官方招聘广告区分开来。区分这两者的关键之一是招聘过程。
45%的招聘广告没有经过任何招聘程序
左图显示,45%的欺诈案例甚至没有面试。这是这些骗局中最大的漏洞,一份工作没有经过任何筛选就被提供了。在大多数情况下,工作邀请之后会询问银行或信用卡详细信息等机密信息,这是这些虚假招聘信息欺骗你的主要方式。
在下图中,查看在没有筛选过程的情况下,这些骗子瞄准的经验水平。这些骗子通常以入门级工作的求职者为目标。这些大多是应届大学毕业生,他们正在寻找自己在行业中的第一个角色,而当前的经济形势,最容易成为骗子的目标。随着我们级别的降低,资历级别增加,这表明随着个人获得更多的经验,他们可以区分假职位和真职位。
入门级的工作最容易被骗子盯上
虚假招聘广告的地理分布
在这里,我们可以看到这些假币是如何在世界各地传播的。我们知道美国的病例最多。这种情况是如此之多,以至于它让世界其他地方黯然失色,不得不创造一个独立的数字。在第二幅图中,我们可以看到英国、加拿大、印度和澳大利亚也有大量此类骗子。
美国的虚假招聘数量最多。
在上图中,我们看到美国是欺诈案件最多的国家,其次是英国。接下来,我们将在城市一级看到更全面的分析。即使在美国,东海岸比西海岸更频繁,这与我们早期的发现相矛盾。我们看到,最脆弱的行业是技术行业,它集中在美国西部,但大多数欺诈案件都发生在对面的海岸。英国和欧洲其他地区的主要金融和技术中心也有大量此类索赔。印度、东南亚和澳大利亚的主要中心遵循同样的模式。
美国城市占据了虚假招聘的主导地位。
词云可视化
在这里,创建了欺诈性职位发布和非欺诈性职位发布的两个词云。我们可以从这两个词云中看到的一个区别是,非欺诈词云对所做的工作有更具体的要求和描述。在欺诈类中,最常见的词是无处不在的词,这些词不能反映工作是关于什么的,需求是什么,只是围绕着一般的概念。这些广告大多很好地运用了文字游戏。LinkedIn 和 Glassdoor 等网站上的过滤器通常会搜索这些通用术语,而不是特定术语,因此这些帖子有时会通过这些网站的欺诈检测算法。这些发现让我们得出结论,也许仅仅是职位描述并不是一个很好的预测变量,我们需要更多的信息。
虚假招聘信息的 Word cloud。
因此,诸如招聘流程、公司标志、广告的在线位置等信息,以及围绕该招聘信息的许多此类外部因素变得至关重要,无法从职位描述中推断出来。在本系列的第 2 部分中,我将更仔细地研究这些变量,以及它们如何影响这个问题的预测性能。
真实招聘信息的 Word cloud。
在这一部分中,我们看到了一个深入的探索性分析,即假职位与真职位有何不同。在当前的经济形势下,我理解尽快找到工作的绝望,但我们需要对这种骗子的损失有所不同。这个问题是求职群体的道德责任,如果发现此类虚假招聘信息,他们应该互相帮助并向有关部门举报。
在当前的经济环境下,虚假招聘是一个严重的问题。随着情况的恶化,我们可以看到越来越多的这种欺诈性帖子到处涌现。我在这篇文章中提出了这个问题的一些趋势和分析,我希望这有助于你下次申请下一份工作时更加注意。
下一部分,我会开发一个机器学习算法,把职位描述作为输入,预测是不是假的。所以非常感谢你看完这一部分,敬请期待下一篇!
参考资料:
https://www . the balances careers . com/list-of-fake-job-scam-examples-2062 168
https://www . weforum . org/agenda/2020/04/新冠肺炎-行动-呼叫-8-apr/
作者注:
你可以在 LinkedIn 上联系我—【https://www.linkedin.com/in/sharad-jain/
预测虚假招聘信息—第二部分(预测分析)
预测哪些招聘信息是假的。
在这个由两部分组成的系列文章的第一部分中,我做了一个详细的探索性分析,分析了虚假的招聘信息与真实的招聘信息有什么不同。下面是第 1 部分的链接,我强烈建议您在继续之前先阅读该部分!
[## 预测虚假职位发布—第 1 部分(数据清理和探索性分析)
COVID19 及其带来的经济低迷导致了许多虚假的招聘信息。这里有一个详细的…
towardsdatascience.com](/predicting-fake-job-postings-part-1-data-cleaning-exploratory-analysis-1bccc0f58110)
前一部分的一些重要见解—
- 虚假的招聘信息大多针对全职职位,这些职位的最低要求是学士学位和中高级工作经验。
- 这些职位主要面向在技术部门寻找工作的个人。
- 45%的帖子甚至没有问一个问题就把工作给了候选人(这是虚假帖子的一个重要标志)。
- 没有经过筛选的职位大多是初级职位。
- 这些虚假帖子主要来自美国,其次是英国、加拿大和印度。
- 创建词云后发现,招聘启事有类似的行为内容,但正版的更具体到角色。
基于这些见解,我们现在知道,有可能发现哪些招聘信息是假的,哪些不是。但在这个前所未有的时代,每天都有数百人被解雇,求职者感到绝望。骗子们正利用这种绝望情绪发布越来越多的虚假招聘广告。因此,我们需要在 LinkedIn、Glassdoor 等求职网站上使用更多这样的算法和工具,以便过滤掉这些虚假的帖子,让求职者只看到真实的帖子。
在接下来的部分,我将对上次使用的数据使用机器学习技术,并从真实的招聘信息中预测虚假的招聘信息。
数据
因此,到目前为止,我们在分析中使用的数据是由爱琴海大学信息与通信系统安全实验室(http://emscad.samos.aegean.gr/)编制的。该数据集包含 800 个 fak 职位描述。
我已经在本系列的第 1 部分中定义了作为数据集一部分的变量。我会提到完整列表中的变量。我将在下一节中使用进行分析。
数据清理
我在我的系统上导入了 Jupyter 笔记本上的数据,并在 Python 3 上工作。由于我希望这一部分更多的是关于洞察力而不是代码,所以我没有在这里附上任何代码要点,但是任何对查看数据清理代码感兴趣的人,都可以随意查看我的 GitHub 库—【https://github.com/sharad18/Fake_Job_Posting
最初的数据集包含 18,000 个帖子。清理后,新数据有大约 11,000 个帖子。
我将用于预测分析的变量子集是—
- 标题:职位发布的标题。
- 描述:职位描述+公司简介+要求
- 远程办公:远程办公职位的 Tru。
- Has_company_logo:如果公司徽标存在,则为 True。
- Has_questions:如果存在筛选问题,则为 True。
- 就业 _ 类型:全职、兼职、合同等。
- 要求 _ 经验:高管、入门级、实习生等。
- 要求 _ 学历:博士、硕士、学士等。
- 行业:汽车、IT、医疗保健、房地产等。
- 职能:咨询、工程、研究、销售等。
- 欺诈性的(目标变量):如果是假的,则为 1,否则为 0。
- 城市:招聘启事中提到的城市。
- Country_name:职位发布中提到的国家的名称。
让我们开始处理这些干净的数据吧!
导入库和读取数据
我暂时导入了以下库,它们是任何人在 Python 中执行分析所需的基本库,
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
%matplotlib inline
import numpy as np
pd.set_option('display.max_columns', None)
让我们看看数据,
df = pd.read_csv('Clean_data.csv')
df.head()
正在使用的数据的预览。
现在,我们试着详细研究“描述”一栏。在我导入的已清理数据文件中,“描述”列是“描述”+“要求”和“公司简介”的组合“描述”中的数据看起来像什么的一个例子—
“描述”列中的单个条目。
接下来,我们将试着看看 20 个最常用的单词,它们既出现在虚假招聘中,也出现在好的招聘广告中。
import spacy
nlp = spacy.load('en_core_web_lg')
import base64
import string
import re
from collections import Counter
from nltk.corpus import stopwords
stopwords = stopwords.words('english')punctuations = string.punctuationdef cleanup_text(docs, logging = False):
texts = []
for doc in docs:
doc = nlp(doc, disable = ['parser', 'ner'])
tokens = [tok.lemma_.lower().strip() for tok in doc if tok.lemma_ != '-PRON-']
tokens = [tok for tok in tokens if tok not in stopwords and tok not in punctuations]
tokens = ' '.join(tokens)
texts.append(tokens)return pd.Series(texts)
对于虚假的招聘信息,
Fraud_1 = [text for text in df1[df1['fraudulent'] == 1]['description']]
Fraud_1_clean = cleanup_text(Fraud_1)
Fraud_1_clean = ' '.join(Fraud_1_clean).split()
Fraud_1_counts = Counter(Fraud_1_clean)
Fraud_1_common_words = [word[0] for word in Fraud_1_counts.most_common(20)]
Fraud_1_common_counts = [word[1] for word in Fraud_1_counts.most_common(20)]fig = plt.figure(figsize = (20, 10))
pal = sns.color_palette("cubehelix", 20)
sns.barplot(x = Fraud_1_common_words, y = Fraud_1_common_counts, palette=pal)
plt.title('Most Common Words used in Fake job postings')
plt.ylabel("Frequency of words")
plt.xlabel("Words")
plt.show()
虚假招聘中的前 20 个词。
对于真实的招聘信息,
Fraud_0 = [text for text in df1[df1['fraudulent'] == 0]['description']]
Fraud_0_clean = cleanup_text(Fraud_0)
Fraud_0_clean = ' '.join(Fraud_0_clean).split()
Fraud_0_counts = Counter(Fraud_0_clean)
Fraud_0_common_words = [word[0] for word in Fraud_0_counts.most_common(20)]
Fraud_0_common_counts = [word[1] for word in Fraud_0_counts.most_common(20)]fig = plt.figure(figsize = (20, 10))
pal = sns.color_palette("cubehelix", 20)
sns.barplot(x = Fraud_0_common_words, y = Fraud_0_common_counts, palette=pal)
plt.title('Most Common Words used in Genuine job postings')
plt.ylabel("Frequency of words")
plt.xlabel("Words")
plt.show()
真实招聘启事中的前 20 个单词。
在上面的两个图中,最常用的词几乎是一样的,很难区分两者。因此,变量“描述”本身不能帮助我们预测,因此完整的变量集是有意义的。更值得一提的是,当一个人在互联网上看到招聘信息时,我在“数据清理”部分提到的这些附加功能并没有直接提供。这些变量仅在职位发布被举报为欺诈后获得。在这种情况下,当务之急是,如果发现这种虚假招聘,他们必须通知有关当局以及他们网络中的其他求职者。
将数据分为训练和测试
在分割数据之前,我们需要对数据做一些最后的修改,之后我们将分割数据。必须将*‘description’列清理成令牌。这是在空间和 nltk 库的帮助下完成的。在下面这段代码中,’ description’ '列已经被转换成标记,这些标记已经被用来使用 sklearn 的 CountVectorizer 创建一个热列。此外,类似于‘就业类型’,‘必需教育’,‘必需经验’,‘行业’,*和’*功能’*的分类列已经被转换成一个热点向量。
STOPLIST = set(stopwords.words('english') + list(ENGLISH_STOP_WORDS))
SYMBOLS = " ".join(string.punctuation).split(" ")def tokenizetext(sample):
text = sample.strip().replace("\n", " ").replace("\r", " ")
text = text.lower()
tokens = parser(text)
lemmas = []
for tok in tokens:
lemmas.append(tok.lemma_.lower().strip() if tok.lemma_ != "-PRON-" else tok.lower_)
tokens = lemmas
tokens = [tok for tok in tokens if tok not in STOPLIST]
tokens = [tok for tok in tokens if tok not in SYMBOLS]
return tokensvectorizer = CountVectorizer(tokenizer = tokenizetext, ngram_range = (1,3), min_df = 0.06)
vectorizer_features = vectorizer.fit_transform(df1['description'])vectorized_df = pd.DataFrame(vectorizer_features.todense(), columns = vectorizer.get_feature_names())
df_final = pd.concat([df1, vectorized_df], axis = 1)df_final.drop('description', axis = 1, inplace = True)
df_final.dropna(inplace=True)columns_to_1_hot = ['employment_type', 'required_experience', 'required_education', 'industry', 'function']for column in columns_to_1_hot:
encoded = pd.get_dummies(df_final[column])
df_final = pd.concat([df_final, encoded], axis = 1)columns_to_1_hot += ['title', 'city', 'country_name']
df_final.drop(columns_to_1_hot, axis = 1, inplace = True)
接下来,我们把数据分成训练和测试两部分—
target = df_vectorized['fraudulent']
features = df_vectorized.drop('fraudulent', axis = 1)X_train, X_test, y_train, y_test = train_test_split(features, target, test_size = 0.1, stratify = target, random_state=42)print (X_train.shape)
print (y_train.shape)
print (X_test.shape)
print (y_test.shape)
我们得到以下输出—
(10144, 857)
(10144,)
(1128, 857)
(1128,)
我们现在万事俱备了。先说机器学习吧!
机器学习算法
我们将在后续章节中使用的库—
from sklearn.model_selection import GridSearchCVfrom sklearn.linear_model import LogisticRegression
from sklearn.neighbors import KNearestNeighbors
from sklearn.svm import SVC
from sklearn.ensemble import RandomForestClassifier
from sklearn.neural_network import MLPClassifierfrom sklearn.metrics import accuracy_score, confusion_matrix, classification_report, roc_auc_score
1.逻辑回归
log_reg = LogisticRegression()
c_values = [0.00001, 0.0001, 0.001, 0.01, 0.1, 1, 10, 100, 1000, 10000]
penalty_options = ['l1', 'l2']param_grid = dict(C = c_values, penalty = penalty_options)grid_tfidf = GridSearchCV(log_reg, param_grid = param_grid, cv = 10, scoring = 'roc_auc', n_jobs = -1, verbose=1)grid.fit(X_train, y_train)log_reg_pred = grid.predict(X_test)print (roc_auc_score(y_test, log_reg_pred))
print (classification_report(y_test, log_reg_pred))
我们得到以下结果—样本 roc_auc 得分= 0.7795,对于分类报告,我们得到—
逻辑回归的样本外结果。
用最基本的模型进行预测,逻辑回归,给我们一个 0.7795 的 ROC-AUC 分数,考虑到数据的不平衡,这是一个很好的分数。在随后的章节中,我们将看到更复杂的模型。
2.k-最近邻(KNN)
knn = KNeighborsClassifier()
k_range = list(np.arange(2, 23, 2))
param_grid_knn = dict(n_neighbors = k_range)
print (param_grid_knn)grid_knn = GridSearchCV(knn, param_grid_knn, cv = 10, scoring = 'roc_auc', n_jobs = -1, verbose = 1)grid_knn.fit(X_train, y_train)knn_pred = grid_knn.predict(X_test)print (roc_auc_score(y_test, knn_pred))
print (classification_report(y_test, knn_pred))
KNN 的样本外 ROC-AUC 得分为 0.5995。对于分类报告,我们得到—
KNN 的样本结果。
从左图中,我们可以看到,与逻辑回归相比,KNN 的表现非常差。
3.支持向量机(SVM)
svc = SVC()
kernel = ['linear', 'rbf']
param_grid_knn = dict(kernel = kernel)
print (param_grid_knn)grid_svc = GridSearchCV(svc, param_grid_knn, cv = 10, scoring = 'roc_auc', n_jobs = -1, verbose = 2)grid_svc.fit(X_train, y_train)svc_pred = grid_svc.predict(X_test)print (roc_auc_score(y_test, svc_pred))
print (classification_report(y_test, svc_pred))
这里报告的样本外得分为 0.8195 ~ 0.82。分类报告如下—
SVC 以 0.82 的分数获得了迄今为止最好的成绩,这明显优于后两种方法。
4.随机森林
rf = RandomForestClassifier()
n_estimators_range = [1, 2, 4, 8, 16, 32, 64, 100, 200]
param_grid_rf = dict(n_estimators = n_estimators_range)
grid_rf = GridSearchCV(rf, param_grid_rf, cv = 10, scoring = 'roc_auc', n_jobs = -1, verbose = 1)grid_rf.fit(X_train, y_train)
print (grid_rf.best_score_)
print (grid_rf.best_params_)rf_pred = grid_rf.predict(X_test)
print (roc_auc_score(y_test, rf_pred))
print (classification_report(y_test, rf_pred))
对于随机森林模型,报告的 ROC-AUC 得分为 0.74。分类报告如下—
的分类报告
说实话,我预计随机森林的表现会比 SVC 好,但到目前为止,SVC 的结果最好。
5.Sklearn 的神经网络 MLP 分类器(solver = 'sgd ')
mlp = MLPClassifier(solver = 'sgd', activation = 'relu', hidden_layer_sizes = (100, 50, 30), max_iter = 1000)
mlp.fit(X_train, y_train)mlp_pred = mlp.predict(X_test)print (roc_auc_score(y_test, mlp_pred))
print (classification_report(y_test, mlp_pred))
在这种情况下,ROC-AUC 得分为 0.7786。分类报告—
MLP 分类器的分类报告(solver = 'sgd ')
带有“sgd”解算器的 MLP 分类器的性能略好于随机森林模型,但仍比 SVC 报告的要差。
6.Sklearn 的神经网络 MLP 分类器(solver = 'adam ')
mlp = MLPClassifier(solver = 'adam', activation = 'relu', hidden_layer_sizes = (100, 50, 30), max_iter = 1000)
mlp.fit(X_train, y_train)mlp_pred = mlp.predict(X_test)print (roc_auc_score(y_test, mlp_pred))
print (classification_report(y_test, mlp_pred))
该模型的样本外 ROC-AUC 值为 0.8595 ~ 0.86。分类报告如下—
MLP 分类器的分类报告(求解器= 'adam ')
这是迄今为止报道的最高分,基于这个模型,我们将能够在 86%的情况下正确预测招聘信息是否是假的。
模型比较
所有模型之间的比较。
从上图中,我们可以看到 Sklearn 基于神经网络的 MLP 分类器与’ adam’ optimizer 表现最好,其次是同一模型与’*【SGD '*解算器和支持向量机分类器。因此,基于 MLP 分类器的样本外性能指标 ROC-AUC 得分,我们可以有把握地说,我们可以在 86%的时间里预测一个职位发布是否是假的。
这种预测分析对于 LinkedIn 和 Glassdoor 这样的求职网站非常有用,可以帮助他们过滤这种虚假的招聘信息。
结论
目前,我们生活在一个我们谁都没有预料到的时代。冠状病毒不仅给各国带来了突发卫生事件,还加速了即将到来的经济衰退。每天都有许多员工被解雇,对工作的需求远远超过了市场上的职位数量。
通过这一系列文章,我试图提出一个正在就业市场蔓延的问题。动荡和混乱是骗子的完美支持者,目前,网络诈骗攻击正在上升。在上一部分,我详细分析了如何区分虚假和真实的招聘信息,以及欺诈性招聘信息的特征。在这一部分中,我提供了一个详细的分析,说明我们如何应用机器学习来预测这种虚假帖子的出现。
正如我在这两部分中提到的,作为互联网用户和求职者,我们有责任让当局和我们的网络知道我们是否遇到了这种虚假的招聘信息,而不是任何模型或分析。
谢谢你看了这两部分。我希望每个人都有美好的一天&请保持社交距离,这样我们可以更快更有效地度过这样的时光!
作者注:
参与这个项目对我来说是一次很好的学习经历。希望你们都觉得它很有帮助,很有启发性。
这篇文章的全部代码都在我的 GitHub 存储库中,在 https://github.com/sharad18/Fake_Job_Posting 的进行分析。我很想在评论区听到你的反馈。
你也可以在 LinkedIn 上联系我—https://www.linkedin.com/in/sharad-jain/