强化学习中的政策网络与价值网络
在强化学习中,代理在他们的环境中采取随机决策,并学习从许多决策中选择正确的决策来实现他们的目标,并以超人的水平进行游戏。策略和价值网络在像蒙特卡罗树搜索这样的算法中一起使用,以执行强化学习。这两个网络都是一种叫做 MCTS 探索算法的方法的组成部分。
它们也被称为策略迭代&值迭代,因为它们被计算多次,使得它成为一个迭代过程。
我们来了解一下为什么它们在机器学习中如此重要,它们之间有什么区别?
什么是政策网络?
考虑世界上的任何游戏,输入🎮用户给予游戏的动作称为动作。每一个输入(动作)都会导致不同的输出。这些输出被称为游戏的状态 **s**
。
由此,我们可以制作不同的状态-动作对**S** = **{(**s0,a0**)**,s1,a1**)**,...,**(**sN,aN**)}**
,表示哪个动作aN
导致哪个状态sN.
同样,我们可以说 S 包含策略网络学习到的所有策略。
通过给博弈一个特定的输入来学习给出一个确定的输出的网络被称为策略网络
Policy Network (action1️, state1) , (action2, state2)
比如:输入a1
给出一个状态s1
(上移)&输入a2
给出一个状态s2
(下移)在游戏中。
此外,一些行动增加了玩家的点数,导致奖励 r 。
States Getting Rewards
让我们来看看一些明显的符号:
Usual Notations for RL environments
Optimal Policy
为什么我们要使用贴现因子γ
它被用作一种预防措施(通常保持在 1 以下)。它阻止报酬达到无限。
对一项政策的无限奖励会压垮我们的代理人&偏向于特定的行动,扼杀探索未知领域和游戏行动的欲望😵。
但是我们怎么知道你下一步该选择哪个州,最终进入最后一轮呢?
什么是价值网络?
价值网络通过计算当前状态
**s**
的预期累积分数来为游戏状态分配价值/分数。每个州都要经过价值网络。获得更多奖励的州显然在网络中获得更多价值。
请记住,奖励是**预期奖励,**因为我们从一组状态中选择了正确的一个。
Value Function
现在,关键目标总是最大化回报*(又名马尔可夫决策过程)*。导致良好状态的行为显然比其他行为获得更大的回报。
因为任何游戏都是通过一个接一个的动作赢得的。博弈的最优策略***π****
由许多有助于赢得博弈的状态-行动对组成。
获得最大回报国家-行动对被认为是最优政策。
使用 arg max 将最优策略的等式正式写成:
Optimal Policy ***π****
因此,最优策略告诉我们应该采取哪些行动来最大化累积折扣回报。
策略网络学习到的最优策略知道在当前状态下应该执行哪些动作以获得最大回报。
如果您有任何疑问、疑问或需求,请在下面评论或发微博给我。
鼓掌吧…分享一下!在 中 关注我获取类似的好玩内容。
要获得即时通知,请在 Twitter 上关注我。
乐意帮忙。值得称赞。
你会喜欢的以前的故事:
每个数据科学爱好者的 MCTS
towardsdatascience.com](/monte-carlo-tree-search-158a917a8baa) [## TensorFlow 图像识别 Python API 教程
在带有 Inception-v3 的 CPU 上(以秒为单位)
towardsdatascience.com](/tensorflow-image-recognition-python-api-e35f7d412a70) [## 激活函数:神经网络
Sigmoid,tanh,Softmax,ReLU,Leaky ReLU 解释!!!
towardsdatascience.com](/activation-functions-neural-networks-1cbd9f8d91d6) [## DeepMind 的游戏《用深度强化学习捕捉旗帜》
#4 研究论文解释
towardsdatascience.com](/deepminds-playing-capture-the-flag-with-deep-reinforcement-learning-a9f71256442e)
堕胎问题上的政治分歧
作为他的第一批行动之一,特朗普总统通过了一项行政命令,阻止美国向从事堕胎或提供堕胎信息的外国组织提供援助。自从 1984 年里根总统的“墨西哥城政策”开始实施以来,共和党和民主党总统就一直在这个问题上进行政治拉锯战。
在美国,最高法院在 Roe v . Wade(1973)一案中具有里程碑意义的判决在政治上分裂了国家,并使堕胎成为“文化战争”的一部分。有趣的是,直到 90 年代初,民主党人和共和党人对堕胎的态度差异相对较小。正如下面的分析所示,自克林顿担任总统以来,公众意见发生了巨大的分歧。
下图显示了按受访者意识形态分类的各类堕胎的时间趋势。有趣的是,斯坦福大学杰出的政治学家莫里斯·菲奥莉娜在他的畅销书*“文化战争?一个两极化的美国的神话”来断定公众对堕胎的意见并不分歧。在第五章(仔细观察堕胎)中,菲奥莉娜总结道…我们经常被告知,这个国家在堕胎问题上存在两极分化。*这种说法是错误的(第 80 页)。
性别差异
让我们看看对“允许强奸堕胎”的态度,并探讨其他人口统计学的相互作用。这个问题最近变得很突出,因为众议员托德·阿金(R-Mo。)为他对堕胎的极端反对进行辩护,声称“合法强奸”的受害者很少怀孕,因为“女性身体有办法关闭这一切。”
有趣的是,保守女性的态度比其他群体变化更大,这或许为 2016 年克林顿/特朗普选举中观察到的性别投票模式提供了线索。
附录:
分析中使用的数据来自综合社会调查(1972-2014 年),该调查提供了不同情况下(例如,婴儿有严重缺陷的风险,太穷而负担不起对孩子的长期护理)合法堕胎公众意见的长期趋势。
I 交互式可视化以及 R 代码和数据可在http://onsocialtrends.org/找到
图表在 Highcharter 中生成(R 包装到 Highcharts )
政治党派:看看数据
传统观点认为,特朗普时代是近期政治中政治极化最严重的时期。我决定看看一些数据,看看是否真的是这样。利用布鲁金斯学会(Brookings)关于国会的重要统计数据,我研究了 1953 年至 2015 年国会政党投票团结和意识形态得分差异。不出所料,我发现这两个指标都处于历史峰值。当前的政治时刻是人们记忆中党派之争最激烈的时刻。
我在 Jupyter 笔记本上为这篇文章写了代码,你可以在这里看到。
国会党派投票团结
民主党人和共和党人多久投票一次?这很容易让人想到著名的党派投票,比如 2010 年 ACA 投票中每个共和党人都投了反对票。最近,上周参议院未能通过同一 ACA 的“小废除”,每一位参议院民主党人都投了反对票。但看看整体数据,就会发现一幅更复杂的画面。如果我们衡量“党内团结投票”(定义为大多数投票民主党人反对大多数投票共和党人的投票)的百分比,随着时间的推移,似乎没有明显的趋势。
很明显,在过去 5 年左右的时间里,国会的党派投票达到了前所未有的统一水平。但是这种趋势会持续下去吗?90 年代中期(金里奇革命前后)也见证了党派团结投票的高峰,但显然几年后事情平静了下来。为了进行预测,我们需要我们亲爱的朋友线性回归的帮助。
首先,让我们制作一些预测线(又名最佳拟合线)。我们将测试的假设是,未来的数据将接近这些线。
在进行测试之前,很明显可以看到过去的数据并不符合这些曲线。肯定有一个微弱的积极趋势,但在某一年,很容易出现比前几年急剧下降的情况。不出所料,一个双边 t 检验揭示了令人难以置信的高置信度(众议院 p=0.9999,参议院 p=1),我们不得不拒绝未来国会将继续看到更高的政党投票团结水平的预测。
需要注意的是,这个测试范围很窄。这并不是说政党投票的统一性会下降——它可能会停留在这个历史峰值。这也不是一个很好的衡量标准:我使用的数据集将“党内团结投票”计算为大多数民主党人投票反对大多数共和党人的投票——但它忽略了低级别的确认、无意义的重命名事物的法案等常规投票,也没有跟踪从未进入议会的法案。
国会意识形态得分
支持党派偏见增加的另一种观点可能指向两党之间日益扩大的意识形态鸿沟。很难量化一名官员的“开明”或“健谈”程度,但一个广泛使用的衡量标准是普尔-罗森塔尔 DW-提名分数。在他们的自由-保守轴下,高负分表示高度自由的国会议员,高正分表示保守,接近 0 表示温和。
在这里,数据讲述了一个清晰得多的故事。与政党团结投票的百分比不同,数据点非常接近它们的最佳拟合线。一个简单的相关性测试(我使用了非参数的斯皮尔曼相关系数)发现了一个非常强的正相关关系。
众议院和参议院都表现出非常强的相关性,r≈0.98(5*10^(-23 的 p 值))和 r≈0.94(7∗10^(−17 的 p 值),r=1 是完美的相关性。相比之下,众议院和参议院的政党团结投票率分别为 0.46%和 0.66%,这仍然是一个积极的关系,但要弱得多。
像政党团结投票的百分比一样,这些数据也有局限性。我只使用了 Poole 和 Roosenthal 的意识形态分数的 1 个维度(“自由-保守”轴),但他们的系统使用了超过 10 个维度,并得出结论认为 2 维模型是最适合的。我怀疑更详细的数据会揭示这个故事更复杂。此外,我只研究二战后的数据,当时两党之间的距离处于历史低点。很有可能,这种统一是一种历史异常,一旦没有战争来统一这个国家,这种异常就结束了。
结论
从这些数据来看,很明显,党派之争达到了历史最高点。这一趋势是否会继续,在政党团结投票的情况下仍有争议,但意识形态的差距几乎肯定会继续扩大。这种分离的趋势可能会增加国会的僵局和对另一方的不信任,这是一个旨在以共识为基础运作的系统的关键弱点。
当然,党派偏见是否增加是一个简单的问题。更重要的问题是如何应对——我不确定我们是否有数据来回答这个问题。
将大规模枪击事件政治化——当我们可以谈论枪支管制的时候
2017 年 10 月 1 日,一名枪手从拉斯维加斯一家酒店房间内射出子弹,造成 59 人死亡,546 人受伤。这是美国近代史上最致命的大规模枪击事件。
在每一次大规模枪击事件后,这种叙述都变得很熟悉,几乎是照本宣科。两边的政治家都为受害者及其家人祈祷,而民主党人利用这个机会吸引人们对枪支管制的关注,共和党人谴责民主党人“将悲剧政治化”
让我们从表面上接受这种政治化的论点,并说在大规模枪击事件后立即谈论枪支管制是不合适的。那什么时候可以谈论它?假设用以下两个标准来决定是否可以谈论枪支管制:
- 当天没有大规模枪击事件(4 起或更多枪击或死亡,不包括枪手)
- 距离上次大规模枪击事件已经过去至少 3 天了
以下是我利用美国 2017 年大规模拍摄数据得出的结论:
让我们从一些推论开始:
- 根据这一标准,在下一次枪击事件发生之前,你最多有连续两天的时间谈论枪支管制和枪支问题。
- 你不能在一月、六月、八月、九月、十月谈控枪。
- 总的来说,我们有 15 天的时间可以谈论枪支管制——仅仅超过 2 周。
3 天,虽然是一个任意的数字,但与事实相差并不太远,因为 10 月 4 日(拉斯韦加斯枪击案发生 3 天后)发表了数十篇观点 文章抨击民主党人将悲剧政治化。
所以,也许这不是为了防止悲剧被政治化。也许是不想谈论枪支管制,并批判性地审查第二修正案,以采取政策防止此类枪击事件再次发生。
多项式回归
这是我在机器学习系列的第三篇博客。这个博客需要线性回归的先验知识。如果您不了解线性回归或者需要复习一下,请浏览本系列以前的文章。
线性回归要求因变量和自变量之间的关系是线性的。如果数据的分布更复杂,如下图所示,会怎么样?线性模型可以用来拟合非线性数据吗?我们怎样才能生成一条最好地捕捉数据的曲线,如下图所示?那么,我们将在这篇博客中回答这些问题。
目录
- 为什么是多项式回归
- 过度拟合与欠拟合
- 偏差与方差的权衡
- 将多项式回归应用于波士顿住房数据集。
为什么要多项式回归?
为了理解多项式回归的需要,让我们首先生成一些随机数据集。
生成的数据如下所示
让我们对这个数据集应用一个线性回归模型。
最佳拟合线的曲线为
我们可以看到,直线无法捕捉数据中的模式。这是欠装配的一个例子。计算线性线的 RMSE 和 R 分数得出:
RMSE of linear regression is **15.908242501429998**.
R2 score of linear regression is **0.6386750054827146**
为了克服欠拟合,我们需要增加模型的复杂度。
为了生成高阶方程,我们可以添加原始特征的幂作为新特征。线性模型,
可以转化为
这仍然被认为是线性模型,因为与特征相关的系数/权重仍然是线性的。x 只是一个特征。然而,我们正在拟合的曲线实际上是二次曲线。
为了将原始特征转换成它们的高阶项,我们将使用由scikit-learn
提供的PolynomialFeatures
类。接下来,我们使用线性回归来训练模型。
To generate polynomial features (here 2nd degree polynomial)
------------------------------------------------------------polynomial_features = PolynomialFeatures(degree=2)
x_poly = polynomial_features.fit_transform(x)Explaination
------------Let's take the first three rows of X:
[[-3.29215704]
[ 0.79952837]
[-0.93621395]]If we apply polynomial transformation of degree 2, the feature vectors become[[-3.29215704 10.83829796]
[ 0.79952837 0.63924562]
[-0.93621395 0.87649656]]
对变换后的要素拟合线性回归模型,给出了下图。
从图中可以清楚地看出,二次曲线比线性曲线更能拟合数据。计算二次图的 RMSE 和 R 分数给出:
RMSE of polynomial regression is **10.120437473614711**.
R2 of polynomial regression is **0.8537647164420812**.
我们可以看到,与直线相比,RMSE 降低了,R 值增加了。
如果我们尝试将三次曲线(次数=3)拟合到数据集,我们可以看到它通过的数据点比二次曲线和线性曲线多。
三次曲线的度量标准是
RMSE is **3.449895507408725**
R2 score is **0.9830071790386679**
下面是在数据集上拟合线性、二次和三次曲线的比较。
如果我们进一步增加次数到 20,我们可以看到曲线通过更多的数据点。下面是 3 度和 20 度的曲线比较。
对于 degree=20,模型也捕捉数据中的噪声。这是过度拟合的一个例子。即使这个模型通过了大部分数据,它也无法对看不见的数据进行归纳。
为了防止过度拟合,我们可以添加更多的训练样本,这样算法就不会学习系统中的噪声,可以变得更一般化。(注意:如果数据本身就是噪声,添加更多数据可能会有问题)。
我们如何选择一个最优模型?要回答这个问题,我们需要理解偏差与方差的权衡。
偏差与方差的权衡
偏差是指由于模型在拟合数据时过于简单的假设而产生的误差。高偏差意味着模型无法捕捉数据中的模式,这导致欠拟合。
方差是指由于复杂模型试图拟合数据而产生的误差。高方差意味着模型通过了大多数数据点,导致过度拟合数据。
下图总结了我们的学习。
从下图中我们可以观察到,随着模型复杂性的增加,偏差减少,方差增加,反之亦然。理想情况下,机器学习模型应该具有低方差和低偏差。但实际上不可能两者兼得。因此,为了实现一个在训练和看不见的数据上都表现良好的好模型,进行了折衷。
Source: http://scott.fortmann-roe.com/docs/BiasVariance.html
到目前为止,我们已经讨论了多项式回归背后的大部分理论。现在,让我们在我们在之前的博客中分析的波士顿住房数据集上实现这些概念。
对住房数据集应用多项式回归
从下图可以看出,LSTAT
与目标变量MEDV
有轻微的非线性变化。在训练模型之前,我们将把原始特征转换成高次多项式。
让我们定义一个函数,它将原始特征转换为给定次数的多项式特征,然后对其应用线性回归。
接下来,我们调用上面的次数为 2 的函数。
使用多项式回归的模型性能:
**The model performance for the training set**
-------------------------------------------
RMSE of training set is 4.703071027847756
R2 score of training set is 0.7425094297364765 **The model performance for the test set**
-------------------------------------------
RMSE of test set is 3.784819884545044
R2 score of test set is 0.8170372495892174
这比我们在之前的博客中使用线性回归获得的结果要好。
这个故事到此为止。这个 Github repo 包含了这个博客的所有代码,用于 Boston housing 数据集的完整 Jupyter 笔记本可以在这里找到。
结论
在这个机器学习系列中,我们介绍了线性回归和多项式回归,并在波士顿住房数据集上实现了这两个模型。
我们将在下一篇博客中讨论逻辑回归。
感谢阅读!!
再倒一杯咖啡!—为什么所有业务都将成为数据业务
在我与多个垂直业务领域的首席技术官和首席信息官的多次交谈中,我听到的最常见的主题是: “我们的组织落后了,我们需要振兴——我们现在希望成为数据驱动的企业” 。如果这听起来很熟悉,要知道你并不孤单,你可以与大量优秀的资源合作,为推动这一转型提供一个平台(想想微软、IBM、亚马逊和谷歌),以及一系列智能系统集成商(普华永道、埃森哲等)。)来帮助部署。但这不是一场向你灌输产品和解决方案的竞赛,这是求爱之外的第一个阶段,也是共生伙伴关系的开始。了解你的业务,它是如何运作的,以及对你的客户来说什么是最重要的,这已经成为一次优雅的技术对话的中心。组织的数据存放在哪里、用于什么目的、如何分析以及谁需要根据数据中的趋势洞察做出决策不再仅仅是 it 部门的事了,现在这些都属于高管层。
根据国际数据公司(IDC)在刚刚过去的 2017 年 3 月发布的研究新闻稿,组织中超过 47%的 IT 支出现在将属于核心运营业务部门,业务线(LoB)支出的复合年增长率为 5.9%。(关于这笔支出是如何分配的,见下图)。这在哪些业务领域最为普遍?根据同一项研究,前五大业务线包括: 【离散制造、医疗保健、媒体、个人和消费者服务以及证券和投资服务】。
(2017 年业务线支出最多的领域:应用、面向项目的服务和外包 )
好吧,所以我们不要开始挑剔它,它们不会很快被机器人取代,它们仍然承载着数据驱动型组织中最重要的业务功能:安全*(它们有助于保护我们的数据免受网络攻击,还记得 Equifax 吗?)*。现在,IT 比以往任何时候都更紧密地融入到企业利用数据的方式中,他们不能/不会独自完成这项工作。但是,当首席技术官&首席信息官致力于为这个多节点技术机场建造一条新跑道时,你作为<插入营销、财务、运营、销售的副总裁>将需要让飞机着陆。
“首席执行官,您的数据需要您的帮助!”
IBM 的首席执行官 Ginni Rometty 在她的 CES 2016 主题演讲中说了一些让我非常感动的话:
“数据是世界上最宝贵的自然资源……80%的数据是黑暗的……挑战在于理解它” 。
这种想法是,暗数据,或者说我们生活中每时每刻都可以收集的数据,是一种丰富的资源,只等着那些处于战略地位并有能力这样做的企业来收集。
想一想你一周的典型旅程图*(或者与我们的会议更相关,想一想零售中心的顾客旅程图:见下文)*。周一早上你开车去上班,和同事一起吃午饭,发一些邮件。当然,我们知道我们开了多少英里,吃了多长时间的午餐,但这里缺少了一些有价值的遥测数据:我们在通勤途中听了多少分钟的播客,它如何影响了你从上午 9 点到 11 点的项目效率?在特定时间吃特定的一餐会影响发送的邮件数量、长度或获得快速回复的成功率吗?我们开车的方式和我们走的路线与我们一天的开始或结束有关联吗,通过心率、睡眠习惯等来衡量。为了这些想法,请将隐私放在一边,想象一下,我们日常生活中的每时每刻背后的遥测技术如何帮助卡车车队减少事故,人力资源提高工作效率或增加员工在工作场所的保留率,并使大学能够构建智能地为最佳学习环境做出更多贡献的课程。
*(*典型顾客体验之旅图 在零售中心购买运动服装:非常感谢我的同事“快乐源于设计” 团队成员,我在奥斯汀的设计思维商业案例挑战赛中向他们展示了我们的原型,我们的原型获得了第一名。)
根据全球领先的技术研究和咨询公司 Gartner 的一些预测,到 2022 年,物联网(包括收集环境数据)将每年为消费者和企业节省 1 万亿美元的耗材、服务和维护成本。关键是,我们日常生活中的环境信息可以被捕获并用于绘制模式,以便更深入地了解*(想想 FitBit 让我们可以测量睡眠模式和步行活动)*我们是谁,以及我们如何才能达到/超过最佳基准。这是一个非常宝贵的商业机会,将结构化和非结构化数据收集到一个安全的存储库中,以便对其进行提取、建模和理解,将允许进一步渗透到为您的客户服务的空白领域。当然,人工智能是过去 20 年来科技领域最热门的话题 ( 见下文 ) 人工智能在公司收益电话会议中的持久性,现在正成为商业领域最热门的话题,但人工智能不能没有大量数据课程,它必须建立在这些数据之上并从中学习。
微软用“联网牛”做了一件令人兴奋的事情。牛群管理公司 SCR Dairy 与微软合作,帮助评估母牛何时发情,以便它们可以在正确的时间进行人工授精,实现最佳的小牛产量。这些数据是在连接到雌性奶牛的物联网设备上收集的,通过人工智能建模确定了雌性奶牛行走的步数与其发情倾向的相关性。事情并没有就此结束,随着所有数据的收集,更多的洞察力被用来创造“黑暗收入”,包括与雌性小牛出生的最高概率(这提供了更大的收入产生)的行走步数、小牛的健康等相关的模式。该系统还设计用于移动部署,以帮助牧场经理在野外进行扩展,从而降低劳动力成本并增加收获的数据。想象一下您自己的组织中可能出现的用例?
拉长长尾:从数据故事中获取$美元
随着企业变得更加数字化,他们参与创造额外收入流的能力将变得更加丰富,这要归功于我们的朋友:长尾。这一理论认为,当企业专注于特定的战略计划(服务和产品)时,在这些焦点上产生最大的收入,当他们离开这些点并进入他们不熟悉的点时,收入就会下降。尽管随着更多产品和服务的加入,收入现在会通过这些额外的产品和服务矢量进行汇总,如下图所示。当然,这是假设这些额外的新的点不是非常成本高昂或资产沉重(进入数据故事)。亚马逊 vs 沃尔玛,在沃尔玛成为“砖头和点击”之前,是长尾理论在起作用的一个完美例子。沃尔玛可能只想在它的砖臼中储存“前 40 本书”,而亚马逊理论上可以在其庞大的互联仓库网络中储存任意多的书籍。尽管亚马逊提供的利基“猫书”并不是最畅销的,但这些书的广泛可用性沿着尾巴向下延伸,增加了更大的收入。
( )——感谢马丁·福特,在他的书中提出了这些观点:《机器人的崛起》。
回数据。让我们以汽车制造商为例。传统汽车制造商的重点领域可能包括几个不同的收入来源,主要是汽车销售和服务(即通用汽车的安吉星)。现在,如果通用汽车将自己定位为战略性地利用其数据资产,利用数据提供更多的创收服务,这些服务单独来看并不令人印象深刻,但累积起来会提供令人印象深刻的产品/服务流“长尾”,当然还有收入。基于从多年的历史和流式(IoT)服务数据中生成的关于轮胎磨损和刹车使用的预测分析,构建一个移动平台,以便在用户的车辆需要维护时联系他们。使用相同的数据来预测客户何时会来进行特定的维护项目,为连接的供应链提供及时的交付,智能的劳动力调度,或规定地建议销售团队为特定的汽车 / 加满油,并为客户来进行例行维护做好试驾准备。这些数据是否可以用来计算客户按月付费的多层消费模式会员资格,并驾驶一个**【共享】**车队?
在这里,我们相互问了很多问题,我们也涉及了很多领域——总的来说,技术有很多不同的方式从成本中心发展到增长中心。它发生得非常快。
现在,您可以在本季度开始做些什么,以确保您的业务更多地成为经济驱动力,并拥有数据驱动的副驾驶员?
请随时联系我进行更多讨论,也可以在 LinkedIn 上关注我。
单个神经元的功率
Neuron (Image Source: https://pixabay.com/illustrations/nerve-cell-neuron-brain-neurons-2213009/)
Basic Unit of a Artificial Neural Network — Artificial Neuron
神经网络是由个基本神经元 —也叫个感知器(上图所示的一个基本单元——中间的绿色圆圈)排列成多层网络的组合(下图中的*)。要了解大型网络的工作原理和功率,首先我们需要了解单个单元的工作原理和功率。这就是我们在这篇文章中要关注的!*
A Network of Neurons
理解任何算法工作的最好方法是尝试自己编写代码。如果您可以编写一个简单的代码,通过计算每次迭代中的质心来创建数据聚类,那么您就知道 k-means。如果您可以编写一个简单的代码,在一个数据子样本上创建多个决策树,并从每个树上获取最大投票来分类一个数据点,您就知道随机森林。同样,如果您可以编写一个简单的代码,通过使用梯度下降来求解一个简单的线性方程、两个线性方程和多个线性方程,您就理解了神经网络和梯度下降。
梯度下降
神经网络的主干是梯度下降。要编写梯度下降的代码,我们首先需要理解它。
假设我们有一个简单的线性方程来求解
这里,我们需要找到 w1 和 w2 的值,这使得等式对于给定的 y、x1 和 x2 的值为真。如果我们简单地猜测 w1 和 w2 的值,我们将得到 y_hat
我们可以通过下式计算由于猜测 w1 和 w2 的值而产生的误差
Cost Function
也就是我们一般所说的成本。现在,我们的目标是找出 w1 和 w2 的值,使得成本 C 最小。成本 C 是相对于 w1 和 w2 的可微分函数。根据一些微积分复习资料,如果我们对 w1 和 w2 的函数进行微分(求导),并使其等于 0,我们将得到 w1 和 w2 的值,此时成本将达到最小值。
Gradients
这些导数称为梯度。基本上,函数在某点的导数是该函数在该点的切线或梯度。看上面的等式,我们不能得到 w1 和 w2 的值,其中成本导数将是 0,因为它们依赖于 w1 和 w2。
现在,为了达到最小值,我们将通过每次少量更新权重,开始朝着最小值的方向(这意味着与梯度方向相反)迈出小步。简而言之,我们是在切线或梯度的相反方向下降——这就是名字**“梯度下降”的原因。**
Gradient Descent
Pictorial Representation of Gradient Descent (Image Source: https://scipython.com/blog/visualizing-the-gradient-descent-method/)
手动编码单神经元解简单线性方程
使用实现梯度下降的 numpy
纪元是我们朝着成本最小化迈出一小步的迭代。学习速度告诉你要迈出多小的一步。一大步永远不会让你达到最小值,而非常小的一步要花太多时间才能达到成本最小值。
通过让 x1 = 3、x2 = 8 和 y = 41 来测试函数
Results
人们可以争辩说,一个方程可以有多个解——神经元将找到最接近开始猜测的解。
单神经元求解两个线性方程
同一个函数可以修改为求解两个方程。这个时间成本函数将是
Cost Vs Epochs
单个神经元求解多个线性方程组
同一个函数可以修改成解多个方程。这个时间成本函数将是
Cost function for Multiple Equations
如果误差随着每个 epoc 的增加而增加,则降低学习率。如果误差减小,但没有低于阈值,则增加周期数(n _ 周期)。
本文简单介绍了梯度下降算法,以及如何使用 numpy 求解线性方程来创建基本神经元。
以上所有代码都可以在我的 git repo 找到。
欢迎评论和反馈!
举重数据和探索性数据分析第 1 部分
几周前,我发现自己在互联网上搜索起重数据。我一直喜欢健身,我想知道是否有任何可行的数据集,可以量化我的一个爱好。然后我偶然发现打开了 Powerlifting 的力量举数据库。OpenPowerlifting 存储了全国各地 Powerlifting 会议上完成的 300,000 多台电梯的数据。我很快发现自己在搜索著名的举重运动员,如马克·贝尔、布兰登·莉莉、斯坦·埃弗丁和乔尼·坎迪托。找到那些大人物后,我也在数据集中搜索朋友咳 AlanZhou 咳。我对 OpenPowerlifting 收集的数据感到高兴和好奇。我决定,当我有时间时,我会重新访问数据集,看看是否有什么我可以做的。
以下是 OpenPowerlifting 对他们的数据的看法:“OpenPowerlifting 项目旨在创建一个永久、准确、方便、可访问、开放的世界举重数据档案。为了支持这一使命,所有的 OpenPowerlifting 数据和代码都可以以有用的格式下载。没必要刮这个网站。”过去我花了几天时间浏览网站,破译写得很糟糕的 HTML 代码,很高兴在 OpenPowerlifting 的 Github 上找到了一个可随时下载的 CSV 文件。
其他数据工程师、数据科学家、软件开发人员和数据分析师喜欢举重,这让我欣喜若狂。OpenPowerlifting 背后的人和我有两个共同点,举重和数据科学。我决定把计时器打开半小时,看看我能做些什么数据。我实施这个时间限制仅仅是因为我可以看到自己在数据上花费了过多的时间,而且我还有其他更紧迫的截止日期要赶。
下表是三大电梯的简单分类。我把数据分成男性和女性两组。此外,我已经包括了总数和威尔克斯系数的平均值。
现在,我要说的是,其中的一些测量对我来说似乎有点偏差。为了更好地理解分布情况,我绘制了直方图,并将它们包含在下面。力量举重的年龄分布特别有希望。我们看到大量年轻人加入这项运动并参与竞争。这可能是由于 YouTube 健身名人的受欢迎程度,如马克·贝尔、奥马尔·伊素福、沉默的麦克、杠铃旅和坎迪托训练总部。希望这一趋势在未来继续下去。
观察男性和女性的散点图表明,体重和举重之间存在正相关。这是显而易见的。但是基于这些散点图,我相信与深蹲相比,体重增加一个单位增加一个人的板凳深度最少,硬拉增加最多。我将在本分析的第二部分尝试证明(或否定)这一假设。我把这个小项目分成两部分的原因是,在我的 30 分钟结束时,我只完成了很少的工作。我计划在第二部分做一些实际的机器学习,所以敬请关注!
一旦我完成分析,我会在 Github 上公开我的 Jupyter 笔记本。下面是打开力量举重的链接。
http://www.openpowerlifting.org/data.html
https://github.com/sstangl/openpowerlifting
数据科学写作的实用建议
(Source)
撰写数据科学项目的有用技巧
写作是每个人都想做的事情,但是我们经常发现很难开始。我们知道写关于数据科学项目的文章可以提高我们的沟通能力,打开大门,让我们成为更好的数据科学家,但是我们经常纠结于我们的文章不够好或者我们没有必要的背景或教育。
我自己也一直在与这些感觉作斗争,在过去的一年里,我已经形成了一种克服这些障碍的心态,以及关于数据科学写作的一般原则。虽然写作没有一个秘诀,但有一些实用的小技巧可以让你更容易养成高效的写作习惯:
- 目标达到 90% :完成的不完美的项目比你从未完成的完美项目要好
- 一致性有助于:你写得越多,就越容易
- **不要担心证书:**在数据科学中,没有任何障碍阻止你贡献或学习任何你想学的东西
- 最好的工具是完成工作的工具:不要过度优化你的写作软件、博客平台或开发环境
- **广泛而深入地阅读:**借鉴、混合和改进他人的想法
在这篇文章中,我们将简要地讨论每一点,并且我将谈到我是如何实现它们来提高我的写作水平的。在几十篇文章的过程中,我犯了很多错误,你可以从我的经历中学习,而不是自己犯同样的错误。
完美被高估了:目标是 90%
我必须克服的最大的精神障碍,也是我经常听到其他人与之斗争的想法是“我的写作/数据科学技能不够好。”这可能会使人变得虚弱:当考虑一个项目时,人们会合理化,因为他们不能达到完美,他们甚至还不如不开始。换句话说,他们让 完美成为了 善的敌人。
这里的谬误是,只有完美的项目才值得分享。然而,一个粗略完成的项目要比一个永远无法完成的理想化项目好得多。
虽然在某些领域,完美的表现是可以预期的——你希望你的汽车刹车每次都能正常工作——但写博客不在这些领域之内。回想一下您最近一次阅读数据科学文章的情形。我猜(尤其是如果你读了我的一篇文章)它至少有一些错误。然而,你可能还是完成了这篇文章,因为重要的是内容的价值。只要文章有引人注目的内容,我们愿意忽略一些错误。
当我写作时,我的目标是让我的文章可读,并做一些编辑,但我不再要求它们完全没有错误。实际上,我的目标是 90%,超过 90%就是额外奖励。发布一篇有一些错误的文章总比一点错误都没有要好(如果你关心语法/风格,我推荐免费的语法工具)。
这种态度不仅限于编写数据科学项目本身。总会有另一种方法可以尝试,或者进行另一轮模型调整。在某一点上,这项工作的回报将少于投入的时间。知道何时停止优化是一项重要的技能。不要让这成为一个半途而废的项目的借口,但是不要强调试图达到不可能的 100%。如果你犯了几个错误,那么你有机会通过把你的工作拿出来征求反馈来学习。
愿意完成不完美的工作,积极回应建设性的批评,这样下次你就不会犯同样的错误。
做一次事情不会让你变得更好:一致性很重要
虽然10000 小时法则已经被揭穿(事实证明,当你练习时专注,被称为“刻意练习”,至少和你练习多少一样重要)对于在一项任务中积累更多的经验还是有好处的。写作不是一项需要特殊能力的活动,而是一个需要反复掌握的过程。
写作也许从来都不简单,但随着练习,它会变得越来越容易。此外,写作是一个正反馈循环:随着你继续写作,它会变得更容易,你的写作也会变得更好,从而让你想写更多。
我写作的一个重要障碍是开始,我喜欢把它看作是激活能量。随着你写得越来越频繁,开始写作的障碍就越来越低,开始写作所需的摩擦也就越来越少。一旦你开始了,你通常会度过最困难的部分。
如果你坚持写作,你可以把你的心态从“现在我要去让从这个活动中抽出时间来写”转变为“现在我已经完成了这个项目,是时候像往常一样写了。”即使是写失败的项目也会很有价值。对每个项目进行写作强化了这样一个概念,即写作不是一件额外的苦差事,而是数据科学管道的一个关键部分。
写作往往不仅仅意味着分享文章。当你在进行分析时,试着在你的 Jupyter 笔记本上添加更多的文本单元格来解释你的思维过程。这是我最初开始写博客的方式:我开始彻底注释我的笔记本,并意识到写一篇文章只需要多做一点工作。此外,当你开始向你的代码添加解释时,你未来的自己和看你作品的同事会感谢你。
写我的前几篇文章确实感觉像是一件苦差事,但当我习惯了这不会是一次性的事情的想法,它变得容易得多,直到我达到了它是我工作流程中被接受的一部分的地步。习惯极其强大,写作和其他习惯一样都是可以习得的。
头衔在数据科学中毫无意义:不要担心证书
想想你上一次安装 Python 包或者从 GitHub 派生 repo 的时候。你搜索过拥有高等学位的作者吗?你只看了专业软件工程师写的代码吗?当然不是:您甚至在检查作者的证书之前就已经查看了存储库的内容(如果您愿意的话)。
同样的概念也适用于数据科学文章:对它们的评判是基于工作的质量,而不是作者的资历。在互联网上——不管是好是坏——出版没有任何障碍。不需要任何证书,不需要攀登象牙塔,不需要通过考试,也没有门卫阻止您学习和撰写任何数据科学方面的内容。虽然某方面的大学学位是有用的(我有一个机械工程学位,尽管从未使用过,但我并不后悔),但对数据科学做出贡献肯定是不必要的(T2)。
在这篇出色的文章中,专业机器学习研究人员 Rachel Thomas 给出了她的观点,即为什么即使在深度学习中,高级学位也不是必要的。以下是她列出的没有博士学位的深度学习贡献者的部分列表:
A partial list of contributors to deep learning who don’t have a PhD. (Source)
在数据科学中,你获取新知识的能力比你的教育背景更重要。如果你对某个科目没有信心,那么有很多资源可以让你学习你需要知道的东西。我个人可以推荐 Udacity,Coursera,还有 Scikit-Learn 和 TensorFlow 的优秀的动手机器学习作为我最喜欢的资源,但是还有无数其他的。虽然 MOOCS 没有在所有科目上完全“民主化教育”,但它们在数据科学上取得了成功。
不要因为你认为自己没有背景而阻止自己接受一个项目。我最初担心我的资历,但在我从读者的角度思考之后——人们在网上阅读他们的文章之前不会考虑某人的头衔——我发表文章变得容易多了,不用担心我的背景。此外,一旦你意识到你的教育来自哪里并不重要,你会发现学习起来容易得多,因为你可以不再认为正规教育是唯一的信息宝库。对于数据科学,你可以从互联网上了解你需要的一切,通常比你在教室里学到的要快得多。
保持开放的心态也很重要:当我不完全确定我是否使用了正确的方法时,我会在文章中承认,并且我总是欢迎任何纠正。做数据科学没有标准的方法,但是你仍然可以从其他有解决类似问题经验的人那里学到很多。
认识到你可以学习任何必要的东西来独自承担任何数据科学项目,但也要虚心接受建议。
最好的工具是完成工作的工具
Windows vs MacOS。 R vs Python 。崇高 vs 原子 vs 皮查姆。媒体 vs 你自己的博客。这些争论都是无益的。正确的回答是使用任何能让您解决问题的工具(在您的环境范围内)。此外,具有更多选项的工具并不总是更好的。
虽然更多的功能听起来很棒,但它们经常会妨碍你的工作。一般来说,我尽量让事情简单。当人们问我关于写作平台的建议时,我说中等,因为它的功能有限。当我写作时,我想把注意力集中在内容上,而不是花时间试图按照我想要的格式编排每一件事。
更多的定制选项意味着更多的时间来定制这些选项,而更少的时间来做你应该做的事情——写作或编码。
我以前陷入过工具优化循环:我被说服转而使用新技术,花时间学习新功能,却被告知这项技术已经过时,下一个将会让我更有效率。不久前,我停止了 ide(集成开发环境)之间的切换,只选择了 Jupyter + Sublime Text,因为我意识到额外的东西只会妨碍编写代码。
当论点足够有力时,我并不反对转换工具,但是仅仅为了新奇而转换工具并不是提高生产力的良方。如果你真的想开始,挑一叠坚持下去。如果你开始一个项目,并注意到你的工具中缺少一些东西,那么你可以开始寻找你需要的东西。不要轻信承诺更多功能的华而不实的新工具,直到你知道你需要那些功能(这也适用于买车)。换句话说,不要让工作程序的优化妨碍工作。
Choose a strategy and stick with it! (Source)
从哪里获得你的想法:广泛而深入地阅读
伟大的想法不会脱离所有其他想法而自行涌现。相反,它们是通过将旧的概念应用到新的问题中来创造的,混合两种现有的想法,或者改进一个已被证实的设计。想知道该写些什么的最好方法是阅读其他数据科学家正在写的东西。当我陷入一个问题或者需要一些新的写作想法时,我不可避免地开始阅读。
此外,如果你对自己的写作风格不自信,可以从模仿你最喜欢的作家开始。看看他们文章的结构,以及他们如何处理问题,并尝试将相同的框架应用到你的项目和文章中。每个人都必须从某个地方开始,建立在别人的技术上并不可耻。最终你会发展出你自己的写作风格,然后其他人可以适应,等等。
我建议广泛阅读和深入阅读,以平衡探索与开发。探索/利用问题是机器学习中的一个经典,特别是在强化学习中:我们有一个代理需要平衡对环境的更多学习,探索,与选择基于它认为会导致最高回报的行为,利用。
通过广泛阅读,我们探索了数据科学的许多不同领域,通过深入阅读,我们加深了对特定专业领域的理解。你可以通过练习已经掌握的技能——利用——并经常学习新的技能——探索,将这一点应用到你的写作和数据科学中。****
我也喜欢将探索/利用的想法应用于选择数据科学项目。这两个极端都可能导致令人不满意的项目:只根据你过去做过的事情来选择一个项目,你可能会发现它已经过时并失去兴趣。如果你选择了一个你不能应用任何先验知识的项目,那么你可能会感到沮丧并放弃。相反,找一些中间的东西,你知道你可以建立那些你已经拥有的技能,但也需要学习一些新的东西。
我对选择项目的最后建议是从小处着手。项目只会随着你的工作而成长,无论你分配给项目多少时间,它都会花费更长的时间。承担一个完整的机器学习项目可能很诱人,但如果你仍在尝试学习 Python,那么你可能想一次解决一部分。也就是说,如果你有足够的信心承担整个项目,那就去做吧!没有比练习更有效的学习方法了,尤其是把所有的碎片放在一个问题里。
结论
正如任何延迟长期回报的活动一样,写作有时会很困难。尽管如此,还是有一些具体的行动让这个过程变得更容易,并且创造了正反馈循环。写作没有一个秘密,而是一系列的步骤,减少开始写作的摩擦,帮助你坚持下去。当您开始或推进您的数据科学职业生涯时,请记住这些提示,以建立和保持高效的写作习惯。
我欢迎关于写作建议、评论和建设性批评的讨论。可以通过推特 @koehrsen_will 联系到我。
相关性测量实用指南
TLDR: 在大多数情况下,使用肯德尔是最好的选择。
相关性度量
相关性度量用于衡量两个变量之间的相关程度。根据数据类型和用例,可以使用不同种类的相关性度量。一些常见的相关性度量是皮尔逊、斯皮尔曼和肯德尔相关性。在这篇文章中,我将试着简要解释这些工具的作用以及何时使用它们。这些公式可以很容易地在其他地方找到,实现可以在 Pandas 库中找到。
皮尔逊
可以计算两个变量之间的相关程度,但是它假设数据是线性的和同方差的。
- 线性:如果 X,Y 是直线,则 X,Y 是线性的
- 同方差性:X,Y 是同方差的,如果它们来自某个高斯分布。
那是什么意思?用简单实用的观点来说。
使用时
- 数据似乎有一个简单的线性关系(如果有的话)。
- 数据是稳定的(均值、方差等)。不要改变)
- 数据似乎正态分布在一个中间点周围,有一些差异。
- 有一些测试可用于确定数据是否来自正态分布。
不使用时
- 数据是不稳定的
- 数据不是线性相关的
- 如果你把它用于非线性、非高斯数据,它会给出一些读数,但这些不会是可靠的相关性指标。
斯皮尔曼相关
这是一个更稳健的相关性度量,因为它没有对数据的分布做任何假设。然而,它只寻找单调的关系,通常适用于顺序变量。找出学生完成比赛的顺序和他们练习的时间之间的关系。注意,这仅捕获单调关系,如图 1 所示,然而它不能捕获如图 2 所示的非单调相关变量。
Fig 1: Spearman coeff = 1
Fig 2: Spearman coeff = 0
注意:Spearman 相关性有助于确定两个变量是否独立,但是当它们相关时,它不能传达太多信息。
使用时
- 这种关系是单调的(要么总是增加,要么总是减少)
- 变量值的顺序可能是感兴趣的(Spearman rho)
- 有必要检查独立性
肯德尔相关
肯德尔相关性不像 Spearman 那样对数据的分布做任何假设。Spearman 有一个缺陷,即很容易发现是否存在单调相关性,如果存在单调相关性,则值很难解释。另一方面,Kendall 可以量化变量之间的依赖强度。
优点
- 非参数(不假设数据的分布)
- 可用于确定两个变量是否相关
- 可以量化,有多少依赖。
参考
Minitab Express Support 的相关页面
statistics solutions . com 的相关页面
维基百科—皮尔森相关
维基百科—斯皮尔曼相关
Statsdirect —肯德尔相关
维基百科—肯德尔相关
实用强化学习—02 Q-Learning 入门
最简单的 Q 学习入门。浏览器中的代码,未安装:)
Smart Cab — GridWorld
这一次,我们将教会我们的自动驾驶汽车开车送我们回家(橙色节点)。我们必须小心,因为一些街道正在建设中(灰色节点),我们不希望我们的车撞上它。
如你所见,我们有从 0 到 8 的街道。这给了我们 9 个独特的州(街道)。在任何给定的时间,我们的汽车(代理)可以处于这 9 种状态之一。状态 8 是我们的目标,也称为终端状态。
我们的车可以左、右、上、下行驶。换句话说,我们的代理可以采取四种不同的动作。我们把它写成:A∈A {上,下,左,右}
代理因达到终止状态而获得奖励 10,除此之外没有奖励。
Q 学习和 Q 表
现在我们将创建一个矩阵,“Q”也称为 Q-table,这将是我们代理的大脑。矩阵 Q 被初始化为零,因为代理开始时什么都不知道(就像约翰·斯诺;))。当它学习时,它用状态-动作对的新值更新 Q 表。下面是计算 Q[状态,动作]的公式
Q[s,a] = Q[s,a] + alpha(R + gammaMax[Q(s ',A)] - Q[s,a])
哪里;
- alpha 是学习率,
- 伽玛是贴现因子。它量化了我们对未来奖励的重视程度。在未来的奖励中估算噪音也很方便。伽玛从 0 到 1 不等。如果 Gamma 接近于零,代理人将倾向于只考虑直接的回报。如果 Gamma 更接近 1,代理人将考虑更大权重的未来奖励,愿意延迟奖励。
- Max[Q(s ',A)]给出下一状态中所有可能动作的最大 Q 值**。**
代理探索不同的“状态-动作”组合,直到它达到目标或落入洞中。我们将把每一次探索称为集。每次代理到达目标或被终止,我们开始下一集。
Q-table
下面用一些简单的数学来演示 Q-table 是如何更新的:
取学习率(alpha)为 0.5 &折现因子(gamma)为 0.9
Q[s,a] = Q[s,a] + alpha*(R + gammaMax[Q(s ',A)] — Q[s,a])
早期剧集
Q[3,L] = Q[3,L]+0.5(10+0.9Max[Q(8,U) 同样 Q[6,D] = 5
下一集
Q[2,L] = Q[2,L]+0.5(0+0.9*Max[Q(6,U),Q(6,D),Q(6,R),Q(6,L)]-Q(2,L))
Q[2,L] = 0 + 0.5 * (0 + 0.9 * Max [0,5,0,0] -0)
Q[2
勘探与开采—ε(ε)
当代理开始学习时,我们希望它采取随机行动来探索更多的路径。但是随着代理变得更好,Q 函数收敛到更一致的 Q 值。现在,我们希望我们的代理利用具有最高 Q 值的路径,即采取贪婪的行动。这就是艾司隆的用武之地。
智能体对概率 ε 采取随机行动,对概率采取贪婪行动(1-ε)。
Google DeepMind 用了一个衰减的ε-贪婪动作选择。其中ε 随时间从 1 到 0.1 衰减*——开始时,系统完全随机地移动以最大化地探索状态空间,然后它稳定到固定的探索速率。*
q 学习伪代码
是时候动手 Q 学习了
现在继续用 OpenAI 健身房练习 Q-learning。你可以在你的浏览器中使用 azure 笔记本来完成。或者克隆这个 git 回购。
更多资源
强化学习:简介 —第六章:时差学习
大卫·西尔弗的强化学习课程第四讲 —无模型预测
大卫·西尔弗的强化学习课程第五讲 —无模型控制
希望这篇教程对刚接触 Q-learning 和 TD-reinforcement 学习的人有所帮助!
如果你想关注我关于强化学习的文章,请在 Medium Shreyas Gite 或 twitter @shreyasgite 上关注我。
如有任何问题或建议,请随时给我写信:)
更多来自我的实用强化学习系列:
- 强化学习简介
- Q-learning 入门
将风格转移到工作中的实用技巧
不熟悉风格转移的可以看这篇总结风格转移的博文。
作为杰瑞米·霍华德的第二部分课程“程序员的前沿深度学习的参与者,我想建立一个风格转移神经网络,它的性能与 prisma 不相上下(在生成图像的时间和图像质量方面)。该项目涉及许多有趣的挑战(图像质量、推理时间)。
我首先进行了许多实验,看看如何提高生成图像的质量。以下两篇博文详细介绍了这些实验:
这篇博文总结了我从这些实验中学到的东西,并包含了一些更实用的技巧来实现风格的转变。
实际环境中的风格转换
上述两篇博文使用了基于图像优化的方法进行风格转换,即通过最小化损失来学习图像像素。在实际设置中,假设你正在构建一个像 prisma 这样的应用程序,这种技术是没有用的,因为它非常慢。因此,取而代之的是使用基于神经网络的方法,其中训练神经网络从内容图像生成风格化图像。这些是在 AWS p2x.large 实例上使用两种方法对一个 1000x1000 图像所花费的时间:
基于优化的方法(NVIDIA K80 GPU): 172.21 秒
基于神经网络的方法(NVIDIA K80 GPU): 1.53 秒
基于神经网络的方法(英特尔至强 E5–2686 v4):14.32 秒
显然,基于神经网络的方法是这里的赢家。基于神经网络的风格转换只是基于优化的方法的近似,但是要快得多。
要详细了解基于神经网络的方法是如何工作的,您可以阅读以下文章:
基于优化的方法描述于:
提高生成图像的质量
让深度学习变得众所周知困难的一件事是搜索最佳超参数。并且风格转移涉及各种超参数,如使用哪些内容层来计算内容损失、使用哪些风格层来计算风格损失、内容权重(与内容损失相乘的常数)、风格权重(与风格损失相乘的常数)、电视权重(与总变化损失相乘的常数)。幸运的是,在风格转换中找到最佳超参数要容易得多。
简单的窍门是:
不使用基于神经网络的方法来训练和寻找最佳超参数,您可以简单地在您的测试图像上使用基于优化的方法来创建它们的风格化版本和交叉验证。
以下是我从实验中学到的关于如何使用基于图像优化的方法来寻找风格化超参数的一些东西。
1.使输出图像更平滑
总变差损失是输入图像中相邻像素值的绝对差值的总和。这衡量图像中有多少噪声。
如这篇博客文章的中的实验 10 所示,将总变差损失添加到训练损失中去除了图像的粗糙纹理,结果图像看起来更加平滑。
2.选择样式层
在大多数发表的作品中(包括的开创性论文),从网络中选择一些层来计算风格损失,并给予相等的权重。正如我在这篇博文中的实验#1 所示,这没有意义,因为不同层次对风格损失的贡献可能相差很大数量级。为此,我首先从每一层中找出输出,一次一个。然后通过给每一层赋予权重来创建一个组合图像。通过交叉验证可以再次找到权重。
3.选择内容层
与选择样式层的情况不同,选择内容层的组合不会产生太大的差异,因为优化一个内容层的内容丢失会优化所有后续层。使用哪一层可以通过交叉验证再次找到(如这篇博文的的实验#2 所示)。
4.修改损耗网络以改善收敛性
vgg-16/vgg-19 网络(在 imagenet 上预训练)通常用于计算内容损失和样式损失。正如我在这篇博文的的实验 8 中所示,用平均池替换最大池显著减少了收敛时间。
我尝试的另一个改变是,用有效的填充替换相同的填充,但效果并不明显。
5.样式图像的大小和裁剪区域
正如我在这篇博文的实验 4 中所展示的,风格图像的大小很重要。如果您使用的是较小尺寸的样式图像,则网络无法计算出足够的样式信息,并且生成的图像质量较差。根据我的实验,我会说风格图片的尺寸至少应该是每边 512。
如这篇博文的实验 11 所示,风格图像的裁剪区域也很重要,这应该根据包含我们想要的风格化图像中的笔触的区域来选择。
6.选择内容、风格权重和电视权重
这些权重只能通过交叉验证找到。但是这里有几条规则,我遵守了,并且做得很好。
当你开始训练时,首先风格损失迅速降低到某个小值,然后内容损失开始降低,风格损失要么降低得更慢,要么波动。这个内容损失和风格损失减少的图表可以在这篇博文的实验#6 中看到。此时,内容权重应使内容损失明显大于样式损失。否则网络将不会学习任何内容。
电视权重应该是这样的,即在训练的后期迭代中,电视损失是内容损失的一半。这是因为如果电视损耗非常高,图像中相邻物体的颜色会混合在一起,图像质量会很差。
7.选择损耗网络
的实验#3、#4、#5、#6 这篇博文详细介绍了如何通过使用不同的初始网络来生成不同种类的图像。使用盗梦空间网络生成的图像看起来更像蜡笔画。
的实验#5 这篇博文比较了使用 vgg-16 和 vgg-19 生成的图像。我的猜测是,使用 vgg-16 生成的图像也可以使用 vgg-19 生成,只需调整内容和样式损失即可。这是因为从这些网络中产生的仿制品没有太大的不同。使用 vgg 网络生成的图像看起来更像油画。
所以如果你针对的是油画质感,就用 vgg-16 和 vgg-19。如果你的目标是蜡笔纹理,使用任何一个初始网络(交叉验证后)。
改善训练和推理时间
假设您正在尝试 10 种不同的风格转换架构,以找出哪种最有效。加速训练以快速交叉验证你的模型变得非常重要。
如果你是和 Prisma 竞争,你需要保证你的网络的推理时间和他们的不相上下。
以下是我用来提高训练和推理时间的技巧。
1.对训练图像进行下采样
最简单的做法是将图像从 512x512 下采样到 256x256,然后测试生成的图像看起来有多好。它将训练时间减少了 4 倍,但可以很容易地用于寻找最佳网络架构,因为使用 512 生成的图像质量与使用 256 生成的图像质量非常相似。
2.使用深度方向可分离卷积代替卷积
这是改善推断时间的最标准的技巧,其中卷积层被深度方向可分离的卷积代替。这导致计算量显著减少。下面是在 aws p2x 大型实例上使用卷积和深度方向可分离卷积的图像的 CPU 和 GPU 推理时间。
inference times using convolution (in secs)
inference times using separable convolution (in secs)
可以看出,图像的推理时间在 CPU 上大约减半,在 GPU 上减少 5-6 倍。生成的图像质量没有明显差异。
3.对图像进行下采样,最后添加上采样层和卷积层
我尝试了许多非标准的架构变化来减少推理时间。一是减少神经网络的层数。另一个是改变卷积运算(将 filter _ size * filter _ size * in _ depth * out _ depth 卷积转换为 filter _ size * filter _ size * in _ depth * k,然后是 11k*out_depth 卷积,其中 k<<out_depth></out_depth>
有效的技巧是,在将图像输入神经网络之前,通过双线性插值将图像的高度和宽度减半。并添加上采样层,然后在末尾添加卷积层。这样你就是在训练你的神经网络学习风格转移和超分辨率。
为什么会有帮助?与以前的方法相比,所有中间层的计算量减少了 1/4。增加的额外计算是由于一个额外的层和双线性插值。但是他们并没有增加很多时间,净时间要少得多。这些是 aws p2x 大型实例上图像的 CPU 和 GPU 推理时间。
inference times using baseline architecture (in secs)
inference times using the resize trick (in secs)
正如我们所看到的,这大大缩短了 CPU 的推断时间。并且还减少了大多数图像的 GPU 推断时间。
将此与可分离卷积技巧相结合,得到:
inference times using separable convolution and resize trick (in secs)
正如我们所见,结合使用这两种技巧可以将所有图像的 CPU 推断时间减少 3 倍,将 GPU 推断时间减少 8-10 倍。我在手机上运行了同样的神经网络。1000 x 1000 的图像需要 6.5 秒。作为对比,prisma 同样的图像需要 9 秒。
更酷的是。这两个技巧适用于任何图像生成方法,而不仅仅是风格转换。
此外,生成的图像质量是相同的:
image generated using baseline architecture (left) and using separable convolution and resize trick(right)
4.预计算训练数据的内容要素
训练数据中的每个图像都需要通过损失网络。并且一些层的输出将用于计算内容损失。这些内容层输出可以预先计算。这样可以节省训练时间。
以下是预计算和未预计算特征的训练时间:
average time without features precomputed
average time with features precomputed
因此,预计算特性带来了 10%的加速,虽然不是很显著,但已经足够了。所用的内容层是 conv4_1。
这些实验中使用的所有代码都可以从 github 上获得。
如果你喜欢这篇文章,请点击下面的小拍手图标帮助他人找到它。非常感谢!
基于张量流服务的实用文本生成
在这篇文章中,我将讨论深度学习模型通过 Tensorflow 的暴露和服务,同时展示我对灵活实用的文本生成解决方案的设置。
使用文本生成,我打算自动生成可变长度的新的语义有效的文本片段,给定一个可选的种子字符串。这一想法是为了能够利用不同用例的不同模型(Q & A,聊天机器人工具,简化,下一个单词建议),也基于不同类型的内容(例如,叙事,科学,代码),来源或作者。
这是句子建议的第一个预览。
Text generation example using seed text (the selected part in the video) for different training sources (i.e. song lyrics, Bible, Darwin)
这段录音显示了使用三种不同模型的按需文本生成,每种模型都基于不同的种子字符串,在相应的文本源(即歌词、钦定版《圣经》和达尔文的《物种起源》)上进行训练。正如预期的那样,每个模型都反映了原始资料的基调和内容——所有其他潜在的模型都是如此——并显示了其特定用途和场景的潜力,这仍然主要取决于作者的需求和期望。预览还允许获得模型性能的直观感受,暗示哪个模型需要改进以满足定义的需求。
下面的段落将准确地描述我遵循的体系结构方法,以获得第一个和后面的示例背后的文本生成功能的提供和使用。
建筑预览
即使 showcase 的重点是文本生成任务,许多与模型管理相关的内容也可以抽象出来。例如,我们可以确定三个独立的步骤,这些步骤已被证明适用于各种不同的用例及情况:
- **训练:**很多领域里的东西大多都习惯;调查最佳方法,定义架构/算法,处理数据,训练和测试模型。
- **上菜:**将训练好的模型曝光消费
- **消费:**使用暴露的模型从原始数据中获得预测
最后两个步骤之间的区别更加微妙,并且很大程度上取决于工作设置和被识别为*的型号。*对于初学者来说,想想你为训练所做的数据预处理有多少实际上没有嵌入到你使用 Keras(或任何其他库)的实际训练中。所有这些工作只是转移到下一个架构块,但是需要委托给一个消费中间件,这样我们就可以通过一个干净的接口只公开基本的所需功能。
这里是我们的架构步骤和交互的示意图。
培养
我不打算深入研究文本生成训练的技术细节,但是如果感兴趣的话,您可以在这个 Jupyter 笔记本中找到本文的大部分训练代码,以及额外的指针和资源。
服务架构的好处是培训可以与其他组件高度分离。这允许通过提供更好的执行模型来快速、简单和透明地交付改进的版本。更好的训练数据、更可控的训练过程、更复杂算法的实施或新架构的测试,都是可以产生更好的模型的选项,这些模型反过来似乎可以取代当前提供的模型。
关于打破完美解耦的方面,例如考虑以下最紧迫的依赖关系:
- 模型签名(输入/输出形状和类型),客户必须知道并遵循。目前没有办法直接从服务服务器发现这一点,因此需要“手动”保证与训练步骤的一致,以避免错误。一旦定义了一个签名,您就可以为新版本的模型服务,或者测试新的架构,而没有额外的负担,只要它在所有这样的模型中是一致的。
- 培训时操作的前后处理需要在消费层“复制”。
- 前/后处理的外部/附加模型数据(如单词索引)需要提供给消费层,同时保证与培训期间使用的数据一致。
模型
模型是我们训练过程的产物。我们可以首先根据它们的功能(例如分类、文本生成、问答)对它们进行分类,然后根据版本进行分类。
对于我们的文本生成案例,即使基本任务实际上是相同的,我们也可以考虑模型根据它们被训练的文本内容提供不同的功能。在大多数情况下,训练过程/代码实际上是相同的,改变的是所使用的训练数据。然后,版本化将特定于该模型功能和内容,并且可以在最简单的情况下通过沿着多个时期的训练过程的基本快照来确定,或者通过采用或测试新的算法和架构来确定。
这样做的想法是建立一个包含大量模型的中央存储库,可以根据需要添加新训练的版本。
作为一个实际的例子,考虑我的文件夹的这个快照,用于我们的三个模型的基本文本生成,每个模型都有可能有多个服务就绪版本、更细粒度的训练检查点(或快照)选择和单词索引数据。
partial tree of the models folder
服务
模型已经准备好了,我们需要一种方法来服务于它们:让它们可以被有效地使用。
TensorFlow 服务是一种灵活、高性能的机器学习模型服务系统,专为生产环境而设计对于那些已经熟悉 Tensorflow 并且没有心情编写自己的服务架构的人来说,这是一种非常好的直接方法。
它包括基于相关模型目录的自动化模型管理,并通过 GRPC 公开它们。樱桃放在上面,可以很容易的 Dockerized。
model config example
您可以在运行 Tensorflow 服务器的机器上拥有所有模型和相关版本的副本,或者您已经可以根据需要进行过滤,以拥有更轻的服务容器。然后,您可以指定直接运行哪个模型,或者通过启动服务服务器时需要传递的模型配置文件来运行。该文件应该为我们计划公开的所有模型指定一个模型配置列表。
然后,Tf 将负责为每个列出的模型提供服务,并自动管理版本。Tensorflow 将自动获取新版本的插入,而全新模型的注入将需要重新启动服务。
所有这些都可以手动完成,但对于生产设置,人们可能更喜欢开发一个“同步”实用程序,它应该负责从托管训练步骤实际结果的任何外部存储中同步 Tensorflow 服务容器内的模型数据。
强烈的
考虑我们当前的用例:我们想要获得特定类型或特定来源的生成文本,并且可选地以种子文本为条件。不幸的是,纯 Tensorflow 服务端点远没有这么直接。我们不仅需要转换文本(输入和输出),而且我们还必须实现一个生成过程,我们希望在最终的界面中完全透明。所有这些都需要委托给消费者中间件来实现。
这适用于许多其他数据科学场景,在这些场景中,导出的模型实际上只是从原始数据到可用预测的管道中的一部分。正如最初的架构模式中所描述的,将需要一个消费者中间件来填补这个预处理和后处理的空白。对于我们的文本生成案例,这个中间件和相关代码再次在我的 Github 库中定义。它包括一个负责文本预处理和后处理的基本类,一个文本生成过程(建立在多个模型调用和二级需求之上)和一个处理不同模型的代理。
假设所需的依赖关系已经解决,可以直接使用代理,否则我建议进一步简化任务,将所有内容公开为一个真正基本的 REST API:使用 Python 和 Flask ,只需要几行代码。此外,我们所有组件的模块化使得通过 Docker 和 AWS 等技术将解决方案外部化和扩展变得容易。
展示时间!
如何实际利用到目前为止描述的设置纯粹是想象和需求的问题(这篇文章很好地探索了各种形式的机器辅助写作)。最好的方面是,我们现在有了一个灵活的架构,可重用于各种场景,而没有太多额外的操作负担。
我烘焙的第一个实际例子是一个基本的文本编辑器插件,现在我正在积极地使用它。在我的情况下,我依靠崇高 3 和记事本++ T7。一旦我启动并运行了文本生成 API,为前者编写插件就相当简单了;下面实际上是所有需要的代码。
Sublime3 plugin for text-generation via REST API
这里发生的事情是,我自己写一些东西,选择我想用作种子的文本,然后调用首选模型上的生成。这是另一个例子。请再次注意,我在这里依靠三个不同的模型,分别接受了关于歌词的训练,詹姆斯国王版本的圣经和达尔文的物种起源。
text gen on same seed for different models. Again notice the weaker Bible one.
这个“文本应用插件”允许我从内容(完整的句子或单个单词)中获得灵感,否则很少会从我纯粹自发的写作中出现。虽然叙事和诗歌的更具创造性的上下文似乎更好地利用了这一工具,但我经常发现对更正式和“严格”类型的内容也有很好的建议,我相信用于训练的源数据集,同时相信“更有可能意味着正确”。
我正在开发的另一个应用是一个用于聊天和即时消息自动回复的 web 浏览器插件,也是通过简单地利用公开的 REST API。我们将会看到有多少我的朋友能区分我和 RNN。
words suggestion based on the song-lyrics dataset
words suggestion based on Darwin’s On the Origin of Species
结论
基于深度学习的技术的文本生成能力已经得到证明,并且适用于各种不同的用例及场景。在这篇文章中,我展示了一个基于 Tensorflow 的基础架构解决方案如何保证高度的灵活性和有效性,为您的内部作者创建一个实用的小文本生成工具箱。
我还相信,我们很快就会看到对预训练模型的更结构化、更精细和更民主化的访问。一种自助服务存储库——类似于其他流行服务——这样人们可以轻松地即插即用新模型,并将它们直接嵌入到任何选择的环境中,而不必从头开始训练它们。
例如,在本文的上下文中,如果能够访问其他人针对不同任务、文本内容或作者训练的模型,并且能够在一个公共平台或“模型中心”上分享我自己的训练结果,那就太好了。
但现在去;好好利用这些强大的机器来达到你的生产和创造目的;用不了多久,他们就会变得非常聪明,不适合这项任务。
专业数据科学初学者实用技巧。揭穿几个神话!
“A robot named Pepper holding an iPad” by Alex Knight on Unsplash
当我在 2015 年开始我的旅程到我现在的位置时,通过专业经验、MOOCs 和在线社区,我学到了很多东西。我认为是时候开始回报数据科学世界了,我以一些我觉得有必要谈论的事情开始了我的博客系列。
这篇文章特别针对那些刚开始数据科学职业生涯(或转投 it 行业)并且对与职业经历相关的一些事实有偏见/不了解的人。
1.黑客马拉松没有教会你的事情——定义问题
大多数人热衷于将机器学习算法应用于已经给出的原始(实际上并不那么原始)数据集,并给出明确的问题陈述。他们通常听起来像这样—“XYZ 公司希望自动化他们的贷款审批流程。使用给定的训练数据,您能识别分类和预测贷款批准的重要因素吗?请注意,评估您的标准是准确性"。这些问题陈述不知不觉地简化了某些事情,如定义问题、获得最终数据集、确定评估指标等。但在现实世界中,情况并非如此。
“记住,你 60%以上的时间都花在了识别/定义问题、集思广益和获取相关数据上。”
要开始解决这个问题——找到开源数据集,提出你的假设,问问自己这个数据集能解决什么问题,想想你可能用什么其他相关数据来解决这个问题。您可能最终会使用带有一些漂亮可视化效果的 t-test 来解决您的问题:)
2.SQL——最被低估的工具
SQL 对于数据科学就像高塔姆·甘比尔对于印度板球一样。如果你没有一个好的开始,你会在比赛中挣扎,但是,有时候,你会被胜利的 76 人遗忘。
毕竟 SQL 是用来取一些数据的。但是想象一下,您在客户级别的数据集上做了整个建模练习,意识到由于数据争论期间的一些错误的“SQL 连接”,数据有客户重复。“重复”是数据获取时的一个主要问题,这可能是因为您的 SQL 代码或后端数据库中的问题。在 SQL 数据争论的每一步之后,都需要进行彻底的质量评估,因为**“没有语法错误的执行并不意味着它按照你想要的方式执行。”**
对于初学者来说,大多数参考资料教授的是基本的 SQL,重点是语法部分,SQL 逻辑如此简单的观念变得越来越普遍,经常被忽视。我建议你选择一个不同主题(航空、电子商务、零售等)的关系数据库(一套 3-10 个表)。)并问一些棘手的业务问题。这将需要执行几个 SQL 块,并将充分测试您的技能。
3.r 还是 Python?两个都学。
已经有很多关于这个主题的博客,如果你读了其中的一些,Python 将会是赢家(以微弱优势)。我不想讨论每种方法的利弊,也不想决定什么,但是,我建议你学习两种方法,并在其中一种方法上获得专业知识。
比方说,RaceR 先生被介绍给 r。在他的旅程中,他喜欢 dplyr 的直观性,他觉得 ggplot2 是继他的女朋友和他的一行花式决策树情节之后的下一个美丽的东西。突然有一天,他接到了他梦想中的公司的面试电话,有一个绝佳的机会。但他知道的唯一令人心碎的事情是,那里的人觉得熊猫很可爱,他们通过 matplotlib 生成报告,并在云 GPU 上运行基于 Jupyter 笔记本的深度学习模型。他觉得他整个余生都是谎言。虽然我把这个故事戏剧化了,但寓意是学习并适应这两者,直到切换变得相当容易(可能是因为工作变化、客户需求、运行时数据问题、更好的包/模块可用性等)。毕竟,语言只是完成事情的工具。你永远不知道还有第三种语言在等着打破风暴。
仅供参考——我喜欢 R,因为我一开始就喜欢它:)
4.先学传统的机器学习,再开始深度学习
我这样建议是因为两个主要原因。第一,你应该喜欢探索未知的数据。结构化数据将是开始的最佳方式,该过程涉及双变量分析、测试一些假设、缺失值处理、异常值识别等。第二——您将经历变量选择、特性工程、参数调整以及最后检查模型变量的业务含义的迭代过程。另一方面,在深度学习中,网络架构负责大多数特征工程部分,超参数调整成为该过程中必不可少的一部分。此外,向业务涉众解释模型是项目不可或缺的一部分,因此,ML 模型在变量重要性方面的直观性(如逻辑回归、决策树)使其成为许多行业中最受欢迎的选择(对于结构化数据)。
5.并不是每个问题都以建立模型告终
是的,重读一遍。
数据科学的艺术不在于构建最佳模型,而在于将数据作为资产来解决问题
还有许多其他传统的方法和技术在行业中广泛使用。
仪表板和报告 —这些是许多业务不可或缺的一部分,涉及使用 SQL 创建自动化数据管道、与利益相关者进行头脑风暴以了解 KPI、用强烈的视觉美感叙述故事
实验设计 —了解特定服务/活动/促销的效果总是至关重要的,衡量它们的影响对于做出关键决策也变得至关重要。测试控制分析,A/B 测试通常用于量化这种影响
对数据进行分段,直到您能够 —通过适当设计的 EDA 和分段,可以快速解决某些问题
对于初学者,我会建议你选择感兴趣的领域,找到相关的数据集(电影、体育等)。创建 Tableau/RShiny 公共仪表板时要记住两件事。信息流动得有多好,图表描述这些信息有多容易。此外,阅读案例研究,重点是设计和制定解决某些问题的方法。
6.不要被可用的资源淹没
是的,在某个时间点,你会迷失在数据科学的数字学习世界中。这并不意味着你必须完成所有的课程才能成为专家。为了摆脱这种偏见并获得持续的学习体验,你应该根据你的学习风格和动机来创建你的学习路径和设定原则。
- 第一,知道自己想采取什么样的方式;自上而下或自下而上。我属于前一种类型的人,希望在应用理论知识之前了解足够多的理论知识,但这完全取决于个人
- 根据目标和上述选择的方法准备学习路线
- 一次做一件事,完成它。让它成为 Coursera 上的一门课程,Kaggle 上的一个项目,或者创建你的 tableau 仪表盘
- 为每一次学习做笔记
- 坚持每天读一篇博客的目标。记下两件你可以带回家的东西
- 最后,一致性是关键
非常感谢你一直读到最后。如果你喜欢,请点击拍手,如果你有什么要说的,请在下面发表评论。它会帮我完善我的帖子:)
这个帖子是基于我到目前为止的职业经验。如果你有任何反馈或主要的补充,你想指出给初学者,请随时发表意见。
在 LinkedIn 上联系我:www.linkedin.com/in/muralimohanakrishnadandu
二进制分类中类别不平衡的实用技巧
0.简介和动机
二元分类问题可以说是机器学习中最简单和最直接的问题之一。通常我们想学习一个模型,试图预测某个实例是否属于某个类。它有许多实际应用,从垃圾邮件检测到医学测试(确定患者是否患有某种疾病)。
稍微正式一点,二进制分类的目标是学习一个函数f(x),该函数将 x (一个实例/例子的特征向量)映射到预测的二进制结果 ŷ (0 或 1)。大多数分类算法,例如逻辑回归、朴素贝叶斯和决策树,输出属于正类的实例的概率:Pr(y= 1 |x)。
类别不平衡是指在一个分类问题中,类别没有被平等地表示,这在实践中是很常见的。例如,欺诈检测、罕见药物不良反应预测和基因家族预测(如激酶、GPCR)。未能解决类别不平衡通常会导致许多分类算法的预测性能不准确和下降。在这篇文章中,我将介绍一些关于如何在二进制分类中克服类不平衡的实用技巧,其中大部分可以很容易地适应多类场景。
1.分层很重要!
首先,您需要对数据进行分层,以便进行训练和验证。分层是一种基于样本类别平均分配样本的技术,以便训练集和验证集具有相似的类别比例。
确保您的训练集和验证集共享来自每个类的大约相同比例的示例是非常重要的,这样您就可以在两个集中获得一致的预测性能分数。一些分类算法对它们被训练的数据的类别比率也极其敏感。例如,朴素贝叶斯分类器使用它从训练数据中的类比率中学习的类先验来进行预测。训练集和验证集之间类比率的较大差异导致类先验估计不准确,降低了朴素贝叶斯分类器的预测性能。类似地,k-最近邻也受到这个问题的困扰,因为它只是记住了用于训练的所有数据点,这几乎肯定会在推理阶段从训练数据中搜索 k-最近邻时引入源于类别不平衡的偏差。
scikit-learn 有一个分层的实现[StratifiedKFold](http://scikit-learn.org/stable/modules/generated/sklearn.model_selection.StratifiedKFold.html)
将其放入代码中:
然后,我们可以比较分层和随机交叉验证(CV)的得分,这通常会对对类别不平衡敏感的分类器产生影响:
2.二元分类的性能度量
有许多度量来评估二元分类器在预测实例/例子的分类标签方面做得有多好。下面是一些关于选择和解释适当指标的警告和建议。
- 准确性可能会误导人。因为准确性是简单的正确预测的实例与用于评估的所有实例的比率,所以有可能获得相当好的准确性,同时对于少数类具有大多数不正确的预测。
ACC: Accuracy, TP: True Positive, TN: True Negative
- 混淆矩阵有助于分解不同类别的预测性能。
-
基于二分的度量(精确度、召回率、F1 分数等。)默认情况下,计算两个类的平均分数。也许对许多人来说并不明显,人们实际上可以得到每门课的分数细目。在这种情况下,
[classification_report](http://scikit-learn.org/stable/modules/generated/sklearn.metrics.classification_report.html)
函数非常有用: -
对于不平衡数据,推荐使用精确召回曲线而非 ROC 曲线。如下图所示,ROC 曲线可能高估了不平衡数据上分类器的性能,而 PR 曲线揭示了不平衡数据在相同召回水平下的精度下降。本文详细讨论了如何选择合适的分类标准。
Fig. 4. Graphical representation of classifier performance avoids setting an exact threshold on results but may be insensitive to important aspects of the data. (from Lever et al. (2016) Nat Methods)
3.重新采样以获得更平衡的数据
既然我们已经知道了如何设置评估方案,以及为不平衡数据的分类问题选择什么度量标准,我们就可以继续应用一些技术来解决类别不平衡问题。最直接的方法是通过重采样来平衡数据:
- 向下采样(欠采样)多数类
- 向上采样(过采样)少数类
- 许多更高级的采样技术,如合成少数过采样技术(SMOTE) ( Chawla 等人, 2012 ),在不平衡学习库中实现
重采样技术可以与诸如随机森林的 Bagging 集合模型相结合。Bagging 代表 bootstrap-aggregation,它们通过在构建单个估计器(通常是决策树)时引导数据来工作,然后聚合单个估计器的预测。由于自举(带替换的随机采样)本质上是一种重采样技术,我们可以用其他重采样技术(如下采样或上采样)来替换自举,以平衡数据。
下面是一些实现随机森林的核心 Python 代码,带有上/下采样。实现重采样森林的完整代码可以在这里找到。
接下来,我们可以比较随机森林在不同重采样技术下的性能。该图表明上采样和下采样都提高了随机森林对不平衡数据的预测性能。
Performance of Random Forest coupled with different resampling techniques on imbalanced dataset.
4.类别加权/成本敏感学习
在不重新采样数据的情况下,还可以通过将类的权重合并到成本函数(也称为目标函数)中来使分类器意识到不平衡的数据。直觉上,我们想给少数类更高的权重,给多数类更低的权重。scikit-learn 有一个方便的实用函数,可以根据课程频率计算权重:
**from** sklearn.utils.class_weight **import** compute_class_weight
class_weights = compute_class_weight('balanced', np.unique(y), y)
交叉熵是许多二元分类算法(如逻辑回归)的成本函数的常见选择。交叉熵被定义为:
交叉熵=ylog(p)——(1—y)log(1—p)
其中 y 是类别二进制指示符(0 或 1 ), p 是例如属于类别 1 的预测概率。为了将两个类别(0 和 1)的权重合并到交叉熵中,可以定义一个加权交叉熵:
,其中 w_0 和 w_1 分别是类 1 和类 0 的权重。可以使用[tf.nn.weighted_cross_entropy_with_logits](https://www.tensorflow.org/api_docs/python/tf/nn/weighted_cross_entropy_with_logits)
在 Tensorflow 中实现类权重。在 Keras 中,class_weight
可以在训练时作为参数传递给模型的fit
方法。将来我会在 Tensorflow 和 Keras 中实现代价敏感分类器的例子。
也可以通过在许多 scikit-learn 分类器(如支持向量机(SVM)和随机森林)中设置class_weight
参数来实现敏感学习。
Classification boundaries for cost-sensitive and cost-insensitive linear SVM
- 在随机森林中:
class_weight='balanced'
:使用 y 值自动调整输入数据中与类别频率成反比的权重class_weight='balanced_subsample'
:与“平衡”相同,只是权重是根据每棵生长的树的 bootstrap 样本计算的。
5.梯度推进
一些分类模型内置了对抗类别不平衡的方法。例如,梯度推进机器(GBM)通过基于错误分类的例子构建连续的训练集来处理类别不平衡。在不平衡数据集上,它通常优于随机森林:
Comparing GBM with Random Forests (RF) with different balancing techniques on imbalanced dataset. 20 trees are grown for every ensemble model.
我希望这些提示有助于改进不平衡数据集的分类模型。我的 GitHub 上有本教程的 Jupyter 笔记本版本:
二进制分类中类别不平衡的 Jupyter 笔记本演示
github.com](https://github.com/wangz10/class_imbalance)
感谢阅读!
练习 AI 的团队不知道偏见
人工智能设计 2018 报告,第 1 部分
我们总是试图向学术界和工业界的其他人学习。单独研究成 AI,机器学习,深度学习等。自 1996 年以来增加了 9 倍。我们想知道当将这些技术应用于人们的问题时,行业中的其他人在做什么,并导致我们创建了“人工智能设计”调查。
起初,我们真的专注于设计方面,并想知道其他团队是如何做的。超过 18 个问题(平均每个回答约 7 分钟)我们深入到人们如何在构建人工智能的团队中工作。我们会发现对 UX 设计的关注较少,而对团队沟通的关注较多。
你可以在这里看到整个报告:
今天,团队被推至包括人工智能(AI)、机器学习(ML)、深度学习(DL)和…
哲学是](https://philosophie.is/design-for-ai-report-2018)
虽然在报告中有很多有趣的信息,但我想进一步探讨一些要点,并提供一些我们必须解决它们的建议。特别是,我想谈谈结盟,沟通,以及在构建人工智能项目时,团队应该更多地关注什么。
最具影响力
调查的影响部分旨在了解人们在构建人工智能系统时在哪里花费脑力。“数据可用性”和“数据清洁度”在影响中排名靠前是有道理的。关于全套因素请查看报告。
没有影响力
最低的影响因素是“伦理”和“法律”业内一直在讨论道德问题,以及当出现不良人类后果时,工程师应该如何更好地考虑这一问题。然而,我不确定这是思考这个问题的正确方式。伦理显然是人类的问题,而不是机器的问题。为什么我们认为工程师不会像他们团队中的其他人一样关注道德?法律是一个很好的例子,说明公司已经有了相关的专家:律师。
最具争议
我们想知道什么是有争议的,所以我们计算了在没有/低影响和一些/高影响之间总体上最接近零的那些。
最让我着迷的是“假阳性/假阴性”和“最坏结果”当处理这些系统的非确定性方面时,我们并不总是知道它将如何失败。由于这一事实,我本以为审议会更加一致。我们发现像混淆映射这样的练习可以帮助每个人在这些问题上达成共识。
最不为人知
最后,一个最少被考虑的因素(大多数“不知道”的回答)今天得到了很多媒体的关注:“偏见。”与伦理不同,偏见是机器知道的东西。他们可以分析识别人类偏见的模式。
我们使用的数据集将严重影响我们系统中的偏差量。机器学习可能是一种可以帮助我们检测和纠正它的机制(正如在深度领域混淆:最大化领域不变性中所讨论的)。
最大的问题是,团队甚至不知道偏见是否应该影响他们的人工智能项目。他们甚至没有进行对话。
接下来是什么:更多的对话
需要就所有这些因素进行更多的对话,尤其是那些没有被提及的因素。
在接下来的两篇文章中,我们将讨论如何在技术和非技术团队成员之间进行讨论,以及如何实现这一点的一些案例研究。
我们如何让包括顾客在内的每个人都有一席之地?
关于克里斯·巴特勒
我帮助团队理解他们应该用以人工智能为中心的解决方案解决的真正的商业问题。我们工作的团队通常被要求用他们拥有的数据“做一些有趣的事情”。我们通过偶发事件相关性帮助他们避免局部极值,并专注于解决巨大的业务问题。我的背景包括在微软、KAYAK 和 Waze 等公司超过 18 年的产品和业务开发经验。在 Philosophie,我创造了像机器移情映射和混淆映射这样的技术,以在构建人工智能产品时创建跨团队对齐。如果你想了解更多或通过电子邮件联系,LinkedIn 或访问 http://philosophie.is/human-centered-ai。
自然语言机器学习中的预处理
我们很容易忘记我们每天的对话中存储了多少数据。随着数字景观的演变,挖掘文本或自然语言处理(NLP)是人工智能和机器学习中一个不断增长的领域。本文涵盖了应用于 NLP 问题的常见预处理概念。
文本可以有多种形式,从单个单词的列表,到句子,再到包含特殊字符的多个段落(比如 tweets)。像任何数据科学问题一样,理解被问的问题将告知可以采用什么步骤来将单词转换为与机器学习算法一起工作的数字特征。
不良贷款的历史
当我还是个孩子的时候,科幻小说几乎总是有一台电脑,你可以吠叫命令,让他们理解,有时,但不总是,执行。当时,这项技术似乎还很遥远,但今天我口袋里装着一部手机,它比任何人想象的都要小,而且功能更强大。语音转文本的历史复杂而漫长,但却是 NPL 的萌芽。
早期的努力需要大量手工编码的词汇和语言规则。1954 年在乔治敦大学首次实现的从英语到俄语的自动翻译仅限于少数几个句子。
1964 年,第一个聊天机器人伊莱扎在麻省理工学院诞生。它建立在模式匹配和替代的基础上,通过提出开放式问题来模拟治疗过程。虽然它似乎复制了意识,但它没有真正的对话背景。尽管能力有限,许多人还是对这种人性化的互动感到惊讶。
该领域的大部分发展实际上始于 20 世纪 80 年代,当时引入了机器学习算法。研究人员从更严格的转换语法模型转向了在缓存语言模型中描述的更宽松的概率关系,这允许更快速的缩放,并更轻松地处理不熟悉的输入。
整个 90 年代,计算能力的指数级增长推动了科技的进步,但直到 2006 年 IBM 的沃森(Watson)上了《危险边缘》(Jeopardy)节目,公众才看到计算机智能的进步。对我来说,是 2011 年 iPhone 引入 Siri 让我意识到了它的潜力。
当前的 NLP 前景很容易成为它自己的文章。私营公司前所未有的投资和普遍的开源态度已经扩展了一些很大程度上为更多的受众和应用所专有的东西。一个有趣的例子是在翻译领域,谷歌正在努力翻译任何语言(即使用户体验中的一些错误需要解决)。
[## 谷歌的即时翻译 Pixel Buds 是其迄今为止最令人难以置信的版本
谷歌昨天宣布了许多激动人心的发布,但也许最激动人心的当然是…
betanews.com](https://betanews.com/2017/10/05/google-pixel-buds/)
预处理的重要性
如果没有大量的后端工作,上面描述的魔术就不会发生。将文本转换成某种算法可以消化的东西是一个复杂的过程。有四个不同的部分:
- 清理包括通过去除停用词来去除文本中不太有用的部分,处理大写和字符以及其他细节。
- 注释包括对文本应用一个方案。注释可能包括结构标记和词性标注。
- 标准化包括通过词干化、词汇化和其他形式的标准化来翻译(映射)方案中的术语或语言简化。
- 分析包括对数据集进行统计探测、操作和归纳,以进行特征分析。
工具
有多种预处理方法。下面的列表并不全面,但它确实给出了从哪里开始的想法。重要的是要认识到,就像所有的数据问题一样,将任何东西转换成机器学习的格式都会将其简化为一种一般化的状态,这意味着在此过程中会损失一些数据的保真度。真正的艺术是了解每一种方法的利弊,从而谨慎地选择正确的方法。
资本化
文本常常有各种反映句子开头、专有名词强调的大写形式。为了简单起见,最常见的方法是将所有内容都简化为小写,但重要的是要记住,一些单词,如“us”到“US”,在简化为小写时可能会改变含义。
无用词
给定文本中的大多数单词是句子的连接部分,而不是显示主语、宾语或意图。像“the”或“and”这样的词可以通过将文本与停用词列表进行比较来删除。
IN:
['He', 'did', 'not', 'try', 'to', 'navigate', 'after', 'the', 'first', 'bold', 'flight', ',', 'for', 'the', 'reaction', 'had', 'taken', 'something', 'out', 'of', 'his', 'soul', '.']OUT:
['try', 'navigate', 'first', 'bold', 'flight', ',', 'reaction', 'taken', 'something', 'soul', '.']
在上面的例子中,它将 23 个单词减少到了 11 个,但是需要注意的是,单词“not”被删除了,这取决于我在做什么,这可能是一个大问题。根据所需的敏感度,用户可以手动创建自己的停用词词典或利用预建的库。
标记化
标记化描述了将段落分割成句子,或者将句子分割成单个单词。对于前一个句子,可以应用边界歧义消除 (SBD)来创建单个句子的列表。这依赖于预先训练的语言特定算法,如 NLTK 的 Punkt 模型。
通过类似的过程,可以将句子拆分成单个单词和标点符号。最常见的是这种跨越空格的拆分,例如:
IN:"He did not try to navigate after the first bold flight, for the reaction had taken something out of his soul."OUT:['He', 'did', 'not', 'try', 'to', 'navigate', 'after', 'the', 'first', 'bold', 'flight', ',', 'for', 'the', 'reaction', 'had', 'taken', 'something', 'out', 'of', 'his', 'soul', '.']
当一个单词被缩写、删节或被所有格时,这有时会引起问题。专有名词在使用标点符号的情况下也会受到影响(比如奥尼尔)。
词性标注
理解词类对确定句子的意思有很大的影响。词性(POS)通常需要查看前面和后面的单词,并结合基于规则或随机的方法。然后,它可以与其他过程相结合,以实现更多的功能工程。
IN:
['And', 'from', 'their', 'high', 'summits', ',', 'one', 'by', 'one', ',', 'drop', 'everlasting', 'dews', '.']OUT:
[('And', 'CC'),
('from', 'IN'),
('their', 'PRP$'),
('high', 'JJ'),
('summits', 'NNS'),
(',', ','),
('one', 'CD'),
('by', 'IN'),
('one', 'CD'),
(',', ','),
('drop', 'NN'),
('everlasting', 'VBG'),
('dews', 'NNS'),
('.', '.')]Definitions of Parts of Speech
('their', 'PRP$') PRP$: pronoun, possessive
her his mine my our ours their thy your
堵塞物
很多自然语言机器学习都是关于文本的情感。词干化是通过去掉不必要的字符(通常是后缀)来去除词尾变化,从而将单词简化为词根的过程。有几个词干模型,包括波特和雪球。结果可用于识别大型数据集之间的关系和共性。
IN:
["It never once occurred to me that the fumbling might be a mere mistake."]OUT:
['it', 'never', 'onc', 'occur', 'to', 'me', 'that', 'the', 'fumbl', 'might', 'be', 'a', 'mere', 'mistake.'],
显而易见,缩减可能会产生一个不是真正单词的“根”单词。这不一定会对其效率产生负面影响,但如果像“universe”和“university”这样的词被简化为“univers”的同一个词根,就有“越界”的危险。
词汇化
词干变化是从词干变化到消除词形变化的另一种方法。通过确定词性和利用 WordNet 的英语词汇库,词汇化可以得到更好的结果。
The stemmed form of leafs is: leaf
The stemmed form of leaves is: leavThe lemmatized form of leafs is: leaf
The lemmatized form of leaves is: leaf
Lemmazation 是一个更密集,因此更慢的过程,但更准确。词干在数据库查询中可能更有用,而词汇化在试图确定文本情感时可能工作得更好。
计数/密度
也许特征工程的更基本的工具之一,增加字数、句子数、标点数和行业特定的字数可以极大地帮助预测或分类。有多种统计方法,其相关性严重依赖于上下文。
单词嵌入/文本向量
单词嵌入是将单词表示为向量的现代方法。单词嵌入的目的是将高维单词特征重新定义为低维特征向量。换句话说,它表示 X 和 Y 向量坐标上的单词,其中基于关系语料库的相关单词被更紧密地放置在一起。 Word2Vec 和 GloVe 是最常见的将文本转换为矢量的模型。
结论
虽然这远不是一个全面的列表,但准备文本是一门复杂的艺术,需要在给定数据和问题的情况下选择最佳的工具。许多预建的库和服务可以提供帮助,但有些可能需要手动映射术语和单词。
一旦数据集准备就绪,就可以应用有监督和无监督的机器学习技术。从我最初的实验(这将是我自己的文章)来看,对单个字符串应用预处理技术与对大型数据帧应用预处理技术有很大的不同。调整步骤以获得最佳效率将是面对扩展保持灵活性的关键。
如果你喜欢这篇文章,请鼓掌,如果你有兴趣看更多关于自然语言处理的文章,请关注!
额外资源
自然语言处理是计算机科学、人工智能和计算科学的一个领域
en.wikipedia.org](https://en.wikipedia.org/wiki/Natural_language_processing) [## 理解和实现自然语言处理的终极指南(带 Python 代码)
根据行业估计,只有 21%的可用数据以结构化形式存在。正在生成数据…
www.analyticsvidhya.com](https://www.analyticsvidhya.com/blog/2017/01/ultimate-guide-to-understand-implement-natural-language-processing-codes-in-python/) [## 深入 NLTK,第一部分:NLTK 入门
第一部分:NLTK 入门(本文)第二部分:句子标记化和单词标记化第三部分:词性…
textminingonline.com](http://textminingonline.com/dive-into-nltk-part-i-getting-started-with-nltk) [## 当帕里遇到伊莱扎时:1972 年的一段可笑的聊天机器人对话
他们可能没有通过图灵测试,但他们赢得了这场古怪之战。
www.theatlantic.com](https://www.theatlantic.com/technology/archive/2014/06/when-parry-met-eliza-a-ridiculous-chatbot-conversation-from-1972/372428/)
使用 InsightR R 包进行沉淀
使用 Insight API 的好处之一是数据的质量和分辨率。大多数气象 API 依赖于一个点观测系统。这意味着当你询问你所在地的天气时,你实际上可能得到的是 20 英里外某个地方的天气。这对于很多用例来说是好的,但是对于其他用例来说就很糟糕了。降水是这种方法失败的一个常见用例:相隔几英里的两个站点收到的总降雨量相差很大的情况并不少见。
Insight API 建立在我们的 SkyWise 数据之上,而不是仅仅依赖于观察站点。这些数据是通过运行一个集成了观测站、卫星和雷达的 1 公里模型产生的。你可以在下图中看到它的好处。如果你依靠一个点观测系统,你可能在你的位置有大雨,而观测站什么也没有收到,反之亦然。
我一直在听新闻报道说俄克拉荷马州中部需要降雨,所以我决定借此机会做一个小项目。
我决定在 R 做这个项目作为学习练习。我的第一步是实际学习一些 r。我从 Rkoans 项目开始,并修复了所有的测试。在编写了一些示例代码之后,我认为一个包是合适的。我发现希拉里·帕克的这个关于创建 R 包的很好的参考。接下来我开始阅读 Hadley Wickham 的一些优秀教程,尤其是编写 API 包装器的最佳实践。完成后,让我们看看如何用它来测量降水量。
首先,我们需要安装软件包:
devtools::install_github('wdtinc/InsightR')
加载后,您需要存储您的认证凭证(免费演示注册):
Authenticate('your_app_id', 'your_app_key')
然后,只需调用包装函数:
dp <- DailyPrecipitation(35.235762, -97.428966, "2017-05-01", "2017-06-13")
假设一切顺利,我们就可以得到总降雨量并绘制数据:
> dp$response$status_code == 200
[1] TRUE
> x <- as.Date(dp$content$series[[1]], "%Y-%m-%d")
> y <- dp$content$series[[3]]
> sum(y)
[1] 39.44
> plot(x,y, xlab="date", ylab="precip in mm")
让我们与几英里外的一个地点进行比较:
> dp <- DailyPrecipitation(35.183235, -97.437611, "2017-05-01", "2017-06-13")
> x <- as.Date(dp$content$series[[1]], "%Y-%m-%d")
> y <- dp$content$series[[3]]
> sum(y)
[1] 77.19
77.19mm vs 39.44mm 就差几里!
在一开始对 R 的语法有点反感之后,我发现自己真的很喜欢写 R 代码。尤其是 RStudio。包装器有点不完整:它缺少文档和测试,并且它目前不支持 Insight API 的“资产”特性,该特性允许您检索字段级轮廓。也就是说,基本级别的功能已经存在,希望有些人会发现它很有用。
用 R 预测客户流失
Photo credit: Pixabay
对于任何一家定期计费的服务公司来说,一个关键的变量就是流失率。《哈佛商业评论》2016 年 3 月
对于这个“即服务”的世界中几乎所有的成长型公司来说,两个最重要的指标是客户流失率和终身价值。创业者,2016 年 2 月
介绍
当客户或订户停止与公司或服务做生意时,就会发生客户流失,也称为客户流失。它也被称为失去客户或顾客。流失率特别有用的一个行业是电信业,因为大多数客户在一个地理位置内有多种选择。
类似于预测员工流动的概念,我们将使用电信数据集预测客户流失。我们将介绍逻辑回归、决策树和随机森林。但这一次,我们将在 r 中完成上述所有工作。让我们开始吧!
数据预处理
数据是从 IBM 样本数据集下载的。每行代表一个客户,每列包含该客户的属性:
library(plyr)
library(corrplot)
library(ggplot2)
library(gridExtra)
library(ggthemes)
library(caret)
library(MASS)
library(randomForest)
library(party)churn <- read.csv('Telco-Customer-Churn.csv')
str(churn)
Figure 1
- customerID
- 性别(女性、男性)
- 老年人(无论客户是否是老年人(1,0))
- 合作伙伴(无论客户是否有合作伙伴(是,否))
- 家属(客户是否有家属(是,否))
- 任期(客户在公司工作的月数)
- 电话服务(无论客户是否有电话服务(是,否))
- 多条线路(客户是否有多条线路(是,否,无电话服务)
- 互联网服务(客户的互联网服务提供商(DSL、光纤、否)
- 在线安全(客户是否有在线安全(是,否,无互联网服务)
- 在线备份(无论客户是否有在线备份(是,否,无互联网服务)
- 设备保护(客户是否有设备保护(是,否,无互联网服务)
- 技术支持(无论客户是否有技术支持(是,否,无互联网服务)
- 流媒体电视(客户是否有流媒体电视(是,否,无互联网服务)
- 流媒体电影(无论客户是否有流媒体电影(是,否,无互联网服务)
- 合同(客户的合同期限(逐月、一年、两年)
- 无纸账单(无论客户是否有无纸账单(是,否))
- 付款方式(客户的付款方式(电子支票、邮寄支票、银行转账(自动)、信用卡(自动)))
- 月度费用(每月向客户收取的金额—数字)
- 总费用(向客户收取的总额——数字)
- 客户流失(客户是否流失(是或否))
原始数据包含 7043 行(客户)和 21 列(特性)。“客户流失”专栏是我们的目标。
我们使用 sapply 来检查每一列中是否有缺失值。我们发现“总费用”列中有 11 个缺失值。因此,让我们删除所有缺少值的行。
sapply(churn, function(x) sum(is.na(x)))
Figure 2
churn <- churn[complete.cases(churn), ]
看变量,可以看到我们有些扯皮要做。
- 我们将六个栏目的“无互联网服务”改为“无”,它们是:“在线安全”、“在线备份”、“设备保护”、“技术支持”、“流媒体电视”、“流媒体电影”。
cols_recode1 <- c(10:15)
for(i in 1:ncol(churn[,cols_recode1])) {
churn[,cols_recode1][,i] <- as.factor(mapvalues
(churn[,cols_recode1][,i], from =c("No internet service"),to=c("No")))
}
2.我们将把“多线”栏中的“无电话服务”改为“无”
churn$MultipleLines <- as.factor(mapvalues(churn$MultipleLines,
from=c("No phone service"),
to=c("No")))
3.由于最短任期为 1 个月,最长任期为 72 个月,我们可以将他们分为五个任期组:“0-12 个月”、“12-24 个月”、“24-48 个月”、“48-60 个月”、“60 个月以上”
min(churn$tenure); max(churn$tenure)
【1】1
【1】72
group_tenure <- function(tenure){
if (tenure >= 0 & tenure <= 12){
return('0-12 Month')
}else if(tenure > 12 & tenure <= 24){
return('12-24 Month')
}else if (tenure > 24 & tenure <= 48){
return('24-48 Month')
}else if (tenure > 48 & tenure <=60){
return('48-60 Month')
}else if (tenure > 60){
return('> 60 Month')
}
}churn$tenure_group <- sapply(churn$tenure,group_tenure)
churn$tenure_group <- as.factor(churn$tenure_group)
4.将“老年人”列中的值从 0 或 1 更改为“否”或“是”。
churn$SeniorCitizen <- as.factor(mapvalues(churn$SeniorCitizen,
from=c("0","1"),
to=c("No", "Yes")))
5.删除分析中不需要的列。
churn$customerID <- NULL
churn$tenure <- NULL
探索性数据分析和特征选择
数值变量之间的相关性
numeric.var <- sapply(churn, is.numeric)
corr.matrix <- cor(churn[,numeric.var])
corrplot(corr.matrix, main="\n\nCorrelation Plot for Numerical Variables", method="number")
Figure 3
每月费用和总费用是相互关联的。因此其中一个将从模型中移除。我们取消所有指控。
churn$TotalCharges <- NULL
分类变量柱状图
p1 <- ggplot(churn, aes(x=gender)) + ggtitle("Gender") + xlab("Gender") +
geom_bar(aes(y = 100*(..count..)/sum(..count..)), width = 0.5) + ylab("Percentage") + coord_flip() + theme_minimal()
p2 <- ggplot(churn, aes(x=SeniorCitizen)) + ggtitle("Senior Citizen") + xlab("Senior Citizen") +
geom_bar(aes(y = 100*(..count..)/sum(..count..)), width = 0.5) + ylab("Percentage") + coord_flip() + theme_minimal()
p3 <- ggplot(churn, aes(x=Partner)) + ggtitle("Partner") + xlab("Partner") +
geom_bar(aes(y = 100*(..count..)/sum(..count..)), width = 0.5) + ylab("Percentage") + coord_flip() + theme_minimal()
p4 <- ggplot(churn, aes(x=Dependents)) + ggtitle("Dependents") + xlab("Dependents") +
geom_bar(aes(y = 100*(..count..)/sum(..count..)), width = 0.5) + ylab("Percentage") + coord_flip() + theme_minimal()
grid.arrange(p1, p2, p3, p4, ncol=2)
Figure 4
p5 <- ggplot(churn, aes(x=PhoneService)) + ggtitle("Phone Service") + xlab("Phone Service") +
geom_bar(aes(y = 100*(..count..)/sum(..count..)), width = 0.5) + ylab("Percentage") + coord_flip() + theme_minimal()
p6 <- ggplot(churn, aes(x=MultipleLines)) + ggtitle("Multiple Lines") + xlab("Multiple Lines") +
geom_bar(aes(y = 100*(..count..)/sum(..count..)), width = 0.5) + ylab("Percentage") + coord_flip() + theme_minimal()
p7 <- ggplot(churn, aes(x=InternetService)) + ggtitle("Internet Service") + xlab("Internet Service") +
geom_bar(aes(y = 100*(..count..)/sum(..count..)), width = 0.5) + ylab("Percentage") + coord_flip() + theme_minimal()
p8 <- ggplot(churn, aes(x=OnlineSecurity)) + ggtitle("Online Security") + xlab("Online Security") +
geom_bar(aes(y = 100*(..count..)/sum(..count..)), width = 0.5) + ylab("Percentage") + coord_flip() + theme_minimal()
grid.arrange(p5, p6, p7, p8, ncol=2)
Figure 5
p9 <- ggplot(churn, aes(x=OnlineBackup)) + ggtitle("Online Backup") + xlab("Online Backup") +
geom_bar(aes(y = 100*(..count..)/sum(..count..)), width = 0.5) + ylab("Percentage") + coord_flip() + theme_minimal()
p10 <- ggplot(churn, aes(x=DeviceProtection)) + ggtitle("Device Protection") + xlab("Device Protection") +
geom_bar(aes(y = 100*(..count..)/sum(..count..)), width = 0.5) + ylab("Percentage") + coord_flip() + theme_minimal()
p11 <- ggplot(churn, aes(x=TechSupport)) + ggtitle("Tech Support") + xlab("Tech Support") +
geom_bar(aes(y = 100*(..count..)/sum(..count..)), width = 0.5) + ylab("Percentage") + coord_flip() + theme_minimal()
p12 <- ggplot(churn, aes(x=StreamingTV)) + ggtitle("Streaming TV") + xlab("Streaming TV") +
geom_bar(aes(y = 100*(..count..)/sum(..count..)), width = 0.5) + ylab("Percentage") + coord_flip() + theme_minimal()
grid.arrange(p9, p10, p11, p12, ncol=2)
Figure 6
p13 <- ggplot(churn, aes(x=StreamingMovies)) + ggtitle("Streaming Movies") + xlab("Streaming Movies") +
geom_bar(aes(y = 100*(..count..)/sum(..count..)), width = 0.5) + ylab("Percentage") + coord_flip() + theme_minimal()
p14 <- ggplot(churn, aes(x=Contract)) + ggtitle("Contract") + xlab("Contract") +
geom_bar(aes(y = 100*(..count..)/sum(..count..)), width = 0.5) + ylab("Percentage") + coord_flip() + theme_minimal()
p15 <- ggplot(churn, aes(x=PaperlessBilling)) + ggtitle("Paperless Billing") + xlab("Paperless Billing") +
geom_bar(aes(y = 100*(..count..)/sum(..count..)), width = 0.5) + ylab("Percentage") + coord_flip() + theme_minimal()
p16 <- ggplot(churn, aes(x=PaymentMethod)) + ggtitle("Payment Method") + xlab("Payment Method") +
geom_bar(aes(y = 100*(..count..)/sum(..count..)), width = 0.5) + ylab("Percentage") + coord_flip() + theme_minimal()
p17 <- ggplot(churn, aes(x=tenure_group)) + ggtitle("Tenure Group") + xlab("Tenure Group") +
geom_bar(aes(y = 100*(..count..)/sum(..count..)), width = 0.5) + ylab("Percentage") + coord_flip() + theme_minimal()
grid.arrange(p13, p14, p15, p16, p17, ncol=2)
Figure 7
所有的分类变量似乎有一个合理的广泛分布,因此,他们都将被保留,以供进一步分析。
逻辑回归
首先,我们将数据分成训练集和测试集:
intrain<- createDataPartition(churn$Churn,p=0.7,list=FALSE)
set.seed(2017)
training<- churn[intrain,]
testing<- churn[-intrain,]
确认分割正确:
dim(training); dim(testing)
【1】492419
【1】2108 19
拟合逻辑回归模型:
LogModel <- glm(Churn ~ .,family=binomial(link="logit"),data=training)
print(summary(LogModel))
Figure 8
特征分析:
前三个最相关的功能包括合同,任期 _ 组和无纸账单。
anova(LogModel, test="Chisq")
Figure 9
分析偏差表,我们可以看到每次增加一个变量时偏差的下降。加入互联网服务、合同和保有权组显著降低了剩余偏离度。其他变量如 PaymentMethod 和 Dependents 对模型的改善似乎较小,尽管它们都具有较低的 p 值。
评估逻辑回归模型的预测能力
testing$Churn <- as.character(testing$Churn)
testing$Churn[testing$Churn=="No"] <- "0"
testing$Churn[testing$Churn=="Yes"] <- "1"
fitted.results <- predict(LogModel,newdata=testing,type='response')
fitted.results <- ifelse(fitted.results > 0.5,1,0)
misClasificError <- mean(fitted.results != testing$Churn)
print(paste('Logistic Regression Accuracy',1-misClasificError))
【1】Logistic 回归精度 0.789373814041746
逻辑回归混淆矩阵
print("Confusion Matrix for Logistic Regression"); table(testing$Churn, fitted.results > 0.5)
Figure 10
赔率比
逻辑回归中一个有趣的性能测量是优势比。基本上,比值比是一个事件发生的概率。
library(MASS)
exp(cbind(OR=coef(LogModel), confint(LogModel)))
Figure 11
决策树
决策树可视化
为了便于说明,我们将只使用三个变量来绘制决策树,它们是“合同”、“任期 _ 组”和“无纸账单”。
tree <- ctree(Churn~Contract+tenure_group+PaperlessBilling, training)
plot(tree)
Figure 12
- 在我们使用的三个变量中,合同是预测客户流失与否的最重要变量。
- 如果客户是一年期或两年期合同,无论他(她)是否有纸质账单,他(她)都不太可能流失。
- 另一方面,如果客户签订的是逐月合同,租期为 0-12 个月,并且使用无纸化账单,那么该客户更有可能流失。
决策树混淆矩阵
我们使用所有变量来制作混淆矩阵表并做出预测。
pred_tree <- predict(tree, testing)
print("Confusion Matrix for Decision Tree"); table(Predicted = pred_tree, Actual = testing$Churn)
Figure 13
决策树精度
p1 <- predict(tree, training)
tab1 <- table(Predicted = p1, Actual = training$Churn)
tab2 <- table(Predicted = pred_tree, Actual = testing$Churn)
print(paste('Decision Tree Accuracy',sum(diag(tab2))/sum(tab2)))
【1】决策树准确率 0.780834914611006
决策树的准确性几乎没有提高。让我们看看使用随机森林是否能做得更好。
随机森林
随机森林初始模型
rfModel <- randomForest(Churn ~., data = training)
print(rfModel)
Figure 14
预测“否”时错误率相对较低,预测“是”时错误率高得多。
随机森林预测和混淆矩阵
pred_rf <- predict(rfModel, testing)
caret::confusionMatrix(pred_rf, testing$Churn)
Figure 15
随机森林错误率
plot(rfModel)
Figure 16
我们用这个图来帮助我们确定树的数量。随着树的数量增加,OOB 错误率降低,然后变得几乎恒定。我们不能在大约 100 到 200 棵树后降低 OOB 错误率。
调整随机森林模型
t <- tuneRF(training[, -18], training[, 18], stepFactor = 0.5, plot = TRUE, ntreeTry = 200, trace = TRUE, improve = 0.05)
Figure 17
我们用这个图来给我们一些选择项目数量的想法。当 mtry 为 2 时,OOB 误码率最低。因此,我们选择 mtry=2。
调整后拟合随机森林模型
rfModel_new <- randomForest(Churn ~., data = training, ntree = 200, mtry = 2, importance = TRUE, proximity = TRUE)
print(rfModel_new)
Figure 18
OOB 误差率从图 14 的 20.61%下降到 20.41%。
随机森林预测和调优后的混乱矩阵
pred_rf_new <- predict(rfModel_new, testing)
caret::confusionMatrix(pred_rf_new, testing$Churn)
Figure 19
与图 15 相比,精确度和灵敏度都得到了提高。
随机森林特征重要性
varImpPlot(rfModel_new, sort=T, n.var = 10, main = 'Top 10 Feature Importance')
Figure 20
摘要
从上面的例子,我们可以看到,逻辑回归,决策树和随机森林可以用于客户流失分析这一特定的数据集一样好。
在整个分析过程中,我学到了几件重要的事情:
- 诸如使用权组、合同、无纸账单、月费和互联网服务等功能似乎在客户流失中发挥了作用。
- 性别和客户流失之间似乎没有关系。
- 月结合同、无单据账单且任期在 12 个月以内的客户更有可能流失;另一方面,拥有一年或两年合同、超过 12 个月任期、不使用无纸化计费的客户不太可能流失。
创建这篇文章的源代码可以在这里找到。我将很高兴收到关于上述任何反馈或问题。
使用深度学习预测黑色星期五的客户购买量
也许机器学习在零售业中最明显的应用之一是预测顾客在商店可能会花多少钱。这种预测器对店主具有明显的商业价值,因为它将有助于他们的财务规划、库存管理、营销和广告。
Analytics Vidhya 提供了一个关于黑色星期五顾客购买模式的很好的数据集。我是通过阅读由 Phani Srikanth 撰写的帖子来了解数据集的。Phani 很好地解释了他如何使用随机森林和 XGBoost 构建预测器。我决定将深度学习模型应用于该问题,并看看它们的表现如何。
问题陈述
这个数据集的优点是它简单明了的特性。图 1 显示了训练数据集的快照。
Figure 1: A snapshot of the Black Friday dataset.
目标是在给定所有其他特征的情况下预测购买字段。大多数特性都是不言自明的。最后三个描述了产品的可能分类。我用 0 替换了这三个字段中缺少的值。完整的描述。
数据探索
我在本笔记本中描述了对数据集的详细探索性分析。这些信息包括:
- 这个数据集中有 50 多万行
- 几乎所有的列都代表分类特征
- 产品类别 2 和 3 有许多缺失值,现在表示为类别 0
- 用数字而不是用类别来表示停留在当前城市的年数可能会有用。
- 特征交叉有很大的实验空间。例如年龄×婚姻状况或性别×职业
- 分别有 5891 和 3623 个不同的用户和产品 id。所以这两个特性都可以从嵌入中受益。
黑色星期五预测者
深度神经网络在正确选择超参数和网络架构以及一些特征工程的情况下表现良好。使用深度学习的数据科学家知道,需要大量的实验才能找出最佳配方。
虽然模型设计因问题而异,但建模、训练、评估和部署深度神经网络的整个过程都非常标准。因此,已经开发了一些框架来自动化这一过程并隐藏其复杂性。对于这个问题,我将使用谷歌的框架 Tensorflow,这是建立可扩展和高效的深度学习模型的最佳工具之一。
使用 Tensorflow,我构建了黑色星期五预测器应用,允许其用户针对这一特定问题快速构建和测试深度神经网络模型。使用该应用程序,您可以指定架构、超参数,甚至使用单个命令来试验特征交叉。然后,您可以使用 tensor board(tensor flow 的另一个强大功能)来比较您的模型,并找出最佳候选对象。要安装和使用该应用程序,请遵循这些说明。
特征工程和建筑
安装应用程序后,创建一个新的目录来存储模型
mkdir my-project
cd my-project
现在你可以开始实验了!
首先,我们将开始训练一个简单的模型,作为我们其余实验的基线。应用程序自带的默认值应该足够了。使用默认值训练模型相当于运行以下命令
train --model-name baseline \--estimator-type DNN_REG \--indicators "Age" "Gender" "Occupation" "City_Category" "Stay_In_Current_City_Years" "Marital_Status" "Product_Category_1" \--embeddings '{"Product_ID":4, "User_ID":4}' \--hidden-units 100 200 100 \--training-steps 10000
请注意,此模型省略了 Product_Category_2 和 Product_Category_3 列,没有通过功能交叉构建任何新功能,并且具有相对较少的隐藏单元和仅 3 个隐藏层。尽管如此,它应该提供一个良好的基线,并快速训练。
训练完成后,你应该会发现两个新目录:my-project
中的savedmodels
和tensorboard
目录
要了解您的第一个模型的表现,让我们使用 tensorboard
tensorboard --logdir tensorboard
Figure 2: Average loss of the baseline model (tensorboard visualization)
对于基线来说还不错!如果你检查 tensorboard 上的均方根误差(RMSE)部分,你应该看到一个 2780 的 RMSE。RMSE 是我们用来比较模型的指标。RMSE 越低,模型越好。
我们有许多方法可以进一步调整模型,使其做得更好。我们可以研究如何表示我们的特征(特征工程),修改模型的架构,或者改进训练。在这篇博文中,我们将重点讨论前两类。
让我们从试验我们的特性开始。该应用程序旨在使这一过程变得非常简单。这样,我们就专注于实验背后的逻辑,而不是代码。
我们可以做的第一个改进是增加 User_ID 和 Product_ID 列的嵌入维度。每个的默认值是 4 维。让我们试着把这个数字提高到 100(我自己做了几次实验后得出了这个值)。
train --model-name emb_100 \--estimator-type DNN_REG \--indicators "Age" "Gender" "Occupation" "City_Category" "Stay_In_Current_City_Years" "Marital_Status" "Product_Category_1" \--embeddings '{"Product_ID":100, "User_ID":100}' \--hidden-units 100 200 100 \--training-steps 10000
注意,我给了这个模型一个描述性的名字。这在 tensorboard 中比较不同模型时非常有用。运行此命令,将训练一个新模型,将其存储在“savedmodels”目录中,并将事件文件写入tensorboard
Figure 3: RMSE of the embed_100 model vs baseline models (tensorboard visualization)
不错!我们的 RMSE 仅仅通过改变嵌入维数就下降了 40 点。为自己尝试一些价值观,不断尝试。
我们可以通过一起创建新功能来进一步改进我们的模型。这可以通过将特征组合在一起(特征交叉)来实现。有很多方法可以做到这一点,所以检查探索性分析笔记本以获得更多的细节。一个有趣的特征是年龄和婚姻状况。让我们试试看
train --model-name emb_100_ageXms \--estimator-type DNN_REG \--indicators "Age" "Gender" "Occupation" "City_Category" "Stay_In_Current_City_Years" "Marital_Status" "Product_Category_1" \--embeddings '{"Product_ID":100, "User_ID":100}' \--crossings '["Age", "Marital_Status", "ind", 1000]' \--hidden-units 100 200 100 \--training-steps 10000
有关 crossing 参数的更多详细信息,请查看应用程序文档和 tensorflow 功能专栏教程。
现在让我们看看我们的新功能如何改进我们的结果
Figure 4: Feature crossing age and marital status improves lowers RMSE (tensorbaord visualization)
好多了!将年龄与婚姻状况交叉确实产生了一个具有新信息的特征。我在探索性分析笔记本中提供的跨越这些特性的推理只是一个例子。我们不能真正说出这些特征之间存在什么潜在的关系,但是我们知道它是有效的。
让我们试试另一个?这一次,我将跨越性别和职业
train --model-name emb_100_ageXms_gendXocc \--estimator-type DNN_REG \--indicators "Age" "Gender" "Occupation" "City_Category" "Stay_In_Current_City_Years" "Marital_Status" "Product_Category_1" \--embeddings '{"Product_ID":100, "User_ID":100}' \--crossings '["Age", "Marital_Status", "ind", 1000]' '["Gender", "Occupation", "ind", 1000]' \--hidden-units 100 200 100 \--training-steps 10000
像往常一样,我们用 tensorboard 找出新模型与其他模型的比较
Figure 5: Feature crossing gender and occupation barely adds any value to our model(tensorbaord visualization)
啊!不是一个令人印象深刻的结果。好了,不要气馁,继续尝试自己的特色穿越组合。思考推理和潜在的关系。当你想出一个有趣的组合时,一定要让我知道!
现在,我们转到改进模型的第二种方法:修改架构。到目前为止,我们使用了默认的简单架构,它由一个 3 层网络组成,每个网络上有 100、200、100 个单元。让我们通过增加一层来加深我们的网络,并将每层的单元数量增加两倍。
train --model-name deeper_model \--estimator-type DNN_REG \--indicators "Age" "Gender" "Occupation" "City_Category" "Stay_In_Current_City_Years" "Marital_Status" "Product_Category_1" \--embeddings '{"Product_ID":100, "User_ID":100}' \--crossings '["Age", "Marital_Status", "ind", 1000]' '["Gender", "Occupation", "ind", 1000]' \--hidden-units 200 400 400 100 \--training-steps 10000
请注意,我们可以通过修改一行代码来做到这一点(嗯,还可以修改模型的名称,但这不算数!) .现在运行命令,看看这个模型是如何执行的。
Figure 6: Adding an extra hidden layer and increasing the number of neurons per layer lowers RMSE further (tensorboard visualization)
更好!这仅仅是通过加深网络和增加更多的神经元。其他更复杂的方法可能会进一步提高性能。请注意,训练时间将显著增加,因为我们增加了可训练变量(参数)的数量。
结论
黑色星期五预测器是一个 tensorflow 应用程序,允许您快速方便地为黑色星期五数据集设计和训练深度学习模型。特征工程和模型架构可以提高模型的性能,但是需要大量的实验来找出最佳方案。现在,您已经知道如何使用该应用程序,并且从探索性分析中对数据集有了很好的直觉,请继续亲自尝试,让我们看看您可以将 RMSE 分数降低多少。玩得开心!
用 Python 预测员工流动率
“大数据可以让公司识别出预测自己队伍中人员流动的变量。”《哈佛商业评论》2017 年 8 月
“员工流失分析是评估员工流动率的过程,旨在预测未来并减少员工流失。”福布斯 2016 年 3 月
介绍
本文展示了一个员工离职分析项目的参考实现,该项目是使用 Python 的 Scikit-Learn 库构建的。在本文中,我们介绍了逻辑回归,随机森林和支持向量机。我们还测量通过使用机器学习建立的模型的准确性,并评估进一步发展的方向。我们将用 Python 来完成以上所有的工作。我们开始吧!
数据预处理
数据是从 Kaggle 下载的。这很简单。每行代表一名员工,每列包含员工属性:
- 满意度 _ 级别(0–1)
- last_evaluation(自上次评估以来的时间,以年为单位)
- number_projects(工作时完成的项目数)
- 平均每月小时数(工作场所平均每月小时数)
- time_spend_company(在公司工作的时间,以年为单位)
- 工作事故(员工是否发生工作场所事故)
- 离开(无论员工是否离开工作场所(1 或 0))
- promotion_last_5years(员工在过去五年中是否得到晋升)
- 销售(他们工作的部门)
- 工资(相对工资水平)
import pandas as pd
hr = pd.read_csv('HR.csv')
col_names = hr.columns.tolist()
print("Column names:")
print(col_names)print("\nSample data:")
hr.head()
栏目名称:
[‘满意度 _ 等级’,‘上次 _ 评估’,‘人数 _ 项目’,‘平均 _ 月 _ 小时’,‘时间 _ 花费 _ 公司’,‘工作 _ 事故’,‘离职’,‘促销 _ 上次 _ 5 年’,‘销售’,‘薪资’]
样本数据:
Figure 1
将列名从“销售”重命名为“部门”
hr=hr.rename(columns = {'sales':'department'})
列的类型如下所示:
hr.dtypes
Figure 2
我们的数据非常干净,没有缺失值
hr.isnull().any()
Figure 3
该数据包含 14,999 名员工和 10 项功能
hr.shape
(14999,10)
“左”列是记录 1 和 0 的结果变量。1 为离职员工,0 为未离职员工。
数据集的部门列有许多类别,为了更好地建模,我们需要减少类别。“部门”列有以下类别:
hr['department'].unique()
数组([‘销售’,‘会计’,‘人力资源’,‘技术’,‘支持’,‘管理’,【T25 ‘,’ IT ',‘产品 _mng ‘,‘营销’,’ RandD’],dtype =对象)
让我们将“技术”、“支持”和“IT”结合在一起,称之为“技术”。
import numpy as np
hr['department']=np.where(hr['department'] =='support', 'technical', hr['department'])
hr['department']=np.where(hr['department'] =='IT', 'technical', hr['department'])
更改后,部门类别的外观如下:
【‘销售’ ‘会计’ ‘人力资源’ ‘技术’ ‘管理’ '产品 _ mng ‘】
【市场营销’ '随机】】
数据探索
首先,让我们找出离开公司和没有离开公司的员工人数:
hr['left'].value_counts()
Figure 4
剩下 3571 名员工,11428 名员工留在我们的数据中。
让我们来了解一下这两个类别的数字:
hr.groupby('left').mean()
Figure 5
几种观察:
- 留在公司的员工的平均满意度高于离开公司的员工。
- 离开公司的员工平均每月工作时间比留下来的员工多。
- 发生工伤事故的员工比没有发生工伤事故的员工更不容易离职。
- 与过去五年中没有获得晋升的员工相比,过去五年中获得晋升的员工离职的可能性更小。
我们可以计算分类变量(如部门和工资)的分类平均值,以获得更详细的数据,如下所示:
hr.groupby('department').mean()
Figure 6
hr.groupby('salary').mean()
Figure 7
数据可视化
让我们将数据可视化,以便更清楚地了解数据和重要特征。
条形图为部门员工工作争取和离职频率
%matplotlib inline
import matplotlib.pyplot as plt
pd.crosstab(hr.department,hr.left).plot(kind='bar')
plt.title('Turnover Frequency for Department')
plt.xlabel('Department')
plt.ylabel('Frequency of Turnover')
plt.savefig('department_bar_chart')
Figure 8
很明显,员工流动的频率在很大程度上取决于他们工作的部门。因此,部门可以很好地预测结果变量。
员工薪资水平和离职频率条形图
table=pd.crosstab(hr.salary, hr.left)
table.div(table.sum(1).astype(float), axis=0).plot(kind='bar', stacked=True)
plt.title('Stacked Bar Chart of Salary Level vs Turnover')
plt.xlabel('Salary Level')
plt.ylabel('Proportion of Employees')
plt.savefig('salary_bar_chart')
Figure 9
员工流动的比例在很大程度上取决于他们的工资水平;因此,工资水平可以是预测结果的一个很好的预测因素。
在探索阶段,直方图通常是我们可以用于数值变量的最有用的工具之一。
数值变量直方图
num_bins = 10hr.hist(bins=num_bins, figsize=(20,15))
plt.savefig("hr_histogram_plots")
plt.show()
Figure 10
为分类变量创建虚拟变量
数据集中有两个分类变量(部门、薪水),它们需要转换成虚拟变量才能用于建模。
cat_vars=['department','salary']
for var in cat_vars:
cat_list='var'+'_'+var
cat_list = pd.get_dummies(hr[var], prefix=var)
hr1=hr.join(cat_list)
hr=hr1
一旦创建了虚拟变量,就需要删除实际的分类变量。
为分类变量创建虚拟变量后的列名:
hr.drop(hr.columns[[8, 9]], axis=1, inplace=True)
hr.columns.values
数组([‘满意度 _ 等级’,‘上次 _ 评价’,‘人数 _ 项目’,
‘平均 _ 月 _ 小时’,‘时间 _ 花费 _ 公司’,
‘离职’,‘晋升 _ 最近 _ 5 年’,‘部门 _ 随机’,
‘部门 _ 会计’,‘部门 _ 人力资源’,‘部门 _ 管理’,【T26’部门 _ 营销’,
‘部门 _ 产品 _ 管理’,【部门 _ 销售’,【部门 _ 技术】,【薪资 _ 高】,
'薪资 _ 薪资
结果变量为“左”,其他变量均为预测变量。
hr_vars=hr.columns.values.tolist()
y=['left']
X=[i for i in hr_vars if i not in y]
特征选择
递归特征消除(RFE) 的工作原理是递归地移除变量,并在剩余的变量上建立模型。它使用模型精度来确定哪些变量(和变量组合)对预测目标属性贡献最大。
让我们使用特征选择来帮助我们决定哪些变量是重要的,可以非常准确地预测员工流动率。X 总共有 18 列,选 10 列怎么样?
from sklearn.feature_selection import RFE
from sklearn.linear_model import LogisticRegressionmodel = LogisticRegression()rfe = RFE(model, 10)
rfe = rfe.fit(hr[X], hr[y])
print(rfe.support_)
print(rfe.ranking_)
***【真真假假真真假假真真假假真真假假
【1 1 3 9 1 1 1 1 1 1 1 5 1 1 6 8 7 4 1 1 2】***
您可以看到 RFE 为我们选择了 10 个变量,它们在 support_ 数组中标记为 True,在 ranking_ 数组中标记为 choice“1”。它们是:
[‘满意度 _ 等级’,‘上次 _ 评价’,‘时间 _ 花费 _ 公司’,‘工作 _ 事故’,‘晋升 _ 最近 _ 5 年’,‘部门 _ 随机’,‘部门 _ 人力资源’,‘部门 _ 管理’,‘薪资 _ 高’,‘薪资 _ 低’]
cols=['satisfaction_level', 'last_evaluation', 'time_spend_company', 'Work_accident', 'promotion_last_5years',
'department_RandD', 'department_hr', 'department_management', 'salary_high', 'salary_low']
X=hr[cols]
y=hr['left']
逻辑回归模型
from sklearn.cross_validation import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=0)from sklearn.linear_model import LogisticRegression
from sklearn import metrics
logreg = LogisticRegression()
logreg.fit(X_train, y_train)
LogisticRegression(C = 1.0,class_weight=None,dual=False,fit_intercept=True,intercept_scaling=1,max_iter=100,multi_class='ovr ',n_jobs=1,penalty='l2 ',random_state=None,solver='liblinear ',tol=0.0001,verbose=0,warm_start=False)
from sklearn.metrics import accuracy_score
print('Logistic regression accuracy: {:.3f}'.format(accuracy_score(y_test, logreg.predict(X_test))))
逻辑回归精度:0.771
随机森林
from sklearn.ensemble import RandomForestClassifier
rf = RandomForestClassifier()
rf.fit(X_train, y_train)
RandomForestClassifier(bootstrap = True,class_weight=None,criterion='gini ',max_depth=None,max_features='auto ',max_leaf_nodes=None,min _ infinity _ split = 1e-07,min_samples_leaf=1,min_samples_split=2,min_weight_fraction_leaf=0.0,n _ estimators = 10,n_jobs=1,oob_score=False,random_state=None,verbose=0,warm _ start = False)【T24
print('Random Forest Accuracy: {:.3f}'.format(accuracy_score(y_test, rf.predict(X_test))))
随机森林精度:0.978
支持向量机
from sklearn.svm import SVC
svc = SVC()
svc.fit(X_train, y_train)
SVC(C=1.0,cache_size=200,class_weight=None,coef0=0.0,
decision _ function _ shape = None,degree=3,gamma='auto ',kernel='rbf ',
max_iter=-1,probability=False,random_state=None,shrinking=True,
tol=0.001,verbose=False)
print('Support vector machine accuracy: {:.3f}'.format(accuracy_score(y_test, svc.predict(X_test))))
支持向量机精度:0.909
获胜者是… 随机森林 对吧?
交互效度分析
交叉验证试图避免过度拟合,同时仍然为每个观察数据集生成预测。我们使用 10 重交叉验证来训练我们的随机森林模型。
from sklearn import model_selection
from sklearn.model_selection import cross_val_score
kfold = model_selection.KFold(n_splits=10, random_state=7)
modelCV = RandomForestClassifier()
scoring = 'accuracy'
results = model_selection.cross_val_score(modelCV, X_train, y_train, cv=kfold, scoring=scoring)
print("10-fold cross validation average accuracy: %.3f" % (results.mean()))
十重交叉验证平均准确率:0.977
平均精度保持非常接近随机森林模型精度;因此,我们可以得出结论,该模型具有良好的通用性。
精确度和召回率
我们构建混淆矩阵来可视化分类器做出的预测,并评估分类的准确性。
随机森林
from sklearn.metrics import classification_report
print(classification_report(y_test, rf.predict(X_test)))
Figure 11
y_pred = rf.predict(X_test)
from sklearn.metrics import confusion_matrix
import seaborn as sns
forest_cm = metrics.confusion_matrix(y_pred, y_test, [1,0])
sns.heatmap(forest_cm, annot=True, fmt='.2f',xticklabels = ["Left", "Stayed"] , yticklabels = ["Left", "Stayed"] )
plt.ylabel('True class')
plt.xlabel('Predicted class')
plt.title('Random Forest')
plt.savefig('random_forest')
Figure 12
逻辑回归
print(classification_report(y_test, logreg.predict(X_test)))
Figure 13
logreg_y_pred = logreg.predict(X_test)
logreg_cm = metrics.confusion_matrix(logreg_y_pred, y_test, [1,0])
sns.heatmap(logreg_cm, annot=True, fmt='.2f',xticklabels = ["Left", "Stayed"] , yticklabels = ["Left", "Stayed"] )
plt.ylabel('True class')
plt.xlabel('Predicted class')
plt.title('Logistic Regression')
plt.savefig('logistic_regression')
Figure 14
支持向量机
print(classification_report(y_test, svc.predict(X_test)))
Figure 15
svc_y_pred = svc.predict(X_test)
svc_cm = metrics.confusion_matrix(svc_y_pred, y_test, [1,0])
sns.heatmap(svc_cm, annot=True, fmt='.2f',xticklabels = ["Left", "Stayed"] , yticklabels = ["Left", "Stayed"] )
plt.ylabel('True class')
plt.xlabel('Predicted class')
plt.title('Support Vector Machine')
plt.savefig('support_vector_machine')
Figure 16
当一名员工离职时,我的分类器多久能正确预测一次?这种测量被称为“召回”,快速浏览这些图表可以证明随机森林显然最适合这一标准。在所有的周转案例中,random forest 在 1038 个案例中正确检索了 991 个案例。这转化为约 95% (991/1038)的周转“召回”,远好于逻辑回归(26%)或支持向量机(85%)。
当一个分类器预测一个员工将离开时,这个员工实际上多久离开一次?这种测量称为“精度”。随机森林再次以大约 95%的精度(1045 中的 991)优于其他两个,逻辑回归为大约 51%(540 中的 273),支持向量机为大约 77%(1150 中的 890)。
ROC 曲线
from sklearn.metrics import roc_auc_score
from sklearn.metrics import roc_curvelogit_roc_auc = roc_auc_score(y_test, logreg.predict(X_test))
fpr, tpr, thresholds = roc_curve(y_test, logreg.predict_proba(X_test)[:,1])rf_roc_auc = roc_auc_score(y_test, rf.predict(X_test))
rf_fpr, rf_tpr, rf_thresholds = roc_curve(y_test, rf.predict_proba(X_test)[:,1])plt.figure()
plt.plot(fpr, tpr, label='Logistic Regression (area = %0.2f)' % logit_roc_auc)
plt.plot(rf_fpr, rf_tpr, label='Random Forest (area = %0.2f)' % rf_roc_auc)
plt.plot([0, 1], [0, 1],'r--')
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.05])
plt.xlabel('False Positive Rate')
plt.ylabel('True Positive Rate')
plt.title('Receiver operating characteristic')
plt.legend(loc="lower right")
plt.savefig('ROC')
plt.show()
Figure 17
受试者操作特征(ROC) 曲线是二进制分类器使用的另一个常用工具。虚线代表纯随机分类器的 ROC 曲线;一个好的分类器尽可能远离那条线(朝向左上角)。
随机森林模型的特征重要性
feature_labels = np.array(['satisfaction_level', 'last_evaluation', 'time_spend_company', 'Work_accident', 'promotion_last_5years',
'department_RandD', 'department_hr', 'department_management', 'salary_high', 'salary_low'])
importance = rf.feature_importances_
feature_indexes_by_importance = importance.argsort()
for index in feature_indexes_by_importance:
print('{}-{:.2f}%'.format(feature_labels[index], (importance[index] *100.0)))
晋升 _ 最后 _ 5 年-0.20%
部门 _ 管理-0.22%
部门 _ 人力资源-0.29%
部门 _ 随机-0.34%
薪资 _ 高-0.55%
薪资 _ 低-1.35%
工作 _ 意外-1.46%
最后 _ 评估-19.19%
时间 _ 花费 _ 公司-25.77
根据我们的随机森林模型,上面以升序显示了影响员工是否会离开公司的最重要的特征。
摘要
这就把我们带到了文章的结尾。我不打算打印出模型预测他们可能会辞职的员工名单。这不是本分析的目的。记住我们不可能有一个适用于所有人的算法。员工离职分析可以帮助指导决策,但不能做出决策。小心使用分析以避免法律问题和员工的不信任,并结合员工反馈使用它们,以做出最佳决策。
创建这篇文章的源代码可以在这里找到。我将很高兴收到关于上述任何反馈或问题。