TowardsDataScience 博客中文翻译 2020(三百七十八)

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

在 JavaScript 中使用贝叶斯搜索寻找丢失的对象

原文:https://towardsdatascience.com/finding-lost-objects-using-bayesian-search-in-javascript-f502e3a1eb8c?source=collection_archive---------47-----------------------

用贝叶斯搜索理论模拟对失踪飞机的搜索。

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

一架飞机在海上失踪的概率分布的例子。

寻找丢失的物品时,有多种搜索方法可供使用。贝叶斯搜索理论就是其中之一。它已经被多次用于搜寻失踪的船只和飞机,如号航空母舰蝎子号号法航 447 航班号马航 370 航班

我会试着用 p5.js 用 JavaScript 模拟贝叶斯搜索理论。

贝叶斯搜索理论

贝叶斯搜索理论涉及应用贝叶斯统计来搜索丢失的对象。它依赖于贝叶斯定理。在贝叶斯优化中使用的相同定理。

贝叶斯搜索理论的目标是在信息有限的情况下最大化检测概率。它有助于在不必等待新数据的情况下做出决策。

贝叶斯搜索通常如下进行:

  1. 设想所有可能的情况。
  2. 计算每个场景的概率分布。
  3. 将它们与每个场景的概率结合起来,做出一个总体概率分布。
  4. 构建一个从最高概率到最低概率的搜索路径。
  5. 使用贝叶斯定理在搜索过程中更新概率。

寻找失踪的飞机

让我们假设我们正在大海中寻找一架失踪的飞机。飞行员宣布他们的发动机失灵了。通讯中断后不久。

可能的情况

由于引擎失灵,一种可能的情况是它们失去了高度,溅入了海洋。在这个例子中,我们将假设这是唯一可能的情况。

计算概率分布

假设我们知道飞行计划和飞机的最后已知位置(LKP)

根据飞行员在溅落前可以保持的高度,我们可以估计一个搜索区域。

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

我们将使用一个正态分布作为飞机距离飞行轨迹距离 d 的概率。

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

标准偏差 σ 将根据水深、水流等进行选择。

分布可能看起来像这样:

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

我们将再次使用正态分布计算飞机飞离最后已知位置的概率。结合这两个分布,我们得到:

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

我们可以加上其他因素,比如水流。在这个例子中,我将添加一些随机值和柏林噪声。

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

我创建了两个函数。generate_lost()生成飞机的随机位置。generate_distribution()生成一个更靠近飞机的随机点,并将其作为 LKP 来生成分布。

搜索模式

通常是从概率最高的地方开始搜索到概率最低的地方。现实生活中有很多搜索模式可以使用,比如:

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

我们将使用不同的方法。我们将总是选择当前方块范围内概率最高的方块。如果有多个,我们将选择最近的一个。虽然对于现实生活中的应用程序来说不是很好,但它更容易实现。

在正方形中搜索时,有三种情况。我们可以用概率来表示它们。

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

  • 真正: 概率 pf 如果找到飞机。
  • 真否定: 概率 1-p. 如果没有找到飞机且正方形不包含飞机。
  • 假阴性: 概率p(1-f) 如果你没有找到飞机但飞机确实在那里。这是因为搜索有可能找不到飞机。

你不可能得到误报,因为你不可能发现一架不在那里的飞机。(或者至少我们会这样假设)。

如果我们在一个正方形中没有找到飞机,我们将使用正方形拥有飞机的概率来更新概率,假设搜索没有找到它。这就是我们要用到贝叶斯定理的地方。

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

也可以写成

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

飞机在那里但搜索没有找到的概率是

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

利用上图我们可以看到,平面 存在而 未被发现的概率为 p(1-f) 。而飞机被没发现的概率就是 有没有 **没发现p(1-f)**有没有 1-p 也就是 p(1-f)+1-p

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

对于其他方块,没有机会( f=0 )在那里找到飞机,因为我们还没有搜索那里。所以,可能性是

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

搜索!

直觉上,随着搜索概率的下降,我们应该期待更多的迭代来找到对象。

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

70%(左)和 30%(右)的搜索发现概率。

**假设:**较高的搜索概率平均需要较少的步骤来找到对象。

当搜索概率较低时,如果什么也没找到,概率会缓慢下降。因此,执行了更多的搜索。

让我们针对不同的概率分布和搜索概率进行多次运行,以确认我们的假设。

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

16 个随机生成的概率分布。

这是运行 1000 次后的结果。

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

对于高概率值(接近 1),与低概率值相比,在发现飞机之前采取的步骤数量非常小且紧凑。

我们可以清楚地证实我们的假设。

你可以在这里找到 JavaScript + p5.js 项目和源代码

我们可以通过给每个方块一个搜索成本来进一步扩展这一点。那么问题就变成了:如何在最小化成本的同时最大化找到对象的几率。这是一个吉廷斯指数的例子。

更进一步,我们可以将这种方法与基于神经网络的搜索进行比较。

用机器学习寻找大气的混合比:一种未知函数的逼近

原文:https://towardsdatascience.com/finding-mixing-ratio-of-the-atmosphere-using-machine-learning-an-approaching-of-the-unknown-2341e3c47f49?source=collection_archive---------45-----------------------

通过数据集对未知函数进行反向工程

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

腾雅特Unsplash 上拍摄的照片

序言

简而言之,我需要编写一个脚本来自动将 TEMP 代码转换为 Wyoming university 表格文本格式,因为我将用来处理高级数据的一些库只接受这种格式。这里是怀俄明大学表格的标题文本格式。

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

压力、位势高度、温度、露点、相对湿度、混合比、风向、风速、位势温度、等效位势温度、虚拟位势温度

这是临时代码的示例

TTAA 75007 96749 99010 25612 25002 00096 24810 29507 92771 21414 31020 85497 18211 32521 70115 00413 33013 88999 77999=TTBB 75008 96749 00010 25612 11981 23017 22914 21212 33886 19411 44837 18214 55799 16216 66782 14413 77762 14014 88744 01420 99739 02219 11721 02218 22717 01815 33716 01015 44715 01613 55714 02410 66710 01009 77693 00016 88659 00517 99650 00015 11648 00315 22644 02615 33639 02516 44615 01911 55581 06302 66580 05901 77579 03100 88578 06500 21212 00010 25002 11977 29513 22850 32521 33611 32514 44588 30507 31313 73508 82330 41414 45422=

我不会详细说明如何解码这段代码,因为这将是一个很长的解释。

通过解码数据,我得到了压力、位势高度、温度、露点、风向和风速。其余的通过预测公式得到。我知道如何利用预测公式得到除混合比之外的其余部分。但是在这里我知道一个事实

混合比受压力、温度和相对湿度的影响

机器学习拯救世界

这是使用机器学习的绝佳机会和绝佳案例。为什么?因为我们只需要得到未知固定函数的近似,而不是经验函数。当你经常要在气象的实际情况中(例如降雨量预测、温度预测等)寻找非线性经验函数时,你不得不考虑诸如昼夜、地形、季节等因素。因此,你不应该只是使用所有现有的数据集和训练模型。不,我打赌你的模特表现会。但是这里我们知道一个事实,在这种情况下,混合比的公式在任何季节,白天或夜晚,在任何地形,在任何条件下都是一样的。所以在这里,你可以直接包含你所有的数据集而不用动脑!

有 3 个参数影响混合比,即压力、温度和相对湿度。所以这些参数会是机器学习模型的参数和作为标签的混合比例。

在这里,我已经从怀俄明大学的网站上抓取了两年的怀俄明格式的临时数据。你可以在这里下载它,但是…

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

