TowardsDataScience 博客中文翻译 2020(七十六)

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

一种简单的卡尔曼滤波实现

原文:https://towardsdatascience.com/a-simple-kalman-filter-implementation-e13f75987195?source=collection_archive---------15-----------------------

一个储罐液位测量应用程序,帮助你开发卡尔曼滤波器的直觉

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

泰勒·尼克斯在 Unsplash 上的照片

传感器本身并不能解决您的测量问题。它们本质上很吵,这可能会导致严重的问题。例如,当用作 PID 控制器的输入时,噪声数据可能会产生单位脉冲——高频信号的导数变得无穷大,导致执行器饱和,过程控制穿过窗口。

另一种需要准确性的情况是批量转移。在这种情况下,供应商希望尽可能精确地测量转移产品的体积,以防止损失金钱或向客户多收费。

在本文中,我们将演示一个简单的例子,说明如何开发一个卡尔曼滤波器来使用超声波传感器测量水箱的水位。

该传感器

HC-SR04 配有声学接收器和发射器。发射机发出一个波,这个波经过障碍物反射后到达接收机。传播时间除以两倍音速,得到传感器和感兴趣物体之间的距离。该传感器的工作范围为 2 至 400 厘米。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

与许多传感器不同,这款传感器不需要模拟端口。通过微控制器的数字输出激活“Trig”引脚后,传感器将发出一个声波,该声波将反射并返回传感器,到达接收器,“Echo”引脚将变为高电平。“Trig”和“Echo”激活之间的时间除以 2 就是波传播时间。

该设置

我在公寓的阳台上养了一些植物,为此我在上面放了一个带水泵的水箱,定期给它们浇水。每次这个油箱低于 30%时,我都会收到系统的电子邮件通知。如果你有兴趣了解如何实现物联网,你可以看看我写的另一篇文章:

[## 使用氯生和粒子光子的物联网家庭灌溉系统

自动给植物浇水,获取警报,并分析数据

medium.com](https://medium.com/@cunhafh/iot-home-irrigation-system-using-losant-and-particle-photon-130df98ce386) 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我知道,我需要清理这个水箱。

卡尔曼滤波器

该算法分为预测和更新两个阶段。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

不要让代数符号吓倒你,让我们分解这些方程。

在预测期间,系统通过执行过去的估计和系统输入的线性组合来估计储罐的容积。在我们的例子中,矩阵 F 将近似等于 1(为了简单起见,我们可以忽略蒸发的影响),因此在给定时刻罐的体积将是过去时刻的体积减去由泵抽吸的体积(我的系统输入)。

因为我每天只灌溉植物一次,而且我的数据是通过 wi-fi 传输的,所以我想最小化负载。因此,我们可以忽略系统输入’ u '的影响。但是请注意,这是有代价的,滤波器的动态响应将受到影响。

预测的第二步是估计协方差 Pk。我们不知道储罐液位的真实值,我们能做的最好的事情是估计最可能的值,并将其分配给最可能的方差。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在创新步骤中,我们将添加更多的信息,并尝试改进这一估计。让我们来看看:

首先,我们需要计算增益 k,现在忽略计算的数学过程,我们将简化它。

一旦计算出 K,我们就可以计算出’后验’状态估计。注意,该量对应于预测状态和‘T4’新息的线性组合,新息由增益和误差的乘积定义。

最后,我们需要更新协方差 p。

算法将总是从产生较小 p 值的组件(预测或创新)获得更多贡献。

因此,对于我们的状态观测器,我们将有:

f =[1]
B =[0]
H =[1]
Q =[1e-5]
R =[3e-3]

所以我们可以把方程改写成:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

密码

有大量的 C++卡尔曼滤波器库可供您使用。我仍然认为编写自己的代码来巩固知识是有用的。在我的例子中,我在本地声明了所有的变量,这样它们就可以被函数访问,但是还有更好的方法。

int kalman_filter(){
    //prediction
    x_hat_k_a_priori = x_hat_k_minus_1;
    P_k_a_priori = P_k_minus_1 + Q;

    //obtaining z_k: my tank height = 25.4, calculates %
    digitalWrite(trigger, LOW);
    delayMicroseconds(2);
    digitalWrite(trigger, HIGH);
    delayMicroseconds(10);
    digitalWrite(trigger, LOW);
    duration = pulseIn(echo, HIGH);
    z_k = (25.4-duration*0.017)/25.4; 

    //innovation 
    K_k = P_k_a_priori * (P_k_a_priori + R);
    x_hat_k = x_hat_k_a_priori + K_k * (z_k - x_hat_k_a_priori);
    P_k = (1 - K_k) * P_k_a_priori;

    return x_hat_k;
}

结果

下图显示了获得的结果。注意时间序列是平滑的。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

储罐液位瞬时和历史测量值

体积的突然增加是由于油箱重新装满。由于泵的激活,出现了小的下降。

结论

实施并测试 KF 算法以从超声波传感器 HC-SR04 获取数据。测试结果表明,该算法能够显著降低噪声。

卡尔曼滤波器可用于多种应用,如传感器融合、不可及变量的状态估计甚至股票市场预测。

如果你喜欢这篇文章或者想分享你的想法,请不要犹豫,在下面留下你的评论。

谢谢!

一个简单的线性回归模型

原文:https://towardsdatascience.com/a-simple-linear-regression-model-f2a53ed61a21?source=collection_archive---------19-----------------------

探索电价与碳排放数据之间的关系

回归分析是一种强大的统计方法,能够在感兴趣的变量之间进行检查。它可以用来评估变量之间关系的强度,并对它们之间的未来关系进行建模。

经济学家痴迷于回归。这可能就是为什么它们是我大学生活中不可或缺的一部分。这种定量估计是理解经济理论最重要和最常用的工具之一。

在经济学中,相关性是常见的,但识别两个或更多变量之间的相关性是否是因果关系却很难做到。回归分析使我们能够预测变化的方向和距离,以及变量之间这种关系的重要性。

它也是统计学、数据科学和机器学习中最广为人知和理解的算法之一。它的简单意味着它是一个很好的起点,对于那些想进入这个领域的人来说。

我之前的工作让我参与了能源行业的一个科技初创企业,特别是电力行业。鉴于我的非能源背景,我有很多关于电力市场运作的东西要学。

我通过接触这个行业获得的一个信息片段——简单易懂,但不是每个人都知道——是电价和电网的碳排放强度是相关的。

这些变量构成了我的线性回归的基础。

查找数据

碳强度

任何数据科学项目的第一部分都是寻找数据。国家电网提供了一个交互式网站,并托管了一个易于使用的 API。我选择了一周的每小时碳强度数据来分析最近的电网排放。

它们还提供了对未来 48 小时的估计。他们这样做是为了尝试和鼓励公司根据他们的预测,使用他们的 API 来自动化 IOT 设备的电力消耗。想想用风力而不是煤炭发电机充电的电动汽车。

我只选择了 2019 年 10 月 20 日至 27 日的日期,来看看上周的情况。

【www.carbonintensity.org.uk】)

电价

当我们以家庭为单位消耗电力时,我们被给予固定的小时费率,而不管一天中的什么时间。然而,公用事业对批发市场有一些敞口。为了最大限度地减少这种情况,大型企业确保绝大多数英国电力通过双边协议出售,远离公开市场,从而限制了它们的价格风险。

然而,因为电力不能大规模储存,所以供给必须始终等于需求。这意味着必须建立一些市场机制来确保平衡。其中之一,前一天市场,正如它听起来的那样——买家和卖家提前 24 小时出价。有各种更不稳定的短期市场机制,确保市场清算和平衡,但是 NordPool 集团的数据相对容易处理。

(www.nordpoolgroup.comT3)

可视化

前一天市场上一周内每兆瓦时的价格。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

电网平均碳强度(gC02/kWh)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

上面的图表直观地展示了我们一天中不同的电力需求(和供应)的结果。总体情况是,价格和碳强度在早上上升,在上午 8 点达到峰值,白天下降,然后在晚上再次上升,在晚上 8 点达到峰值。这在碳强度和价格方面大体相似。

下面作图,可以更清楚的看到这种关系。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这些可视化可以证明是获得数据感觉的有用工具,但在变量之间的相互作用的统计分析中是有限的。

虽然看起来有某种相关性,但线性回归允许我们进一步研究这种关系。

假设

线性回归需要满足五个关键假设:

  • 线性关系
  • 多元正态性
  • 没有或很少多重共线性
  • 无自相关
  • 同方差性

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

普通最小二乘法

我导入并运行了 stats models——一个 python 库——来执行普通的最小二乘回归(OLS)。

OLS 发现 Y(电价)的平均变化是由 X(碳强度)的变化引起的。最小二乘法是指通过绘制最佳拟合线来找到这一平均变化。它采用实际数据和预测值(最佳拟合线)之间的距离,计算误差并对其求平方,以找到预测值的实际距离。如果模型可以改进,直线会移动到该点,直到它与所有数据点的距离尽可能小。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Statsmodels 使用它的 summary()超级功能提供了一个非常棒的模型摘要,这正是我选择使用它而不是其他也可以执行回归分析的库的原因

可视化可以再次帮助描绘模型。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

该模型显示了变量之间的平均关系。如果我们知道哪些发电机目前正在运行,它们的碳强度和当前输出,我们将应该能够参考这条线并估计价格。然而,其准确性取决于通过各种统计测试来评估其显著性。

在这种情况下,由于其低 durbin-watson 结果,它不符合无自相关的假设。除此之外,它的 Jarque-Bera 比可接受的高得多,表明非正态分布。这可能会使我们的模型失效。

误差分布:

检查同质性

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

首先,当价格正态分布时:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

碳强度不是:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

结果讨论

因此,我们的模型在统计学上充其量是可疑的,但这并不意味着某种关系不存在。如果我有更多的时间,或者得到别人的帮助,这段关系肯定会很有趣。最重要的是,如此小的数据集不可能产生这些无关紧要的结果。

极度简化的高碳密度燃料和高价格是相互关联的,因为可再生能源发电不需要燃料,以及随之而来的所有成本:采购燃料、购买土地、钻探或挖掘燃料、提炼燃料、运输燃料、处理废物。

煤炭是效率最低的燃料来源,也是我们电网中最脏的,在转换成电力时会损失 70%的能量。另一方面,风能最终成为最有效的能源,产生的电能比它所消耗的能量多 1126%。

(https://blogs . wsj . com/numbers/what-is-the-most-efficient-source-of-electricity-1754/?ns = prod/accounts-wsj)

继续进一步建模

为了进一步分析电价指标,我们可以使用各种方法来强化我们的模型:

包含更多数据:

这可能包括更长时间内的数据,或来自其他国家的数据——前提是我们还可以访问或计算电网的碳强度。(这通常很难计算)

包含更多变量:

包括其他变量,如全球油价、天然气和煤炭价格,显然是帮助预测价格的有力竞争者。除此之外,我们还可以研究太阳能电池板成本和风力涡轮机成本,甚至探索局部天气数据的粒度,预测电力需求(大型体育赛事往往会产生有趣的结果——尽管橄榄球世界杯没有)。

使用线性回归作为分析电价的基础可以证明是能源转型的有用工具。如果我们想摆脱对化石燃料的依赖,将我们的能源需求转向可再生和低碳发电是至关重要的。

分析和预测是让我们实现这一目标的第一步,有像 Nest 这样的公司帮助控制大量房屋的能源消耗,以限制我们的碳足迹。

这一点尤其重要,因为我们的交通工具实现了电气化,电力消耗激增。如果所有这些额外的需求都由煤炭而不是风力来提供,那么关键的好处将会丧失。

一个简单的电影推荐系统

原文:https://towardsdatascience.com/a-simple-movie-recommendation-system-d135cfd0a22d?source=collection_archive---------18-----------------------

基于亚马逊基于商品的协同过滤

机器学习领域的推荐系统已经变得非常流行,对于网飞、亚马逊等科技巨头来说,这是一个巨大的优势,可以让他们的内容面向特定的受众。这些推荐引擎在预测方面非常强大,它们可以根据用户与应用程序的交互动态改变用户在页面上看到的内容的状态。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

格伦·卡斯滕斯-彼得斯在 Unsplash 上拍摄的照片

基于项目的协同过滤

基于项目的协同过滤是由 Amazon 开发的一种方法,用于推荐系统中,主要基于数据集中各种项目之间的相似性向用户提供推荐。这些推荐是基于用户对该特定项目的评级来计算的。

一种电影推荐系统

我们将在这个项目中使用的数据集来自 MovieLens

让我们从将数据集导入笔记本开始。有两个文件特别需要导入。因此,将用户的评级导入到 r_cols 数据帧中,将电影导入到 m_cols 数据帧中。我们还将把编码类型设置为 utf-8

import pandas as pdr_cols = ['user_id', 'movie_id', 'rating']
ratings = pd.read_csv('ml-100k/u.data', sep='\t', names=r_cols, usecols=range(3), encoding="ISO-8859-1")m_cols = ['movie_id', 'title']
movies = pd.read_csv('ml-100k/u.item', sep='|', names=m_cols, usecols=range(2), encoding="ISO-8859-1")

现在,我们必须合并这两个数据帧,以获得一个完整的数据帧,该数据帧包含任何给定电影的用户评级。

ratings = pd.merge(movies, ratings)

让我们看看这个数据帧是什么样子的,

ratings.head()

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

下一步是旋转这个表,创建一个用户和他们评价的电影的矩阵。这个表格是为了让我们了解哪个用户看过什么电影,以及他们提供了什么样的评级。

movieRatings = ratings.pivot_table(index=['user_id'],columns=['title'],values='rating')
movieRatings.head()

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们将对 1977 年的星球大战电影进行分析。所以,让我们把所有星球大战的这些值分配给一个叫做星球大战等级的数据框架。

starWarsRatings = movieRatings['Star Wars (1977)']
starWarsRatings.head()

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们将使用 pandas corr()函数来查找与星球大战相关的所有列之间的成对相关性。

similarMovies = movieRatings.corrwith(starWarsRatings) # pairwise correlation of Star Wars vector of user rating with every other movie

让我们放弃任何没有数据的结果,

similarMovies = similarMovies.dropna() # Drop any results that have no data

构建具有关于星球大战的每部电影的相关分数的新鲜的新数据帧。

df = pd.DataFrame(similarMovies) # Construct a new Dataframe of movies and their correlation score to Star Wars

让我们看看这个数据框里有什么,

df.head(10)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

现在让我们根据分数对这些值进行排序,

similarMovies.sort_values(ascending=False)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

是的,这些结果没有任何意义。

这是因为我们的结果被那些只被一小撮人评级的电影搞砸了,他们也给《星球大战》评级。让我们来看看这些条目。

import numpy as np
movieStats = ratings.groupby('title').agg({'rating': [np.size, np.mean]})
movieStats.head()

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

让我们去掉那些少于 100 人评价的条目。

popularMovies = movieStats['rating']['size'] >= 100 # Ignore movies rated by less than 100 people
movieStats[popularMovies].sort_values([('rating', 'mean')], ascending=False)[:15]

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

将这些数据与类似于《星球大战》的原始电影集结合起来。

df = movieStats[popularMovies].join(pd.DataFrame(similarMovies, columns=['similarity']))

现在让我们来看看我们的数据框。

df.head()

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

最后,根据相似性得分对这些值进行排序。

df.sort_values(['similarity'], ascending=False)[:5]

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

结果

瞧😆!你可以看到,我们刚刚获得的最终输出中的前三个条目都是星球大战电影。接下来的几部电影基于相似的类型,即动作和冒险。我们刚刚建立了一个令人惊叹的电影推荐系统,它能够建议用户观看与他们过去观看过的内容相关的电影。

你可以在我的 GitHub 上找到完整的代码。如有任何疑问,请随时通过我的 LinkedIn 联系我。

谢谢你。

功率 BI 中的简单时间计算

原文:https://towardsdatascience.com/a-simple-problem-98329b0e49f4?source=collection_archive---------48-----------------------

…DAX 日期、小时和分钟。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Johannes Plenio 在 Unsplash 上拍摄的照片

我今天遇到了一个“简单”的问题。在我开始做之前,我觉得这很简单。见鬼,这太简单了,我甚至说我可以在 5 分钟内解决这个问题。有时候一个简单的问题对每个人来说可能都不简单。

5 分钟变成了一个小时,还需要大量的谷歌搜索。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

作者图片

我真的不需要处理精确到分钟的时间分析,所以如果这听起来对你来说是一个简单的问题,那么你能够解决它就很好了。

背景:

我有一个调查的完成时间栏。它包括日期和时间,如下所示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我只想做一个声明说,“所有在 10 月 14 日上午 8:48 之前回复的人”说“已报告”。

我尝试了下面的计算列。

Incorrect =VAR DAY = DATE(2020,10,14)VAR HOUR = HOUR(8)VAR MINUTES = MINUTE(48)VAR Cut_Off = DAY+HOUR+MINUTERETURNCut_Off

好像不管用。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

作者图片

至少对我来说是合理的。Power BI 将日、小时和分钟相加,并将其与[完成时间]列进行比较。

它并不完全有效。权力毕没有拿起我的意思是小时和分钟。我想要的不是 12 点。现在是早上 8 点 48 分。

然后我意识到可能是因为时间的原因,也可能不是日期时间数据类型,所以我把它改成了下面的。

Time_Solution =VAR DAY = DATE(2020,10,14)VAR HOUR_MINUTE = TIME(8,48,00)VAR Cut_Off = DAY+HOUR_MINUTERETURNCut_Off

成功了:)。现在,我刚刚添加了 If 语句,它非常有效。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