我超过 50%的数据被省略:(

不过不用担心,我已经为这个机器学习实验这里保存了 npy 格式的怀俄明格式数据中提取的参数(压力、温度、相对湿度)和标签(混合比例)。

这里是从 Wyoming 数据中提取参数和标签的脚本。

在我们提取数据并获得矩阵后,现在我们用这些数据训练机器学习模型。

这里我们使用线性回归(作为一个比较器,任何模型的准确性都低于线性回归,这意味着该模型在这种情况下不太可行,或者未知的混合比例函数在这种情况下是线性的,因此使用机器学习是多余的)、多层感知器(MLP)、随机森林、梯度增强和支持向量回归(SVR)。在这种情况下,我们将使用除 MLP 之外的所有车型的超参数的默认设置。这是因为 MLP 的默认设置是 1 层 100 个神经元,这对于只有 3 个参数的情况来说太多了。这也是因为与这里的其他模型相比,MLP 模型是我最了解的一个。如果我像了解 MLP 一样了解其他模型,我也会设置其他模型的超参数,以避免不平衡设置。

我设置了 10000 个数据作为测试数据,其余的作为训练数据。我们使用均方根误差(RMSE)和运行时间作为性能指标。结果是

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

最大的 RMSE 和最快的运行时间来自线性回归,这意味着我们的未知函数是非线性的。第二大 RMSE 是 MLP,这意味着最差的模式,在这种情况下,是 MLP。最小的 RMSE 来自随机森林,它在其他模型的最左边。

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

如果从运行时间来看,最长的来自 SVR。它的运行时间远远落后于其他型号,其 RMSE 是第三大。最快的机器学习模型是梯度推进,RMSE 次之。这是一场精彩的表演。

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

最后,如果你真的想使用机器学习模型,你可以用

因为我们已经训练了模型,并且运行时间的最大部分是训练时间,所以最好的选择是保存最准确的模型,不管训练时间有多长。

你可以在这里访问全部代码和数据。另一篇文章再见。

参考文献

http://weather.uwyo.edu/upperair/columns.html 于 2020 年 6 月 18 日进入

https://www . geeks forgeeks . org/saving-a-machine-learning-model/2020 年 6 月 19 日访问

在 Python 中查找最常见的颜色

原文:https://towardsdatascience.com/finding-most-common-colors-in-python-47ea0767a06a?source=collection_archive---------6-----------------------

图像处理任务中的标准但至关重要的功能

如果我们知道图像或物体最常见的颜色是什么,就可以解决图像处理中的几个用例。例如,在农业领域,我们可能想要确定水果的成熟度,例如橙子或草莓。我们可以简单地检查水果的颜色是否落在预定的范围内,看看它是否成熟、腐烂或太年轻。

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

照片由莎拉·瓜尔蒂埃里Unsplash 上拍摄

像往常一样,我们可以使用 Python 加上简单而强大的库(如 Numpy、Matplotlib 和 OpenCV)来解决这个问题。我将演示几种方法来使用这些包找到图像中最常见的颜色。

步骤 1 —加载包

我们将在这里加载基本包。我们会继续加载更多的包。还有,既然我们是用 Jupyter 编程,那就别忘了包含%matplotlib inline命令。

步骤 2 —加载并显示样本图像

在本教程中,我们将大量并排显示两幅图像。因此,让我们创建一个助手函数来完成这项工作。

接下来,我们将加载一些我们将在本教程中使用的示例图像,并使用上面的函数显示它们。

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

来源:作者图片

现在我们准备好了。是时候找出这些图片中最常见的颜色了。

方法 1 —平均

第一种方法是最简单的(但不是最有效的),只需找到平均像素值。

使用numpyaverage函数,我们可以很容易地得到整个行和宽度的平均像素值— axis=(0,1)

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

最常见的颜色#1 —平均法

我们可以看到,平均方法可能会产生误导或不准确的结果,因为它给出的最常见的颜色有点偏离。这是因为平均值考虑了所有像素值。当我们有高对比度的图像(在一个图像中既有“亮”又有“暗”)时,这确实是个问题。这在第二张图中更加清晰。

它给了我们一种新的颜色,在图像中看不清楚/不明显。

方法 2 —最高像素频率

第二种方法会比第一种方法更精确一点。我们将简单地计算每个像素值中出现的次数。

对我们来说幸运的是,numpy再次给了我们一个函数,给出了这个精确的结果。但是首先,我们必须重塑图像数据结构,以仅给出 3 个值的列表(每个值对应一个 R、G 和 B 通道强度)。

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

我们可以简单地使用numpyreshape函数来获取像素值列表。

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

既然我们有了正确结构的数据,我们可以开始计算像素值的频率。我们可以使用numpyunique函数,带参数return_counts=True

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

好了,让我们运行它到我们的图像。

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

最常见的颜色#2 —频率法

这比第一个更有意义,对吗?最常见的颜色在黑色区域。但是我们可以更进一步。如果我们不只选择一种最常见的颜色,而是不止一种呢?用同样的概念,我们可以取前 N 个最常见的颜色。除此之外,如果你看第一张图片,许多频率最高的颜色很可能是相邻的颜色,可能只有很小的像素差异。

换句话说,我们想要取最普通的、不同的色群

方法 3 —使用 K 均值聚类

Scikit-learn package 来拯救我们。我们可以使用臭名昭著的 K-Means 聚类来将颜色分组。

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

很简单,对吧?现在,我们需要的是一个函数来显示上面的颜色簇,并立即显示出来。

我们简单地创建一个高度为 50,宽度为 300 像素的图像来显示颜色组/调色板。对于每个颜色簇,我们将其分配到调色板中。

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

最常见的颜色# 3—K-均值聚类

很漂亮不是吗?K-Means 聚类在图像中最常见的颜色方面给出了很好的结果。在第二个图像中,我们可以看到调色板中有太多的棕色阴影。这很可能是因为我们选择了太多的集群。让我们看看是否可以通过选择一个更小的 k 值来修复它。

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

是的,解决了。由于我们使用 K-Means 聚类,我们仍然需要自己确定合适的聚类数。三簇似乎是个不错的选择。

但是我们仍然可以改进这些结果,并且仍然可以解决一些集群问题。

不如我们也显示整个图像中聚类的比例?

方法 3.1-K 均值+比例显示

我们需要做的就是修改我们的palette函数。我们不使用固定的步长,而是改变每个聚类的宽度,使其与该聚类中的像素数量成比例。

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

最常见的颜色# 3.1—K-表示聚类+比例

好多了。

它不仅给了我们图像中最常见的颜色。它还给出了每个像素出现的比例。

它还有助于回答我们应该使用多少个集群。在顶部图像的情况下,两到四个集群似乎是合理的。在第二个图像的情况下,看起来我们至少需要两个集群。我们不使用一个集群( k=4 )的原因是我们会遇到与平均方法相同的问题。

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

结果为 k=1 的 k 均值

结论

我们已经介绍了几种使用 Python 和几个著名的库来获得图像中最常见颜色的技术。另外,我们也看到了这些技术的优缺点。到目前为止,使用 K-Means 和 k > 1 找到最常见的颜色是找到图像中最常见的颜色的最佳解决方案之一(至少与我们经历过的其他方法相比)。

如果你对剧本有问题,请在评论中或者我的 Github 中告诉我。

使用 Python 数据可视化寻找最佳 NBA 体格

原文:https://towardsdatascience.com/finding-optimal-nba-physiques-using-data-visualization-with-python-6ce27ac5b68f?source=collection_archive---------27-----------------------

使用 python、pandas 和 Plotly 探索和可视化数据,以获得快速、即时的洞察力(包括代码 &交互式图表)

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

照片由拉米罗·皮亚诺罗萨Unsplash (RIP Kobe)上拍摄

在开始详细分析之前,您是否希望更好地评估数据集?这篇文章是一个例子,展示了我是如何用篮球运动员的身体数据来做这件事的。如果你感兴趣,请继续阅读。像以往一样,主题(篮球)的讨论被留到了最低限度。

我敢打赌,你见过一个非常高的人,并想知道(大声)他们是否打篮球。或者向一个发育过度的孩子的父母建议。篮球运动员都很高。在这项运动中,将球放入离地 10 英尺(305 厘米)高的篮圈,身高将是一个优势。

但是优势有多大呢?这种优势表现出来了吗,尤其是在最高层?如果我管理一个篮球队,在其他条件都相同的情况下,哪种体质更有优势,随着时间的推移,球员会如何发展或变老?

因为我希望建立一个模型,可以根据过去的表现数据以及球员的身体属性来预测球员的表现。在建立一个严格的模型之前,我想先感受一下这些问题的答案。所以让我和你们分享一下我是如何做到的。

和往常一样,代码包含在我的git lab repo here(NBA _ physiques目录)中,请放心下载使用/改进。

我还包括了 链接到图的交互版本 s 沿途适用的地方。这些链接在图的标题中。

在开始之前

数据

本文使用 Kaggle 的 NBA 球员数据集。数据集来自 basketball-reference.com,由于它相对较小,我的 repo 中包含了一个副本(在 srcdata 目录中)。

包装

我假设您熟悉 python。但是,即使你相对较新,这个教程不应该太棘手。如果你有什么不确定的地方,请随时联系 twitter 或这里。

你需要用一个简单的pip install [PACKAGE NAME]plotlypandas.安装到你的虚拟环境中。

数据清理/预处理

虽然我们在前面的文章中直接进入了数据可视化,但是让我们从一点数据工作开始。

注意:我将这一部分保持简短,但是如果您对数据清理/处理不感兴趣,请随意跳到“数据概述”部分—我们通过加载已处理的数据(在我的 repo 中提供)来了解这一部分。

我们将使用 kaggle 数据集中的Seasons_Stats.csvplayer_data.csv。由于player_data.csv包含玩家的身体属性,我们将通过匹配Seasons_Stats.csv数据集中的玩家姓名来加入数据集。

使用以下内容加载两个数据集:

import pandas as pd
player_data_df = pd.read_csv('srcdata/player_data.csv')
season_stats_df = pd.read_csv('srcdata/Seasons_Stats.csv', index_col=0)

而且看一下数据,有.head(), .info().describe()。有一些(小)问题。

球员身高值为string值,比较困难,在[FEET-INCHES]中。还有一些丢失的值,您将通过每列中非空值的计数看到(在.info())。

首先,让我们在球员数据中填入身高&和体重NA的值。

熊猫。describe()方法提供关于数据集分布的统计信息。通过season_stats_df[[‘Year’, ‘MP’]].describe()查看赛季统计数据告诉我,75%的统计数据是从 1981 年开始的,这些数据包括 0 分钟比赛的赛季(平均 1053 分钟)。

在这项研究中,让我们忽略旧的(1980 年以前)数据,忽略少于 1000 分钟的小样本赛季(相当于一场比赛 12 分钟)。

这将引入一点生存偏差,但由于我们正在寻找最佳体质,这可能没那么重要。(请随时联系( twitter )如果您对此有任何意见,我很乐意了解更多。)

此处执行进一步的数据清理是为了:

  • 对于年中换队的球员,去掉部分赛季(只保留总数)(例如通过交易)
  • 将身高/体重数据添加到赛季统计数据框架中
  • 简化列在多个位置下的玩家的位置(“C-F”变成“C”)
  • 填充值,
  • 删除一些空白列,然后
  • 重置数据帧索引

数据集有一个错误,如果玩家有两个以上的名字,他们的名字会被截断。“尼克·范·埃克塞尔”变成了“尼克·范”。我更正了这些,但是在做了一些检查之后,我发现正确的全名正在被查找。这也无妨,因为:

令人惊讶的是,多个名字前两个都是“飞车手罗德”的人在 NBA 打球。飞车手罗德·威廉姆斯和飞车手罗德·亨德利。

检查统计年和球员生物年帮助我找到了正确的飞车手罗德。

结果数据保存为“Seasons_Stats_proc.csv”。

数据概述

使用以下内容加载数据集(如果尚未加载):

proc_stats_df = pd.read_csv('srcdata/Seasons_Stats_proc.csv', index_col=0)

数据包括大量的列,但是为了简单起见,我们只使用其中的几列。

在我们对体质的分析中,如果没有身高的背景,体重本身可能不是一个有用的统计数据。

相反,让我们添加一个新的衡量标准(身体质量指数),它的定义考虑了身高。下面的代码引入了一个新列:

proc_stats_df = proc_stats_df.assign(bmi=proc_stats_df.weight / ((proc_stats_df.height/100) ** 2))

展望未来,身高和身体质量指数将被用作主要的独立变量(物理属性)。我们为初始视图制作一个散点图:

import plotly.express as px
fig = px.scatter(
    proc_stats_df, x='height', y='bmi',
    color='pos_simple', category_orders=dict(pos_simple=['PG', 'SG', 'SF', 'PF', 'C']),
    marginal_x="histogram", marginal_y="histogram", hover_name='Player')
fig.show()

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

NBA 历史球员 bmi vs 身高(1981–2015)(互动)

身高分布看起来基本正常。这表明在 NBA 打球有最佳高度,尽管还不清楚为什么会有最佳高度。

有趣的是,许多 NBA 球员的 BMI 超过 25,这被认为是标准人的“超重”。这确实表明,这些标准化的衡量标准并不真的适用于所有人。他们(大部分)都是精英运动员,不可能有这么多 NBA 球员超重。

你可能会注意到有更多的高个子球员比矮个子球员有更高的 BMI。在我们继续前进的时候,请记住这一点。

此外,高度和身体质量指数属性数据将被放入离散数据箱(类似于直方图)。这有助于使数据对异常值不那么敏感,允许更容易的比较,并将帮助我们在精神上/视觉上过度拟合数据。毕竟,我们只有成千上万的数据点(尽管每个“点”都是由整个赛季收集的数据组成的——并非所有的数据点都是相同的)。

Pandas 提供了一个方便的功能来实现这个功能(pandas.cut)。实现为:

ht_limits = [0, 190, 200, 210, np.inf]
ht_labels = [str(i) + '_' + str(ht_limits[i]) + ' to ' + str(ht_limits[i+1]) for i in range(len(ht_limits)-1)]
proc_stats_df = proc_stats_df.assign(
    height_bins=pd.cut(proc_stats_df.height, bins=ht_limits, labels=ht_labels, right=False)
)

通过查看百分位数数据并使用我自己的判断,得出了区间宽度。

引入列表ht_limitsht_labels是为了让我能够更容易地跟踪使用了什么样的限制,也是为了以后可以重用标签来指定图表中的顺序。

身体质量指数被分成四个容器。我们现在准备开始研究身体素质与职业的细节——让我们开始吧。

注意:如果你想要基于分位数的分类——使用pandas.qcut

让我们变得强壮

韵律学

在这篇文章中,我使用了一个高级指标——“PER”(玩家效率等级)。这一指标旨在“将一名球员的所有贡献归结为一个数字”。你可以在这里了解更多。

我选择这个统计数据是因为它将一个球员的统计数据与他们的同龄人进行了比较(所以平均 PER 总是每年 15),这使得跨时代的球员比较更加容易。

职业生涯长度

作为常识的检查,让我们看看在联盟中打球的年数(或者,在我们的数据库中),vs 身高/身体质量指数。我是这样计算的。

有意思。每个身高和身体质量指数组显示非常相似的年龄/球员人数全面!因此,根据身体质量指数/身高,职业寿命看起来相对均衡,至少根据这个非常粗略的标准。

PER(玩家效率等级)—散点图

那么,看看性能指标怎么样呢?一般来说,个子高会让你变得更好吗?PER 数据与高度的散点图可创建如下:

fig = px.scatter(
    proc_stats_df, x='height', y='PER', hover_name='Player'
    , color='Year', color_continuous_scale=px.colors.sequential.Teal,
)
fig.show()

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

PER(绩效评定)与身高(互动)

那很有趣。似乎存在一个最佳的高度“区域”。只有身高在 183 厘米(6 英尺)到 216 厘米(7 英尺 1 英寸)之间的人才能达到超过 30 的赛季。

将同样的数据与身体质量指数而不是身高进行对比:

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

PER(绩效评分)vs 身体质量指数(互动)

同样,似乎存在一个中间最佳范围。除了一个人——那就是沙奎尔·奥尼尔,他在那个时代是一股不可阻挡的力量,防守者被他弹开就像孩子对抗跳跃的城堡一样。

然而,他是一个非常特殊的人,公平地说,这些数据并没有充分地捕捉到他这些年来不断变化的体格,因为他的身体质量指数在他的职业生涯中波动很大。

另一个观察结果是,PERs 的下限似乎随着身体质量指数数字的增加而增加。

PER(玩家效率等级)—箱线图

尽管如此,这些数据还是很嘈杂。让我们再画一次这些,但是作为一个方框图。

使用箱线图,我们可以很容易地将数据(PER)的分布可视化为独立变量(身体质量指数&高度箱)的函数。

fig = px.box(
    proc_stats_df, x='height_bins', y='PER', color='bmi_bins', hover_name='Player',
    category_orders=dict(height_bins=ht_labels, bmi_bins=bmi_labels))
fig.show()

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

PER vs 身高/身体质量指数(互动

结果中跳出了两个输出,我已经在上面的输出中标记了它们。

190 厘米以下球员的曲线显示了 22.5 到 24 岁身体质量指数带的 PER 增加。210 厘米及以上的极右翼群体的数据表明,越大越有可能成为伟人。

暂停一会儿,你会想起数据还包括每个球员的位置。让我们看看这些身高是否对应于特定的球员位置分组。

我们可以将这些位置的计数绘制成直方图,并使用子图来分离出每个高度和身体质量指数仓的位置分布。

下面的代码片段实现了这个目的:

fig = px.histogram(
    proc_stats_df, x='pos_simple', facet_row='bmi_bins', facet_col='height_bins', color='pos_simple',
    category_orders=dict(height_bins=ht_labels, bmi_bins=bmi_labels, pos_simple=['PG', 'SG', 'SF', 'PF', 'C']))
fig.show()

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

身高/身体质量指数组,按职位(互动)

首先,事实证明,身高是一个非常合理的位置预测指标。把注意力转回到方框图,它表明身体质量指数 22.5 到 24 的增加主要与控卫有关。

篮球中的控球后卫是主要的控球者,他们负责进攻和分配球。

我对这个身体质量指数带(22.5-24)的 PER 增加的业余解释是,它是一种身体类型的指示,这种身体类型最大限度地提高了灵活性和爆发力,这在主要控球者中是有价值的,而不是太小,这可能会对你的耐用性产生不利影响。

大个子的数据(在箱线图和直方图的最右边)可能更简单。作为中锋或大前锋,在篮筐附近打球,更大的块头可能会让你在身体上控制你的对手,就像沙克或查尔斯·巴克利一样。

老化

太好了。父亲时间呢?某些体型会比其他体型更容易衰老吗?这一部分根据身体类型来看球员的表现范围随时间的变化。

我们再一次创建了年龄箱:

age_limits = [0, 23, 25, 27, 29, 31, np.inf]
age_labels = [str(i) + '_' + str(age_limits[i]) + ' to ' + str(age_limits[i+1]) for i in range(len(age_limits)-1)]
proc_stats_df = proc_stats_df.assign(
    age_bins=pd.cut(proc_stats_df.Age, bins=age_limits, labels=age_labels, right=False)
)

下面是按身高细分的每对年龄箱线图。

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

按年龄段,按身高细分(互动)

那不是很迷人吗!对于年轻球员来说,身高是一个明确的优势,但这种优势在他们的壮年时期(23-31 岁之间)或多或少会消失,然后在老年时期再次出现。

我认为这表明身高可以让球员更容易补偿年龄的增长和运动能力的丧失。

同样,下图显示了按身体质量指数范围细分的 PER 与年龄。

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

PER 按年龄段,由身体质量指数细分(互动)

在这种情况下,更大的身体质量指数似乎对年轻球员更有优势。对此的解释可能是,这使他们能够在块/内部发挥更好的作用,但随着年龄的增长,任何优势都会被灵活性的损失所抵消。

这种敏捷性的损失对某些类型的玩家的影响会比其他玩家更大吗?我们可以按位置把数据分成支线剧情来看一下:

fig = px.box(
    proc_stats_df, x='age_bins', y='PER', color='bmi_bins', hover_name='Player', facet_row='pos_simple',
    category_orders=dict(bmi_bins=bmi_labels, age_bins=age_labels, pos_simple=['PG', 'SG', 'SF', 'PF', 'C'])
)

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

按年龄段,按身体质量指数和职位细分(互动)

随着我们对数据的划分越来越深入,我们处理的样本规模越来越小,我们应该警惕对太多数据的解读。说到这里,答案似乎是一个响亮的是!

这与我们之前所想的高度补偿运动中的损失是完全一致的。后卫一般都比较矮,随着年龄的增长,很难弥补他们运动能力的不足。

更重要的是,如果组织后卫(在次要情节的顶部)和得分后卫有更大的身体身体质量指数,他们会不成比例地受到年龄的影响。处于底部的中心,似乎随着年龄的增长做得越来越好——而且身体质量指数和表现之间根本没有太大的关联。年纪大、块头也大的警卫受害最深。

有趣的是,年纪大的大前锋和中锋看起来最显老。这是真的吗?

我们把数据翻过来,把身高仓作为我们的 x 轴数据,按年龄段排列。

fig = px.box(
    proc_stats_df, x='height_bins', y='PER', color='age_bins', hover_name='Player',
    category_orders=dict(height_bins=ht_labels, age_bins=age_labels)
)
fig.show()

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

按身高分类,再按年龄分类(互动)

这张图表显示,高个子球员绝对比矮个子球员更容易衰老。

事实上,高个子球员从很小的时候就被期望有更高的生产力,而矮个子球员需要更长的时间来发展。这将意味着,在他们成为重要贡献者之前,将他们吸收到团队中的团队所需要的时间投入会显著减少。

现代篮球

作为最后的回顾,让我们看看这对于现代篮球来说是否成立。上面使用的数据集涵盖了 1981 年至 2017 年。篮球在那个时候发生了显著的变化,包括防守规则的变化,三分革命和对空间的重视,而不是大个子在内线的统治。

这产生了什么影响?如果我们把数据分成三组 12 年的时间段会怎么样?

yr_limits = [0, 1995, 2007, np.inf]
yr_labels = [str(i) + '_' + str(yr_limits[i]) + ' to ' + str(yr_limits[i+1]) for i in range(len(yr_limits)-1)]
proc_stats_df = proc_stats_df.assign(
    year_bins=pd.cut(proc_stats_df.Year, bins=yr_limits, labels=yr_labels, right=False)
)

我们可以将 PER 作为年龄和身高的函数,用子图(行)显示不同的年龄:

fig = px.box(
    proc_stats_df, x='height_bins', y='PER', color='age_bins', hover_name='Player', facet_row='year_bins'
    , category_orders=dict(height_bins=ht_labels, age_bins=age_labels, year_bins=yr_labels)
)
fig.show()

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

按年龄段,按身高和年龄细分(互动)

根据这些数据,2007-2017 年的 NBA 是大个子的黄金时代,远远超过 81-94 和 95-06。我将在另一篇文章中谈到篮球方面的事情,但看起来 NBA 的大个子变得更重要、更好,而不是更差。

这就是可视化探索数据集的力量。通过划分来自近 1500 名球员的约 8700 个赛季的数据,我们可以快速识别数据中的趋势。

仅仅在很短的时间和一些图表中,我们就发现了潜在的有趣和有价值的数据,这些数据可能值得进一步研究。我们已经看到了特定身高的最佳身体质量指数范围,不同身高范围的球员如何才能充分发挥生产力,或者根据年龄回归,并比较各个时代。

这些也可能成为选择在机器学习模型中包括什么特征或者开发新特征的有价值的输入。

此外,用跨时代标准化的身高/身体质量指数数据重新审视这些数据可能会很有趣,可以补偿跨时代的任何变化。评估另一个联赛(国际、欧洲联赛或 WNBA)的数据也是很有趣的,看看这些数据如何比较。

我希望这是一个有用的例子,你可以通过简单的操作和可视化数据来获得信息。有时候,在你能很好地理解它之前,没有什么可以替代眼前的事物。

如往常一样,如果你有任何问题或意见,打电话给我。

如果你喜欢这个,比如说👋/在推特上关注,或者关注更新。我还写了这些可视化篮球投篮数据的文章,以及关于可视化气候数据的文章。

[## 用 Plotly 实现交互式篮球数据可视化

用 hexbin shot 图表分析体育数据,用 Plotly 和 Plotly Express 分析气泡图(源代码&我自己的数据…

towardsdatascience.com](/interactive-basketball-data-visualizations-with-plotly-8c6916aaa59e) [## 用 Python & Plotly 实现交互式气候数据可视化

使用 plotly 可视化时间序列数据,包括条形图(柱形图)和子图(我的 GitLab repo 中的源代码和数据)

towardsdatascience.com](/interactive-climate-data-visualizations-with-python-plotly-de0472490b09)

使用知识图和语义推理寻找有规则的模式

原文:https://towardsdatascience.com/finding-patterns-with-rules-4227ee4e8f58?source=collection_archive---------38-----------------------

概念和示例

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

机器学习算法现在等同于在数据中寻找模式,但并非所有模式都适合基于统计的数据驱动技术,例如当这些模式没有明确标记的学习目标时。

在某些情况下,这些模式可以精确地表达为一个规则。推理是匹配基于规则的模式或验证它们在图中不存在的过程。因为这些模式是用演绎逻辑发现的,所以与从数据中归纳的机器学习模式相比,它们可以被更有效地发现和更容易地解释。

本文将介绍一些常见的模式,以及如何使用牛津语义技术公司开发的知识图和语义推理引擎 RDFox ,用规则语言 Datalog 来表达它们。RDFox 是基于标准的,RDF-三重存储,我们将使用 SPARQL 对其进行查询。如果你还不熟悉知识图和推理,你可以在这里阅读发表在《走向数据科学上的介绍。如果您没有 RDF 数据,请阅读我们的简单教程将 CSV 和 SQL 数据导入 RDF 图。

传递关系模式

“位于”关系在直觉上是可传递的,但可能无法在图中完全表达。例如,一个图形可能包含以下三元组:

@prefix : <https://oxfordsemantic.tech/RDFox/tutorial/> .:oxford       :located_in :oxfordshire .
:oxfordshire  :located_in :england .
:england      :located_in :uk .

SPARQL 查询不会返回牛津位于英格兰,因为它缺少三个字符:

:oxford       :located_in :england .

该三元组可以一次性添加,但这很快在较大的图表上变得不切实际,因为位于牛津郡的其他城镇也可能会缺少位于英格兰边缘的城镇。

在这种情况下,传递关系规则可以毫不费力地自动绘制相关的:located_in 边:

[?x, :located_in, ?z] :- 
   [?x, :located_in, ?y], 
   [?y, :located_in, ?z] .

第一部分是规则的头,如果在图中找到符号:-后的模式,该规则将变为?x :located_in ?z 三元组。

在我们的例子中,规则将变量?x绑定到:oxford,变量?y绑定到:oxfordshire,变量?z绑定到:england,然后作为满足规则的逻辑结果,通过用:oxford替换?x和用:england替换?z来创建:oxford :located_in :england三元组。

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

原始数据被规则扩展,新的关系在这里显示为绿色。

无论何时在图表中添加或删除新的数据点,RDFox 都会在运行中逐渐实现规则,这使得它成为动态数据源的有效解决方案。

传递闭包模式

传递闭包模式有助于将图中尚不存在但可能存在的传递关系具体化。例如,一些 Twitter 关注者可以用下图来表示:

:alice :follows :bob .
:bob   :follows :charlie .
:diana :follows :alice .

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

将图表可视化。

当向用户推荐以下建议时,我们可能希望使用以下规则将缺失的连接计算为:follows_closure边:

[?x, :follows_closure, ?y] :- 
   [?x, :follows, ?y] .[?x, :follows_closure, ?z] :-
   [?x, :follows, ?y], 
   [?y, :follows_closure, ?z] .

第一个规则指定新关系:follows_closure是关系:follows的扩展。第二个规则实现了闭包,它说如果一个人?x直接跟随?y并且?y(直接或间接)跟随人?z,那么?x(间接)跟随?z

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

更新的关系显示添加了:follows_closure 边。

因此,最初不是:follows关系的新:follows_closure关系是:

:diana :charlie .
:alice :charlie .
:diana :bob .

这些简单的规则可以被增强以包括用户兴趣、地理、语言、共同的追随者等。

将关系定义为其他关系的组合

知识图的一个重要实际用途是支持开放式问答(Open QA)应用程序或聊天机器人,其中用户用自然语言提出一个问题,然后自动根据图进行回答。开放式问答系统通常很难解释涉及图中几个“跳”的问题。例如,考虑由下面给出的三元组组成的图。

:douglas_adams :born_in  :uk .
:uk            rdf:type  :country.

用户可能会问道格拉斯·亚当斯出生在哪个国家。为了获得这些信息,系统需要在图中构建一个包含两跳的查询。特别是 SPARQL 查询

select ?c where {
   :douglas_adams :born_in ?c .
   ?c rdf:type :country .
}

会返回:uk作为答案。

如果只需一跳就能获得所需的信息,那么开放式质量保证系统的结果将会大大提高。在这种情况下,可以使用 RDFox 规则来提供一个干净的解决方案。特别是,我们可以使用规则来定义一个新的:country_of_birth关系,为直接访问所需信息提供一条“捷径”。

[?x, :country_of_birth, ?y] :- 
   [?x, :born_in, ?y], 
   [?y, rdf:type, :country] .

规则说,如果一个人?x出生在一个地方?y,而那个地方?y是一个:country,那么?y就是?x的出生国。

因此,RDFox 会推断出道格拉斯·亚当斯的出生国是英国。开放的 QA 系统现在只需要构造以下更简单的查询,该查询涉及图中的单跳,以获得期望的信息。

select ?x ?y where {?x :country_of_birth ?y}

正如我们已经看到的,规则可以建立在其他规则的结果上,因此这种模式与第一个传递关系相结合,可以满足包括道格拉斯·亚当斯出生地点的更多完整细节的数据。比如:

:douglasAdams   :born_in    :cambridge .
:cambridge      :located_in :cambridgeshire .
:cambridgeshire :located_in :england .
:england        :located_in :uk .
:uk             rdf:type    :country .

当这些规则应用于这些数据时,它们会生成下图。

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

输入数据以及由规则导出的边的图表。

循环检测

知识图中的一个常见任务是识别循环关系。例如,部分经济关系通常是非循环的(例如,如果引擎是汽车的一部分,我们不会期望汽车也是引擎的一部分!).在这些情况下,可能需要循环检测来检测图表中的错误,从而提供数据验证。通过识别例如网络中不应该存在的通信关系,周期检测对于检测欺诈或内部交易也是有用的。

考虑下图中的“部分”关系:

:piston :part_of :engine .
:engine :part_of :car .
:car    :part_of :piston .

该图包含一个循环路径:piston->-:engine->-:car->-:piston。通过:part_of关系。

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

通过查看这个小图表,很明显有些地方不对劲。想象一个更大的东西,在结构中有许多层次的嵌套和分支。

该关系自然是可传递的,并且可以用以下规则来定义:

[?x, :part_of, ?z] :- 
   [?x, :part_of, ?y], 
   [?y, :part_of, ?z] .

下面的 SPARQL 查询将返回(直接或间接)属于其他元素的元素

select ?x ?y where {?x :part_of ?y}

这给了我们以下结果

:piston :piston .
:car. :car .
:engine :engine .
:piston :car .
:car :piston .
:engine :car .
:piston :engine .

一个循环通过自循环的存在来表明它自己(例如:piston被导出为它自己的一部分)。

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

因此,可以用下面的 SPARQL 查询检测关系的循环部分。

ask {?x :part_of ?x}

或者,我们可以用以下规则定义循环关系:

[:part_of, rdf:type, :cyclic_relation] :- 
   [?x, :part_of, ?x] .

它告诉我们,如果任何物体被确定为自身的一部分,那么部分命名关系就是循环的。

我们现在可以很容易地检索图中的循环关系列表。

select ?x where {?x rdf:type :cyclic_relation}

获得:作为结果的一部分。

排序模式

许多关系自然意味着某种顺序,在这种情况下,我们可能有兴趣找到这种顺序的第一个和最后一个元素。

例如,考虑一家公司的管理结构。

:alice  :manages :bob .
:bob    :manages :jeremy .
:bob    :manages :emma .
:emma   :manages :david .
:jeremy :manages :monica .

我们希望认可公司中哪些人是“高层管理者”。我们可以用一个规则来定义一个高层管理者,他管理一个人,而不被其他任何人管理。

[?x, rdf:type, :top_level_manager] :-
   [?x, :manages, ?y], 
   not exists ?z in ([?z, :manages, ?x]) .

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

如此处所示,Alice 符合规则的模式,因此标记为类型:top_level_manager。

该查询

select ?x where {?x rdf:type :top_level_manager}

询问高层经理的名单,答案是:alice

我们现在可以用一个规则来定义“初级员工”为那些有一个经理但自己不管理其他任何人的人。

[?x, rdf:type, :junior_employee] :- 
   [?y, :manages, ?x], 
   not exists ?z in ([?x, :manages, ?z]) .

对初级雇员的查询是

select ?x where {?x rdf:type :junior_employee}

这将返回:monica:david作为答案。

在实践中寻找模式

这是对基于规则的模式示例的简短介绍,我将在下一篇文章中用更多的例子和应用来扩展它。想象一下,将这些规则与其他规则相结合,并在您的数据上大规模运行,会有什么样的效果。

如果您想自己搜索基于规则的模式,请访问 RDFox 的入门指南。

关于牛津语义技术

牛津语义技术背后的团队于 2011 年在牛津大学计算机科学系开始研究 RDFox,他们坚信灵活和高性能的推理是数据广泛应用的一种可能性,而不会危及结果的正确性。RDFox 是第一个面向市场的知识图,它是基于推理从头开始设计的。牛津语义技术公司是牛津大学的一个分支,由主要投资者支持,包括三星风险投资公司(【SVIC)、牛津科学创新公司( OSI )和牛津大学的投资部门( OUI )。笔者很自豪能成为这个团队的一员。

照片由 波维切维斯基 Unsplash

在 Python 中寻找性能瓶颈

原文:https://towardsdatascience.com/finding-performance-bottlenecks-in-python-4372598b7b2c?source=collection_archive---------5-----------------------

是什么让你的代码如此缓慢?

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

来源

在这篇文章中,我将解释如何分析一段代码,并可能发现性能瓶颈。

让我们首先创建瓶颈

假设我们需要创建一个在循环上迭代的脚本,每次循环执行都会产生一个依赖于当前迭代的值和一个独立值。独立值是初始设置的一部分,这可能是一个相对繁重的功能:

import timedef initial_setup():
  a = 7
  time.sleep(1)
  return a

我们的“initial_setup”函数只是返回一个固定值,但是我添加了一个 1 秒钟的 time.sleep() 调用来模拟一个更重的函数。让我们继续构建脚本的主函数,我们姑且称之为“slow_function”。

def slow_function():
  x = range(5)
  for i in x:
    a = initial_setup()
    b = a + i
    print(b)

我们的新函数只是简单地迭代[0,4]并将当前数字添加到初始设置中返回的固定数字。您可能已经注意到,我在循环块中错误地调用了“initial_setup()”。即使结果是正确的,这仍然是一个性能错误,因为“initial_setup()”不依赖于循环迭代,而且,它是一个很重的函数。

无论如何,让我们假装没有注意到,并测试我们的解决方案。您应该会得到以下结果:

7
8
9
10
11

很管用,对吧?虽然它比我预期的要长…我不知道是什么让它这么慢,所以也许是时候使用 Python 的分析器了…

cProfile 入门

我们需要剖析我们的功能,并找出是什么阻碍了它的性能!幸运的是,Python 提供了一个可以帮助我们完成这项任务的模块: cProfile 。我们将从创建 Profile 类的一个实例开始:

import cProfileprofile = cProfile.Profile()

我们现在准备好分析我们的函数了!我们将开始使用一种简单的方法,使用 runcall()方法,它接收要分析的函数(及其参数,如果有的话)。在我们的例子中,我们想要分析“slow_function()”,所以我们将添加以下指令:

import cProfileprofile = cProfile.Profile()
profile.runcall(slow_function)

现在,如果您运行上面的代码片段,您将会看到,显然,什么都没有发生。至少,在 stdout 中没有输出任何分析信息。这是因为我们缺少了拼图的最后一块: pstats 。让我们继续将它添加到我们的代码片段中:

import cProfile
import pstatsprofile = cProfile.Profile()
profile.runcall(slow_function)
ps = pstats.Stats(profile)
ps.print_stats()

如您所见,我们将“profile”实例传递给了构造函数 Stats 来创建这个类的新实例“ps”。这个实例最终允许我们打印分析结果。

好了,说够了(或写够了),让我们运行我们的代码片段,看看我们得到了什么!

7
8
9
10
11
         17 function calls in 5.011 seconds Random listing order was used ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        5    0.001    0.000    0.001    0.000 {built-in method builtins.print}
        5    5.010    1.002    5.010    1.002 {built-in method time.sleep}
        5    0.000    0.000    5.010    1.002 python-performance-bottlenecks.py:5(initial_setup)
        1    0.000    0.000    5.011    5.011 python-performance-bottlenecks.py:10(slow_function)
        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}

如何解读 print_stats()的结果?

很好!我们现在可以看到一系列信息,这些信息应该可以指出性能瓶颈。为了找到它,我们应该首先理解每一列的含义。

  • ncalls:被分析的函数被调用的次数
  • tottime:在分析的函数中花费的总执行时间(不包括子函数的执行时间)
  • percall:总时间除以 ncalls
  • 累计时间:所分析的函数花费的总执行时间(包括子函数的执行时间)
  • percall:累计时间除以 ncalls
  • 文件名:行号(函数):文件、行号和分析的函数

既然我们理解了每一列的含义,我们可以寻找阻碍我们表现的原因。嗯…哦!“initial_setup()”被调用了 5 次。实际上累计执行时间在 5 秒以上!这是有意义的,因为我在 for 循环中错误地调用了“initial_setup()”!好吧,我在循环外调用它,因为它不依赖于它。

我们已经解决了第一个性能问题!现在,我们将如何解决未来的瓶颈?我们应该一直关注 ncalls 吗?嗯,有时候。但有时,我们会面临另一种问题,ncalls 不会告诉我们任何事情。例如,我们可能不得不处理一个只被调用一次,但是非常慢的函数。作为一般策略,我倾向于首先查看具有较高累积时间(cumtime)的函数,然后检查是否有任何函数在 ncalls 中表现突出。然而,我要说的是,选择一个策略是一个相当个人化的旅程,是我们根据自己的经验建立起来的。

更灵活的分析方法

有时,您可能不想分析整个函数,而只想分析它的一部分。这也是可能的,而且很容易,方法如下:

def slow_function():
  profile = cProfile.Profile()
  profile.enable()
  x = range(5)
  for i in x:
    a = initial_setup()
    b = a + i
    print(b)
  profile.disable()
  ps = pstats.Stats(profile)
  ps.print_stats()

我们必须将我们想要分析的代码片段放在“profile.enable()”和“profile.disable()”之间。请记住,在这种情况下,我们正在分析一个玩具示例,但在实际情况下,您可能必须分析一个更大的函数,因此,如果您怀疑瓶颈可能在哪里,限制被分析的代码片段的范围总是有用的。

此外,从 Python 3.8 开始,您还可以选择将其用作上下文管理器,将“profile”实例的范围限制在封闭的块中:

with cProfile.Profile() as profile:
  x = range(5)
  for i in x:
    a = initial_setup()
    b = a + i
    print(b)
  ps = pstats.Stats(profile)
  ps.print_stats()

充分利用 pstats

一旦您开始在真实世界的代码库中进行分析,您将会看到打印的统计数据会大得多,因为您可能会分析更大的代码片段。嗯,在某些时候,有这么多的信息,它变得有点混乱。幸运的是, pstats 可以帮助您使这些信息更易于管理。

首先,您可以使用 sort_stats() 来确定打印函数的顺序(您也可以在链接中找到可用的排序键)。例如,根据呼叫次数或累计时间对其进行分类可能会有所帮助。您可以定义多个排序键,按照键的顺序定义它们的优先级。另一个方便的选择是设置打印功能数量的限制。你可以通过传递一个整数给 print_stats() 来实现。让我们修改我们的示例,按照 ncalls 和 cumtime 的顺序对输出进行排序,并限制为 3 个函数:

def slow_function():
  profile = cProfile.Profile()
  profile.enable()
  x = range(5)
  for i in x:
    a = initial_setup()
    b = a + i
    print(b)
  profile.disable()
  ps = pstats.Stats(profile)
  ps.sort_stats('calls', 'cumtime') 
  ps.print_stats(3)

您的输出应该如下所示:

7
8
9
10
11
         17 function calls in 5.017 seconds Ordered by: call count, cumulative time
   List reduced from 5 to 3 due to restriction <3> ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        5    0.000    0.000    5.016    1.003 python-performance-bottlenecks.py:5(initial_setup)
        5    5.016    1.003    5.016    1.003 {built-in method time.sleep}
        5    0.001    0.000    0.001    0.000 {built-in method builtins.print}

如您所见,已经应用了定义的顺序和限制。还要注意,这些限制是在输出中声明的。

好了,就这样,你现在已经准备好让你的代码更快了!

通过 Python 中的 API 查找相关工作技能

原文:https://towardsdatascience.com/finding-relevant-job-skills-via-api-in-python-ced56cbb3493?source=collection_archive---------21-----------------------

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

令人敬畏的开源插图 unDraw

工作技能的世界

所以你想弄清楚你的技能适合今天的就业市场。也许你只是好奇,想看看一系列全面的、干净的、标准化的工作技能。或者你需要一个简历解析项目的技能分类。嗯, EMSI 技能 API 是这项工作的一个可能工具!

在本教程中,我将带您浏览一些样板代码,您可以使用这些代码从 API 访问一些关键的端点:一个全局技能列表、从文档中提取技能、按名称查找技能,以及最后按技能 ID 查找相关技能。让我们开始吧。

设置

开始使用就像注册免费获取 API 一样简单。完成该过程后,您会收到通过电子邮件发送给您的身份验证凭据。

导入报表

我们将在这里使用几个包,所以让我们先导入它们:

导入报表(来源)

所有这些都很标准。我使用的是json_normalize包,这是一种将 JSON 转换成 Pandas 数据帧的简单方法,可读性会更好。

验证您的连接

访问 API 的第一部分只是使用注册电子邮件中的凭证来建立连接并获得访问令牌。我用 Python 在 Jupyter 笔记本的一个单元格中运行了以下内容。

认证(来源)

旁注:如果我的代码块(就像上面的代码块)被截掉了,请按照它们标题中的源代码链接阅读完整的代码!

这段代码产生一个认证 JSON 对象,其中一个键是access_token。在这里,我显式地访问了那个键的值,并将它赋给了一个同名的变量,供以后使用。

“你好,世界!”EMSI 的技能 API

EMSI 有多个 API,但在本教程中我们将重点关注技能 API。首先,我们将使用该访问令牌来获取可供我们使用的完整技能列表。

调出全球工作技能列表

我编写了一个简单的函数来提取技能列表,并将其写入 Pandas 数据帧,以获得更好的格式和可读性。

全球技能列表(来源)

我将 url 设置为技能列表端点,将访问令牌与 API 的必要语法规范连接在一起,并使用请求库来获取数据。这会产生以下技能的全局列表:

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

全球技能列表的数据框架

您可以看到这里有硬技能和软技能,每个技能都有一个唯一的 ID,并且每个技能都是标准化的,有适当的大小写。每个技能类型也有一个类型 ID。这里列出了近 3 万个技能!

提取给定文档中出现的技能

换句话说,你有一份文件(例如简历或工作描述),你想找到简历持有人或招聘者想要的相关技能。下面的函数将提示您输入文本。将文本粘贴到那里,并设置一个介于 0 和 1 之间的置信区间(我通常使用 0.4 来查看更长的技能列表),瞧——技能提取!

提取文档中出现的技能(来源)

作为一个简单的例子,我输入了“python 等”,毫无疑问,它以 100% (1.0)的置信度返回了这个技能提取:

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

从文档中提取的技能的数据框架

这一切都很好。但是,如果您想找到一种技能在这种分类法中是如何引用的呢?嗯,有一个 API 是通过 ID 查找相关技能的,但是我们需要先知道 ID!我们现在就去找。

通过名称查找技能来找到它的 ID

下面的代码使用 Python 的str.contains方法来查找包含作为函数参数输入的子串的技能。

通过名字查找技能 ID(来源

正如您所看到的,使用str.contains(name_substring)方法可以找到所有包含单词Python的技能。这使我们能够看到所有的可能性,并选择我们想要找到相关技能的 id。上述函数返回的数据帧如下所示:

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

这里有很多粒度!接下来让我们以熊猫和 Python 为例,通过获取它们的 id 并将其输入到下一个代码块中来找到相关的技能。

查找与技能相关的技能

我们有自己感兴趣的技能的 id。现在我们想找到与他们相关的技能。我已经将相关技能的 id 添加到有效负载的代码中,并作为注释添加在下面代码块的顶部。如果要添加更多,请密切注意payload的格式。它避开了“和其他细微差别,如在结束前需要空格}。

相关技能(来源)

我们在前面涉及单词Python的技能输出中看到有很多选项。我选择寻找与PythonPandas相关的技能。生成的数据帧如下所示:

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

Python 和熊猫相关技能的数据框架

这是伟大的表演!它本质上向我们展示了其他 Python 包,包括 NumPy,它几乎总是伴随着我们在数据科学中的 import 语句!

结论和今后要做的工作

感谢阅读这个关于 EMSI 技能 API 的快速教程。我希望它对您的任何用例都有用。如果你想看到这在一个特定的进一步的方向发展,请在下面给我留言!还有许多来自 EMSI 的有趣的数据集值得一查,包括那些关于劳动力市场、招聘信息以及更多信息的数据集。

在接下来的步骤中,我可以重新设计相关的技能代码块,使其成为一个函数,将技能 id 列表作为关键字参数,并将它们添加到有效负载中。现在它有点挑剔,还没有标准化。我想把它设计成一个模块,其中一个连接是一个类,每个端点的利用是一个具有更健壮的属性和参数的方法。这肯定会节省许多行代码。

但是下一次——快乐编码!

奢侈的生活

使用余弦相似度查找相似名称

原文:https://towardsdatascience.com/finding-similar-names-using-cosine-similarity-a99eb943e1ab?source=collection_archive---------20-----------------------

客户数据很乱。这里有一个简单的方法来寻找看起来相似的名字。

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

Photo by 浮萍 闪电 on Unsplash

人类容易犯错误。有了手动输入的数据,出错只是时间问题。对于客户数据来说尤其如此。这通常有两个原因:

  • 客户必须通过用户界面自己输入信息,或者
  • 其他人会代表他们输入信息。

因此,错误是必然会发生的。这些错误可能是文本错误,如输入姓名时的打字错误。它们可能是误击,比如在输入邮政编码后从下拉菜单中选择错误的地址。因此,同一客户的多个条目可能会显示为两个不同的客户,尤其是在他们是回头客的情况下。即使你正确地分析了数据,由于数据质量差,你也可能从分析中得出错误和误导性的结论。

收集不正确的客户信息是一个非常普遍的问题。试图在大型数据集中找到文本错误和异常可能会非常困难。也就是说,已经有很多技术可以找到看起来相似的名字/文档。 C osine 相似度就是这样的技术之一。它实现起来相对简单,为查找相似文本提供了一个简单的解决方案。

由于我们通常收集客户数据的方式,不正确的客户信息是一个非常常见的问题。试图在大型数据集中找到文本错误和异常可能会非常困难。幸运的是,已经有很多方法可以找到看起来相似的名字/文档。其中一种方法叫做 余弦相似度。 实现起来相对简单,并且提供了查找相似文本的简单解决方案。

余弦相似性

与许多自然语言处理(NLP)技术一样,该方法计算数值。因此,该技术仅适用于矢量

这个想法很简单。余弦相似度通过取两个非零向量之间角度的余弦来计算一个称为 相似度 的值。范围从 0 到 1,0 表示最低(最不相似),1 表示最高(最相似)。

为了证明,如果两个向量之间的角度是 0,那么相似性将是 1。相反,如果两个向量之间的角度为 90°,则相似度为 0。对于两个大于 90°的向量,我们也认为它们是 0°。

然而,重要的是要注意余弦相似性考虑向量的大小。只有两个向量之间的角度有关系。这在某些情况下很有用。

例如,假设我们正在比较两个文档,其中它们各自向量的每个维度都代表一个唯一的单词。如果一个文档大得多,并且某个特定单词出现的频率高得多,它们仍然可以被认为是相似的。

当比较名字而不是单词时,我们可以做同样的事情。我们只需要让每个向量维代表一个字符。假设我们有两个拼写相似但字符长度不同的名字,如 ConorConor,那么这仍然会导致高相似性得分。

公式

余弦相似性的数学定义如下:

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

其中θ是两个非零向量 AB 之间的角度。虽然这个公式看起来很复杂,但它只是两个向量的 点积 的定义的重新排列。我们取矢量 AB 的点积,并除以这两个矢量的大小的乘积。每个 i 代表向量的一个维度;在这种情况下,它可以是字母或单词。如果没有匹配的字母或单词,那么我们忽略它们(即认为它们是 0)。

将名称转换成向量

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

丘特尔斯纳Unsplash 上拍照

我们的第一个任务是定义一个函数,它可以将单词作为输入,并将它们转换成向量表示。代码将使用 Python 3,但是您可以随意使用您觉得最舒服的语言——基本概念应该是相同的。

我们的目标是创建一个名为word2vec()的函数,它将把一个单词分解成它的字符组成部分,这样我们就可以在以后输入这些信息作为cosine_similarity()函数的输入。

def word2vec(word): # Count the number of characters in each word.
    count_characters = Counter(word) # Gets the set of characters and calculates the "length" of the vector.
    set_characters = set(count_characters) length = sqrt(sum(c*c for c in count_characters.values())) return count_characters, set_characters, length, word

首先,我们使用collections库中的Counter()方法来统计每个字母在我们输入的单词中出现的次数,如count_characters变量所示。这只是一本字典,每个键代表一个字符。键值是该字符出现的次数。

然后,我们通过使用set()函数获得输入单词中使用的字符集,这样我们就可以获得两个单词之间的字符交集,我们将这个变量命名为set_characters。我们稍后在计算余弦相似度时需要用到这个。

最后一部分是计算单词的“长度”。这是前面余弦相似性公式中所示的单词向量的大小。请记住,我们这样计算长度的原因是因为我们将这些单词表示为向量,其中每个使用的字符表示向量的一个维度。

这些都以元组的形式返回,这样我们可以很容易地提取信息。我们还将输入单词添加到输出元组的末尾,以便在我们想要使用该函数来迭代一个姓名列表时,可以很容易地计算出原始单词是什么。

余弦相似函数

我们现在可以创建cosine_similarity()函数,如下所示。这里的输入将是word2vec()功能的输出;也就是说,vector1vector2通过应用word2vec()函数来计算。

def cosine_similarity(vector1, vector2, ndigits):
    # Get the common characters between the two character sets
    common_characters = vector1[1].intersection(vector2[1]) # Sum of the product of each intersection character.
    product_summation = sum(vector1[0][character] * vector2[0]                  [character] for character in common_characters) # Gets the length of each vector from the word2vec output.
    length = vector1[2] * vector2[2] # Calculates cosine similarity and rounds the value to ndigits decimal places.
    if length == 0:
        # Set value to 0 if word is empty.
        similarity = 0
    else:
        similarity = round(product_summation/length, ndigits) return similarity

首先,我们需要通过使用intersection()函数获得两个单词共有的字符列表,我们称这个变量为common_characters

回到这个公式,我们必须计算点积。这是通过遍历列表common_characters并获得每个迭代字符的计数值来完成的,如变量product_summation所示。

然后,我们计算两个向量长度的乘积,并将这个变量称为length(回头看,我可能应该使用一个不那么容易混淆的变量名)。

我们现在准备将所有东西都插入公式中。然而,由于涉及除法,余弦相似性仅允许非零向量。因此,我们需要添加一个条件,如果length = 0,那么相似度为 0;否则,照常计算余弦相似度。还使用了round()函数,这是我们利用ndigits参数将相似性分数四舍五入到所需的小数位数的地方。

寻找相似的名字

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

乔·塞拉斯Unsplash 上的照片

创建了必要的函数后,我们可以把所有的东西放在一起创建一个名为find_similar()的函数,它扫描一个名字列表并返回结果的数据帧。结果数据框将是一个pandas数据框(因此确保pandas已安装并别名为pd),它将由三列组成:

  • 名称列表中使用的名称将是第一列。这些是用作cosine_similarity()函数第一个参数的向量。
  • 第二列将包含用于与第一列进行比较的名称。这些是用作cosine_similarity()函数第二个参数的向量。
  • 第三列将包含使用第一和第二列中的名称计算的相似性得分。

最终代码

下面是这个函数的 Python 代码。它接受一个名字列表作为输入和一个“相似性阈值”。此阈值设置了在最终结果数据帧中包含名称对所需的最小值。这样做可以从结果中去除那些没有意思的比较。然后,像cosine_similarity()函数一样,有一个用于计算小数位数的参数叫做ndigits

def find_similar(full_names_list, similarity_threshold, ndigits):# Initiate an empty list to store results.
    results_list = [] # Apply word2vec function to each name and store them in a list.
    vector_list = [word2vec(str(i)) for i in full_names_list] # Two loops to compare each vector with another vector only once.
    for i in range(len(vector_list)):
        # Get first vector
        vector1 = vector_list[i] for j in range(i+1, len(vector_list)):
            # Get the next vector
            vector2 = vector_list[j] # Calculate cosine similarity
            similarity_score = cosine_similarity(vector1, vector2, ndigits) # Append to results list if similarity score is between 1 and the threshold.
            # Note that scores of 1 can be ignored here if we want to exclude people with the same name.
            if 1 >= similarity_score >= similarity_threshold:
                results_list.append([vector1[3], vector2[3], similarity_score]) else:
                pass # Convert list to dataframe.
    results_df = pd.DataFrame(results_list)
    if len(results_df) != 0:
        results_df.columns = ['full_name', 'comparison_name', 'similarity_score']
    else:
    # Can add error here if there's no results to return if desired.
    pass return results_df

首先,我们初始化一个结果列表来存储我们的结果。然后我们使用word2vec()函数在列表中理解名字列表中的每个名字。

现在我们需要一种方法将每个名字与其他名字只比较一次;这可以使用两个for循环来完成,我们在每次迭代中应用cosine_similarity()函数。由于我们不希望导致相似性分数低于我们指定的输入阈值的比较,我们在内部的for循环中包含了一个if语句。这基本上就是说,如果相似性分数高于阈值,我们将把它附加到results_list上。

然后我们将列表转换成一个pandas数据帧。最后,有一个if语句来检查数据帧是否为空。我个人没有为此在else语句中添加任何东西,但是如果需要的话,可以在这里为空结果添加一个错误。然后,它返回最终的数据帧作为输出。

示例 1

假设我们有 4 个名字:康纳康纳乔恩约翰。我们可以通过比较每个名字和其他名字来计算余弦相似度。现在我们已经准备好了函数,接下来就是简单的插入所有东西了!

首先,我们将创建一个姓名列表。

names_list = ['Conor', 'Connor', 'Jon', 'John']

然后,我们需要决定相似度阈值和我们想要的小数位数。现在让我们使用相似性阈值 0。这样做将给出每一个比较对,我们还将把所需的小数位设置为 3。

similarity_threshold = 0
ndigits = 3

让我们把这些放进去,看看我们能得到什么。

results_df = find_similar(name_list, similarity_threshold, ndigits)

print(results_df)

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

立刻,我们应该注意到我们有 6 个比较。这是我们所期望的,因为一组 N 个项目中唯一对的数量是 N*(N-1)/2。我们还可以看到具有高相似性得分的配对是康纳康纳配对,以及乔恩约翰配对,这也是我们所期望的。

如果我们将相似性阈值更改为 0.8,那么我们应该预期只有提到的对会保留下来。让我们试一试。

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

是的,正如我们所料。然而,我们可以通过使用我们已经知道结果的名字来做额外的检查。例如,我们知道如果我们比较完全相同的名字,那么我们期望相似性得分为 1。相反,如果我们比较完全不同的名字(完全没有共同的字符),那么我们期望相似性得分为 0。

示例 2

让我们通过使用不同的名称列表来做同样的事情。假设我们有两个名字:康纳。现在我们可以创建一个新的名字列表。

names_list_2 = ['Connor', 'Connor', 'Lee', 'Lee']

如果我们使用这个相似性阈值为 0 且小数位数相同的新名字列表运行find_similar()函数,那么我们会得到下面的结果。

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

检查通过!这正是我们预期的分数。如果我们想的话,我们可以在单元测试的时候使用它作为检查,但是我不会深究这个。这给了我们一些信心,让我们相信事情正在按计划进行。

最后的想法

W 我们已经看到,通过将名字转换成向量并计算余弦相似度,可以很容易地找到相似的名字。如果我们将此应用于真实的客户数据,我们还可以对其他属性进行额外的检查,如性别、出生日期等。因为当我们找到相似的名字时。例如, LeonLeona 将获得高相似性分数,但是 Leon 最有可能是男性而 Leona 最有可能是女性;如果是这样的话,这种相似性不太可能是由于诸如打字错误之类的错误造成的。我们想排除这些。像这样进行一些额外的检查会降低返回这种比较的可能性。

我们也可能不想包括那些相似性得分为 1 的,因为人们可能有相同的名字。同样,我们可以添加一些对其他属性的检查,比如性别和出生日期。例如,如果有两条 Leon 记录,我们可以检查它们是否具有相同的性别和出生日期。如果有,那么很可能是重复记录。无论如何,您是否希望包含相似性分数 1 都可以在find_similar()函数的if语句中轻松更改。

一些读者指出,word2vec()函数也没有考虑字谜。你可以像滑动窗口一样查看每个单词的(或更多)字母来解决这个问题。如果我们将检查员检查员接收器进行比较,算法会认为检查员更类似于检查员。这是因为尽管起始符检查员的变位词,但是

最后,我们可能希望在应用find_similar()函数之前添加一个过程来首先清理名称,比如删除大写字母和连字符,连接每个客户的名和姓,等等。

就是这样!希望这为基于名称在数据集中查找可能的错误提供了一个简单的起点。如果任何人有任何关于如何改进这一点的其他想法,或者想讨论如何在真实环境中实现它,或者只是对代码有一般的疑问,请随时与我联系。我很想聊聊!

通过通话详细记录发现社会行为模式

原文:https://towardsdatascience.com/finding-social-behavior-patterns-through-call-detail-records-e3c107be62f7?source=collection_archive---------19-----------------------

移动运营商数据如何让我们了解社会隔离?

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

社会行为与流动模式相关,因为社会和其他外部因素会影响我们对交通方式或路线的选择。袁等人[1]将一些移动性度量与用户的性别和年龄相关联。在其他有趣的结论中,人们发现青少年和老年人不像中年人和年轻人那样长途旅行。Isaacman 等人[2]得出结论,人们倾向于在夏天比冬天旅行更多。所以,季节实际上会影响我们旅行的数量。此外,Cho 等人[3]向我们表明,与短途旅行相比,长途旅行受我们的社会关系影响更大。他们使用 cdr(呼叫详细记录)来描述迁移的数量、方向、持续时间和季节性。Blumenstock [4]也能够通过 cdr 分析推断内部迁移模式。

根据 Deville 等人[5],cdr 实际上是预测人口流动的一个很好的工具。Wang 等人[6]和 Tatem 等人[7]的贡献与通过移动运营商数据描述人类移动性来理解流行病学现象和病毒传播相关。此外,Eagle 等人[8]帮助我们了解人们如何适应和改变他们在交流中的行为,以更好地适应新的社会环境。这项研究的发现构成了事件管理和拥塞减少的关键信息来源。

为了检查迁移期间用户社会关系中的联系强度、社交水平和其他因素的演变,Phithakkitnukoon 等人[9]利用了葡萄牙 11 个月的 cdr。Krings 等人[10]也发现了有价值的结论。例如,获得了以下描述两个城市之间通信强度的公式:强度“与两个人口的乘积除以城市之间距离的平方成比例”。除此之外,还观察到“城市内部通信规模与城市人口呈超线性关系”[10]。

按照这种思路,现在是讨论离散选择模型的时候了。这些模型允许我们通过考虑多种因素的函数来发现用户使用确定的交通方式的概率[11]。因此,这个模型假设用户的行为是由可能获得的最大收益和其他竞争者的替代品的吸引力决定的。然而,我们的选择并不像我们想象的那样理性,Phithakkitnukoon 等人[11]试图在社交度和用户移动模式之间建立一种关系。那么,在某种意义上,我们需要意识到,我们倾向于与和我们相似的人交往并建立联系,在这个意义上,同性恋的概念是核心。这些人倾向于与我们分享共同的特征或财产(例如,性别或年龄)。因此,可以合理地推断,使用特定旅行方式的社会关系越多,我们使用相同旅行方式的可能性就越大。这项研究的结果证明,我们最密切的关系对选择私人交通工具有更大的影响。相反,我们最脆弱的关系是那些说服我们更多地采用公共交通工具的关系。除此之外,奇怪的是地理上离我们更近的朋友在我们的通勤旅行中对交通工具的选择上有更大的权力。不出所料,研究还发现,乘坐公共交通工具的距离也是拒绝乘坐公共交通工具的原因之一。

仔细研究 Phithakkitnukoon 等人[12]的工作,我们发现可以从 cdr 中提取移动性度量,如移动性多样性、移动性离散度和范围。移动性多样性是用户“访问的不同位置的总数”。迁移率分散“测量迁移率的变化量(或随机性)”[12]。移动性范围“推断人的移动性的旅行距离范围,其被定义为从人的家庭位置到人曾经到过的最远位置的距离(以千米为单位)”[12]。除了移动性度量,社交度量也从 cdr 中提取(例如,呼叫频率、呼叫持续时间和社会联系的数量)。对所有这些指标进行分析,以了解哪一个指标影响我们的交通模式,即我们对交通方式的选择。通过 cdr,我们可以计算出我们的社会互动有多激烈,从而推断出我们和我们最紧密的社会联系之间的一些重要的共同特征。然而,由于这种数据总是匿名的,除了他/她的位置和他/她呼叫的用户之外,我们无法知道更多关于用户的信息。

在对每个用户及其社会关系的六个测量值进行比较之后,得出的结论是,移动多样性与社会关系的强度成比例。这是成比例的,社会联系越强,他们的流动性多样性和流动性范围就越相似。相反,人们发现流动性分散与社会关系的强度完全不相关。在社会性度量方面,我们发现在用户和他们最亲密的社会关系之间,这三个度量都是相似的。因此,由于我们倾向于与最亲密的朋友有相似的社会行为,这项研究向我们表明,从我们最亲密的社会关系中观察到的行为中推断出一些流动模式是可能的。流动性分散是唯一偏离这一结论的指标。通过这项研究,人类哲学得到了加强。这项研究的潜在问题是,它仅限于分析共享同一移动运营商的社会关系。

知道如何计算社会关系中的社会力量变得至关重要。为此,我们需要回忆一下 Granovetter 等人的工作。他们将其定义为“时间量、情感强度、亲密度(相互信任)和互惠服务的组合”。因此,受 Nicholas 等人[14]工作的启发,在我们的案例中,我们可以将通过语音通话交流的时间与符合 Granovetter 先前定义的社交能力测量联系起来。为此,我们需要考虑以下比率:

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

该公式意味着具有社交关系 i 的用户社交强度 (s) 等于用户与关系 ic(i) 交谈的时间量除以用户与其所有社交关系交谈的时间量( N )。为了正确地进行计算,最基本的是将社会关系视为那些与被观察用户保持相互通话的人。我们说这是至关重要的,因为我们经常会偶尔打电话给一些服务或不一定是我们的朋友或熟人的人(例如,处理一些业务)。

在推断社交网络的关注点时,cdr 可能被定位为使用的最佳机会数据之一。一旦我们拨打/接听电话的人尽可能地模仿我们真实的社交网络,这就是一个合理的结论。例如,如果我们从脸书或 Instagram 等社交网络获取数据,并将我们的社交关系建立在这些平台上所谓的“朋友”或“关注者”的基础上,我们最终会高估用户社交关系的实际数量。

Olivier 等人[15]也调查了天气状况对我们社会交往的影响。天气对社会经济活动有影响。由于周围的天气条件,人们可能更喜欢居住在一个确定的区域。除了调节社会交往,天气状况的变化也影响着流动模式。除了 CDRs,这次调查还需要气象数据集。数据集来自里斯本的三个基站,每 30 分钟测量一次温度、湿度和压力。最后得出的结论是,天气状况对人们的平均通话时间没有显著影响。在极端的温度(过冷或过热)和压力(高或低)以及 20%-100%的湿度水平下,人们愿意与较少数量的社会关系交谈,并与他们牢固的关系保持更多的联系。

尽管有有价值的结论,这项研究也有一些问题。大气参数的影响可能是相互依赖的;然而,一次只研究了一个标准的重要性。可能已经调查了天气条件的多个参数的同时变化的影响。此外,该研究忽略了一个事实,即人们可能在一些基础设施内,可以免受某些类型的天气影响。也不考虑与被观察个体有联系的人的天气条件。事实上,节假日和其他社交活动也会影响平均通话时间,这一点也没有考虑在内。

Olivier 等人[16]开展的研究是关于人口流动的社会地理的另一项重大研究。在这项研究中,我们发现 80%的受访地点都在距离最近的用户社交网络 20 公里的范围内。如果我们考虑 45 公里的地理社交半径,那么我们可以说百分比增加到 90%。同样令人惊讶的是,我们往往在地理上更接近弱关系,而不是强关系。一般来说,我们所在的地区越是城市化,我们与社会的联系就越遥远,我们的地理社会半径就越短;此外,我们 80%的旅行范围将在 10 公里地理社交半径内。这里,地理社交半径被定义为与社交关系的地理距离。因此,如果“受试者访问的地方(或旅行范围)在受试者社会关系的 x 公里范围内”,那么地理社会半径将是 x。这个概念在图 1 中进行了适当的描述。

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

图 1—红点表示社会关系的位置, r地理社会半径。轮廓线包围了预测的行程范围。该图最初来自 Olivier 等人[16]。

这项研究的一个更普遍和令人惊讶的结论是,“尽管人们倾向于居住在他们强关系附近,但他们的流动性偏向于他们弱关系的地理位置”[16]。这项研究和其他研究一样,提出了一些问题。我们假设我们在分析期间给每个朋友打电话/接电话,这是不现实的。此外,我们都有社会关系,我们经常面对面地与他们交谈,我们不需要给他们打电话。还假设在研究期间,人们没有迁移或没有改变居住地,而是迁移到另一个地方。人们也可能因为度假而暂时住在某个地方。然而,由于假期只是人们生活中的一小部分,它不太可能对这项研究产生重大影响。

参考

[1]Yuan,M. Raubal,和 Y. Liu,“计算机、环境和城市系统与手机使用和出行行为的关系——中国哈尔滨的案例研究”,computu。环境。城市系统。,第 36 卷,第 2 期,第 118-130 页,2012 年。

[2] S. Isaacman、R. Becker、S. Kobourov、M. Martonosi、J. Rowland 和 A. Varshavsky,“洛杉矶和纽约的人口流动范围”,第 1-6 页。

[3] E. Cho,“友谊和移动:基于位置的社交网络中的用户移动”

[4] J. Blumenstock,“从手机通话记录推断国内移徙模式:来自卢旺达的证据”,2012 年。

[5] P. Deville,C. Linard,S. Martin,M. Gilbert,F. R. Stevens,A. E. Gaughan,“使用手机数据进行动态人口制图”,第 111 卷,第 45 期,2014 年。

[6] P. Wang、M. C. González、C. A. Hidalgo 和 A. Barabási,“了解手机病毒的传播模式”,第 1076 卷,第 1071-1076 页,2009 年。

[7] A. Tatem 和 D. L. Smith,“量化人口流动对疟疾的影响量化人口流动对疟疾的影响”,2014 年 3 月号,2012 年。

[8] N. Eagle 和 M. A. Bettencourt,“社区计算:使用移动电话数据比较农村和城市社会”,第 144-150 页,2009 年。

[9] F. Calabrese,“眼不见心不烦——我们的移动社交网络在迁移过程中如何变化”,2018 年。

[10] C. Link、G. Krings、F. Calabrese、C. Ratti 和 V. D. Blondel,“城市间通信网络的扩展行为”,2012 年。

[11] S. Phithakkitnukoon、T. Sukhvibul、M. Demissie、Z. Smoreda、J. Natwichai 和 C. Bento,“使用移动电话数据推断交通方式选择的社会影响”,《EPJ 数据科学》。,2017 年第 6 卷第 1 期。

[12] S. Phithakkitnukoon 和 Z. Smoreda,“社会关系对人类流动性和社会性的影响:细胞网络中社会联系的研究”, Soc .Netw。肛门。量滴2016 年第 6 卷第 1 期第 1–9 页。

[13] M. S. Granovetter,T. American 和 N. May,“弱关系的力量”,第 78 卷,第 6 期,第 1360-1380 页,2007 年。

[14] A. Nicholas、J. Onnela、S. Arbesman 和 M. C. Gonza,“社交网络群体的地理限制”,第 6 卷,第 4 期,2011 年。

[15] S. Phithakkitnukoon、T. W. Leong、Z. Smoreda 和 P. Olivier,“天气对移动社交互动的影响:葡萄牙里斯本移动电话用户案例研究”,《公共科学图书馆综合报告》,第 7 卷,第 10 期,第 1-13 页,2012 年。

[16] S. Phithakkitnukoon、Z. Smoreda 和 P. Olivier,“人类流动的社会地理:利用纵向移动电话数据进行的研究”,《公共科学图书馆综合报告》,第 7 卷,第 6 期,第 1-9 页,2012 年。

使用 Python 寻找灵魂伴侣

原文:https://towardsdatascience.com/finding-soul-partners-using-python-883d6017442c?source=collection_archive---------41-----------------------

使用 Jaccard 相似性来查找最相似的可能匹配

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

来源

目标是什么?

目标是使用 OkCupid 的个人资料数据创建一个匹配算法,找到你的灵魂伴侣,他有最相似的特征和异性。Jaccard 算法将用于计算相似性得分。

数据是什么?

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

图 1:查看数据

这些数据包括来自最大的在线约会网站之一 OKcupid.com 的近 6 万份个人资料。它由年龄、体型、教育、宗教和一些习惯等特征组成。这些功能是人们在注册交友平台时被问到的问题。第一眼看到的数据表明,它有许多非空值,需要特性工程。

首先,我想根据一个人对 10 个不同的作文问题的回答,了解他的积极/消极和极性/非极性程度。问题的范围从“我这辈子在做什么”到“我永远离不开的六件事”。为了对一个人有一个整体的了解,我把所有的论文答案都放在了一个专栏里,并使用 TextBlob 的情感分析工具运行了一个情感分析器。

找到极性和主观性分数后,需要将语言口语列改为整数。这是通过计算逗号的数量并添加 1 作为默认值(英语)来完成的。

profiles[’ speaks ']= profiles . speaks . str . count(“,”)+ 1

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

来源:https://www . pexels . com/photo/黑白-game-match-chess-2902/

由于数据的复杂性,我使用了众数或中位数估算法,而不是更复杂的估算方法,如随机森林估算法。然后我删除了收入和星座列,因为它们缺少太多的值。

整数列和浮点列被转换成 bin 的字符串表示。例如,年龄被转换成带有代码的箱:

用户积极性得分——随着年龄的增长,人们会变得更加痛苦吗?

为了继续下去,我想看看我的情感分数是否显示出显著的结果,并且与其他特征有关系。为了展示这一点,我绘制了用户积极情绪得分与年龄的关系图。在这样做的时候,我回答了一个流行的问题。人,尤其是交友网站上的人,会不会随着年龄的增长而失去希望,变得更加苦涩?

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

图 2:年龄和积极性图

该图显示,年轻人可能写了非常积极的回答,但却是离群值。平均而言,随着年龄的增长,乐观情绪会略有增加。没有很强的增量,但绝对可以观察到一个关系。

雅克卡相似性

集合 S 和 T 的 Jaccard 相似度为|S ∩ T |/|S ∪ T |,即 S 和 T 的交的大小与它们的并的大小之比。我们将用 SIM(S,T)来表示 S 和 T 的 Jaccard 相似性。

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

图 Jaccard 相似性的维恩图

该图显示了 3/8 的 Jaccard 相似性。

Jaccard 相似性编码为:

匹配查找函数被写成:

当我们运行随机用户 id 4002 的函数时;我们得到用户和匹配:

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

图 4:用户和他/她的匹配

我们可以看到特征大多相似。Jaccard 相似性得分为 0.811。特征基本相同,两个没有孩子也不吸毒的年轻人。这些通常对普通人来说更重要,但是我们的准则不考虑问题值。

结论

这里,我们只讨论了一个基本的匹配算法。像 OKCupid 这样的顶级约会网站使用更复杂的代码和各种其他指标,例如用户之间的距离,以及不同指标的不同权重,这取决于用户最不重视/最重视什么。

在本文中,我演示了一个函数,它可以查找与所选用户相似的用户。一般来说,Jaccard 相似性可用于查找相似产品或基于文本的问题。由于这里的数据来自一个交友网站,我称之为“the match”。结果表明,它确实找到了具有最相似特征的最佳匹配。当我在做的时候,我发现随着年龄的增长,积极的情绪会增加,这否定了约会网站上的人随着年龄的增长会变得更加痛苦的观点。

有问题吗?在 Linkedin 上联系我,在这里找到代码

查找资料——使用 Azure 搜索和图形连接器来搜索您的数据。

原文:https://towardsdatascience.com/finding-stuff-using-azure-search-and-graph-connectors-to-search-your-data-f0dae02a11af?source=collection_archive---------62-----------------------

微软 365 解决方案

搜索东西很费时间。让我们使用 Azure Search 和 Graph Connectors 使 Power BI 文档(或任何其他来源)可以在您的 Microsoft 365 和业务线应用程序中进行搜索

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

照片由埃迪·利贝丁斯基Unsplash 拍摄

随着 Graph Connectors for Microsoft Search 的推出,我们现在可以使用 Graph Search API 从我们最喜欢的 Microsoft 365 应用程序(如 SharePoint)或我们的业务线应用程序中查询任何内容。

本文使用 Microsoft Power BI 公共文档作为我们搜索的来源,引导您创建这样一个连接器。

遵循此指南,您将从您的 Microsoft 365 应用程序中获得以下结果。

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

从 Microsoft 365 应用程序中查询任何数据

创建图形连接器

为了创建我们的第一个连接器,我们打开管理中心并进入设置>微软搜索。切换到连接器选项卡,点击**+添加**。

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

从内置连接器列表中选择企业网站,点击下一步

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

给你的连接器起一个名字,比如Power BI Fundamentals Docs和一个 ID,比如powerBiFundamentalsDocs检查条款和服务(值得一读!)并点击下一步

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

我们现在输入将数据抓取到图表中的 URL。

对于我们的场景,我们将连接器指向 Power BI 基础文档。随意抓取网络上的任何其他文档或数据。

注意:根据您正在搜索的网站的大小,完全填充可能需要几个小时。

选择认证类型无**,点击测试连接,点击下一步**结束。

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

随意过滤网址,甚至进一步或留为空白,以抓取所有低于给定的网址。点击下一个的**。**

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

保持模式不变,点击下一步

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

企业网站连接器到目前为止还不支持权限,组织内的每个人都可以搜索到。点击下一个的**。**

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

完全刷新间隔设置为任意值,然后点击下一步

重要提示:请始终遵守您抓取的任何网站的网页抓取和抓取政策。

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

查看所有内容,点击完成添加

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

创建连接器需要几分钟时间。使用上面的刷新图标刷新连接状态

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

当连接器准备好时,点击所需动作栏中的创建结果类型

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

在接下来的几个步骤中,我们将定义搜索结果的显示方式以及结果中包含的数据。

将结果类型命名为Power BI Fundamentals Docs并点击 Next。

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

选择我们之前创建的连接器,点击下一步

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

规则保持原样。这将允许我们基于某些条件在各种结果类型之间切换。点击下一个的**。**

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

在我们点击启动布局设计器之前,请注意下面的可用属性列表。这些是由企业网站连接器返回的属性。

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

布局设计器中,我们从模板列表中选择一个模板来可视化搜索结果。我们选择第一个也是最简单的,点击开始

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

现在,我们用连接器的可用属性映射搜索结果的可视化表示。相应地放置标题、URL、描述属性,点击生成并复制 JSON

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

回到结果类型向导,粘贴剪贴板中生成的 JSON,点击下一步

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

查看所有内容并点击添加结果类型

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

一旦确认,点击完成

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

现在是时候建立一个垂直市场了。这基本上是我们的用户在任何微软 365 应用程序(如 SharePoint)中看到搜索选项卡的方式。

点击创建垂直

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

请给它一个用户友好的名称,如 Power BI Fundamentals ,然后单击下一步

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

选择之前创建的连接器,点击下一个

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

查询留空,点击下一个

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

一旦确认,在点击完成之前,点击启用垂直

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

就是这样!现在是时候从您的 SharePoint 中搜索一些内容了。

在 SharePoint 和其他地方搜索🔎

搜索内容非常简单,并且适用于各种场合。以下是几个你可以搜索的地方:

SharePoint

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

什么是 Power BI?

注意:要查看这些结果,用户必须分配有适当的许可证。根据文档显示,要么是微软 365 for enterprise E3/E5 要么是微软 365 Education A3/A5 。根据我的测试,在任何情况下都可以通过 API 进行搜索(参见下面的示例)。

Office 365 门户

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

什么是 Power BI?

来自 Windows 应用商店的 Windows 10 Office 应用

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

什么是 Power BI?

使用图形搜索 API ⚡

除了从各种 Microsoft 365 应用程序中搜索连接器,我们还可以轻松地将它嵌入到我们的业务线应用程序、脚本或命令行中。

为此,我们使用图形 API ,以及它的搜索端点。最简单的测试方法是使用图形浏览器

确保您已登录到图表浏览器。在您可以查询外部连接器之前,您需要您的应用程序的许可,在这种情况下,它是图形浏览器(它只是一个像任何其他应用程序一样的应用程序)。

为此,点击修改权限选项卡,并点击External.Read.All权限范围旁边的同意

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

一旦授权,我们可以使用下面的有效负载向搜索端点发出一个 put 请求。

**put:** https://graph.microsoft.com/beta/search/query

请注意contentSources阵列,它必须与您的连接器 ID 匹配。

随意调整query_string,使用运行查询按钮发出请求,并浏览响应预览

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

这种方法适用于任何定制的应用程序或脚本。使用许多不同编程语言和平台的可用图形库,将搜索集成到应用程序中。

就是这样!玩得开心!

就这样吧👉,
塞巴斯蒂安

找到你的播客中最好的部分来通过 NLP 推广

原文:https://towardsdatascience.com/finding-the-best-part-of-your-podcast-to-promote-via-nlp-f844a88b287a?source=collection_archive---------57-----------------------

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

我们最后的管道

播客正在蓬勃发展,因此推广你的播客以增加你的观众比以往任何时候都重要。在头条,我们帮助播客制作用于社交媒体的视频。我们的用户每天制作超过 10,000 个视频,带来数百万次的收听,我们一直在寻找方法来加快他们的过程。最耗时的活动之一是选择播客的最佳部分进行推广。从历史上看,有两种选择可以从 2 小时的剧集中找到最好的 30 秒剪辑:在后期制作中标记它,或者参加一个名为“seek-seek-oh-this-is-good-no-seek-seek”的无趣练习。想象一下这有多痛苦。通常情况下,找到正确的片段会变成再次听完整集。制作一个 30 秒的社交媒体帖子不应该花几个小时,这就是我们想要解决的问题。

目标:自动向我们的用户推荐好的剪辑。

第一步:转录

nRelate (我们上一家公司),我用绝对令人惊叹的斯坦福解析器NLTK 库编写了我们上下文推荐引擎的主干。然而,音频是另一个野兽,因为几乎所有成熟的 NLP 库都是用于书面文本,而不是音频。我们计划将来向开源社区发布一个全声学模型。目前,鉴于我们在文本处理方面的历史,我们从转录开始我们的目标。

谷歌微软 ASR(自动语音识别)对我们很有帮助。在英语中,WER(单词错误率)非常好,加上我们有句子标记,这使得剪切文本更容易。随着语音二进制化,我们可以实现播客的良好表示。

第二步:主题分段

一旦我们得到了抄本,我们希望在向量空间中表示文档并对片段进行聚类。对于矢量化,我们尝试了包括 word2vec通用句子编码(使用)和 RoBERTa 在内的技术。对于聚类/分组,我们尝试了像 t-SNE (以克服“维数灾难”)和 HDBSCAN 这样的技术,这样我们可以从句子到主题片段。

接下来,我们设置了一种方法来观察各种技术在表示和后续主题分割方面的表现。对大量转录本进行精确标记需要花费大量时间,而且成本相当高。因此,我们选择了一种无监督的方法,并选择将我们的结果与一小组人类注释进行比较(下图中的红线)。最初的结果看起来很有希望,尽管所有的算法都发现了更多的主题段边界(用 x 表示)。

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

主题边界(不同颜色的 x 符号)由不同的算法结合不同的矢量器找到。x 轴是抄本中的第 n 个句子,y 轴代表不同的算法组合。红线是人类注释者发现的边界。

我们需要的是从连续的句子组中形成有意义的簇的解决方案。为什么?因为我们的技术比人类注释者发现了更多的主题片段。

第三步:句子聚类

我们开始寻找一种方法,将句子组合在一起,形成更好的片段。在我们的例子中,使用普通聚类方法的一个关键问题是它们忽略了给定句子的位置(由它们的向量嵌入表示)。我们发现,即使我们成功地运行了基于邻域的聚类技术,如 HDBSCAN 并在其中添加了明确的位置信息,得到的聚类也是基于意义的。这里的问题是它们并不总是以文本的连续片段出现。

为了改善这些结果,我们需要一种更好的方法。幸运的是 TextSplit 提供了一种方法来寻找最佳的“分割边界”,给出了一个大的高维向量序列。这允许放开维数减少。请参见下面的结果:

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

算法发现的彩色编码主题片段。用橙色标识的广告被准确挑选出来

步骤 4:测量文本簇以提高准确性

看是一回事,“测”又是另一回事。为了正确地比较不同的基本向量(word2vec average、USE 和 RoBERTa),我们必须找出要使用的最佳度量。首先,我们认为通过 Jaccard 距离进行分段重叠是一个很好的衡量标准。然而,不一致的数据段大小会导致许多问题。我们很快意识到口语文本是基于序列的,我们可以利用这个属性。接下来,我们进行了一项分析,并确定了一个可以代表两个序列之间距离的度量标准,即使它们表现出不同的长度:动态时间扭曲。在这种情况下,我们将人类和机器生成的注释表示为一系列分割点,以测量这两个系列的 DTW 距离。

那成功了!基于这一分析,我们决定使用 DTW 作为我们的比较指标。我们认为这种方法将在片段识别中提供期望的准确性。

然而,我们还有更多的工作要做:我们如何区分好坏呢?例如,我们如何将介绍/结尾/广告与播客的真实有机部分区分开来?

事实证明,在嵌入中测量语义相关性的常用方法,即余弦距离,对于转录的口语单词音频非常有效。文本的向量表示的方向比向量的欧几里德距离重要得多(参见这里的好文章)。由于广告中的句子通常与剧集的主题不同,我们可以很容易地区分介绍/结尾、广告和播客的主题。所要做的就是抓住这一集的“精髓”,或者说“主题”。下图显示了文字记录中不同的主题片段:

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

我们的注释/使用/Roberta 主题片段相对于整个播客剧集评分的屏幕截图。

在上图中,深色部分表示与整个文档的片段向量更相似的片段。蓝色部分表示相对的线段。注意广告是如何突出的!

基于这些距离,可以建立一个阈值。如果达到(或超过),我们会将这些片段视为“非核心内容”,例如广告、介绍、结尾。

一旦我们调整了阈值,我们得到了这些分类分数:

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

得分输出

主题细分的“精确度”是我们的主要标准。“回忆”现在并不重要,因为对于我们的用例来说,丢失一些片段是可以接受的——我们更担心挑选一些我们不应该挑选的东西,而不是挑选最好的东西(至少在这个阶段)。

实施阈值后,我们得到了以下结果:

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

仅使用文本分割可视化通用句子嵌入。如图所示,该算法可以完美地识别广告片段。

输出中的底部(浅红色)线表示人工注释。最上面一行(更多样/丰富多彩)是使用 Textsplit 找到的内容。同样,蓝色表示我们不想用来向用户建议的部分,作为该集推广播客的最佳部分。我们发现的界限与广告非常吻合。

我们还有最后一个变通办法要考虑。我们大多数的假阳性都发生在介绍上。这是有意义的,因为介绍通常总结播客的插曲,这就是为什么他们在我们的模型中是红色的。解决方法是使用一个简单的时间界限来消除这些误报。

通过利用 NLP,我们能够找到值得推广的播客片段。以下是我们目前收到的一些精彩反馈:

  • “这个。是。厉害了!”
  • “我非常喜欢这个自动听力图工具。我觉得很神奇!!我节省了很多时间来挑选和识别可用于社交内容的剪辑。”
  • “首先,我想说我喜欢自动播客视频!我特别喜欢剪辑功能,它可以从我的播客中挑选出一段特定的引文。”
  • “我其实挺喜欢选拔的!”

当然,并不是所有的反馈都是积极的,但总的来说,我们非常受鼓舞,并将继续改进我们的用户如何在他们的播客集中识别最佳剪辑。

请继续关注,我们的下一篇文章将关注第五步:通过找出红色片段中最好的部分来识别播客中最突出的部分。我们还将介绍如何在模型中使用声音信号(人们的声音或笑声)。如果你读到这里,很有可能你对 NLP 和音频非常感兴趣,所以请告诉我们,我们正在招聘

感谢米克罗斯托特勒万特·萨巴多斯亚当·杰曼,他们与我们一起参与了这个项目。

供进一步阅读的好参考:

https://www . researchgate . net/publication/321227216 _ Text _ Segmentation _ techniquences _ A _ Critical _ Review

https://www . aims press . com/file other/PDF/BDIA/2380-6966 _ 2016 _ 2&3 _ 261 . PDF

https://www . INF . uni-Hamburg . de/en/inst/ab/lt/publications/2012-riedl-biemann-jlcl-text-segmentation . pdf

https://pdfs . semantic scholar . org/da03/9 DBC 849 C4 e 2e C1 b 0 F2 b 324 ADB 38 DC 45989 DC . pdf

https://arxiv.org/abs/1908.10084

不用任何数学就能找到圆面积的公式

原文:https://towardsdatascience.com/finding-the-formula-for-circle-area-without-using-any-math-898cbee70253?source=collection_archive---------63-----------------------

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

去飞溅

当有疑问时,使用计算能力

问任何人一个圆的面积是多少,他们都会告诉你,“π-r 平方”。让他们告诉你为什么,他们很可能不知道。

这是有充分理由的——圆的面积公式的证明,在很大程度上,要么不直观,不令人满意,要么充斥着积分等高级数学概念。

借用统计学和机器学习的核心原理,我们将使用蒙特卡罗模拟和多项式/二次回归来创建一种基于计算的方法来寻找圆的面积公式。

为了在不使用任何数学的情况下求圆的面积,我们使用蒙特卡罗方法。从寻找不规则形状的区域到预测股票市场,这种方法背后的主导思想是,通过向系统中添加随机性并测量系统对它的响应,我们可以获得关于系统的有用信息,甚至不需要知道它背后的机制。

在使用蒙特卡洛来近似圆的面积的情况下,我们生成随机坐标点( x1x2 ),其中两者都是从- 半径到+ 半径的均匀分布中抽取的。让我们在圆上放置 250,000 个这样的点。正如大数定律所说,我们应用的真正随机采样的数据点越多,结果就越准确。

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

对于圆内的每一个点,我们给一个变量加 1,该变量计算落入圆内的点的数量。在放置了所有随机点之后,圆内的点数除以总点数(在本例中为 250,000)表示包围属于该圆区域的方框的正方形的分数。

这个正方形的边长是半径的两倍,所以正方形的完整面积是 4 r ,其中 r 代表半径。4 r 乘以导出的分数,得到圆的面积。通过蒙特卡罗方法,我们可以非常非常接近一个圆的真实面积,甚至不知道计算它的数学公式。

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

几乎完全正确!

给定半径 r 我们可以求出任意圆的面积,但是我们还没有把它推广成一个公式。为了找到公式,我们将创建一个二次方程来建模,该方程接受半径并试图输出面积。为了正确拟合方程,我们必须收集每个半径的蒙特卡罗近似区域的数据。

接下来,我们将手动编写一个程序,将二次模型(回归模型)拟合到数据中,该程序将采用 y = ax 的形式。我们可以通过绘制数据来验证数据是二次的,而不是某个三次或四次多项式。这从根本上来说是一个基本的机器学习问题,所以我们必须了解该领域的一些术语:

  • 模型参数。这些是程序为了找到最佳方案而修改的参数。在这种情况下,参数是 a 。当一个模型有 n 个参数时,称其为 n 维。我们的基本模型只有一维,而深度神经网络(仍然遵循类似的、更有效的学习过程,如下所述)可以对图像进行分类,可能有数百万维。
  • *损失函数。*损失函数或误差度量是对当前参数表现有多差的度量。该程序希望通过找到产生最低误差度量的一组参数来最小化损失函数。如果某个参数值 j 产生的损失函数值为 3,而参数值 k 产生的损失函数值为 2,程序应切换到参数值 k
  • 指绝对误差。我们的程序将使用这种损失函数/误差度量,因为它易于实现和理解。给定当前参数( a )和真实值(面积)的模型预测,平均绝对误差得出给定半径的圆的预测和真实蒙特卡罗近似面积之间的平均差。较低的 MAE 意味着模型更符合数据。
  • 学习率。为了优化参数,模型将参数逐渐向某个方向偏移。由于我们的模型仅优化一个参数( a ),因此它仅需要决定是否增加或减少一维平面上的参数值(基于哪个变化产生更低的损失函数)。它在任一方向上移动的程度称为学习率。较高的学习速率意味着模型可以快速达到一组良好的参数,但不能获得精度,而较慢的学习速率将能够以较长的训练时间为代价,利用最佳参数的值获得高水平的精度。

考虑到这些变量,我们可以构建一个非常基本、简单的程序,用二次模型来拟合我们的数据:

  1. 将参数coef ( a) 的初始值初始化为 0.1。
  2. 对于训练循环总数中的每次迭代;
  3. coef提出两条路径;coef+lrcoef-lr,其中lr是学习率。

  4. 评估带有coef = coef+lr的模型和带有coef = coef-lr的模型的平均绝对误差。

  5. 设置coef等于coef+lrcoef-lr,取决于哪一个具有较小的平均绝对误差。

通过对平均绝对误差的反复优化,该模型将最终收敛于coef的“最佳”值(最大程度地最小化平均绝对误差)。这种想法是机器学习的核心原则——通过反复预测、评估和校正,机器可以锁定一组最佳参数。

当我们查看coef的训练值时,我们看到该值为π:

的确,圆的面积公式是𝜋r!在不使用任何微积分中的严格数学或其他圆面积证明的情况下,我们能够找到它的公式,并发现了一种使用蒙特卡罗模拟和二次回归来计算𝜋值的方法。我们用这种方法找到了一个圆的面积公式,但是人们可以用这种方法找到任何东西的面积公式——一个椭圆,一个心形,一个二维的乌龟——只要画出了形状的参数。

计算机证明正开始接管高变量、复杂的数学问题,这只是它如何用于简单问题的一个例子。考虑一下四色地图定理(假设任何地图都可以只用四种颜色适当着色),这是第一个被数学家广泛接受的计算机生成的证明。在计算机的帮助下,人类将能够探索以前从未敢涉足的极其复杂的数学和科学领域。

利用高维数据分析发现人类最重要的染色体

原文:https://towardsdatascience.com/finding-the-most-important-chromosome-in-human-using-high-dimensional-data-analysis-10cc466b440f?source=collection_archive---------54-----------------------

染色体

人体细胞通常由细胞膜、细胞质和细胞核组成。细胞核内有 23 对染色体。每条染色体都是由紧密排列的 DNA 链组成的。第 23 对由女性的 XX 染色体和男性的 XY 染色体组成。男性的 Y 染色体相对来说比其他染色体要小。

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

X 和 Y 之间的大小比较

DNA 是一种携带遗传指令的分子,用于所有已知生物的生长、发育、功能和繁殖。这些指令位于被称为基因的 DNA 链的特定区域。据估计,人类有超过 20,000 个蛋白质编码基因。

基因编码指令产生消化食物的酶,构建骨骼结构的胶原蛋白,指甲、皮肤和头发的角蛋白,保护大脑的脑脊液等。基因表达是一个过程,通过这个过程,来自这些基因的信息被用来合成所说的产物,这些产物给予我们作为一个人的可观察的特征。

当一个基因表达时,储存在 DNA 中的遗传密码被转录成一种叫做信使 RNA (mRNA) 的特殊分子。mRNA 现在携带着遗传密码,其中包含在那个时间点制造哪种蛋白质的指令。接下来,mRNA 被运输到称为核糖体的细胞中的工厂。制造蛋白质的过程叫做翻译。在生产出想要的产品后,它们将被折叠成能够正常工作的结构。

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

为了控制蛋白质合成的数量和时间,基因表达受到细胞机制的高度调控。控制表达对细胞生产所需的适量产品至关重要;反过来。在特定环境条件下正常细胞中表达的基因可以不同于在不同环境中表达的基因。在正常细胞中表达的基因可能不同于癌细胞;一种组织类型可能与另一种不同,等等。

测量基因表达水平

Affymetrix 基因芯片微阵列通常用于测量基因表达量。DNA 由 4 个分子组成——腺嘌呤(A)鸟嘌呤(G)细胞素胸腺嘧啶(T) 。在 RNA 中,胸腺嘧啶被尿嘧啶(U) 取代。在自然界中,A 总是与 T 结合形成 A-T 对,而 C 和 G 形成 C-G 对,形成 DNA 双链螺旋。在 RNA 中,配对是 A-UC-G 。这些配对是自然发生的,如果你把双链 DNA 拉开,它们会像两条长长的磁铁链一样,合在一起。基因芯片微阵列利用了这种配对特性。

基因芯片就像一个棋盘,上面有成千上万个方格。每个方块都有一个探针,它是一个短的 DNA 序列。每个探针检测一个特定的基因。

在活细胞的基因表达过程中,在细胞核中合成的 RNA 分子被运输到细胞质中。在实验室实验中,从细胞质中提取 RNA 分子,并将其置于芯片表面,使其与探针结合。测量与每个探针结合的 RNA 的量,并用作计算每个基因表达水平的基础。这是通过将荧光分子连接到 RNA 链的末端来实现的。然后,这种 RNA 链在芯片上找到互补的 DNA 链(回想一下,U 总是找到 A,C 总是找到 G)并与之结合。当激光从传感器照射到荧光分子上时,荧光分子会发光。测量发射光的强度,作为代表细胞中基因表达量的 RNA 量的指标。

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

基因表达数据

数据采集

两组基因表达数据用于该分析:研发环境中的 GSE5859SubsettissueGeneExpression 。这两个数据集都可以在 Github 包中找到,由哈佛大学 TH Chan 公共卫生学院的 Rafael A. Irrizary 教授向公众提供。安装这些数据集的步骤描述如下:

install.packages("devtools")

library(devtools)

install_github("genomicsclass/tissuesGeneExpression")

install_github("genomicsclass/GSE5859Subset")

成功安装后,将数据加载到 R:

library(GSE5859Subset)

data(GSE5859Subset)

library(tissuesGeneExpression)

data(tissuesGeneExpression)

GSE 5859 子集数据集包含 3 个表格:

基因注释表:

  • 探针:与基因相关的基因芯片探针 ID
  • CHR :基因所在的染色体
  • 例如,基因 DDR1 与位于染色体 6 上的探针 ID 1007_s_at 相关联

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

基因注释

基因表达式表格:

  • 每一列(GSM136508.CEL.gz,GSM136530.CEL.gz等)表示一种细胞类型,如肝、肺、结肠等

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

基因表达

表格:种族:ASN =亚洲人,CEU =高加索人

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

样本信息

tissueGeneExpression 数据集包含两个表格:

e 表:

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

e

选项卡表:

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

标签

数据有效性

使用多维标度(MDS) 图验证数据。这些图用于确定数据的有效性和质量。

MDS 为结肠:

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

肝、肾和结肠的 MDS 图

MDS 用于海马小脑胎盘子宫内膜:

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

上面的图是先前描述的不同环境、组织类型等中基因表达的一致概念。MDS 还表明,功能相似的组织之间的距离比功能不同的组织之间的距离短。

最重要染色体的标准

为了从高维基因芯片基因表达数据的分析中找到最重要的染色体,感兴趣的染色体上的基因表达谱似乎与所有其他染色体不同。这可以通过 189 个样本中的所有对来完成,这可能需要成千上万个图,非常耗时且不切实际。

一种可行的方法是使用降维方法。这种方法使我们能够尽可能地保留数据的重要属性,例如样本之间的距离。减少的数据维度使我们更容易可视化每个染色体的基因表达特征。

主成分分析奇异值分解是两个潜在的候选。选择 SVD 是因为它有几个特性适合于基因表达数据。

属性 1 : SVD 解决方案不是唯一的

对于这个测试,我们使用 SVD 的形式:

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

这个性质表明,如果我们翻转 U 的每一列的符号,我们仍然会得到相同的解。

首先,在表 e 上执行 SVD,然后翻转 U 列的符号:

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

翻转标志后。通过使用 sweep 函数获得新的 U 和 V,将函数 FUN=“*” 应用于每一行,最终得到 x[i] * a[i]

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

现在我们来看看我们是否能为 UDVT 得到同样的答案。因为我们比较的是矩阵而不仅仅是变量,所以我们使用 all.equal 函数。以下应给出响应:

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

属性 2:改变意味着不改变距离

根据行数生成随机值:

random.vals <- rnorm(nrow(e))

然后,通过添加随机值来修改 e 中的值:

new.e <- e + random.vals

计算原始 e 值的距离:

sqrt(crossprod(e[,3] — e[,45]))

计算修改后的 e 值的距离:

sqrt(crossprod(new.e[,3] — new.e[,45]))

两者给出的答案应该是一样的 156.5662

特性 3:能够降维

最后,SVD 必须能够帮助我们降低维数。在 e 上应用 SVD 后,可以单独得到其单独的 U、D、V。使用 dim(e)获得数据的维数,预计为 22215 x 189。

在测试 SVD 的这种能力之前,我们先回顾一下属性 2。从属性 2 得出的结论是,每行的平均值并不能帮助我们近似列距离,我们将通过减去每行的平均值来计算新的 SVD:

e.new <- e — rowMeans(e)

s.new <- svd(e.new)

通过使用 dim 函数,我们可以确定 Um x p 矩阵,V 是 p x p 矩阵, Dp x n 矩阵。

创建一个变量 z 来存储计算出的 VD^T:

z <- s.new$v * t(s.new$v)

检查 z 的尺寸:

dim(z)

答案应该是 189 x 189 。我们已经成功地将的尺寸从的 22,215 减少到仅仅 189 。随后的分析将采用在应用奇异值分解之前从表 e 中移除行平均值的方法。这样做还有一个最大的好处。它使 SVD 能够产生更精确的结果。

使用奇异值分解进行分析

基因表达数据进行奇异值分解:

tge.s <- svd(geneExpression — rowMeans(geneExpression))

提取 SVD 产品中的成分 U。稍后将使用基因注释对该数据子集进行分层:

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

创建一个函数来从 SVD 获得的 U 矩阵的每一列中检索基因表达:

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

通过将 U 分量的每一列与从基因注释中检索到的染色体名称相结合,创建了一个函数:

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

通过移除空值来清理基因表达数据:

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

使用以下函数中的盒图完成了降维表达式数据的可视化:

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

使用箱线图可视化 SVD 结果

为了简洁起见,这里只显示了其中两列的可视化效果。从箱线图来看,所有常染色体和 X 染色体的数据点都分布在盒子的两侧。然而,Y 染色体看起来与其他染色体不同,因为其数据点仅位于一侧。我们可以得出这样的假设,Y 可能是人类最重要的染色体。然而,Y 染色体基因表达谱的尴尬展示也意味着它是最不重要的染色体。让我们做一些文献调查,看看染色体研究结果对此有什么说法。

SVD 中 U 成分的第 1 列:

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

SVD 中 U 成分的第 7 列:

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

Y 染色体文献综述

历史上,Y 染色体被认为是基因垃圾场,因为它存在似乎没有任何用途的高重复序列。y 染色体在遗传上是退化的,已经失去了它们祖先中存在的大部分活性基因。Y 染色体迅速衰退甚至完全消失的理论得到了比较昆虫、脊椎动物(包括哺乳动物)的研究的支持。根据活跃基因的平均丢失率,人类 Y 预测它将在 1000 万年后灭绝。Y 染色体不能与其相邻的染色体重组,这进一步加速了它的衰变。

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

格雷夫斯,J. A. (2006 年)。哺乳动物的性染色体特化和退化。单元格。124(5):901–14

人类 Y 中活性基因的丢失率,假设为恒定速率(蓝色),指数下降(绿色),目标大小最初增加然后减少(橙色),或在最后阶段通过正向选择减慢的指数下降(紫色)。

因此,这条染色体似乎在人类染色体中扮演了少年犯的角色:

  • 富含垃圾
  • 缺乏有用的属性
  • 不愿与邻居交往
  • 有不可避免的堕落趋势

但是等等…

在我们屈服于人类男性在 1400 万年后从地球表面消失的悲惨命运之前,让我们去马萨诸塞州的剑桥旅行吧。

面对无数对 Y 的人格及其未来前景的侮辱,马萨诸塞州剑桥市怀特黑德生物医学研究所的主任兼教授大卫·c·佩奇几乎花费了他的整个科学生涯来研究和捍卫 Y 的荣誉。他开创性的研究导致发现 Y 基因的关键作用不仅仅是性别决定,这表明人类的福祉可能取决于这个小小的 Y

y 包含了数量惊人的高度重复的序列,本质上是回文序列。当一段 DNA 序列是相邻序列的镜像时,就会出现回文序列。例如, ABCDEF 的序列是 FEDCBA 的镜像。大量回文序列通过对受损基因进行自我修复而提供了一种非常复杂的防御机制( Skaletsky, et al ,2003 )。当检测到一个受损的基因时,细胞会利用回文序列,通过在其镜像轴上弯曲来进行折叠,这样受损的基因就会与另一端未受损的基因非常接近,然后它会复制并替换受损的基因。多年来,Y 染色体经历了主要的倒位,以防止遗传物质与 X 染色体交换,从而使这一机制不被破坏。

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

修改自 Skaletsky,h .、Kuroda-Kawaguchi,t .、Minx,P. J .、。(2003).人类 Y 染色体的男性特异性区域是离散序列类别的镶嵌体。性质。423(19): 825–837

为什么这种不寻常的机制存在的答案在于它试图保护的基因。除了性别决定和精子发生之外,这些基因在健康和疾病的两性间的表型差异中起着至关重要的作用。已经发现 y 基因在人体各处都起作用——皮肤、肝脏、大脑等。我们都听说过人类的基因组有 99.9%是相同的。只有在男性或女性之间进行比较时,这种情况才是真实的。然而,当一个男性和一个女性的基因组进行比较时,只有 98.5% 。换句话说,就 DNA 序列的数量而言,一个男性和一个女性之间的遗传差异是两个男性或两个女性之间的 15 倍。有趣的是,一个男性人类和一只黑猩猩有 98.5%相同。这 1.5%的差异,即大约 4500 万个序列(0.015×30 亿个 DNA 序列),被时尚地忽略了。

自从工业革命以来,在过去 250 年的现代医学中,我们一直在科学研究中对人类基因组进行男女通用的观察。每一名男性患风湿性关节炎,就有 3 名女性患同样的疾病;每有一名女性患有自闭症谱系障碍,就有 5 名男性患有;每一个患狼疮的男人,就有 6 个女人。此外,女性比男性更容易患扩张型心肌病肺动脉高压。这些疾病不在生殖道。

更具挑衅性的是,不考虑这 1.5% 的差异(同样,4500 万 DNA 碱基对),同样,在过去的 250 年里,现代医学研究在理解疾病和寻找治疗方法方面,我们一直在做一门有缺陷的科学吗?

作为最后的思考,到底是什么让 Y 染色体如此神圣,以至于必须不惜一切代价保护它?

在量子计算机上大海捞针

原文:https://towardsdatascience.com/finding-the-needle-in-a-haystack-on-a-quantum-computer-d658bce3e3cc?source=collection_archive---------43-----------------------

Grover 的量子搜索算法在 O(√N)时间内从无序元素列表中找到目标元素。

给你一个数字列表和一个目标数字,要求你在列表中找到目标数字出现的索引。如果列表已排序,您可以使用搜索算法,如二分搜索法。但是如果列表没有被排序,你真的没什么可以做的;您只需遍历整个列表,直到找到元素。就算法复杂性而言,这需要 O(N)时间。然而,使用量子计算机,你可以在 O(√N)时间内解决这个问题。本文解释了这是如何通过 Grover 的搜索算法实现的。

如果你是量子计算的新手,你应该先读读这本简短的入门书: 量子并行性——量子计算机从 那里得到它们的魔咒。

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

大海捞针(图片来自 Pixabay

让我们从框架问题开始。我们被给予:

  • 一组 N 个元素X = {x_1, …, x_i, … ,x_N},使得每个x_i是由 0 和 1 组成的 m 位串。
  • 目标元素x*也是由 0 和 1 组成的 m 位字符串
  • 函数 f 将 m 位字符串作为输入,如果该字符串为x*则返回 1,否则返回 0。这个函数可以写成:

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

Grover 的搜索分三步进行,如下所述。

步骤 1:设置状态

一个量子态建立在基态的相等叠加上。作为一个例子,考虑 N=8。我们使用 3 个量子位设置状态如下:

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

第二步:相位反转

在第二步中,如果f(x)=1我们翻转每个元素x的振幅,如果f(x)=0保持不变。这是使用实现以下单式门 O 的电路来执行的:

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

假设我们的目标元素x*出现在第四个位置。应用 O 门将为我们提供:

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

第三步:围绕平均值反转

第三步称为围绕平均值的反转涉及围绕它们的集合平均值翻转所有元素。这是使用 Grover 扩散算子实现的,该算子由下式给出:

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

将这个算符应用于我们的量子态,我们得到:

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

这完成了一个回合。如果我们在这一点上测量系统,我们将得到目标元素作为概率(5/(4*√2))等于 78%的结果。

第二步和第三步重复√N 次,最大化这个概率。在第二次迭代之后,我们得到下面的状态,它将以 95%的概率找到目标元素。

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

像许多量子算法一样,格罗弗的搜索是概率性的。它以很高的概率给你正确的结果。为了使这个概率足够大以至于实际上有用,您可能需要多次运行它。

同样的算法也可以用来查找 k 个匹配条目,而不是单个目标元素。已经提出了许多变体。其中之一是 Durr 和 Hoyer 最小化算法,该算法从列表中找到最小元素的索引——这在量子机器学习中找到了有趣的应用。详见:监督学习的量子计算方法

如果你喜欢这篇文章,可以在 中型 上查看我的其他作品,在LinkedInTwitter,查看我的 个人网页 ,或发邮件给我viraj@berkeley.edu

使用正则化找到正确的模型复杂度

原文:https://towardsdatascience.com/finding-the-right-model-complexity-using-regularization-af13606cb393?source=collection_archive---------45-----------------------

理解偏差-方差的权衡,以及如何使用收缩正则化技术实现它们之间的平衡。

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

图片来源:Pixabay.com

在正态线性回归模型中,我们试图通过将所有预测因子拟合到一个线性方程来预测一个响应变量,如下所示:

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

在上面的等式中,我们尝试使用两个预测因子 X1 和 X2 来预测 Y,其中β1 和β2 是有助于估计预测因子对响应变量 Y 的影响的系数。这里ε是不可约误差,不在我们的控制范围内。

当我们用单个预测器/特征对一组训练数据点拟合上述方程时,我们得到一个模型,该模型可以如下所示

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

我们可以看到,上面的等式试图在数据点上拟合一条线,该线近似空间中的每个数据点。就训练数据而言,上述线并不理想,因为该线并不完全适合每个点。在被拟合的点和线之间有一个距离,我们称之为残差

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

在上图中,残差显示为实际数据点和拟合的线性方程线上的点之间的垂直距离。因此,我们可以用下面的等式来表示残差

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

在上面的等式中,我们取实际数据点和直线上拟合点之间的差值。每当我们试图拟合一个线性模型时,我们都试图使所有点的残差之和最小化。这个总和被称为残差平方和

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

我们计算距离的平方,这样正距离值和负距离值的处理方式是一样的。下图显示了一个最小化所有数据点残差的模型。

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

上述模型适合曲线上的所有点。上述模型的 RSS 等于 0,并且该模型具有高复杂度。具有高复杂性的模型试图捕捉数据点中的每一个变化。这样的模型据说有高方差。

在训练数据上具有高方差的模型往往在测试数据上表现不佳,因为当模型试图捕捉训练数据中的每个变化时,它还考虑离群值、随机数据点和高杠杆点,这些点很少并且可能不存在于测试数据中。在这种情况下,我们说模型是过拟合列车数据**。**

因此,为了提高模型在测试数据上的性能,我们降低了模型的复杂性并减少了它在训练数据集上的方差。当我们减少模型的方差时,我们在模型中引入了误差。该误差被称为偏差

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

从上面一行可以看出,模型的复杂度降低了。上面的模型没有试图以增加偏差为代价来捕捉每一个数据点。这样一个复杂度稍低的模型在测试数据上会比我们上面看到的模型表现得更好。

因此,减少方差会增加我们模型中的偏差,反之亦然。这被称为**偏差-方差权衡。**偏差方差权衡可在下图中总结。

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

从上面我们可以看到,随着模型复杂度的增加,模型的方差增加,方差减小。随着复杂度的增加,测试误差也开始减小,但是直到某个点,之后它开始增加。我们必须在拟合模型时找到这个最佳点。

我们必须在拟合模型时找到合适的方差,并且必须确保方差不会太高。

减少方差的正则化技术

正则化技术本质上用于减少模型中的方差并避免过度拟合的问题。

减少模型中方差的一种方法是将系数估计值向零收缩。我们估计系数βi,用于估计预测值/特征 Xi 对响应变量变量 y 的影响。因此,将βi 的值向零收缩将低估该特征对响应变量的影响,并将使模型不那么复杂。我们有两种使用这种思想的正则化技术:

  1. 山脊正则化(L2)
  2. 套索正规化(L1)

山脊正规化

由于我们希望降低系数估计βi 的值,从而降低特征对响应变量的影响,因此我们需要一个模型来惩罚系数估计的高值**。**

在回归模型中,残差平方和(RSS)被最小化。这种方法在岭回归中得到了扩展,除了最小化 RSS 之外,还最小化了系数估计的平方。

我们在岭回归中最小化以下内容

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

这不过是

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

因此,在岭回归中,我们不仅最小化 RSS,而且最小化所有特征的系数估计的平方。这导致系数估计值向零收缩。系数值向零收缩的程度由调谐参数λ控制。如果λ的值很大,模型将更多地惩罚系数估计的大值,并且将更多地降低模型复杂性。因此,调整参数用于控制模型复杂性。

请注意,我们只是缩小了特征的系数值,也就是说,我们减小了β1、β2、…,βp 其中 p 是特征的数量。我们没有缩小截距β0 的值,它是所有特征都为 0 时响应变量的平均值(X1=X2=…。Xp=0)

套索正规化

脊正则化成功地将系数的值缩小到零,但从未将它们减小到等于零。这似乎是具有大量预测值的模型的一个问题。使用岭正则化和大量预测因子的模型是不可解释的。例如,如果我们有 p 个预测值,其中只有 3 个预测值是有用的,那么岭正则化将创建一个包含所有 p 个预测值的模型。

套索正则化是一个轻微的修改岭,克服了这个问题。在套索正规化,我们试图尽量减少以下

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

唯一的区别是,不是最小化系数估计的平方,而是最小化模数。在 lasso 正则化中,如果调谐参数λ的值足够大,一些系数估计将恰好等于零。因此,lasso 也有助于只找到那些对模型有用的预测因子。

选择调谐参数 λ

脊和套索正则化都利用调整参数来控制模型的复杂性。为了确定λ的最佳值,我们使用了交叉验证。我们制作λ值的网格,并对每个值的数据进行交叉验证,并检查哪个值的误差最小。然后,我们用从交叉验证中获得的λ值来拟合模型。

分类问题的正则化

我们现在知道,在回归模型中,我们最小化 RSS,并且当我们在这些模型中应用正则化技术时,我们最小化 RSS 之外的系数估计。

类似地,由于 RSS 在回归中被最小化,我们有许多用于分类模型的损失函数。例如,一个这样的损失函数是交叉熵

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

其中 y 为实际值,**y′**为模型预测值。除了损失函数之外,其余的思想保持不变:将系数估计值向零收缩,并降低模型的复杂性。代替 RSS 的是分类的损失函数。

使用哪种技术?套索还是山脊?

至于用哪种技术的问题,全靠数据。如果响应变量只能由一些预测值来衡量,lasso 将优于 ridge,因为它使系数估计值等于零。如果响应变量需要许多预测值,ridge 将优于 lasso。我们可以通过使用交叉验证来检查哪种技术更合适。

抛开模型的准确性不谈,lasso 总是具有固有特征选择的优势,因为它使系数估计等于零,因此人们可以解释哪些预测因子对于模型是不必要的。

为 AB 测试找到正确的显著性水平

原文:https://towardsdatascience.com/finding-the-right-significance-level-for-an-ab-test-26d907ca91c9?source=collection_archive---------40-----------------------

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

为什么使用默认的 95%显著性和 80%功效水平的 AB 测试可能无法充分评估业务风险。

AB 测试是如今产品和营销团队运作中不可或缺的一部分。这样做的原因是,它提供了一种方法来控制支持或反对新功能、营销活动或网站组件的简单颜色变化的决策风险。

基本上有两个参数可以控制 AB 测试的风险,从而控制基于测试结果的决策的风险:显著性和功效水平。从业者通常会退回到 95%显著性和 80%功效水平的默认值。虽然有些人可能仍然会考虑选择不同的显著性水平(主要是 90%或 99%),但功效水平通常会被完全忽略。事实上,有相当多的在线样本大小计算器首先不能改变这个参数。

控制风险相关成本

那么,为什么这是进行 AB 测试的一种危险方式呢?让我们回忆一下这两个变量的实际含义:

显著性水平决定了我们实施变体的概率,尽管它实际上并不比对照更好(也称为 I 型错误)。这意味着显著性水平限制了实施劣质变体的风险相关损失(例如,可能是开发成本、转化率下降等。).

另一方面,功率水平控制决定反对变体的概率,尽管该变体实际上比当前版本更好(也称为类型 II 错误)。这意味着功率水平限制了不实施更好的变体的机会成本,例如转化率的增加。

实践中的意义和力量

对每个测试使用相同的显著性和功效水平相当于假设每个测试具有相同的风险/回报特征。

让我们假设我们为一家网上商店进行两个不同的实验:一个是关于直接在产品页面上添加一个 【立即购买】-按钮,用户可以在这里获得关于某个特定商品的更多信息。如果用户单击该按钮,商品将被添加到购物篮中,用户将被直接发送到结帐页面以完成购买过程。第二个实验包括一个新功能,让用户有机会留下关于他们购买的产品的评论。产品页面上的其他用户可以直接看到这些评论。

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

立即购买按钮与评论——在 AB 测试中,它们的风险/回报是否相同?

“立即购买”按钮似乎没有太多的实现风险(假设技术实现正确):转化率很可能不会受到负面影响,如果用户不使用该按钮,很容易再次删除它。与此同时,这个概念非常有前途,可以提高转化率。第二个实验包括很大一部分风险相关成本:差评可能会对潜在客户的转化率产生重大影响。与此同时,一旦审查功能对所有市场发布,几乎不可能回滚到以前的状态。用户将坚持保持审查的透明度。

因此,两个实验有非常不同的风险/回报曲线:对于“立即购买”按钮,我们希望确保我们没有错过一个好机会,而实施风险相当低。在这种情况下,统计能力变得更加重要。虽然这些评论可能会对业务产生负面的长期影响,但我们希望确保如果我们决定支持这一功能,我们做出的决定是正确的。这意味着我们需要设置一个更高层次的重要性。

为什么我们必须选择

现在有人可能会问,为什么我们不简单地使用高重要性级别以及高功率级别。原因是两者之间的反比关系:一个参数的增加导致另一个参数的减少,所有其他参数(样本大小、最小可检测效应等。)保持不变。增加样本量以增加两个参数会导致测试持续时间的增加。更长的测试持续时间再次导致风险相关成本的增加,因为更多的用户暴露于潜在的劣质变体,或者更少的用户看到潜在的更好的变体。下图描述了不同样本量的 I 型误差和 II 型误差之间的权衡。

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

如何处理取舍

一种更通用的权衡方式是使用损失函数,它计算两个参数的每个组合的预期损失。让我们假设原假设为真的概率是已知的,因此另一个假设也是已知的(P(H0) = 1 — P(H1))。实施一个新功能,尽管它的性能没有控制好,与 C1 成本相关,而不实施新功能,尽管它确实更好,与 C2 成本相关。这导致以下损失函数:

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

对于 P(H0)=0.5,根据相关成本,我们获得了不同的重要性理想水平和功率水平:

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

在第一种情况下(C1,C2) = (100,80),90%的显著性水平和 95%的功效水平最小化损失函数,从而最小化预期成本。在第二种情况下,潜在机会成本的显著下降导致理想权力水平下降到 80%,从而重要性水平上升到 95%。

因此,使用损失函数有助于在特定实验的显著性水平和功效水平之间找到适当的平衡。当然,很难为我们进行的每个测试定义这样一个损失函数,但在考虑这两个参数的正确值时,记住这个想法是有帮助的。

摘要

应始终根据基础测试的风险/回报情况选择显著性和功效水平,并考虑风险相关的成本和收益。我认为,特别是在软件开发中,由于大多数变更的可逆性,人们可以经常考虑使用比默认的 95%更低的重要性级别。另一方面,在许多情况下,高于 80%的功率水平可能是合理的,以避免错过机会。

参考资料和进一步阅读

非常有趣的论文对本文很有帮助,并提供了更详细的概述:

显著性水平。0.05,0.01,还是?

经济学和计量经济学中的统计与经济意义

如何选择重要性水平:教育学笔记

寻找数据科学独角兽

原文:https://towardsdatascience.com/finding-unicorns-335705c35403?source=collection_archive---------63-----------------------

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

来自 CC0皮克斯拜斯蒂芬·凯勒的图片

面试官对寻找数据科学职位理想候选人的看法,基于大约 15 次面试。

“总有一天,你会得到面试应聘者的机会。当你这么做的时候,一定要像剥洋葱一样剥开这个人的很多层,看看什么才是真正的核心。”几年前,这是我的一位领导给我的告别建议。我很惊讶地说,这四年来一直伴随着我,并且在我作为面试官筛选数据科学家职位候选人的过程中,它一直是我的灯塔之一。

最近,我面试了我团队中多个数据科学家职位的几位候选人。我一直在反思那次经历,以巩固原则,提出一个我将来也可以使用的数据科学面试框架。经常,当我问我网络中的人们他们是如何决定一个角色的特定候选人时,我听到的反应是*【预感】【经验】【你就是知道】*。这篇文章是我的一次尝试,旨在将面试经历总结成一个对被面试者和面试官都有益的框架。

寻找独角兽的框架

既然我们在谈论寻找理想的数据科学家,我们需要定义的基本问题“谁是数据科学家?”。数据科学家有几个定义。每个人都有自己的版本,不幸的是,没有一个是普遍认同的。

多年来,下图为我作为数据科学家提供了一个很好的心智模型。正如上面的维恩图所述,数据科学家是指能够融合编程、统计/机器学习和业务知识,从数据中产生建议/可操作的见解的人。

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

谁是数据科学家?,由斯蒂芬·格林纳,CC BY-NC 3.0 AU

因此,当我开始寻找数据科学家的采访之旅时,我提出了一些问题来剥离各个层面,以了解前面提到的 3 个领域(编程、数学和统计以及领域专业知识)的核心是什么。通过几次面试和反思那些被证明是伟大的发现和不合群的候选人,我学到了在面试过程中也要寻找更柔和的特质,以获得每个人都愿意与之共事的高绩效团队成员的最终结果。如果我不得不选择有助于一个人在商业数据科学团队中出色工作的两大性格特征,那将是 a)同理心和 b)好奇心。

因此,在面试数据科学职位的候选人时,我希望从以下 5 个方面入手。

商业技能/领域专长

编程技巧/数据角力

数学/统计知识

感同身受

好奇心

那么,在上述每个领域中需要考虑什么呢?请继续阅读,了解我评估上述每个领域候选人的方法:

1。业务技能/领域专长:

我认为评估领域专业知识的最好方法是问一些开放性的问题,这些问题类似于你正在解决的现实世界中的问题。大多数时候,候选人不会来自同一个行业。所以,你也在试图评估他们的专业知识有多少可以转移到你的行业。另一种有趣的评估方式是询问他们将从哪些数据元素开始寻找给定的问题。对这个问题的回答通常展示了候选人领域知识的深度和广度。

。编程技巧/数据角力:**

通常,作为一名数据科学家,您必须理解 a)哪些数据元素是可用的,b)然后,痛苦地将它们全部为您展示出来。对于大数据科学团队来说,可能会有数据工程师和数据建模师来帮助做这件事。但是,对于小团队来说,数据科学家应该能够通过追踪数据并将它们拼接在一起,将粗略的想法转化为现实。就背景而言,数据科学家面试的角色需要处理原始数据。如果是这样的话,确认候选人乐于争论数据和处理脏数据是非常重要的。以我的经验来看,澄清你的期望与候选人的期望相符总是好的,因为这里经常会缺乏一致性。如果候选人乐于处理脏数据,那么通过问几个问题来评估他们的技能,继续剥离几层。

3。数学/统计知识:

由于数据科学候选人的概况和专业知识可能会有很大差异,从专注于安全的数据科学专业人员到信用风险专业人员,再到来自零售行业的候选人,我倾向于采用两阶段方法来评估这方面的技能。第一阶段,考核对关键原理、机器学习概念和算法的掌握程度。在第二个方面,深入了解这个人过去参与过的一些项目。在这次深入探讨中,重要的是要发现候选人如何从基本原则*中阐述机器学习概念,以及候选人如何阐述业务优势。其中一个方法是让候选人向一个对机器学习技术一无所知的商业利益相关者解释这个项目。然后,告诉候选人关于假设的数据科学实习生的情况,他在基础知识方面有所欠缺,候选人应该提升技能,这是他的角色的一部分。询问候选人他将如何向假设的实习生候选人解释项目的所有技术细节?

4。移情:**

作为一名在业务团队中工作的数据科学家,候选人最有可能与业务团队密切合作,他们非常擅长经营业务,但可能不太精通数学/统计。因此,非常重要的一点是,候选人要有同理心,愿意将复杂的概念表达成易于理解的形式。

**5。好奇心:

数据科学领域在不断发展,新技术总会让您尽最大努力做得更好。尽管同理心和好奇心是很难评估的属性,这里有一个我最喜欢的问题来评估。*“描述一个你不得不交付非常困难的东西的情况”。你会听到很多关于他们必须解决的难题。然后,问自己,现在,如果你不得不回到过去,你被给予这个问题,你必须从头再做一遍,你会怎么做?这是一个很好的问题,可以发掘求职者的好奇心和反思能力,并使事情变得更好。通常,数据科学领域是不断变化的,新的研究几乎总是有更好的方法来做事情。在结语中阅读更多关于这个问题背后的故事。