作者图片

然后我泡了一杯咖啡,意识到了一些事情。

有一个索引栏可以帮我。我知道当有更多的回答者时,这个索引栏会自动填充。它总是以 1 为增量增加。随着调查结果的出现,数字会变得更高,所以我会做相应的调整。

现在我有两个解决方案:

1)将 ID 用作比较器— Id_Solution

2)使用时间作为比较器—时间解决方案

我的表现在看起来像这样。

Id_Solution = IF([ID]<=30,"Reported","Did not Report")

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

作者图片

我甚至不需要时间去做我想做的事情。我想用最短的代码来代替 Id 解决方案。

问题是很难有人知道为什么我用 30 这个数字作为比较。

因为还有其他人在使用这个文件,所以我只能选择最容易解释的。也就是时间解。

这种情况让我想起了一句名言。

"的确,通过帮助他人成功,你可以最快最好地获得成功。"拿破仑·希尔。

一个问题有很多解决方案,但是有时候对你来说最明显的一个可能对所有人来说都不是最明显的。

最好实施一个每个人都理解的解决方案,而不仅仅是你。如果团队中的每个人都理解你的解决方案,这对每个人都是一个胜利。

带走:

  • 可以使用 TIME()函数添加日、小时、分钟、秒钟。不需要单独的列。
  • 索引列可能比您想象的更有用。
  • 想想你的队友。他们会理解你的措施在做什么吗?容易解释吗?车型怎么样?
  • 帮助你的队友成功,你也会成功

如果你想知道如何在 Power BI 中使用日期和日历,这里有一篇文章给你

保重,注意安全!

一个简单的 Python 歌曲推荐系统(教程)

原文:https://towardsdatascience.com/a-simple-song-recommender-system-in-python-tutorial-3e4c111198d6?source=collection_archive---------31-----------------------

协同过滤和推荐系统的基础,以及为什么脸书和谷歌似乎知道你在说什么,即使他们不记录你的谈话。

本材料基于我在 2020 年 4 月教授的一个研讨会的内容。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

DJ R3X 在 Oga 的酒吧策划歌曲。图片来源 : 约书亚·苏多克(迪斯尼公园)

我们大多数人现在每天都在使用基于人工智能的推荐系统:在网飞上寻找一个节目,在社交媒体上滚动,在 YouTube 上观看“up next”视频,在 Spotify 上收听“Discover Weekly”播放列表。

那么这些推荐器是如何工作的呢?

他们变得非常好,在某些情况下,好得令人毛骨悚然。我们中的许多人都收到了一些推荐和广告,这让我们不禁要问:“他们在给我录音吗?“一般来说,公司不会通过窃听你的麦克风,录下你的对话来做推荐。相反,他们会给你做一个模型,或者像特里斯坦·哈里斯所说的那样,“一个小小的巫毒娃娃,你的化身版本”,然后对那个娃娃做出预测。我会把这个娃娃称为你品味的数学模型。

本教程中的方法远没有谷歌、脸书和 Spotify 使用的方法复杂,它们不会产生任何令人毛骨悚然的好推荐。尽管如此,大多数建议的工作原理都是一样的,分为三个步骤:

  1. 公司为你和其他人建立了一个数学模型
  2. 他们利用这些模型来寻找和你相似的人
  3. 他们发现那些相似的人喜欢什么,并推荐给你

我将重复这三个步骤两次,首先是一个简单的可视化示例,然后是一个更大的基于代码的示例。

第 1 部分:视觉介绍

为你的品味建立一个数学模型

让我们首先考虑三个人(杰克、尼克和特雷弗)以及他们如何在 1 到 5 的范围内给三首歌曲(一支舞、向前一步和向日葵)评分。这是一个简单的表格:

我们现在有了一个简单的音乐品味的数学模型。在现实世界中,Spotify 使用其他信号来确定这个评级,比如你听了一首歌多少次。不管怎样,原则是*把你的喜好转化成一串数字,*其中也被称为向量、矩阵或数组。不管你怎么称呼它们,把这些数字形象化在图表上是很有帮助的。下面,我们将“一支舞”的评分放在 x 轴上,将“倚在”的评分放在 y 轴上:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

使用该模型寻找相似的人

我们现在有了一个记录你音乐品味的数字列表,所以我们可以进入下一步:找到有相似品味的人。让我们回到图表:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在视觉表征中,相似的人只是附近的人。因此,找出谁与杰克“最相似”只是找出谁与杰克最接近的问题。我们可以用中学几何中古老的毕达哥拉斯定理来测量这个距离:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

酷!我们快到了。我们已经可以看出,杰克最像尼克,而不是特雷弗,但让我们把它正式化:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

数学证实:在歌曲品味的小宇宙中,杰克离特雷弗有 3.2 个单位的距离,但离尼克只有 1.4 个单位。

推荐相似的人喜欢的东西

现在我们知道杰克和尼克有相似的品味,我们可以根据尼克是否喜欢向日葵来预测杰克是否会喜欢《向日葵》。只需要在表中查找:

尼克给了“向日葵”5/5 的评分,所以我们可以预测杰克可能也会喜欢这首歌。

显然,这个微小宇宙的规模比 Spotify 的宇宙要小很多。我们看了三首歌和三个人,而 Spotify 据称拥有超过 5000 万首歌曲和超过 2.71 亿活跃用户。所以现在,我们要扩大规模。

第 2 部分:用 Python 编写示例代码

为你的品味建立一个数学模型

为了生成更大的数据集,我们将加载一个更大的表。这里的是一个有 25 首歌和 8 个人的:

在 Python 中,您可以使用 Pandas 通过以下命令加载这些数据:

from pandas import read_csvdata_url = 'https://gist.githubusercontent.com/jackbandy/5cd988ab5c3d95b79219364dce7ee5ae/raw/731ecdbecc7b33030f23cd919e6067dfbaf42feb/song-ratings.csv'ratings = read_csv(data_url,index_col=0)

使用该模型寻找相似的人

现在,让我们试着预测一下我(还是杰克)会不会喜欢《7 响》这首歌。就像在视觉示例中一样,我们会找到离我最近的人。使用勾股定理,二维空间中的距离函数就是distance=sqrt(a^2 + b^2),我们可以这样写:

def distance(person1,person2):
  a_squared = (person1[0] - person2[0])**2
  b_squared = (person1[1] - person2[1])**2
  c = sqrt(a_squared+b_squared)
  return c

但这一次,有 25 个维度,而不仅仅是 2 个。当我们有 25 个维度而不是只有一个 x 轴和一个 y 轴时,我们如何找到最接近的人?

事实证明,可信的毕达哥拉斯定理非常普遍。(大多数推荐器使用其他距离度量,如余弦距离,但在本教程中我们将忽略它)。如果有三个维度,我们可以称之为abc,然后在平方根下面加上:distance=sqrt(a^2 + b^2 + c^2)就可以了。实际上我们可以在任何维度上这样做:distance=sqrt(a^2 + b^2 + c^2 + d^2 + ... + n^2)

scipy 库编写了一个函数来完成我们需要的功能:计算任意维数的欧几里德距离。让我们使用它:

from scipy.spatial.distance import euclideandef distance(person1,person2):
  distance = euclidean(person1,person2)
  return distance

现在,我们可以使用距离函数来查看任何两个人之间的相似性。唯一的问题是我们需要使用fillna用“0”填充空白。下面的块执行该操作,然后检索这三个人的数据行:

ratings=ratings.fillna(0)jack=ratings.loc['Jack']
nick=ratings.loc['Nick']
trevor=ratings.loc['Trevor']

然后,我们可以看看杰克和另外两个人之间的距离:

print("Distance between Jack and Nick:")
print(distance(jack,nick))
# 10.63014581273465print("Distance between Jack and Trevor:")
print(distance(jack,trevor))
# 13.490737563232042

就像在《小宇宙》中,杰克离尼克(10.63 个单位远)比离特雷弗(13.49 个单位远)更近。但实际上,我们想看看杰克和其他人之间的距离。下面是一个使用“for 循环”来实现这一目的的函数:

def most_similar_to(name):
  person = ratings.loc[name]
  closest_distance=float('inf')
  closest_person='' for other_person in ratings.itertuples():
    if other_person.Index==name:
      # don't compare a person to themself
      continue distance_to_other_person = distance(person,ratings.loc[other_person.Index]) if distance_to_other_person < best_similarity:
      # new high score! save it
      closest_distance = distance_to_other_person
      closest_person = other_person.Index return closest_person

开头是这样说的:“到目前为止最亲近的人,在无限远的地方。”然后,它循环查看每个人,并询问“这个人比目前为止最亲近的人更亲近吗?”回答“和 Jack 最相似的人是 Jack”并没有太大帮助,这也是为什么名字相同的话循环会跳过(即continue)。

现在,我们可以只调用most_similar_to来查看谁与任何人最接近。让我试试(杰克):

print("Jack is most similar to:")
person_most_similar_to_jack = most_similar_to('Jack')
print(person_most_similar_to_jack)
print(distance)# Meg
# 8.660254037844387

推荐相似的人喜欢的东西

最后,我们可以通过看和我最相似的用户来预测我是否会喜欢“7 环”。当时资料上说这是梅格,那我们来看看梅格是怎么评价这首歌的:

print(ratings.at['Meg', '7 Rings (Ariana Grande)'])
# 3.0

梅格对这首歌的评价是 3/5,所以我可能不会对它太着迷。

一个 Google Colab 笔记本全部代码都有 这里

后续步骤

如果你真的想做 Spotify 正在做的事情,你会利用每个 T21 人的音乐品味做出预测,而不仅仅是最亲近的人。例如,也许如果我知道特雷弗和我一直有非常不同的品味,认识到特雷弗喜欢《7 环》可能会告诉我,我会不喜欢这首歌。我可能会在未来的教程中涉及到这一点,所以如果您感兴趣,请告诉我!

向任何人解释版本控制的简单故事

原文:https://towardsdatascience.com/a-simple-story-to-explain-version-control-to-anyone-5ab4197cebbc?source=collection_archive---------12-----------------------

让我们一起盖房子吧…用 git。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

照片由扬西·敏Unsplash 上拍摄

当我开始在项目中使用版本控制时,这个概念很难理解。我看到很多人,包括我自己,运行着 git pull、git push 之类的命令,应用着我不理解的进程。为什么我既需要承诺又需要推动?为什么每个新特性都需要一个新的分支?在一个每天使用 Git 的项目中工作了几个月之后,这个概念对我来说变得非常清晰,我终于理解了使用版本控制,更具体地说,使用 Git 进行协作的全部潜力。

在 12 月的最后两周,我被要求举办一个关于版本控制的研讨会,更具体地说是如何在项目中使用 git。由于研讨会将有不同背景的人参加,我想到了一个小故事来说明版本控制的工作方式及其在项目中的优势。

让我们一起盖房子吧

在这个美丽的合作项目中,我们试图一起建造一所房子。简单点说,我们只有两个人在那栋房子里工作。我们不是房子的主人,我们为其他人工作,一个利益相关者,他告诉我们他想要什么,他想要在哪里。

免责声明:我绝不是建筑师,我对实际建造一栋真正的房子知之甚少。请记住,这只是一个帮助人们容易理解版本控制概念的故事。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

照片由 Unsplash 上抓拍

我们有 4 面墙——我们的主分支

我们从 4 面墙(和一个屋顶?),坚固、耐用且非常精细。这四面墙代表我们的总支。它们目前仍然有效,已经实施,不会被删除。利益相关者认可了这四面墙,他甚至可能自己选择了它们,他想保留它们。我们需要做的只是改善这四面墙,并在它们的顶部或周围进行建设。无论如何,我们将要建造的任何东西都将以这四堵墙为基础。

主人想要一个客厅和一个厨房——特色树枝