如果在面试过程中,他们已经通过了以上 5 个方面的门槛。 那么,答案是——是吗? 最有可能。如果你没有发现任何交易破坏者,答案是肯定的。那么,即使候选人对涵盖 5 个方面的问题回答得足够好,哪些因素会使他失去资格呢?

交易破坏者

在面试过程中,有几个方面绝对是决定性因素。

  1. 诚实: 这是一个不用动脑筋的问题。如果你有确凿的证据证明候选人在面试过程中撒了谎,那么即使候选人出色地完成了上面提到的 5 个方面,他也不应该进入下一轮。我只看到了不同面试之间的不一致。因此,与正在进行其他回合的人进行笔记比较是非常重要的。
  2. 表达能力: 面试对大多数人来说是一个充满压力的过程。因此,有点笨拙是很正常的。我认为,作为一名面试官,你必须做好平衡工作,让人们感到舒适,这样他们才能成为最好的自己,你才能评估他们的技能,能够剥离几层,了解背后的真实人物。通过这种微妙的平衡,你将能够清楚地了解候选人表达概念的能力。候选人能够清楚地表达概念和商业利益是很重要的。

这篇文章是我试图将面试官的直觉转化为一个面试框架。然而,我的旅程才刚刚开始。而且,随着我经历其他生活经历,我的尝试肯定会发展。大多数情况下,面试只有 1 个小时,你可能需要留出至少 15 分钟的时间进行概述和提问。因此,你需要依靠其他面试和背景调查来填补有待进一步审查的领域的空白。

结论

我从采访者的角度写了这篇文章。 我很想听听你在面试台 两边的经历。

给面试者:

你有没有遇到过面试官的模范行为,他们让你感到舒服,这样你就可以做最好的自己,同时他们也很舒服地问你一些困难的问题,剥去你的几层皮,以了解背后的真实的人?

对面试官

你对自己招聘的各种角色有心理框架吗?介意分享一下他们背后的心智模型吗?

请通过评论分享你的想法。

结语:

  • 几年前,在我搞砸的一次面试中,有人问我这个问题。当我有机会面试时,我一直在努力回忆曾经被问到的那个棘手的问题。当我偶然发现朱莉·卓的这篇美国消费者新闻与商业频道文章时,我很高兴能把它加入到节目单中。
  • 从第一原理理解事物是什么意思?基本上,它是一种从头开始清晰表达事物的能力。例如,如果你是一个从事自然语言处理的候选人,并且提到了 tf-idf 。作为一名采访者,你可以进一步了解 tf-idf 。如果候选人能够举出一个例子,清楚地说明 tf-idf 是如何计算的,利弊是什么,这就是从基本原则考虑问题。

.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值