正如我之前提到的,有两个人在做这个项目,我和另一个人,我们叫他鲍勃,因为我对名字没有任何想象力。每个房间都是一个特色。在这种情况下,为了最大化结果,Bob 和我将致力于不同的功能。我将设计客厅,鲍勃将设计厨房。到目前为止一切顺利。简单。

我们都创建了一个特性分支。我们也知道我们必须使用约定来命名我们的分支。所以我们将从我们的名字开始,我们正在做什么(在这种情况下,一个新的特性)和那个特性的名字。

  • 朱莉娅/特写/客厅
  • 鲍勃/特写/厨房

(分支机构的命名有几种惯例。这只是一个建议。)

我们都从主分支创建我们的特征分支。所以我们都从同样的四面墙开始。然而,我们的特性分支是完全独立于主分支的副本,对主分支的内容没有直接影响。这确保了如果 Bob 或我完全破坏了主墙中的一面,包含我们四面墙的主分支仍然屹立不倒,并且可以依靠。

我想在本地保存我的设计— git commit

提交就像在本地保存您的更改一样。每个新的提交都有一个数字,也代表一个你可以返回的保存点,就像在一个任务游戏中,你可以返回到上一个保存点。因此,当 Bob 构建厨房橱柜时,他可以提交它们,以便不丢失他的更改,并且如果他构建的下一部分危及橱柜的质量,他还可以提交。

每个提交还需要一个消息,因为写一些关于你的提交的东西是一个好习惯,为了让每个人都知道这个“保存点”包括什么,sweet Bob 写了“创建红色的厨房橱柜”。

我想把我的设计保存在一个安全的地方,在资源库上——git push

您的存储库是存储所有分支的地方,包括主分支。它就像一个文件夹,其中包含了有关项目的所有文件,包括它们的修订历史。

Git push 获取您所有的提交,并将它们发送到您的分支的 remote 版本,该版本可以在您的在线存储库中获得,在那里所有相关的开发人员都可以看到对您的分支所做的更改。因此,Bob 将他的提交推送到他的远程分支,我现在可以看到 Bob 关于红色文件柜的提交。

我的客厅完工了。现在怎么办?-开发分支和合并请求

我们的开发分支是整合我们的房间(或功能)的地方。这是我们尝试将我们的设计(或功能)结合在一起的地方,看看我们的客厅和厨房是否能很好地配合。

如果我想把我的客厅添加到开发分支,我必须做一个合并请求(或者拉请求,这取决于你使用的平台)。一般来说,在合并发生在远程分支之前,至少有一个其他开发人员必须批准您的合并请求。

鲍勃的厨房完工了。我们的设计不相配。—合并冲突

我正在尝试将 Bob 的新更改合并到我的分支中。但是,如果我没有在鲍勃的开放式厨房一侧做好墙,会发生什么呢?我们的设计(代表代码,记得吗?)有冲突。 Git 可以自动解决一些冲突,但不是全部。Git 有时需要您的帮助来确定哪些更改应该保留,因为其中一些更改是冲突的。换句话说,它需要知道谁的“设计”(或代码)是应该保留的。

假设我是犯错的人(不要责怪可怜的鲍勃)。我可以告诉 Git,当涉及到厨房墙壁时,保留 Bob 的部分设计,而不是我的。

什么时候可以把我们的厨房和客厅加到 Master 分店?

项目的这一部分通常包括测试、涉众和批准(至少)。一旦我们的设计被彻底测试,这意味着它们也能很好地一起工作,并且我们的利益相关者,房屋所有者批准了设计,我们就可以决定将我们的变更合并到主分支。这意味着从现在开始,我们房子的稳定版也将包括我们的客厅和厨房。所以所有新的分支机构至少应该包括这些房间。

在某些情况下,一个聪明的方法可能包括将主分支的每个以前的版本作为以前的版本保存在不同的分支中。然而,处理主分支的正确方法取决于您的团队和公司可能有的需求或指导方针。(我保持这个故事简单。不是每个团队或公司都以相同的方式处理主分支。)

总之,版本控制是轻松安全协作的核心。

在一个团队项目中使用 Git 允许几个开发人员在同一个项目中独立工作,而不会经常干扰彼此的输入。每个开发人员都可以获得独立版本的代码,他们可以修改这些代码,而不必冒破坏代码稳定版本的风险。

复制代码和在不同版本上独立工作的能力使 Git 成为任何构建应用程序的人的好选择,甚至是单独工作的开发人员。它让您有机会保留代码的几个版本,并跟踪每个更改的所有特征,例如谁在何时做了更改。

感谢阅读!

一个简单的基于 SVM 的半监督学习实现

原文:https://towardsdatascience.com/a-simple-svm-based-implementation-of-semi-supervised-learning-f44eafb0a970?source=collection_archive---------30-----------------------

扫清半监督学习的迷雾

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

来源:-https://unsplash.com/photos/GhFn3mddePk

我们都遇到过作为一种机器学习问题的半监督学习。但这是一个没有被很好理解的概念。最好通过弄脏我们的手来理解这一点,而这正是我们正在带来的。

用例很简单,我们有一些数据,可能有 100 个观察值,其中 30 个是有标签的(有监督的),其余的是无标签的(无监督的),我们正在解决一个分类问题。我想大家都会同意,如果我们可以使用所有 100 个观察值,那么通过对 30 个案例或观察值进行训练所能达到的性能会更低,不幸的是,其中 70 个没有标记。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 1:无监督学习场景(来源:作者)

本质上这是一个二元分类问题。这两个类别由蓝色三角形和红色圆圈表示。灰色菱形表示未标记的数据。

我们的第一个策略是

步骤 1:在标记的数据上建立一个分类器(常规的东西)

第二步:用这个来预测未标记的数据。然而,除了预测,你还要检查你的信心水平。

第三步:将这些观察结果添加到你有一定把握的训练数据中。这些被称为伪标记与标记数据相对照。

步骤 4:使用这个扩充数据集,现在用于训练,并使用这个模型。

由于我们使用非监督数据来增加监督学习的训练数据,这介于两者之间,因此称为半监督。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 2:扩展数据集

在上图中,说明了训练数据的扩展。对于我们有信心的观察结果,我们使用了伪标签,而对于我们没有信心的观察结果,我们仍然保持不加标签。

让我们现在跳到代码

我们正在创建一个虚拟场景,其中我们将数据集(wine)分为 train(已标记)、unl(未标记)和 test。

X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.3, random_state=1)
X_train, X_unl, y_train, y_unl = train_test_split(
    X_train, y_train, test_size=0.7, random_state=1)

这里分别是训练、测试和未标记的形状。请注意,我们不会考虑 unl 部分的标签信息,因此将其视为未标记

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

数据集的形状(图片来源:作者)

接下来,我们简单地在标记的部分进行训练,它刚刚走了 19 行。

clf = svm.SVC(kernel='linear', probability=True,C=1).fit(X_train, y_train)
clf.score(X_test, y_test)

获得的精度如下

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

初始分类准确性(来源:作者)

接下来,我们对未标记的数据进行预测

df = pd.DataFrame(clp, columns = ['C1Prob', 'C2Prob','C3Prob']) 
df['lab']=lab
df['actual']=y_unl
df['max']=df[["C1Prob", "C2Prob","C3Prob"]].max(axis=1)

你可能已经注意到了,我们使用了预测概率,它预测了类别概率,而不是标签,这实际上会帮助我们找到有把握的猜测

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

对预测的信心(来源:作者)

我们只看预测概率之间的绝对差异

  • 当这三个类别的概率相等时,则所有类别的概率大约为 0.33
  • 任何大于这个值的值都显示出一定的可信度

本质上,我们希望在训练中添加这些概率差异较大的观察值。代码如下

下图给出了置信度的分布,以最有可能的类别的概率表示。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

对预测的信心(图片来源:作者)

接下来,我们运行一个循环,对于最可能类的不同阈值,将数据添加到观察值中。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

不同阈值下的准确性(来源:-作者)

  • 当最可能的类的概率大于 0.4 且高达 0.55 时,情况会有所改善
  • 在那之后,几乎没有任何改善,因为在那些我们超级自信的人身上,这并没有增加知识,因为观察结果与标记非常相似。

尾注:

在本教程中,我们已经展示了如何使用 SVM 来采用简单的半监督策略。这种技术可以很容易地扩展到其他分类器。影响将取决于类的重叠或区分程度、要素的信息量等等。

参考资料:

[1]https://www . ka ggle . com/saptarsi/a-simple-semi-supervised-strategy-based-on-SVM

[2]https://towards data science . com/supervised-learning-but-a-lot-better-semi-supervised-learning-a 42 dff 534781

一种在不同服务器之间自动化和安排 SQL Server 数据库复制的简单方法

原文:https://towardsdatascience.com/a-simple-way-of-automating-and-scheduling-sql-server-database-replication-between-different-servers-fa53fe22b856?source=collection_archive---------13-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图片提供:https://www . spiria . com/site/assets/files/2398/2016-SQL-server-logo。-large.jpg

微软 SQL Server 提供了SQL Server Replication功能,我们可以利用这些功能将一个数据库设置为Publisher和另一个数据库为Subscriber,这样我们就可以在脚本中通过定制来复制数据库。但是,有时需求可能没有那么复杂,因此 SQL Server 复制可能有点过头了。

例如,最近我的一个客户想要启动一个概念验证项目来构建一个数据仓库。他们担心他们赖以保持业务运行的生产数据库。因此,在我们从数据库中提取数据来构建数据仓库之前,我们需要复制数据库,以便所有的开发工作都可以在这些副本上进行。

在这种情况下,没有必要在复制过程中包括任何定制,这只是简单地镜像数据库。在本文中,我将介绍一种在不同服务器之间自动复制 SQL Server 数据库的非常简单的方法。

在 Azure 中创建 SQL 服务器

让我们首先为这个实验创建两个 SQL 服务器。强烈建议使用 Azure,否则,您需要准备两台不同的机器,获得适当的 SQL Server 许可证并安装 SQL Server 软件,这可能需要一整天的时间。

如果你是 Azure 的新用户,当你注册 Azure 为新用户时,你将获得 200 美元的积分(一个月内)。

转到您的 Azure 订阅,首先创建一个资源组,这将是 SQL 服务器的容器。然后,去 marketplace 搜索“sql server”,如截图所示选择 Windows Server 2016 上的 SQL Server 2017。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在下拉手册中,选择标准版以拥有所有标准功能。然后,单击“从预设配置开始”以节省时间。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在这里,我们可以选择开发/测试环境和 D 系列虚拟机(都是最小的)来节省成本,特别是如果您已经用完了所有的免费积分。然后,单击“创建虚拟机”

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

确保您选择了为此创建的资源组。然后,单击下一步。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

填写管理员凭据。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

磁盘对这个实验不重要,所以我们可以跳过。然而,虚拟网络非常重要。确保您创建了一个新的虚拟网络和子网,更重要的是,如果您不想在这个实验中产生一些可访问性问题,那么稍后创建的另一个 SQL Server 必须在同一个虚拟网络和子网中。另外,为了方便起见,打开 RDP 端口 3389。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

不要更改默认端口号并创建 SQL 身份验证。之后,我们已经完成了配置。点击创建按钮在 Azure 中创建资源。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在等待部署资源的同时,我们可以创建另一个 SQL Server。我就叫它SQL-Server-Test

准备“生产”SQL Server

在部署了第一个 SQL Server 之后,转到资源组并找到用于SQL-Server-Prod的 Windows VM。因为我们已经为该机器打开了 RDP 端口,所以我们可以使用它的公共 IP 地址来远程控制该虚拟机。

请记录私有 IP 地址,稍后测试机器将使用该地址连接到该产品机器

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

下载一个示例数据库

让我们安装一个来自微软的示例数据库。在生产机器上,下载数据库备份:https://github . com/Microsoft/SQL-server-samples/releases/download/adventureworks/adventureworks 2017 . bak

在 SSMS,使用默认的 Windows 管理员帐户登录数据库实例。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

恢复示例数据库

右键单击“数据库”并选择“恢复数据库”。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在弹出窗口中,单击“设备”单选按钮右侧的浏览按钮->添加->浏览您刚刚下载的 bak 文件->确定->确定->确定。恢复整个数据库可能需要大约 1 分钟。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

准备备份路径

接下来,我们需要创建一个文件夹来存放备份文件。此外,我们需要在网络中共享这个文件夹,以便测试机器可以访问备份文件并恢复它。

我创建了目录C:\backup\。然后,将该文件夹共享到另一台机器上的同一个管理员帐户。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

请注意,将MSSQLSERVER用户添加到共享中很重要。否则,共享后 SQL Server 可能无法将备份文件写入此文件夹。只需输入MSSQLSERVER用户名并点击添加按钮,然后确保授予它读/写权限。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在测试机器上,我们现在将能够访问backup目录。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在 SQL-Server-Production 上创建备份

因为 SQL Server 代理在默认情况下是禁用的,所以我们需要再次远程控制生产机器来启用它。右键点击SQL-Server-Agent - >开始。然后,在弹出的确认窗口中点击Yes

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

等到 SQL Server 代理启动后,返回测试计算机。您需要重新连接生产 SQL Server 才能看到 SQL 代理的启用。

右键Jobs->-New Job...

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

New Job窗口中,输入名称并转到Steps选项卡。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Steps页签中,点击New按钮。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

New Job Step窗口中,输入步骤名称和脚本如下:

USE AdventureWorks2017
GODECLARE [@filename](http://twitter.com/filename) varchar(255)
DECLARE [@date](http://twitter.com/date) datetimeSELECT [@date](http://twitter.com/date)=getdate()
SELECT [@filename](http://twitter.com/filename)='C:\backup\AdventureWorks2017-' + CAST(DATEPART(yyyy, [@date](http://twitter.com/date)) as varchar) + '-' + CAST(DATEPART(mm, [@date](http://twitter.com/date)) as varchar) + '-' +  CAST(DATEPART(dd, [@date](http://twitter.com/date)) as varchar) + '.bak'BACKUP DATABASE AdventureWorks2017 TO DISK=[@filename](http://twitter.com/filename) WITH INIT
GO

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

之后,进入Advanced选项卡,配置成功和失败行为。这里,你需要考虑你的情况,比如你的数据库有多大等等。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

点击确定确认应用作业步骤,然后转到Schedule选项卡并点击新建按钮。您可以根据自己的需求配置时间表。在本例中,我将让备份在每天凌晨 1:00 进行。然后,单击“确定”按钮确认该计划。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

您可能还希望创建警报或通知,例如在作业失败时发送电子邮件。在这个实验中,我们将跳过这一步,因为并不总是需要。

现在,与其等到明天凌晨 1 点,我想测试一下这个作业。我们可以右键单击我们创建的作业,然后选择“在第…步启动作业”来测试该作业。由于我们在此作业中只有 1 个步骤,它将直接启动并运行备份步骤。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

过一会儿,作业就成功了,您也可以在备份目录中找到备份文件。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在 SQL-Server-Test 上还原备份

首先,我们通过 access \\SQL-Server-Prod\backup\<backup-file>来检查一下测试机上备份文件的可访问性。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

另一个关键步骤是将远程备份文件夹装载到本地驱动器。这是因为 SQL Server Windows 服务通常是作为无权使用网络/远程资源的服务帐户运行的,因此远程资源对它是不可见的。

只需右键单击备份文件夹并选择“映射网络驱动器…”。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

让我们将它安装到测试机上的 Z: drive。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

然后,我们需要让 SQL Server 使用xp_cmdshell命令识别网络驱动器。默认情况下,这个命令是不启用的,所以我们需要启用它。打开一个新的查询表,并运行以下脚本来启用它。

EXEC sp_configure 'show advanced options', 1;
GO
RECONFIGURE;
GO

EXEC sp_configure 'xp_cmdshell',1
GO
RECONFIGURE
GO

然后,使用xp_cmdshell定义网络驱动器。您可以使用任何可以访问该网络驱动器的 Windows 用户。注意,您只需要运行这个命令一次,所以密码不会以明文格式保存在任何地方。

EXEC XP_CMDSHELL 'net use Z: \\SQL-Server-Prod\backup <password> /USER:<username>'

在 result 面板中,您应该会看到输出,表明它是成功的。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们也可以通过下面的脚本来测试它是否有效。

EXEC XP_CMDSHELL 'dir Z:'

如果可以,您应该会看到包含备份文件的文件列表。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

之后,我们只需要创建另一个 SQL Server 代理作业,其中包含从所标识的网络驱动器还原数据库的步骤。该步骤的脚本如下:

DECLARE [@filename](http://twitter.com/filename) varchar(255)
DECLARE [@date](http://twitter.com/date) datetimeSELECT [@date](http://twitter.com/date)=getdate()
SELECT [@filename](http://twitter.com/filename)='Z:\AdventureWorks2017-' + CAST(DATEPART(yyyy, [@date](http://twitter.com/date)) as varchar) + '-' + CAST(DATEPART(mm, [@date](http://twitter.com/date)) as varchar) + '-' +  CAST(DATEPART(dd, [@date](http://twitter.com/date)) as varchar) + '.bak'RESTORE DATABASE AdventureWorks2017
FROM DISK=[@filename](http://twitter.com/filename)
WITH REPLACEGO

然后,重复我们之前在生产计算机中所做的操作,右键单击代理作业并选择“在步骤启动作业”来测试作业。等待一段时间,直到恢复完成,右键单击“数据库”刷新数据库列表,你会看到恢复的数据库!

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 [## 通过我的推荐链接加入灵媒-陶

作为一个媒体会员,你的会员费的一部分会给你阅读的作家,你可以完全接触到每一个故事…

medium.com](https://medium.com/@qiuyujx/membership)

如果你觉得我的文章有帮助,请考虑加入 Medium 会员来支持我和成千上万的其他作者!(点击上面的链接)

资源

使网络路径对 SSMS 的 SQL Server 备份和恢复可见:
https://www . MSSQL tips . com/SQL Server tip/3499/make-Network-Path-Visible-For-SQL-Server-Backup-and-Restore-in-ssms/

BACKUP 语句(Transact-SQL,微软官方文档):
https://Docs . Microsoft . com/en-us/SQL/t-SQL/Statements/BACKUP-Transact-SQL?view=sql-server-ver15

RESTORE 语句(Transact-SQL,微软官方文档):
https://Docs . Microsoft . com/en-us/SQL/t-SQL/Statements/RESTORE-Statements-Transact-SQL?view=sql-server-ver15

用 Python 分析学生成绩数据的简单方法

原文:https://towardsdatascience.com/a-simple-way-to-analyze-student-performance-data-with-python-cc09c7508c4c?source=collection_archive---------26-----------------------

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

斯蒂芬·道森在 Unsplash 上拍摄的照片

探索如何使用 Python 和 Dremio 以高效的方式分析数据和构建信息图表

介绍

数据分析和数据可视化是数据科学的重要组成部分。实际上,在机器学习时代之前,所有的数据科学都是关于用不同的工具解释和可视化数据,并对数据的本质做出结论。如今,这些任务仍然存在。他们只是众多杂项数据科学工作中的一个。通常,所谓的 EDA(探索性数据分析)是机器学习管道中的一个必需部分。它允许更好地理解数据、其分布、纯度、特征等。此外,建议可视化,以向不同的利益相关者呈现机器学习工作的结果。他们可能不熟悉复杂的数据科学原理,但查看图形和图表对他们来说很方便。此外,如果不需要深入挖掘数据,数据分析和可视化可以作为独立的任务来完成。无论如何,一个好的数据科学家应该知道如何分析和可视化数据。

在本教程中,我们将展示如何分析数据,以及如何构建美观且信息丰富的图表。我们将使用流行的 Python 库进行可视化,即 matplotlib 和 seaborn。此外,我们将使用 Pandas 作为操纵数据帧的工具。我们将使用的数据集是学生表现数据集。我们将演示如何将数据加载到 AWS S3,以及如何通过 Dremio 将数据导入 Python。Dremio 也是数据管理和预处理的完美工具。这就是为什么我们会在 Dremio 中立即对数据做一些事情,然后再将它放入 Python 的手中。

假设

本文假设您拥有对 Dremio 的访问权限,并且拥有一个 T2 AWS 账户。我们将使用 Python 3.6PandasSeabornMatplotlib 包。要将 Dremio 连接到 Python,还需要 Dremio 的 ODBC 驱动。所有 Python 代码都是在 Jupyter Notebook 环境下编写的。

将数据加载到 AWS S3 有两种方式,通过 AWS web 控制台或以编程方式。在本教程中,我们将展示如何直接从 Python 代码向 S3 发送数据。为了能够从 Python 管理 S3,我们需要创建一个用户,您将代表该用户从代码中执行操作。为此,从 AWS 控制台的服务列表中选择,单击,然后按按钮:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

给新用户起一个名字(在我们的例子中,我们选择了 test_user )并为这个用户启用编程访问:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

下一步,您必须设置权限。在大多数情况下,这是一个重要的阶段,您可以为不同的用户调整权限。您甚至可以在这里创建自己的访问策略。但是在本教程中,为了简单起见,只给用户对 AWS S3 的完全访问权:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

创建用户后,您应该复制所需的凭证(访问密钥 ID 和秘密访问密钥)。您将在后面的代码中使用它们向 AWS S3 发出请求。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在配置文件中,设置要为其创建存储桶的区域,等等。在 S3:

现在一切都为编码做好了准备!先做点简单的吧。例如,显示 S3 的现有时段:

在上面的代码中,我们导入库 boto3 ,然后创建客户端对象。作为一个参数,我们指定“ s3 ”来表明我们想要使用这个 AWS 服务。之后,我们使用创建的对象的 list_buckets() 方法来检查可用的桶。下面是我们在响应变量中得到的结果(一个带有桶的空列表):

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

现在让我们创建一个桶。为此,使用客户端对象的 create_bucket() 方法:

下面是创建存储桶后, list_buckets() 方法的输出:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

您还可以在 AWS web 控制台中看到创建的存储桶:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们有两个文件需要加载到亚马逊 S3, student-por.csvstudent-mat.csv 。为了加载这些文件,我们使用客户端对象的 upload_file() 方法:

最后,您应该能够在 AWS web 控制台中看到这些文件(在前面创建的存储桶中):

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

连接到您的 AWS S3 数据源

要连接 Dremio 和 AWS S3,首先转到服务列表中的部分,选择 删除根访问密钥 选项卡,然后按下 管理安全凭证 按钮。然后选择 访问键 选项卡然后点击 新建访问键 按钮。按下 显示访问键 后,复制 AWS 访问键AWS 访问密码:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在 Dremio GUI 中,单击按钮添加新源。然后选择 亚马逊 S3 。应该会出现以下窗口:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在上面的窗口中,您应该指定源的名称( student_performance )以及您在上一步中生成的凭证。

准备您的数据

在这部分教程中,我们将展示如何处理关于学生在葡萄牙语课上表现的数据框架。然而,需要同样的行动来管理其他数据框架(关于数学课的表现)。

首先,打开 student_performance 源文件中的 student-por.csv 文件。请务必更改字段分隔符的类型(“;”),行分隔符(" \n "),并勾选 提取字段名 复选框,如下图所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们不需要 G1G2 列,我们把它们去掉吧。单击每列名称旁边的箭头,调出上下文菜单。然后从菜单中选择选项:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

通过同一个下拉菜单,我们可以将 G3 列重命名为 final_target 列:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

接下来,我们注意到所有的数值都是字符串数据类型。我们想把它们转换成整数。为此,单击列名附近的小 Abc 按钮,然后选择所需的数据类型:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

结果中将出现以下窗口:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

在这个窗口中,我们需要指定新列的名称(具有新数据类型的列),还需要设置一些其他参数。准备好后,按下按钮。我们应该对所有数字列进行类型转换,这些数字列是字符串: age、Medu、Fedu、traveltime、studytime、failures、famrel、freetime、goout、Dalc、Walc、health、absenties

在对数据执行上述所有操作后,我们将数据帧保存在名为端口 1学生性能空间中。

在 Dremio 中,您所做的一切都会在 SQL 代码中得到反映。例如,我们上面描述的所有操作都生成了下面的 SQL 代码(您可以通过点击 SQL 编辑器 按钮来检查):

此外,您可以编写自己的 SQL 查询。假设我们想要创建新的列 famsize_bin_int 。该列应为二进制。当来自列 famsize 的给定行中的值等于“GT3”时,它应该包含“1”;当 famsize 列中的相应值等于“LE3”时,它应该包含“0”。下面是实现这一想法的 SQL 代码:

在下图中,您可以看到在单击按钮后,列 famsize_int_bin 出现在 dataframe 中:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

最后,我们希望根据 final_target 列对 dataframe 中的值进行排序。我们希望在表格顶部看到分数最低的学生,因此我们从下拉菜单中选择 升序 选项:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

最后,我们在student _ performance _ space中以 port_final 的名字保存策划的数据帧。数学数据集也是如此(我们将其保存为 mat_final 表)。

连接到 Python

要连接 Dremio 和 Python 脚本,我们需要使用 PyODBC 包。下面的代码用于将 port_finalmat_final 表作为 pandas dataframes 导入 Python。

如您所见,我们需要指定主机、端口、dremio 凭证和 Dremio ODBC 驱动程序的路径。然后我们使用 PyODBC 对象的方法 connect()建立连接。Pandas 使用 read_sql()方法从远程数据源获取数据。在创建 SQL 查询时,我们使用了表的完整路径(name _ of _ the _ space . name _ of _ the _ data frame)。

Python 中的数据分析和可视化

探索性数据分析的主要目标是理解数据。它可以作为一项独立的任务,也可以作为机器学习过程中的准备步骤。EDA 有助于确定您的数据具有哪些特征,分布情况如何,是否需要进行数据清理和预处理等。

可能每个 EDA 都是从探索数据集的形状和浏览数据开始的。为了显示 dataframe 中的前 5 条记录,可以在 Pandas dataframe 上调用 head() 方法。您还可以将行数指定为该方法的参数。换句话说,5 是该方法显示的默认行数,但是您可以将其更改为 10,例如。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

要检查数据的形状,使用数据帧的形状属性:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

你可以看到葡萄牙语数据框中的行数远远多于数学数据框中的行数。此外,在本教程中,我们将只使用葡萄牙语数据帧,以避免文本过载。但是这些数据框架是完全相同的,如果你愿意,你可以用数学数据框架做同样的操作,并比较结果。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

现在我们只想看看来自市区的学生。为此,我们只提取那些在地址中包含值“U”的行:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

从上面的输出,我们可以说来自城市地区的学生比来自农村地区的学生多。例如,如果我们继续进一步研究机器学习模型,我们可能会发现这些信息对一些特征工程很有用。

除了 head()函数,还有另外两个 Pandas 方法允许查看数据帧的子样本。 tail() 方法从表的末尾返回行。 sample() 方法从 dataframe 返回随机的 N 行。如果您不仅想查看表的开头或结尾,还想显示数据帧不同部分的不同行,这可能会很有帮助:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

为了检查你的数据框架有哪些列,你可以使用属性:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

如果需要编写代码来处理列名,可以使用 Python 的原生列表轻松完成。

任何 EDA 中的一个重要步骤是检查数据帧是否包含空值。对于熊猫,这不需要任何复杂的代码就可以完成。只需在数据帧上调用 isnull() 方法,然后使用 sum() 方法聚合值:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

正如我们所看到的,我们的数据帧经过了很好的预处理,它不包含丢失的值。

同样,您可能希望查看不同列的数据类型。数据类型可通过 dataframe 的 dtypes 属性访问:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们数据集中的所有列要么是数字型(整数),要么是分类型(对象)。

了解数据集的基本统计数据通常很有用。在 Pandas 中,您可以通过调用 describe() 方法来实现这一点:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

此方法返回统计数据(计数、平均值、标准偏差、最小值、最大值等)。)关于数据帧的每个数字列。要查看关于分类特性的一些信息,您应该指定 describe() 方法的 include 参数,并将其设置为 [‘O’] (见下图)。但是对于分类列,该方法只返回计数、唯一值的数量、最频繁的值及其频率。我们的大多数分类列都是二元的:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

现在我们要用 Matplotlib 和 Seaborn 构建可视化。但是首先,我们需要导入这些包:

import matplotlib.pyplot as plt import seaborn as sns

让我们看看数据集中男性和女性的比例。为此,我们选择列性别,然后使用 value_counts() 方法,其中 normalize 参数等于 True 。然后我们调用 plot() 方法。这将使用 Matplotlib 来构建一个图形。我们可以看到数据集中的女生(大约 60%)比男生(大约 40%)多。相应的代码和可视化你可以在下面找到。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们已经看到了性别特征在数据集中的分布。但是通常,最有趣的列是目标列。在我们的例子中,这个列叫做 final_target (它代表一个学生的最终成绩)。这次我们将使用 Seaborn 制作一个图表。Seaborn 包有用于此目的的 distplot() 方法。我们指定的参数是颜色(绿色)和箱数 (10)。代码和图像如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

从上面的直方图中,我们可以说最频繁的等级在 10–12 左右,但是从左侧开始有一个尾部(接近零)。也许在未来,在建立模型之前,值得对目标变量的分布进行转换,使其更接近正态分布。

Seaborn 包有很多方便的比较图形的函数。其中一个函数是 pairplot() 。您可以选择要分析的列,Seaborn 将在对角线上构建这些列的分布,并在所有其他位置构建散点图。每个散点图显示两个指定列之间的相互关系。在我们的例子中,这种可视化可能没有它应有的用处。它更适合连续的特征,而不是整数。但是,您可以理解这种可视化的要点:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

让我们使用 Matplotlib 来看看数据集中所有数字列的分布。首先,我们创建一个只有数字列的 data frame(df _ num)。为此,我们使用 select_dtypes() Pandas 方法。我们指定只接受 float64int64 数据类型,但是对于这个数据集,只接受整数列就足够了(没有浮点值)。此外,我们删除了 famsize_bin_int 列,因为它最初不是数字。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

现在,我们在 df_num dataframe 上使用 hist() 方法来构建一个图:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

hist() 方法的参数中,我们已经指定了绘图的大小、标签的大小和容器的数量。

或许,分析不同列和特定条件下的值的范围是很有趣的。这是如何工作的。我们想看看 final_target 列的范围如何根据学生父母的工作而变化。为此,我们使用 Seaborn 的函数 boxplot() 。在此之前,我们使用 Matplotlib 调整绘图的大小。父亲工作的图表如下所示:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这是母亲工作的图表:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

箱线图允许查看平均值以及数据的高低四分位数。胡须显示了分布的其余部分。胡须外的点代表异常值。

从上面的图表中你可以得到一个有趣的认识,那就是如果学生的父亲或母亲是老师,那么这个学生很有可能获得高分。

同样的,我们可以看到女生在学业上比男生更成功:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

EDA 最有趣的一点是探索变量之间的相关性。我们可以分析相关性,然后使用 Seaborn 将其可视化。这里我们只看数字列。在为机器学习模型训练做真正的准备时,科学家应该对分类变量进行编码,并像处理数字列一样处理它们。但是这超出了我们教程的主题。

下面代码的第一行使用方法 corr() 来计算不同列和 final_target 特性之间的相关性。我们丢弃最后一条记录,因为它是 final_target (我们对 final_target 与自身具有完美相关性这一事实不感兴趣)。

代码的第二行过滤掉所有弱相关性。在我们的例子中,我们只想看相关性,它大于 0.12(绝对值)。我们还想对列表进行降序排序。

第三行只是打印出结果。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们可以看到,有 8 个特征与目标变量密切相关。有些是正相关,有些是负相关。例如,最强的负相关性与故障特征相关。如果学生过去成绩不好,他/她将来也可能继续学习不好,这是合理的。

此外,学生在周末或工作日饮酒越多,他/她的最终成绩越低。在空闲时间行程时间变量之间也存在负相关性。学生的空闲时间越多,他/她的表现就越差。旅行越多的学生成绩也越差。

同时,我们有 3 个与目标变量正相关:studytime,Medu,Fedu。很明显,你花在学习上的时间越多,你的学习成绩就越好。有趣的事实是,父母的教育程度也与孩子的表现密切相关。

在热图上,您不仅可以看到与目标变量的相关性,还可以看到变量之间的相关性。例如,父亲和母亲的教育程度、学生外出的时间和饮酒量、失败次数和学生年龄等之间有很强的相关性。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

探索相关性是 EDA 中最重要的步骤之一。它允许理解哪些功能可能是有用的,哪些是多余的,以及哪些新功能可以人工创建。

结论

在本文中,我们介绍了如何以编程方式将数据加载到 AWS S3,如何使用 Dremio 准备存储在 AWS S3 中的数据,以及如何在 Python 中分析和可视化这些数据。我们还展示了如何使用 Dremio 以及 Dremio 和 Python 代码连接到您的数据湖。在工作过程中,我们使用了 Matplotlib 和 Seaborn 包。

最初发表于【https://www.dremio.com】

创建 python CLI 应用程序的简单方法

原文:https://towardsdatascience.com/a-simple-way-to-create-python-cli-app-1a4492c164b6?source=collection_archive---------13-----------------------

将机器学习应用程序包装到命令行界面的简单示例

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

克里斯里德在 Unsplash 上的照片

当我们创建任何类型的应用程序时,我们必须提供一个其他人有机会使用的接口。我想向您展示一个将 ML 应用程序包装到 CLI 界面的简单示例。

我认为可以肯定地说,我们希望用最少的努力获得最好的结果。在这种情况下,fire库将是最好的选择。fire是一个库,由 Google 开发并广泛使用。让我们通过具体的例子来探索它的功能:

main.pyimport fire

def add(a: int, b: int):
    *"""
    Returns sum of a and b* ***:param*** *a: first argument* ***:param*** *b: second argument* ***:return****: sum of a and b
    """* return a+b

if __name__ == "__main__":
    fire.Fire({
        "sum": add
    })

这里fire从函数add创建 CLI 命令sum。从 python doc 中,它创建一个命令描述。

python main.py sum --help的输出:

NAME
    main.py sum - Returns sum of a and bSYNOPSIS
    main.py sum A BDESCRIPTION
    Returns sum of a and bPOSITIONAL ARGUMENTS
    A
        first argument
    B
        second argumentNOTES
    You can also use flags syntax for POSITIONAL ARGUMENTS

因此,您现在可以通过多种方式使用该命令:

python main.py 1 2

python main.py --a 1 --b 2

此外,您可以通过在函数定义中定义默认值来定义可选的命令参数:

def add(a: int, b: int = 2):
    *"""
    Returns sum of a and b* ***:param*** *a: first argument* ***:param*** *b: second argument (default: 2)* ***:return****: sum of a and b
    """* return a+b

现在python main.py sum --help的结果是:

NAME
    main.py sum - Returns sum of a and bSYNOPSIS
    main.py sum A <flags>DESCRIPTION
    Returns sum of a and bPOSITIONAL ARGUMENTS
    A
        first argumentFLAGS
    --b=B
        second argument (default: 2)NOTES
    You can also use flags syntax for POSITIONAL ARGUMENTS

因此,您现在可以通过多种方式使用该命令:

python main.py 1

python main.py 1 2

python main.py 1 --b 2

python main.py --a 1 --b 2

无需多言,您可以看到 CLI 应用程序配置是多么简单快捷。

现在让我们为 ML 应用程序的一个常见用例创建一个程序框架。假设您需要创建一个具有两个函数trainpredict的 CLI 应用程序。训练函数输入是训练数据和一些模型参数,输出是经过训练的模型文件。Predict 接受用于预测的输入数据、定型模型,并将预测保存到输出文件中。

除了函数映射,fire可以从 python 类实例创建 CLI 接口,在这种情况下,这可能是一个更好的选择。在我们的例子中,代码可能是:

import fire
import pickle
import logging

import pandas as pd
from sklearn.neighbors import KNeighborsClassifier

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

def load_model(model_path: str):
    *"""Loads model from `model_path`"""* with open(model_path, 'rb') as file:
        saved_model = pickle.load(file)
        return saved_model

def save_model(model, model_path: str):
    *"""Saves `model` to `model_path`"""* with open(model_path, 'wb') as file:
        pickle.dump(model, file)

class Classifier:
    *"""
    Some classifier, that makes some random classifications.
    """* def train(self, train_data_path: str, model_path: str, k: int = 5):
        *"""
        Trains model on `train_data_path` data and saves trained model to `model_path`.
        Additionaly you can set KNN classifier `k` parameter.* ***:param*** *train_data_path: path to train data in csv format* ***:param*** *model_path: path to save model to.* ***:param*** *k: k-neighbors parameter of model.
        """* logger.info(f"Loading train data from {train_data_path} ...")
        df = pd.read_csv(train_data_path)
        X = df.drop(columns=['y'])
        y = df['y']

        logger.info("Running model training...")
        model = KNeighborsClassifier(n_neighbors=k)
        model.fit(X, y)

        logger.info(f"Saving model to {model_path} ...")
        save_model(model, model_path)

        logger.info("Successfully trained model.")

    def predict(self, predict_data_path: str, model_path: str, output_path: str):
        *"""
        Predicts `predict_data_path` data using `model_path` model and saves predictions to `output_path`* ***:param*** *predict_data_path: path to data for predictions* ***:param*** *model_path: path to trained model* ***:param*** *output_path: path to save predictions
        """* logger.info(f"Loading data for predictions from {predict_data_path} ...")
        X = pd.read_csv(predict_data_path)

        logger.info(f"Loading model from {model_path} ...")
        model = load_model(model_path)

        logger.info("Running model predictions...")
        y_pred = model.predict(X)

        logger.info(f"Saving predictions to {output_path} ...")
        pd.DataFrame(y_pred).to_csv(output_path)

        logger.info("Successfully predicted.")

if __name__ == "__main__":
    fire.Fire(Classifier)

python main.py的输出为:

NAME
    main.py - Some classifier, that makes some random classifications.SYNOPSIS
    main.py COMMANDDESCRIPTION
    Some classifier, that makes some random classifications.COMMANDS
    COMMAND is one of the following:predict
       Predicts `predict_data_path` data using `model_path` model and saves predictions to `output_path`train
       Trains model on `train_data_path` data and saves trained model to `model_path`. Additionaly you can set KNN classifier `k` parameter.

以及相应的命令文档:

python main.py train --help:

NAME
    main.py train - Trains model on `train_data_path` data and saves trained model to `model_path`. Additionaly you can set KNN classifier `k` parameter.SYNOPSIS
    main.py train TRAIN_DATA_PATH MODEL_PATH <flags>DESCRIPTION
    Trains model on `train_data_path` data and saves trained model to `model_path`. Additionaly you can set KNN classifier `k` parameter.POSITIONAL ARGUMENTS
    TRAIN_DATA_PATH
        path to train data in csv format
    MODEL_PATH
        path to save model to.FLAGS
    --k=K
        k-neighbors parameter of model.NOTES
    You can also use flags syntax for POSITIONAL ARGUMENTS

python main.py predict --help:

NAME
    main.py predict - Predicts `predict_data_path` data using `model_path` model and saves predictions to `output_path`SYNOPSIS
    main.py predict PREDICT_DATA_PATH MODEL_PATH OUTPUT_PATHDESCRIPTION
    Predicts `predict_data_path` data using `model_path` model and saves predictions to `output_path`POSITIONAL ARGUMENTS
    PREDICT_DATA_PATH
        path to data for predictions
    MODEL_PATH
        path to trained model
    OUTPUT_PATH
        path to save predictionsNOTES
    You can also use flags syntax for POSITIONAL ARGUMENTS

使用示例:

python main.py train train.csv knn.sav --k 7
python main.py predict test.csv knn.sav out.csv

现在,您可以使用这个代码片段来创建自己的 CLI 应用程序。进一步改进的一些提示:

  1. 使用日志记录代替打印
  2. 创建参数验证
  3. 为最终用户创建带有简短应用程序使用说明的自述模板。
  4. https://github.com/google/python-fire上探索更多酷炫功能

我希望这篇文章将是有用的和信息丰富的。期待您的反馈!

向您的 Dash 应用程序添加广告身份验证

原文:https://towardsdatascience.com/a-simple-way-to-integrate-dash-with-ldap-4d5d059ee3a6?source=collection_archive---------14-----------------------

使用 Flask 集成 Dash 和 LDAP 的一个非常简单的方法

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

Unsplash 上由 Dane Deaner 拍摄的照片

在大多数组织中,登录凭证由目录服务(如 Active Directory)管理。如果您设法将 Dash 与您组织的目录服务相集成,那么用户只需使用他们现有的凭证登录您的 Dash 应用程序。一种常见的方式是通过 LDAP (一种用于与 Active Directory 等目录服务对话的开放协议)和 Flask (一种轻量级 web 应用程序框架)。在这篇文章中,我将演示如何用 Python 中的 Dash 以最简单的方式集成 LDAP 和 FLASK。

先决条件

在进入任何代码之前,您需要已经启动并运行了 LDAP。这是一个重要的步骤,超出了本文的范围,本文只关注 Python 方面的内容。然而,如果你需要广告整合,我假设你在一个有自己 IT 部门的大公司工作,希望这个部门(1)不是你,( 2)愿意帮助你!

假设 LDAP 已经启动并运行,继续运行以下命令,从 GitHub 克隆示例代码:

git clone https://github.com/epetrovski/dash_ldap

我们还需要几个库来构建一个 Dash 应用程序,并让它与 LDAP 一起工作——总共四个。如果您已经使用了 Pipenv ,只需在克隆的 dash_ldap 目录内的终端中运行以下命令,即可获得一个安装了依赖项的完整的工作虚拟环境:

pipenv sync

如果您不想弄乱 Pipenv,只需安装您需要的依赖项:

pip install dash flask flask-simpleldap gunicorn

app.py 演练

你需要的所有代码都在 app.py 里。让我们一行一行地过一遍。

第一个技巧是让 Dash 在一个 Flask 应用程序中运行,这个应用程序向外界提供 Dash 应用程序。这是通过在初始化时将 Flask 对象传递给 Dash 应用程序的服务器参数来实现的,如下所示:

app = Dash(__name__, server=Flask(__name__))

然后,为了举例,我们定义一个 Dash 应用程序。这个应用程序只是一个简单的占位符,但是不要担心,当你用高级回调等构建自己的应用程序时。,它不需要对 LDAP 集成设置进行任何更改。

app.layout = html.P('Hello world!')

您现在需要通过更新 Flask 的配置字典来为 LDAP 配置 Flask。下面的详细信息只是一个占位符,因为您的凭据将取决于您公司的 LDAP 设置—再次询问!

app.server.config.update({
   'LDAP_BASE_DN': 'OU=users,dc=example,dc=org',
   'LDAP_USERNAME': 'CN=user,OU=Users,DC=example,DC=org',
   'LDAP_PASSWORD': os.getenv('LDAP_PASSWORD')})

你可能已经注意到,我冒昧地在LDAP_PASSWORD后面加了一个os.getenv()。我假设你永远不会在代码中存储密码,而是使用类似于环境变量的东西。

非常重要的是,现在我们需要通过用LDAP(app.server).basic_auth_required()包装所有已经用 Flask 注册的视图函数来保护它们:

for view_func in app.server.view_functions:
   app.server.view_functions[view_func] = LDAP(app.server).basic_auth_required(app.server.view_functions[view_func])

最后,我们可能需要一种方法来快速运行 Flask 应用程序以进行测试。通常我们会使用app.run(),但是因为这个应用是在 Flask 服务器上提供的,所以我们使用app.run_server():

if __name__ == '__main__':
   app.run_server()

测试一下

您可以通过运行以下命令来确认 AD 集成正在运行:

python3 app.py

现在导航到 http://127.0.0.1:8000 ,您应该会看到一个登录提示。输入你的身份证明,你应该会看到“你好,世界!”首页。

既然您对一切顺利运行感到满意,请记住,使这一切工作的关键部分是 flask-simpleldap 包。这是一个很棒的 Python 包,它可以解决一个非常乏味但却至关重要的 It 需求。

投入生产

如果您在生产中运行 Dash 应用程序,您应该在生产级 http 服务器上运行该应用程序,如 gunicorn 。您已经安装了这个,所以只需运行:

gunicorn app:server

这是因为在app.py中,我定义了:

server = app.server

这就是你要的,一个登录受保护的 Dash 应用程序,集成了一个目录服务,适合生产!

在 Python 中优化“某物”的简单方法

原文:https://towardsdatascience.com/a-simple-way-to-optimize-something-in-python-740cda7fd3e0?source=collection_archive---------15-----------------------

使用 Python 中的线性规划解决预算优化问题

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

UnsplashNeONBRAND 拍摄的照片

为什么优化预算很重要?它让我们能够控制广告支出,决定花费多少,并最大化预期结果(访问,点击等)。例如,给定 10,000 美元的预算及其约束条件,我们能够确定每个营销渠道的最优预算分配,从而使**结果最大化。**这将使我们能够避免在单一渠道上的拥挤,即我们把所有东西都放在一个篮子里,而是分散到表现最好的渠道。

优质的预算优化策略可以显著提高搜索广告活动的效果,从而帮助广告主在激烈的在线营销竞争中取得成功。

什么是线性规划?

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

线性规划优化中的一个线性规划问题的图解

线性规划(LP)是获得最佳结果的最广泛使用的优化技术之一。David G. Luenberger 所著《线性和非线性编程》一书摘录:

顾名思义,线性规划问题的特征在于未知数的线性函数;目标在未知数中是线性的,约束是未知数中的线性等式或线性不等式。

似乎线性规划的流行主要在于分析的公式化阶段,而不是求解阶段——这是有道理的。因此,对于我们今天所关心的问题,它可以表述为:

预算约束限制在三个不同渠道(电视、广播、报纸)之间分配的资金总量,预算约束采用 x1 + x2 + x3 ≤ B 的形式,其中 B 是预算。电视的总花费应该少于 200 美元,广播应该少于 500 美元,报纸应该少于 500 美元。而总预算上限为 1000 美元。

除此之外,我们还应该找出一个问题的目标函数,在这个问题中,我们计划最大化或最小化我们喜欢的结果(点击、销售等)。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

从 David G. Luenberger 于 1973 年出版的《线性和非线性规划》一书中获得的线性规划问题公式示例

我将使用来自 Kaggle 的开源广告数据集来展示它是如何工作的!

履行

理想情况下,当使用 LP 时,目标函数应该是线性的。

如果一个目标函数由于其固有的定义而不是纯线性的,那么将其定义为线性的往往比决定某种其他函数形式并使其他人相信更复杂的形式是最好的选择要容易得多。因此,线性由于其简单性,经常被选择作为简单的解决方法,或者当寻求一般性时,被选择作为在一类类似问题中同样适用(或不适用)的唯一函数形式

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

纸浆优化工艺2009

建立预测模型

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

数据帧

我们首先使用 SK-Learn 的线性回归建立一个多元线性回归模型。这个内核提供了一个很好的方法来验证线性回归是否可以被使用,因为线性回归受到几个假设的限制。

### SCIKIT-LEARN ###feature_cols = ['TV', 'Radio', 'Newspaper']
X = df_advertising[feature_cols]
y = df_advertising[["Sales"]]# instantiate and fit
lr = LinearRegression()
model = lr.fit(X, y)# print the coefficients
print(SkLearn_result.intercept_)
print(SkLearn_result.coef_)

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

y 轴截距和系数

我们能够从给定的模型中获得 y 截距和系数。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们模型的准确性

RMSE 为 1.509,我们的模型非常准确,根据上图,我们可以看到,与实际值相比,它的预测相对较好。有了预测模型,我们现在可以开始构建线性规划的目标函数。

使用 LP 优化

我们将使用一个名为 PuLP 的 python 包。这是一个针对 Python 的优化包。纸浆是直截了当的,非常容易使用!

prob = LpProblem("Ads Sales Problem", LpMaximize)

我们从使用 LpProblem 函数定义问题开始,我们希望最大化输出,因此“LpMaximize”将是参数。然后,我们将指定我们的约束条件,例如我们应该为给定的渠道花费多少预算。

#TV <= 200
x = LpVariable("x", 0, 200)#Radio <= 500
y = LpVariable("y", 0, 500)#Newspaper <= 500
z = LpVariable("z", 0, 500)#Should be less than $1000
prob += x + y + z <= 1000

有了约束条件,我们现在可以使用模型给出的系数构建我们的目标函数:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

coef = model.coef_prob += coef.item(0) * x + coef.item(1) * y + coef.item(2) * z + model.intercept_[0]

然后通过调用 solve()函数,它将为我们解决这个问题,我们还可以检查优化的状态。通过打印它,我们可以得到下面的结果。

prob.solve()
LpStatus[status]

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们如何知道每个变量的最优值?

只需使用一个简单的 for 循环来访问概率变量,我们就能够获得每个变量的最优值以及下面的最大目标值。

for v in prob.variables():
    print(v.name, "=", v.varValue)

print("Objective = %f" % (prob.objective.value()))

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

分析

现在我们知道了每个营销渠道应该花多少钱,我们肯定应该使用它作为基线模型来分配我们下一次营销活动的预算。实际上,我们可以实现整个流程的自动化,在这一过程中,每天都可以为一次活动分配或优化预算。

结论

当可以应用于正确的用例时,优化的线性规划是强大的,因为它提供了关键的管理洞察力。广告商通常将预算视为简单的约束,并投入大量精力来寻找更有效的方式,以实现各种市场所定义的可能运营。一个简单的预算分配和调整策略可以在活动管理中显著减少有效点击/收入/销售方面的损失。

参考

  1. 线性和非线性规划https://www.springer.com/gp/book/9780387745022
  2. 纸浆—【http://coin-or.github.io/pulp/
  3. 本教程的资源库—https://github . com/georgeblu 1/Data-Projects/blob/master/Budget % 20 optimization . ipynb
  4. https://towards data science . com/linear-programming-and-discrete-optimization-with-python-using-pulp-449 F3 C5 F6 e 99

图像引用

  1. https://www . researchgate . net/figure/Graphical-solution-of-a-linear-programming-problem _ fig 1 _ 2420905
  2. https://link.springer.com/book/10.1007/978-0-387-74503-9
  3. http://coin-or.github.io/pulp/

如果您有任何问题或反馈,请随时通过我的 LinkedIn 联系我。简单介绍一下,我是 Airasia.com 的一名数据科学家,专注于打造优秀的产品和推动增长,因为我热爱我所做的事情。

如何挑选合适的型号

原文:https://towardsdatascience.com/a-simple-way-to-pick-the-right-model-d362272b453d?source=collection_archive---------32-----------------------

从精确度分布来看,IQR 和箱线图是选择最佳模型的一种方法

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

来源

在数据科学中,发现自己有几个表现几乎相同的模型/方法并不少见。当这种情况发生时,您如何知道选择哪个模型呢?在本文中,我将介绍一种选择最佳模型的方法,即真实模型。

我将使用乳腺癌威斯康星州数据集,可在这里:【https://www.kaggle.com/uciml/breast-cancer-wisconsin-data】T2。它包含 569 个观察值和 32 个描述性变量。因变量诊断是二元的。如果癌症是恶性的,它等于 1,如果癌症是良性的,它等于 0。让我们从导入所需的包和数据开始。

library(ggplot2)
library(randomForest)
library (e1071)
library(devtools)
library(ggbiplot)**#Import data** df = read.csv("data.csv")

然后,快速地,让我们清理数据(有些列是空的或无用的),将诊断变量转换为[0,1]变量,而不是字符串。

**#Y as factor** df$diagnosis =  ifelse(df$diagnosis=="M", gsub("M", 1,                                                            df$diagnosis), gsub("B", 0, df$diagnosis))df$diagnosis = as.factor(df$diagnosis)**#Remove useless columns** df = df[,c(-33,-1)]

这是因变量的分布:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

诊断分布

这些课程看起来并不不平衡。我们现在可以进入下一步了。下面,我将创建一个“for 循环”。在循环的每次迭代中,我会将数据分成两组,训练和验证。之后,我将使用随机森林、SVM 和逻辑回归来训练和预测三个独立的模型。通过将所有这些放入一个“for 循环”并每次改变种子,它将允许我每次收集三个模型在每次迭代中的精度性能。更改 set.seed()会更改训练和验证之间数据的随机重新分配。

这实质上是同时在三个模型上进行交叉验证。这也是有益的,因为它允许我每次都在相同的数据集上比较模型。对于每次迭代,每个模型都在相同的数据上进行训练和验证。这意味着我们可以在每个拟合模型之间进行公平和一致的比较。代码如下:

这是三个模型在 200 次迭代中的平均精确度:

  1. 随机森林:96.7%
  2. SVM: 95.1%
  3. 逻辑回归分析:97.1%

逻辑回归似乎是该数据集的最佳算法。然而,要选择正确的模式,我们不能止步于此。

选择正确的模型

查看上面的结果,我们看到逻辑回归胜出,但其准确性与其他模型准确性的差异并不显著。为了知道我们是否真的有最好的模型,我们需要查看准确性度量的分布。这类似于边际解释 vs 条件解释的思想:无论数据如何,模型平均来说是好的还是总是表现良好。

这很有用,因为它让我们知道模型是否总是精确的,或者它们的性能是否是可变的。根据具体情况,我们可能需要最佳平均模型或最小变量模型。拥有准确的分布信息只会有助于做出一致的选择!

以下是如何使用密度函数获得存储在 result_matrix 中的分布图:

a=density(result_matrix[,1])**#Getting the plot** plot(a, xlim=c(0.92, 1), ylim=c(0, 60), col='blue', lwd=2, main='Accuracy distribution of all models',
     xlab='Accuracy')
lines(density(result_matrix[,2]), col='red', lwd=2)
lines(density(result_matrix[,3]), col='green', lwd=2)
legend(x=0.975, y=59,legend = c("Random Forest", "SVM", "Logistic Regression"), col = c("blue","red", 'green'), lty = c(1,1))

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

三种模型的精度分布

我们看到,逻辑回归似乎确实比随机森林好得多,即使两种精度分布都非常对称地分布在它们的平均值附近(逻辑回归似乎稍微瘦一些)。事实上,这两种分布看起来都很正常。然而,SVM 分布似乎更易变,传播范围更大,几乎第二次达到约 95%的准确性。

我们还可以获得箱线图和分位数间范围,这将让我们看到我们是否有异常值(使用箱线图),以及在我们的准确度值中第一和第三分位数之间的范围有多窄(使用 IQR)。下面是如何做到这一点:

**#Boxplots** boxplot(result_matrix, use.cols = TRUE, 
       main='Boxplot by algorithm', 
       ylab='Accuracy', xaxt = "n", col=c('blue', 'red', 'green'))
axis(1, at=1:3, labels=c('Random Forests', 'SVM', 'Logistic           Regression'))**#IQR** IQR(result_matrix[,1])
IQR(result_matrix[,2])
IQR(result_matrix[,3])

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

三种模型的箱线图

以下是三种算法的 iqr:

  1. 随机森林:1.05
  2. SVM: 1.4
  3. 逻辑回归:1.05

这意味着对于随机森林和逻辑回归,50%的值(在第一个和第三个分位数之间)在 1.05%的精确度范围内。对于 SVM 来说,IQR 更宽一些,为 1.4%。

查看箱线图,我们看到的是,对于所有三种方法,我们只有很少的异常值(1 或 2)。逻辑回归只有 1,而随机森林有 2。

现在,我相信我们可以客观地说,逻辑回归算法是在我们的情况下使用的最佳算法,我们有数据来证明这一点。

感谢阅读!

一个简单而有用的 EDA 数据可视化库

原文:https://towardsdatascience.com/a-simple-yet-useful-data-visualization-library-for-your-eda-76c41a46d63b?source=collection_archive---------76-----------------------

探索性数据分析/双变量分析/数据科学

以有意义的方式可视化因变量和任何特征之间的关系

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

探索性数据分析(EDA)尤其适用于包含表格数据的项目。在 EDA 过程中,谨慎的数据科学家通常会通过寻找异常值或检查某些列是否有异常数量的缺失值来评估数据集的质量。EDA 也是初步了解预测变量和因变量之间的二元关系的理想平台。

对于连续数据,传统的线性相关系数通常表现不错,可以快速显示最具预测性的特征。然而,对于分类数据,事情变得有点复杂。

令我惊讶的是,我找不到一个 python 库*可以让你快速理解目标和任何预测器之间的关系,不管它们是什么类型(连续的还是分类的)。因此,我决定按照以下要求编写自己的工具:

  • 提供与数据类型无关的统一接口
  • 生成易于传达给非技术受众(如业务利益相关者)的视觉输出

这篇文章的目的是提供一个图书馆主要功能的游览。这个库被命名为 tprojection,它可以在 GitHub 上获得,并且可以很容易地用 pip 安装

pip install tprojection

我将使用流行的 Titanic 数据集来说明该库的主要功能。

案例 1:目标和预测都是分类的

构建预测模型时,您通常会寻找允许您定义与目标值有很大差异的部分的特征。这些都是很好的预测。

当目标和预测器都是分类的时,您可以通过将目标投影到每个设备上来评估预测器的质量。这可以通过一个熊猫声明来实现:

df.groupby(predictor).agg({target: [“mean”, “count”]})

如果我们对预测值“性别”应用此命令,并且目标从 Titanic 数据集中“幸存”,我们将获得类似的结果:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

从这个结果来看,很明显男性比女性更不容易存活。在其最基本的用途中,库投影将简单地提供一种可视的方式来携带上述信息。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

此图表显示了目标“存活”和预测值“性别”之间的关系。蓝色条表示每种设备的观察次数(左侧 y 轴)。红线代表每个设备的目标平均值(右侧 y 轴)。黑色虚线表示目标在整个数据集上的平均值(右侧 y 轴)。红色阴影区域是通过引导数据估计的置信区间。

上面的图表可以用几行代码生成:

from tprojection import Tprojection
from tprojection.datasets import load_datadf = load_data("titanic")
target = "survived"
predictor = "sex"tproj = Tprojection(df, target, predictor, target_type=”categorical”, feature_type=”categorical”, n_estimators=100)
tproj.plot()

首先,用所需的参数和选项创建一个 Tprojection 实例。然后,调用方法plot并绘制图表。标题中提供了情节的完整描述。请注意,图表坐标轴存储为属性(tproj.ax1tproj.ax2),因此您可以轻松地更改图表的属性。

当观察数量变小时,置信区间(红色阴影区域)特别有用。在这种情况下,我们可能会观察到条件平均值与基线概率的较大偏差,这表明该模态适用于分割目标。然而,当置信区间很大时,这种解释必须小心。事实上,这意味着预测值和目标值之间的关系可能在不同的引导样本中有很大差异,这表明存在过度拟合的风险。

这种影响在下图中可以清楚地看到,该图分析了该目标对父母/子女人数的依赖性。对于模式parch = 3parch = 5,我们观察到存活率相对较高,而相关的置信区间跨越基线概率的两侧。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

目标“存活”和预测值“烤焦”之间的关系。

有趣的是,与parch = 4parch = 6相关联的置信区间的宽度等于零,即使相应的观察数量很小。当目标和模态之间存在一对一的关系时,就会发生这种情况。换句话说,在载有 4 或 6 名父母/儿童的乘客群体中没有幸存者。

该库还可以处理具有高基数的预测器。在这种情况下,显示设备的完整列表会使图表变得非常模糊。为了解决这一点,您可以向 tprojection 传递一个可选参数,该参数允许您根据最大值nb_buckets对设备进行分组。

tproj = Tprojection(df, target, “parch”, target_type=”categorical”, feature_type=”categorical”, n_estimators=100, nb_modalities=10)
tproj.plot()

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

预测者“小屋”和目标“幸存”之间的关系。左图显示原始设备,右图显示分时段设备。

上面的图表清楚地显示了这种方法的好处。左图显示了原始模态的预测值“舱室”和目标值之间的关系,无法阅读。右边的图更清晰,因为它只显示了一些编码的模态。可以通过一个属性来访问原始设备和编码设备之间的映射:

print(tproj.encoding)

当其他模态被分组时,投影将试图“按原样”保存具有足够数量观察值的模态。t 投影旨在构建包含大约相同数量观察值的nb_buckets组。然而,这并不总是可能的,特别是如果模式的分布严重倾斜。而实际情况往往如此。在上面的例子中,我们最初需要 10 个桶,但最终只需要 3 个桶。这是因为模态cabin = nan构成了几乎 80%的观察结果。因此,剩余的观察值仅分布在 3 个桶上。桶g1g2各包含大约 10%的观测值,其余的分配给g3

情况 2:目标是连续的,而预测值是分类的。

这在某种程度上是第一种情况的变体。除了目标平均值之外,我还添加了一个箱线图,描述目标在每种设备上的分布。置信区间的计算和显示已被禁用,以保持 viz 可读。

tproj = Tprojection(df, "fare", “cabin”, nb_modalities=10)
tproj.plot()

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

预测“舱位”(分桶)和目标“票价”之间的关系。

在上面的代码片段中,没有指定选项target_typepredictor_type。在这种情况下,库使用经验法则来评估变量是连续的还是分类的。

情况 3:目标是分类的,而预测值是连续的

在这种情况下,我们简单地比较由目标值决定的预测值的分布。为了便于比较,直方图被归一化。图例中提供了每个目标值的计数。

tproj = Tprojection(df, "survived", “fare")
tproj.plot()

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

预测值“票价”和目标值“存活”之间的关系。

默认情况下,正类对应于二进制目标的少数类。您可以通过用可选参数target_modality指定所需的值来改变这种行为。在这个阶段,tprojection 还不能真正处理多类问题,但是请注意,您可以通过使用target_modality kwarg 来模拟一种以一敌众的方法。

情况 4:预测值和特征都是连续的

包含这个案例是为了详尽,但它肯定不是项目带来最大价值的地方。该库只显示两个变量的散点图以及线性相关系数。还显示了从 seaborn regplot方法得出的最佳回归线。没有额外的特殊功能,因为有许多好的工具提供高级功能来分析两个连续变量之间的相关性。

tproj = Tprojection(df, "fare", “age")
tproj.plot()

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

预测值“年龄”和目标值“票价”之间的关系。

那都是乡亲们!我希望你会发现这个简单的库很有用。随意派生出 repo ,破解代码,并使其适应您的需求。

*免责声明:我在发布这个帖子之前发现了伟大的 sweetviz 库。尽管 sweetviz 包括类似的功能和更多功能,我仍然认为 tprojection 带来了有趣的特性。尤其是关于置信区间的内置估计或它处理高基数预测值的方式。

一种使用 PyCaret 进行异常检测的简化方法

原文:https://towardsdatascience.com/a-simplified-approach-using-pycaret-for-anomaly-detection-7d33aca3f066?source=collection_archive---------44-----------------------

用 python 中的 PyCaret 包解释离群点检测。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

鲁珀特·布里顿在 Unsplash 上拍摄的照片

什么是异常?

按照谷歌的定义“ ”偏离标准、正常或预期的 ”的东西。同样的引用适用于数据科学领域,我们遇到了这样的异常,需要检测、处理或消除这些异常,以提供更好的业务解决方案或建立最佳的预测机器学习模型。就数据集而言,这些异常也被称为“异常值”,也指新奇、噪声、偏差和异常。

异常检测用例

有各种各样的领域实施这种技术,例如故障检测、入侵、欺诈检测、医疗保健监控、检测生态系统干扰等等。

在本文中,我们将学习如何使用 python 中的 PyCaret 库,通过几个步骤来检测给定数据集的异常值。

👉安装 PyCaret 库

建议在安装 PyCaret 库之前创建一个单独的 Conda 环境。如果您尝试在基本环境中安装它,可能会出现一些与依赖项相关的错误。当我尝试在一个新的单独的 Conda 环境中安装时,它很容易安装。要通过创建新的 Conda env 来了解安装的完整细节,请单击[ 此处

为了演示 PyCaret 库的异常值检测,我创建了一个数据集,并有意引入了一些极值。

在继续之前,请查看异常检测模块文档及其工作原理,以便更好地理解[ 此处为 ]

👉创建数据集

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

数据集中突出显示的异常值

👉导入模块并初始化设置()

setup()函数将采用强制数据帧参数,并在执行后开始处理。它自动推断变量的所有数据类型,要求我们确认或退出。从下面可以看出,数据类型被推断为分类的而不是数值的。我们需要包含另一个参数来更改数据类型。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

输入退出,因为数据类型不是分类的

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

添加 numeric_features 参数后安装完成

👉创建模型

create_model()函数用于创建模型,有许多预定义的算法可用。我选择了“隔离森林”估计量,缩写为“iforest”。它返回训练好的模型对象。它们是“knn”,“PCA”,“SVM”,以及更多可供探索的模型。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

使用 iforest 训练模型

👉可视化离群值

感谢 PyCaret 如此精彩的 3d 剧情。从下面的图中,我们可以看到黄点代表异常值,这些标记为 1。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

表示标签的 3D 可视化绘图

👉分配标签

assign_model()函数返回带有异常值标志(1 =异常值,0 =内部值)和决策得分的数据帧。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

离群值用标签值 1 表示

现在我们可以看到 PyCaret 如何轻松地检测异常值。还有其他函数也可用于预测,以便在该模块中保存和部署模型。请在此浏览 py caret中异常检测模块的文档

总结

在数据科学领域,有许多统计技术和传统方法可用于检测异常值。人们应该了解这些技术,以获得这一概念背后的基本原理,并在处理异常值时理解业务的细微差别。

本文通过一个示例数据集来展示 PyCaret 库在异常检测方面的强大功能,以便更好地理解。您可以使用真实数据集在项目中实现这种方法,以节省时间并捕捉美丽的图形。

我成为了 PyCaret 库的粉丝,我希望你也能经历同样的事情😊

你可以从我的 GitHub [ 链接 ]中找到代码

参考文献

  1. https://pycaret.org/anomaly-detection/
  2. https://pycaret.org/
  3. https://www.youtube.com/watch?v=q0dxYDq1A40

感谢阅读,快乐学习!🙂

ML 术语被终结:电气和电子工程师的监督机器学习

原文:https://towardsdatascience.com/a-simplified-explanation-of-supervised-machine-learning-for-electrical-and-electronics-engineers-6d533cdedc6d?source=collection_archive---------63-----------------------

电气和电子工程师监督机器学习术语的简单解释

如果你进入了电气或电子工程领域(就像我曾经自己一样),你可能一直在和电阻、电容和电感打交道。

假设您以前没有去过实验室,但您还是仔细阅读了实验室分发的材料,并且能够识别出在实验过程中提供给您的不同电阻、电容和电感。

恭喜你!你的大脑刚刚执行了一个监督机器学习算法。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图像来源

为什么我称之为监督?

因为你已经知道它们是什么,它们看起来是什么样子,可能是它们如何工作的一些细节。这是训练机器的经典方法之一,向它们提供每个小数据单元的含义。

因此,让我们按顺序将其分解为机器学习术语:

1.实例或数据点

知识的来源是以文本、数字或图像的形式呈现的信息单元,就像你在去实验室之前已经在你的讲义中学习过的那样。对你来说,成功识别的食物是你手中的照片,可能类似于下面的照片。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图像来源:图像一图像二图像三

2.数据标志

你认为之前的图像有足够的信息吗?你怎么知道哪张图是电阻还是电容?你的传单上一定有图片说明。所以你知道了每张图片对应的是什么。

考虑一下这个:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图像来源:图像 1图像 2图像 3

因此,每当你指出一个实例并告诉你的计算机它是什么时,它就被称为数据标签,无论你告诉你的计算机关于你的实例的什么都是你的数据标签

3.特征

你有没有注意到电阻的黄色调和红蓝带?或者可能是他们的沙漏图。你一定注意到了电容器的圆柱形状。陶瓷电容器是圆形和扁平的。至于电感,你一定注意到了它们周围的线圈。

这些都是电阻、电容和电感的特性或特征,有助于你正确识别它们。你基本上有一个如何识别它们的思维导图,但是在把它们输入 Excel 表格后,看起来会像这样。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

你看到“标签”一栏了吗?这个标签列就是我们在电子白板上预测的那个。

4.培训用数据

你在传单上读到的一切都是你的训练数据。对于一个机器学习算法来说,表中的观察值汇总就是训练数据。

5.监督机器学习算法

一旦你在脑海中有了自己的特征,你就已经试着在黑板上寻找模式并匹配它们。人类的思维很敏捷,不是吗?

机器学习模型的基础是良好的数据。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图像来源:图像一图像二图像三

如果你有这样的图像,就很难画出图案。机器学习算法本质上是从训练数据中的大量实例中学习,并试图找到类似人脑的模式。

但是我们为什么需要机器学习算法呢?

这里看起来很简单,有三个不同的标签。嗯,在大多数真实世界的场景中,情况并非如此。将会有成千上万的标签和天文训练实例。这能用人脑测量吗?不是吧?我们有自己的局限性,这就是为什么我们需要计算机辅助预测。我们利用机器的巨大计算能力,这就是为什么使用机器来学习模式是重要的。

6.测试数据和性能

当你试图从一个电容中识别出一个电阻时,你已经在处理测试数据了。测试数据是机器应用识别的模式并试图预测标签的看不见的实例。

现在,想象一下,如果您的实验室教师对每个正确的电阻给一分,对每个识别错误的电阻扣一分。然后将你的总分加起来,你发现你在我们班排名第五。

类似地,机器学习算法根据其在测试数据上的性能进行评估。对于监督学习,最常见的指标是准确度、精确度和召回率。重要的是要评估性能指标,以了解哪个是性能最好的模型。

7.因此,让我们尝试一个测试实例

你认为这是什么?

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图像来源

两个固定的圆柱形平顶物体,有一个线圈——它是一个感应器。

盛大,你猜对了!您刚刚使用训练数据集中的特征通过监督方法正确标记了一个看不见的感应器,这就是监督 ML 算法所做的事情!

图片来源:图片用于演示,来源于图片标题中提到的链接。没有侵犯版权的意图。

我的链接: |LinkedIn|GitHub

感谢光临。我希望你喜欢阅读这篇博客。

分析飞机登机方法的模拟框架

原文:https://towardsdatascience.com/a-simulation-framework-to-analyze-airplane-boarding-methods-410def726350?source=collection_archive---------14-----------------------

开发 Python 程序来计算各种配置的登机时间并可视化登机程序

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

照片由 Suhyeon ChoiUnsplash 上拍摄

1.介绍

人们害怕字母 C 有各种各样的原因。较低的学术等级用 C 表示,复杂的、较低级的编程语言被命名为 C,然而,在一个晴朗的冬天早晨,最让我害怕的 C 出现在我的登机牌上——西南寄宿组 C。

对于那些不熟悉西南航空公司登机流程的人,在办理登机手续时,您会被分配到三个组别(A、B 或 C)中的一个。A 组先登机,然后是 B 组,最后是 c 组。每个人在队列中都有一个号码(例如 A-10 或 B-25),并根据各自组的号码登机。当我的航班被指定 C-10 号时,你可以理解我的沮丧。

因此,我是最后几个登机的人之一。当 A 组和 B 组登机的时候,我在悲伤和安静的沉思中度过。我从来没有真正考虑过航空公司如何选择登机,但那天我考虑了。我想知道分析登机程序和比较各种方法的性能的可能性。

2.这个想法

如果给你一架飞机和几百名志愿者,让你测试一种登机方法的性能,你会怎么做?简单!给他们分配座位,排好队,装满飞机,测量完成这个过程需要的时间。

但是我没有飞机,我也不认为我能说服几百个人浪费他们宝贵的时间来满足我狂热的好奇心。所以我考虑在电脑上做同样的事情(这没什么可抱怨的)。

主要思想可以分为以下五点:

  • 将飞机座位图表示为一个矩阵,每个元素都有一个唯一的索引(座位号)。
  • 将外面的乘客队列和过道表示为一维数组。
  • 给每位乘客一个预定义的座位号和他们在过道上移动的速度。
  • 根据启发法,定义将乘客从过道转移到各自指定座位的规则。例如,移动到空行比移动到有人坐的行的座位更快。
  • 将乘客从最初的队列转移到过道,然后转移到他们的座位,直到所有座位都被占用。然后测量整个过程所用的时间。

现在我们已经定义了原始的想法,让我们试着把它转化成一个算法,并用代码实现它。

3.定义移动规则

在我们开始编写代码之前,我们需要基于行为学定义一些东西,比如乘客速度和移动规则。

3.1 乘客通道移动

让我们假设一般人在过道里从一个座位移动到另一个座位所需的时间是 1 。请注意,我们在这里没有定义任何单位(如 s 或 min)。你可以认为这是无量纲的时间。

如果我们将时间 1 分配给所有乘客,由于每个人都有自己不同的速度,该模型将不太适用于现实生活。为了让它更真实,我们可以从平均值为 1、标准偏差为 0.2 (这是任意的,可以改变)的高斯分布(或钟形曲线)中采样通道移动的时间。因此,我们可以考虑乘客速度的可变性。

3.2 存放行李和座椅移动

当乘客到达他们指定的座位时,他们会先把行李放在头顶的行李架上,然后移到他们的座位上。这会占用一些时间,并导致后面的乘客停下来。让我们假设这个时间等于 2(移动时间的两倍)。

关于从过道到座位的移动规则,有 6 种可能的情况:

  • 靠窗的座位,相邻的两个座位空着。
  • 靠窗的座位,中间的座位有人,靠走廊的座位空着。
  • 中间和过道都有人的靠窗座位。
  • 中间靠过道的座位空着。
  • 中间靠过道的座位有人。
  • 靠过道的座位。

从过道移动到相应座位所需的时间取决于以下哪种情况适用。对于靠窗的座位,如果相邻的座位是空的,搬进去会更快。否则,相邻座位上的人必须首先走到过道,让乘客进来,然后回到自己的位置上。所有这些都会占用登机过程中的大量时间。

因此,计算每个乘客在每个场景中需要走多少步,我们可以定义一组乘数,当乘以乘客的移动时间,给出移动到特定座位所需的时间。

我们将乘数定义如下(每个乘数加 2 以说明行李的存放):

  • 空行:1+2=3
  • 过道占用:4+2=6
  • 中间被占用:5+2=7
  • 过道和中间有人:7+2=9

我们现在准备开始算法和代码。

4.用 Python 实现

我们将在 Jupyter 笔记本中详细介绍上述想法的实现。代码片段贴在下面,整个 Jupyter 笔记本的链接在最后给出。

步骤 1:初始化

我们将只需要 scipy 模块进行模拟,所以我们从导入它开始。

**注意:**像可视化这样的附加特性将需要像 matplotlib 这样的绘图工具,但这不包括在本演示中。关于可视化,请参考文章末尾的“可视化说明”。

import scipy as sci

首先,我们需要初始化许多参数和数组/矩阵来存储所有的乘客数据。由于西南航空公司通常使用一架波音 737 ,我们将把它的规格包括在我们的模型中。它有 23 行6 列。

我们将使用大量的字典来记录事物。所有乘客都将被分配一个从 0 到 137 的独一无二的识别号码(比如说 UIN 的号码),这个号码将作为我们字典的密钥。下面定义的变量执行以下功能:

  • 座位:存储飞机座位图(-1 表示无人,乘客 UIN 表示有人)
  • 过道 _q :存储飞机的过道车道(-1 表示无人,乘客 UIN 表示有人)
  • pass_q :存储机外乘客队列(乘客 uin 列表,从 0 到 137)
  • row_q_initcol_q_init :存储分配给每位乘客的座位行号和列号。

moveto 数组和字典将在后面的章节中解释。

#Initialize
#Define number of rows and columns
n_rows=23
n_cols=6#Calculate number of passengers
n_pass=n_rows*n_cols#Create seat matrix
seats=sci.zeros((n_rows,n_cols))
seats[:,:]=-1#Create aisle array
aisle_q=sci.zeros(n_rows)
aisle_q[:]=-1#Create initial passenger number queue
pass_q=[int(i) for i in range(n_pass)]
pass_q=sci.array(pass_q)#Create array for seat nos
row_q_init=sci.zeros(n_pass)
col_q_init=sci.zeros(n_pass)#Let's create moveto arrays
moveto_loc=sci.zeros(n_pass)
moveto_time=sci.zeros(n_pass)moveto_loc_dict={i:j for i in pass_q for j in moveto_loc}
moveto_time_dict={i:j for i in pass_q for j in moveto_time}

第二步:分配座位

在乘客进入过道之前,他们需要分配座位。座位分配的顺序取决于登机方式。例如,与随机订单相比,从后到前的董事会订单将有不同的座位分配。

我们将在这里看一下两种不同的座位分配(更多信息,请参考文章末尾的 Jupyter 笔记本)。我们将在这里定义一个函数,它接受行和列数组(空),一个指定分配类型、乘客数量和行数的字符串(最后两个是预定义的)。这里定义的第一个顺序是超理想不实际(SINP) ,第二个是随机顺序。

我们将在最后看一下各种不同的登机方法及其结果,但现在,SINP 包括首先填满所有的窗口,然后是所有的中间,然后是所有的过道,这样就绝对不会浪费时间在换座位上。这是(几乎)最理想的寄宿方式。随机是不言自明的——座位分配是随机的。

代码中需要理解的内容:

  • 0 和 5 列指的是窗口
  • 1 和 4 列指的是中间
  • 第 2 栏和第 3 栏指的是过道

很难定义座位顺序,因为它本质上涉及到 2D 座位图到 1D 乘客队列的编码。有多种方法可以做到这一点,下面的代码代表了其中一种可能的方法。你可以自由地尝试你自己的顺序和方法来定义它们。

def AssignSeats(rq,cq,assign_type,n_pass=n_pass,n_rows=n_rows):
    if(assign_type=="SINP"):
        #Initialize initial and final positions
        i=0
        f=n_rows

        #Define column seating positions 
        c=[0,5,1,4,2,3]

        #Define iteratiion counter
        count=0

        #Assign queue
        while(f<=n_pass):
            rq[i:f]=list(reversed(range(0,n_rows)))
            cq[i:f]=[c[count]]*n_rows
            i+=n_rows
            f+=n_rows
            count+=1

    if(assign_type=="Random"):
        #Initialize possible row positions
        av_rows=sci.arange(0,n_rows,1)
        #Make as many copies of these positions as the number of columns
        av_rows=sci.tile(av_rows,(n_cols,1))
        av_rows=av_rows.T.flatten()

        #Initialize possible column positions
        av_cols=sci.arange(0,n_cols,1)
        #Make as many copies of these positions as the number of rows
        av_cols=sci.tile(av_cols,(n_rows,1)).flatten()

        #Create list of all possbile seat positions
        av_seats=sci.zeros((n_pass,2))
        for i in range(n_pass):
            av_seats[i]=[av_rows[i],av_cols[i]]

        #Randomize seat positions
        sci.random.shuffle(av_seats)
        rq=av_seats[:,0]
        cq=av_seats[:,1]return rq,cq

第三步:定义时间,运动规则和字典

现在我们已经定义了分配座位的函数,是时候使用它来创建我们的乘客队列了。出于演示的目的,我们将使用 random

此外,我们需要为每个乘客分配移动时间(基于高斯分布)并定义我们的乘数。

我们还需要将所有这些信息编码到字典中,以便根据每个乘客的 UIN 轻松获得他们的时间和座位分配。

最后,我们需要定义这里所谓的 sum_time 。当时间到的时候,每个乘客都必须从外面的乘客队列移到过道。这基本上是在他们前面的乘客的时间总和已经过去的时候。然后你会看到我们需要定义一个数组,数组中的每个元素都等于当前乘客的时间和前面乘客的时间之和。

#Assign seating order
row_q,col_q=AssignSeats(row_q_init,col_q_init,"Southwest")#Create array for times
mean_time=1.
stddev_time=0.2
time_q=sci.random.normal(loc=mean_time,scale=stddev_time,size=n_pass)#Define multipliers (+2 for stowing luggage)
empty_mult=1+2
aisle_mult=4+2
middle_mult=5+2
aisle_middle_mult=7+2#Create seat and speed dictionary
pass_dict={}
time_dict={}seat_nos=sci.column_stack((row_q,col_q))
for i in range(n_pass):
    pass_dict[i]=seat_nos[i]for i in range(n_pass):
    time_dict[i]=time_q[i]#Create sum time array
sum_time=sci.zeros(n_pass)
for i in range(n_pass):
    sum_time[i]=sum(time_q[:i+1])

步骤 4:定义从乘客队列到过道的移动

我们的乘客队伍已经在飞机外面准备好了。在我们开始登机之前,我们需要定义他们从外面的队列到里面的通道的移动。这可以通过定义一个简单的函数来完成。该功能检查乘客的 sum_time 是否已过。如果有(并且通道中的第一个位置是空的),那么它将乘客的 UIN 复制到通道中,并从乘客队列中删除它。因此,随着时间的推移,乘客队伍将变得越来越短,最终会空出来。

#Create function to move passengers into aircraft
def MoveToAisle(t,aisle_q,pass_q,sum_time):
    if(t>sum_time[0]):
        if(aisle_q[0]==-1):
            aisle_q[0]=pass_q[0].copy()
            pass_q=sci.delete(pass_q,0)
            sum_time=sci.delete(sum_time,0)
    return aisle_q,pass_q,sum_time

第五步:让乘客登机

这是代码中最复杂的部分,因为它涉及到嵌套许多 if 条件和玩弄字典。

**基本理念是为乘客分配行动,要么分配到他们过道前面的位置,要么分配到他们的座位(如果他们已经到达那一排),当时间到了,通过像移动棋子一样移动乘客来“行动”。**每位乘客将在通道中向前移动一段等于其移动时间的时间,并在一段等于其移动时间乘以适当乘数的时间后进入座位。

算法如下:

  1. 浏览所有过道元素。对于过道中的每个乘客,执行以下操作。
  2. 检查是否有任何移动被分配给乘客。
  3. 如果已经分配了移动,检查时间是否已经过去。如果有,将乘客移到他们的座位(如果他们已经到达指定的排)或过道的下一个位置(如果是空的)。如果时间还没有过去,什么也不要做。
  4. 如果没有分配移动,请参考乘客座椅分配。如果他们已经到达分配给他们的排,给他们各自的座位分配一个移动,并分配一个适当的移动时间。如果他们还没有到达分配给他们的排,分配一个移动到通道中的下一个位置,并分配一个合适的移动时间。
  5. 更新时间并返回步骤 1。

算法退出条件如下:座位图中所有乘客的 uin 之和必须与飞机外初始乘客队列中所有乘客的 uin 之和相匹配。

下面的代码墙可能看起来很长,令人望而生畏,但几乎每一步之后都有注释来解释。

5.结果

文章中给出的代码只能为一种登机方法运行一次登机程序。如果该过程重复多次,则可以为每种登机方法计算平均时间(以及等于标准偏差的误差)。这是针对六种不同的方法进行的,并且比较了它们的时间。每个登机方法模拟运行 20 次。

5.1 超理想不实际(SINP)

方法:首先登上所有窗户,然后是中间,最后是过道。然而,必须这样做,使得第一个乘客到最后一排,第二个到倒数第二排,等等,以确保没有时间浪费在站在过道上。

时间:2105

5.2 窗口-中间-过道(WMA):

**方法:**这类似于 SINP,但是窗户、中间和过道是随机登上的,这样一些时间就浪费在过道上了。这种方法被一些航空公司使用,比如联合航空。

时间:2699

5.3 随机

**方法:**随机登板,无特定方案或顺序。

时间: 347 19

5.4 西南

方法:没有“西南方法”,因为开放式座位意味着你可以坐任何你想坐的座位。然而,我在西南航空公司的航班上观察到了一种特殊的模式,这种模式是由于乘客的偏好而产生的。通常情况下,飞机前部的靠窗和靠过道的座位会被占满,然后是后面的座位。接下来,所有的中间座位都是从前到后填满的(对飞机中间座位的厌恶似乎是普遍的,因此给西南航空公司的登机过程提供了某种模式)。

时间: 362 11

5.5 从后到前(BTF)

**方法:**分三组登机,第一组占飞机后三分之一,最后一组占前三分之一。这是大多数航空公司登上经济舱的方法。

时间: 366 20

5.6 从前到后(FTB)

方法:你了解 BTF 吗?把它反过来。这听起来是个糟糕的主意,对吗?头等舱、商务舱和非常特别的超级高级行政舱的座位就是这样做的。

时间: 418 18

6.讨论

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

一些意见和相关结论:

  • 模型给出的时间数字只有在比较这些方法时才有意义。如果我们需要以秒或分钟为单位的精确登机时间,我们需要根据实验数据定义移动时间和乘数。
  • SINPWMA 方法提供了比其他方法更高的性能,因为在过道上的等待时间明显更少,座位移动也更少。它们的标准差也很低,因为其中有相当小的随机因素。
  • 令人惊讶的是(也可能不是,根据实验和其他计算机模拟),随机方法比常用方法更好。这是因为如果人们真的是随机分布的,过道里的等待时间会更少。
  • 西南和 BTF 的方法同样有效。虽然《流言终结者》的研究显示,西南方的方法比普通的 BTF method⁴方法要好得多,但由于我们在模型中所做的假设,这种方法在这里可能没有得到很好的体现。一个更详细的模型,允许乘客动态地占据空的位置和那些导致更少等待时间的位置,可能会导致西南方法的更好性能。
  • 毫不奇怪,FTB 的方法效果最差。即使从视觉上也很清楚,这种方法具有最长的过道等待时间,当乘客从前到后占据座位时,会导致非常频繁的停车。

SINP 方法似乎是完美的缩影(尽管一点也不实用)。然而,在 Jason Steffen 的一篇研究文章中,实际上定义了一种更快的理论方法,称为 Steffen 方法。你可以从文章末尾的链接中了解更多信息。

7.关于可视化的注释

本文中的视觉效果是通过在每几次迭代后捕捉座位图矩阵,并使用 matplotlib 制作 imshow 图来生成的。然而,我没有在文章中包含代码,因为它不涉及任何算法复杂性,而只是一些绘图技巧。

我已经编写了一个通用程序,可以解决任何方法(如果需要的话,可以多次)并绘制一个可以保存的动画。可以在 GitHub 上查看并下载。

如果您想查看模拟的 Jupyter 笔记本,请点击此处。

参考资料和阅读

  1. “不同的航空公司如何搭载他们的乘客”(Lifehacker),https://life hacker . com/How-Different-Airlines-Board-Their-Passengers-1794474413
  2. “飞机登机方法实验测试”(杰森·h·斯特芬,乔恩·霍奇基斯),【https://arxiv.org/pdf/1108.5211v1.pdf
  3. “航空公司乘客的最佳登机方法”(杰森·h·斯特芬),https://arxiv.org/pdf/0802.0733.pdf
  4. 《流言终结者》第 222 集:飞机登机(流言终结者)https://mythresults.com//airplane-boarding

关于这个话题的一个有趣的视频:“航空公司不会使用的更好的登机方法”(CGP Grey 在 YouTube 上),https://www.youtube.com/watch?v=oAHbLRjF0vo&VL = en

**免责声明:**这篇文章和分析背后的动机纯粹是好奇,而不是试图证明任何一种方法优于另一种方法。

如果您有任何问题、意见或建议,您可以[给我发电子邮件](mailto: gauravsdeshmukh@outlook.com)或在 Twitter 上联系我

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值