5G+AI,设备上的智能(第一部分)
随着 5G 的推出,人工智能肯定会有超能力。
T2 也许你已经听说过这件事了?近几十年来最具颠覆性的两项技术。你可能会分别听说过它们。
让我们合并他们!5G +人工智能
嗯…这似乎不对。你确定吗?
照片由 Balázs Kétyi 在 Unsplash 上拍摄
与+1K 人一起加入我的电子邮件列表,获取更多独家内容
如果你想了解更多,请访问oscargarciaramos.com
AI 增强 5G,在网络上,在设备上。
“5G 是第五代无线通信技术和标准”。把我们只能说话的第一部手机(1G)、第一条短信(2G)、第一个互联网连接(3G)以及最后的移动带宽(4G)抛在身后。
我们正在谈论更远的东西,其中最重要的进步将来自速度,5G 将允许我们导航到 10GBps,比今天快 10 倍。
5G 将意味着什么?更大规模的物联网生态系统的扩散,无线网络将满足数千亿互联设备的通信需求,而不会影响它们的速度、延迟和成本。
其他优点:
- 高达 10Gbps 的数据速率->比 4G 和 4.5G 网络高 10 到 100 倍。
- 低功耗物联网设备的电池续航时间达到 10 倍。
- 能耗降低 90%和 100%覆盖率。
- 1 毫秒延迟&每单位面积宽带快 1000 倍。
- 每单位面积最多可多连接 100 台设备(与 4G LTE 网络相比)。
这就是 边缘分析 概念出现的地方,或者广义地说,是一种“新的”数据分析模型,其中数据流处理发生在系统的非中心点,例如设备或传感器。
正如我们所见,5G 将导致我们周围的传感器激增,每个传感器都为分析数据和创建机器学习模型开辟了新的机会。
也就是说,我们可以用那些传感器作为 AI 输入。
不仅如此。我们不再谈论将大量数据从其来源移动到一个集中的存储库,在那里我们可以处理这些数据。
我们正在谈论让处理更接近源头,即设备本身,除了有助于扩展智能之外,还为提供隐私和可靠性等至关重要的好处。
新挑战,新机遇
更高效的无线连接、更长的电池续航时间,从而带来更好的用户体验。
想象一下,使用 5G 和 AI 来重新创建一个可以与客户实时交互的虚拟人,远程给他建议或只是作为一个伴侣。负责在危急情况下做出决策或需要立即响应的传感器。我们不是简单地谈论在数据源附近处理信息,而是通过高速共享和接收新数据来添加更多的上下文,利用它们之间的低延迟。
如今,当我们向我们的人工智能语音助手提出任何问题时,都需要几秒钟才能做出响应,因为它会去云端处理请求并获得响应。当我们问天气如何时,这种情况会发生,这并不重要。但是,如果您需要在几毫秒内做出响应,比如紧急情况,该怎么办呢?我们被卖了。我们最好耐心点。
5G 的低延迟、高容量和可用性还将允许人工智能处理分布在设备或传感器、边缘云和公共中央云之间,从而允许开发比今天创建的解决方案更加灵活的解决方案。
游戏或工业 4 等行业。x 也可以从这些复杂用例的功能中受益,这些复杂用例可以从这种分布式无线处理中受益。
一种新范式:无线传感器网络上的分布式学习
我们已经迈出了第一步:使用设备上的处理能力来节省能源,并在将数据传递到云中进行更全面的分析之前对其进行提炼。
**下一步更进一步:**我们不会满足于简单地在设备本身上进行推断,而是在那里训练模型,也就是 分布式学习。
理论如下:
- 中央云向每个设备发送一个模型。
- 每个设备在设备上收集和存储本地数据样本。
- 最后,每个设备执行或实施设备上的训练。
我们从大规模培训到**“小规模可扩展分布式培训】**。
设备上的培训使我们能够:
- 规模:将处理扩展到我们想要的任意多的设备,显著降低必要的计算能力。
- 定制:本地数据训练,其中模型适应每个设备的诡辩(例如它自己的智能手机)。
- 隐私:原始数据永远不会像现在这样离开你自己的设备进行处理。在保护隐私的同时获取价值。
那么下一步是什么?
如你所见,一个激动人心的世界向我们敞开了大门。
没有限制,人工智能不仅可以受益于设备外的数据,还可以受益于新的数据,如设备上的数据(日历、消息、应用程序等)。)以及传感器数据(环境光、麦克风、温度、眼睛跟踪、脉搏等等)。
让游戏开始吧!
如果你想继续阅读,去看看第二部分:
AIoT:要聪明,要有人脉。
欢迎发表评论或分享这篇文章。关注 me 未来帖子。
与+1K 人一起加入我的电子邮件列表,获取更多独家内容
速度快 5 倍的 sci kit-在 5 行代码中学习参数调整
利用 Tune-sklearn 来增强和扩展 scikit-learn 的 GridSearchCV。
作者图片
每个人都知道 Scikit-Learn——它是数据科学家的主食,提供了几十种易于使用的机器学习算法。它还提供了两种现成的技术来解决超参数调优:网格搜索(GridSearchCV)和随机搜索(RandomizedSearchCV)。
这两种技术虽然有效,但都是寻找正确的超参数配置的强力方法,这是一个昂贵且耗时的过程!
作者图片
如果你想加快这个过程呢?
在这篇博文中,我们介绍 tune-sklearn 。 Tune-sklearn 是 Scikit-Learn 的模型选择模块的替代产品**,采用尖端的超参数调整技术(贝叶斯优化、提前停止、分布式执行)——这些技术提供了比网格搜索和随机搜索显著的加速!**
以下是 tune-sklearn 提供的内容:
- 与 Scikit-Learn API 的一致性: tune-sklearn 是 GridSearchCV 和 RandomizedSearchCV 的替代产品,因此您只需在标准 Scikit-Learn 脚本中更改不到 5 行就可以使用该 API。
- 现代超参数调优技术: tune-sklearn 允许您通过简单切换几个参数,轻松利用贝叶斯优化、HyperBand 和其他优化技术。
- 框架支持: tune-sklearn 主要用于调优 Scikit-Learn 模型,但它也支持许多其他具有 Scikit-Learn 包装器的框架并提供示例,如 Skorch (Pytorch)、KerasClassifiers (Keras)和 XGBoostClassifiers (XGBoost)。
- 纵向扩展: Tune-sklearn 利用 Ray Tune ,一个用于分布式超参数调整的库,在多个内核甚至多个机器上高效、透明地并行化交叉验证。
tune-sklearn 支持的框架示例。
Tune-sklearn 也是快**。为了看到这一点,我们在标准超参数扫描上用本机 Scikit-Learn 对 tune-sklearn (启用了早期停止)进行了基准测试。在我们的基准测试中,我们可以看到普通笔记本电脑和 48 个 CPU 内核的大型工作站的显著性能差异。**
对于更大的基准 48 核计算机,Scikit-Learn 花了 20 分钟来搜索超过 75 个超参数集的 40,000 大小的数据集。Tune-sklearn 只用了 3 分半钟——牺牲了最小的准确性。*
******
左图:在个人双核 i5 8GB RAM 笔记本电脑上,使用 6 种配置的参数网格。右图:在使用 75 种配置的参数网格的大型 48 核 250 GB RAM 计算机上。**
*注意:对于较小的数据集(10,000 或更少的数据点),在尝试适应早期停止时可能会牺牲准确性。我们预计这不会对用户产生影响,因为该库旨在加速大型数据集的大型训练任务。
简单的 60 秒演练
让我们来看看它是如何工作的。
运行pip install tune-sklearn ray[tune]
或pip install tune-sklearn "ray[tune]"
开始使用下面的示例代码。
超参数集 2 是一组没有希望的超参数,它们将被 tune 的早期停止机制检测到,并被早期停止以避免浪费训练时间和资源。
TuneGridSearchCV 示例
首先,只需修改我们的 import 语句,就可以获得 Tune 的网格搜索交叉验证接口:
从那里,我们将像在 Scikit-Learn 的界面中那样继续进行!让我们使用一个“虚拟”自定义分类数据集和一个SGDClassifier
来对数据进行分类。
我们选择SGDClassifier
是因为它有一个partial_fit
API,这使它能够停止拟合某个超参数配置的数据。如果估计器不支持提前停止,我们将退回到并行网格搜索。
如您所见,这里的设置正是您为 Scikit-Learn 所做的!现在,让我们试着拟合一个模型。
请注意我们上面介绍的细微差别:
- 新的
early_stopping
变量,以及 max_iters
参数的说明
early_stopping
决定何时提前停止——MedianStoppingRule 是一个很好的默认设置,但是请参见 Tune 关于调度器的文档这里有一个完整的列表可供选择。max_iters
是给定超参数集可以运行的最大迭代次数;如果提前停止,它可能会运行较少的迭代。
试着将它与 GridSearchCV 的等价内容进行比较。
TuneSearchCV 贝叶斯优化示例
除了网格搜索接口, tune-sklearn 还提供了一个接口 TuneSearchCV,用于从超参数分布中采样。
此外,只需修改几行代码,就可以轻松地对 TuneSearchCV 中的分布进行贝叶斯优化。
运行pip install scikit-optimize
来测试这个例子:
第 17、18 和 26 行是为了支持贝叶斯优化而修改的唯一几行代码
如你所见,将 tune-sklearn 集成到现有代码中非常简单。查看更多详细示例并开始使用 tune-sklearn 点击让我们知道您的想法!还可以看看 Ray 对 joblib 的替代,它允许用户在多个节点上并行训练,而不仅仅是一个节点,从而进一步加快训练速度。
文档和示例
- **文献 ***
- 示例:带 tune-sklearn 的 sko rch
- 示例:sci kit-Learn Pipelines with tune-sk Learn
- 示例: XGBoost 带 tune-sklearn
- 示例:带 tune-sklearn 的角膜分类器
- 示例:带 tune-sklearn 的 LightGBM】
*注:如链接文档所示,从 *ray.tune*
导入仅适用于夜间光线控制盘,并将很快在 pip 上提供
6 个惊人的 TensorFlow.js 项目启动了网络机器学习
进行手部跟踪、风格转换、背景移除等操作
杰瑞米·多洛在 Unsplash 上的照片
随着机器学习不断加速,越来越多的语言加入了这一行列。JavaScript 曾经一度是网络生态系统的领导者,现在也在慢慢加快机器学习的步伐。
在过去的一年中,已经发布了相当数量的专门用于机器学习的 JavaScript 库。这肯定会推动人工智能驱动的网络浏览器。此外,JavaScript for machine learning 通过利用 web 视图,具有在移动应用程序中快速轻松部署模型的优势。
在 TensorFlow 的核心,我们有一个 Web GL 加速的 TensorFlow.js 库,让您可以直接在浏览器中或使用 Node.js 来训练和运行模型。最棒的是,您不需要成为机器学习专家就可以部署基本模型,因为该库已经提供了一堆用于分类、分段等的预训练模型。
让我们看看几个基于 TensorFlow.js 构建的令人敬畏的库,以激发您的下一个机器学习项目。
1.人脸和情感识别
人脸检测一直是 Open-CV 中的经典用例之一,自然地,它也成为机器学习中的常见用例。
face-api.js 是一个基于 TensorFlow.js 实现的 JavaScript 人脸识别库,它可以让你检测和识别人脸和地标,同时还可以确定图像中的情绪和性别。
该库完全抽象了底层实现,为您提供了一个易于使用的高级 API。您所需要做的就是调用相关神经网络模型的方法,并选择调用现成的绘图函数在画布上覆盖特征点。
以下是使用地标和表情检测设置面部检测的基本代码:
const detection = await faceapi.detectAllFaces(image) .withFaceLandmarks() .withFaceExpressions();
2.图像风格转移
风格转移是当今最流行的深度学习任务。从照片编辑应用程序到自定义应用程序中的主题,它的可能性是无穷的。
在一个非常高的层次上,神经风格转移包括将风格从一幅图像传递到另一幅图像。一般来说,你可以使用名画或抽象艺术来为你的输入图像带来新的外观。
任意样式传输构建在 TensorFlow.js 之上,可以完全在浏览器中工作。
您可以将多种样式组合到一个图像中,还可以设定样式强度密度来控制最终输出中可见的纹理级别。
3.NSFW 分类器
nsfw.js 是另一个很酷的库,可以让你在浏览器中对图片或 gif 进行筛选和分类。如果你需要审查不适合孩子的内容,这很方便。
运行该模型将返回 5 个类,根据这些类的概率,您可以选择对输入图像应用模糊或像素化滤镜。
下面的代码展示了加载模型和运行推理是多么容易:
const model = await nsfwjs.load()
const predictions = await model.classify(img)
nsfw-filter 是上述库的一个很好的扩展,可以阻止 nsfw 图片在你的浏览器中显示。
4.人物分割
图像分割帮助我们突出和裁剪出图像中的某些特征。改变图像的背景是最简单的用例。
但是如果你需要做相反的事情呢?很高兴,有一个很酷的开源项目,可以让你从图像中去除人类。
这个 TensorFlow.js 项目在实时图像处理方面非常有效,当你在网络应用程序中使用视频通话功能时,它非常方便。
5.手跟踪
手部跟踪是另一个有趣的机器学习任务。通过实时跟踪手的位置,你可以构建基于手势的无接触浏览器,并对点击自拍进行动作捕捉。
从用手指书写和绘制涂鸦到不用鼠标或滑动就能滚动屏幕,手部跟踪的用例真的是无限的。
Handtrack.js 正是你在这种时候需要的库。除了提供边界框点,它还允许您在运行模型时设置自定义参数。
6.一个类似熊猫的图书馆
Panda 是一个强大的 Python 包,是机器学习中最受欢迎的库之一,用于执行数据操作、清理、可视化和许多其他任务。
尽管 JavaScript 在机器学习方面取得了长足的进步,但它总是缺乏一个像熊猫一样的库来完成预处理任务。但现在不是了。
Danfo.js 是一个基于 TensorFlow.js 构建的新的开源 JavaScript 库,它提供了易于使用的数据结构,可以轻松地将数组、JSON、对象、张量和不同索引的数据结构转换为 DataFrame 对象。
这将使处理数据集和执行任务,如合并或分割它们变得更加容易。
结论
TensorFlow.js 旨在让开发人员完全在其浏览器中训练和运行机器学习模型。对于 JavaScript 开发人员来说,这是进入机器学习世界的一个很好的方式。
最棒的是,与运行在苹果生态系统内的 CoreML 不同,TensorFlow.js 可以运行在 iOS、macOS、Linux、Android 以及任何支持浏览器的平台上。
我希望上面的库和项目能启发你开始构建令人惊叹的基于人工智能的 web 应用程序。
这一次到此为止。感谢阅读。
人工智能的 6 个最佳创业选择
意见
想用 AI 创业成功?
来源:Ian Stauffer 在 Unsplash 上拍摄的照片
人工智能是当今发展最快的领域。据财富报道,统计数据显示,人工智能专家的雇佣量在过去 4 年里增长了 74%。人工智能被认为是当代人最热门的工作。对熟练人工智能专家的需求正以前所未有的速度增长。对机器学习、深度学习、计算机视觉、统计学和自然语言处理等人工智能子领域专家的需求和空缺职位每天都在激增。
还有什么更好的时机来创业呢?你可能是一个拥有一些人工智能技能和知识的白手起家的企业家。感谢所有的大肆宣传,这是在人工智能领域建立自己的创业公司的最佳时机。然而,这需要一些事实核查和挖掘。
哪些领域实际上辜负了 AI 的所有加速炒作?为了回答这个问题,我们将不得不探索人工智能的各个领域以及伴随每个主题而来的各种想法。我将讨论各种可能的人工智能创业。然后,我会推荐一些建议,让你从这个特定的创业开始,并进一步详细解释。让我们开始分析 AI 的 6 个最佳创业选择,排名不分先后。
1.机器学习初创公司:
理念和方法— 解决复杂问题的优化算法、高质量推荐系统、高级垃圾邮件过滤、欺诈检测。
来源:丹尼尔·韦德罗在 unsplash 上拍摄的照片
机器学习初创公司提供了广泛的机会。有这么多方向可以选择。对于精通机器学习知识但缺乏深度学习视角或对深度学习不感兴趣的人来说,这也是一个很好的选择。有些人只是喜欢更复杂的数学和机器学习设计。他们真幸运!这是完美的启动选项。各种机器学习模型的设计、战略规划和部署可以根据他们选择的想法来执行,以在他们的商业风险中赚取现金和利润。
2.自然语言处理:
理念和方法— 面向商业和工业的独特创新聊天机器人,关注区域语言、文本到语音和语音到文本任务的机器翻译的序列到序列模型。
来源:Kourosh Qaffari 在 unsplash 上拍摄的照片
你喜欢文本、大量阅读、预处理和用基于文本的数据建立模型吗?答对了。这是规划和建立创业的最佳选择。自然语言处理作为创业选择的可能性是多种多样的。这些包括文本分类、有用数据的分离、高级聊天机器人的构建等等。如果你住在一个地区语言还没有在谷歌翻译中被确认为官方语言的地方,那也是一个很好的商业选择。此外,大多数谷歌翻译在某些语言上效果不佳。你可以即兴创作自己的数据集和想法,从而成功创业。如果你想建立聊天机器人,最好的方法是寻找你的目标受众、公司或企业。制作特定的聊天机器人是理想的,因为你可以极大地提高特定任务的性能。
3.计算机视觉:
思路和方法— 人脸识别、物体检测、人体活动识别、人体情绪和手势检测、图像分割、光学字符识别(OCR)。
来源:卡尔·海尔达尔在 unsplash 上拍摄的照片
我个人对计算机视觉项目和计算机视觉相关的初创公司非常感兴趣。这一领域提供了独特和多样的选择,以建立如此多的创新项目。计算机视觉项目旨在解释和可视化周围的图像和物体。一个卓有成效的计算机视觉商业风险可以产生很高的收入。计算机视觉可以跨许多平台使用。可以在智能手机、物联网设备等上执行人脸识别任务。对象检测任务可以用于图像检索、监视、自动车辆和机器检查。这里是我举的一个人类情感和手势识别的例子。通过选择你的目标受众和你想执行特定计算机视觉任务的公司来建立你的创业公司。
4.基于人工智能的医疗创业公司:
理念和方法— 先进的 x 射线扫描,恶意疾病的高级筛查和诊断,视网膜扫描,针对特定情况识别各种症状。
来源:照片由欧文·比尔德在 unsplash 上拍摄
人工智能正被广泛应用于医学研究和科学领域。由于预测的精确性和准确性,采用人工智能技术的医疗初创公司正获得极高的人气。开发高质量的模型,尤其是在医学和医学科学领域,是至关重要的。这是因为每个预测都可能危及个人的生命。这是对这些创业公司的需求每天都在上升的主要原因之一。如果你有兴趣在医疗行业帮助人们和创新设备,这是你最好的创业想法。
5.具有 AI 的物联网(基于物联网的 AI 创业公司):
理念和方法— 基于人工智能的机器人、使用嵌入式系统的安全性、自动驾驶人工智能汽车、嵌入式设备上的人脸识别和情感分析、家庭自动化设置。
来源:马文·迈耶在 unsplash 上拍摄的照片
这可能是人工智能最酷的创业想法。物联网和人工智能都是当今世界的热门词汇。将人工智能与物联网集成有大量选项可供选择。将人工智能与嵌入式系统结合起来执行各种杂务,如安全、监控、人脸识别和指纹识别等,是非常好的创业选择。机器人和人工智能是最受欢迎的领域之一。要阅读更多关于基于人工智能的机器人梦的内容,请点击这里查看这篇文章。总的来说,对于任何对物联网项目的现实生活和实时计算处理以及人工智能感兴趣的人来说,这是最佳选择。
6.虚拟助手:
**思路和方法——**语音识别与用户交互,对话式聊天机器人 AI,自然语言处理,计算机视觉知识。
来源:本斯·波罗斯在 unsplash 上拍摄的照片
虚拟助手需要特别提及他们自己。这是因为更精确和更健壮的虚拟助手构建起来相当复杂。然而,这些虚拟助理创业公司产生的收入可能非常高。掌握一些物联网、自然语言处理、计算机视觉和语音翻译方面的知识非常重要。现有的热门虚拟助手有亚马逊 Alexa,苹果的 Siri,谷歌助手,微软的 Cortana。市场需要更多的虚拟助手。人们喜欢这些虚拟助手提供的选择。然而,像 Alexa 这样的虚拟助手对某些人来说可能会稍微贵一些。这打开了一个惊人的创业想法出售。更便宜性能更好的虚拟助手和优化的算法可能是一个很大的卖点。在不久的将来,我会做一个关于如何制作你自己的虚拟助手的系列。
来源:照片由 V2osk 在 unsplash 上拍摄
最终想法:
一个人的性格不可能在安逸和平静中发展。只有经历考验和苦难,灵魂才能得到强化,抱负才能得到激发,成功才能实现。
海伦·凯勒
在我的经验中,这是 6 个最好的创业想法。如果你觉得我错过了什么,或者你觉得其他创业想法正在兴起,请随时告诉我。在一天结束的时候,自我满足和对你所感知的事物感到快乐是生活中最重要的事情。如果你选择了以下任何一个创业想法,我祝你好运!享受你的创业想法,不要害怕成功或失败。
真正的考验不是你是否会避免失败,因为你不会。而是你是否让它变得冷酷无情,或者让你羞愧而无所作为,或者你是否从中吸取教训;你是否选择坚持。巴拉克·奥巴马
确立你的创业想法和具体计划对你的创业成功和成为成功企业家至关重要。我希望所有人都喜欢阅读这篇文章,并能从中学习到一些东西。祝所有打算成为现代人工智能企业家的人好运!祝你有美好的一天,在另一篇文章中再见。
NBA 的 6 度分离:为什么中止它是不可避免的
用 Python 可视化 NBA 的旅游连接链(带数据和代码)
想象 NBA 中的关系网
截至 3 月 11 日,美国国家篮球协会已经暂停其赛季。这是 2020 年的另一个重大发展,它被各种与新冠肺炎相关的事件所主导,导致整个城市完全停滞。
(嗯,可能不是完全的停顿。人类的精神是一种神奇的东西——看看西西里的这个街区。)
(这是没有关系的;我只是想在这个糟糕的时期增加一些有趣的亮点。)
尽管西西里的好人尽可能多地利用手中的牌,但现实是艰难的。我们正在经历一个降低传染风险至关重要的时代,社会隔离和自我隔离等机制正在为此而部署。
虽然看到数百万人最喜爱的娱乐活动如 NBA 被推迟或推迟令人难过,但在这种环境下,这可能也是不可避免的。
事实是,除了暂停体育赛事之外,几乎没有其他理由,尤其是像 NBA 这样的网络。加倍如此,在这种情况下,作为一名球员已测试阳性的病毒。
NBA 赛季涉及大量的旅行——平均每个赛季每支球队将近 40,000 英里,并且一支球队不需要很长时间就可以最终与联盟中的所有其他球队联系起来。
NBA 球队每年走过的路程(摘自我之前写的文章
因此,我想用这篇文章来分析和直观地展示 NBA 是如何相互联系的,考虑到他们繁忙的旅行和比赛日程。
像往常一样,我将使用 Python 进行分析,使用进行可视化。我希望在这个充满挑战的时代,这是一个有用的、有益的和有趣的喘息。
准备
数据
我把代码和数据放在我的 GitLab repo 这里 ( sixdegs_leagues
目录)。所以请随意使用它/改进它。
Packages
我假设您熟悉 python。即使你相对较新,这个教程也不应该太难。
你需要pandas
和plotly
。用一个简单的pip install [PACKAGE_NAME]
安装每一个(在你的虚拟环境中)。
入门指南
此分析的目标是确定每个团队在从某个特定日期开始与来源团队的“联系链”团队连接之前需要多长时间。
也就是说,通过一个曾经和另一个队比赛过的队来连接一个队。以此类推,直到他们到达源团队。本质上,我们将玩六度分离/凯文·贝肯,但与 NBA 球队,并可视化我们的结果。
加载数据
将日程数据csv
加载到 Python / pandas 中
nba_sch_data = pd.read_csv(‘srcdata/2020_nba_schedule_fulldata.csv’, index_col=0)
该数据包含一个“est_time
”列,该列以字符串格式包含美国东部时间的比赛日期(和开球时间)。这对于操作来说不太方便,所以让我们用pd.to_datetime
函数创建一个新的包含这些数据的’datetime
’列。
nba_sch_data = nba_sch_data.assign(datetime=pd.to_datetime(nba_sch_data.est_time))
加载我们的球队颜色字典,并列出球队名单,包括:
with open('srcdata/teamcolor_dict.pickle', 'rb') as f:
teamcolor_dict = pickle.load(f)
teamcolor_dict = {k.replace(' ', '_').upper(): v for k, v in teamcolor_dict.items()}
teams_list = nba_sch_data.home_team.unique()
选择“源”团队/日期
让我们选择一个开始日期,和一个源团队。我们可以随机进行;我们就挑 2020 年 3 月 10 日吧,也就是联赛停摆的前一天。
# Pick a random/particular "seed" team
seed_date = '2020-03-10' # YYYY-MM-DD
seed_tm = random.choice(teams_list)
在我的例子中,seed_tm
结果是国王队(可能是他们在一段时间内赢得的唯一一次彩票)。
创建新的数据框架
首先,我们将创建一个新的 Pandas 数据框架,捕获每个团队的数据,这些数据与他们如何融入源团队的连接链有关。数据框架将包括:
- 团队名称(
team
) - 他们是否在联系的团队链上有联系(
contacted
) - 第一次连接到链上的日期(
date
) - 将它们连接到链条上的团队(
con_from
),以及 - 分离的度数(
deg_sep
)。
teams_contacted_list = [{'team': tm, 'contacted': False, 'date': None, 'con_from': None, 'deg_sep': None} for tm in teams_list]
teams_contacted_df = pd.DataFrame(teams_contacted_list)
计算分离度
概括地说,我们的算法将:
- 从
seed_date
开始或之后循环播放日程数据, - 评估一个游戏是否涉及链上的一个团队和接触链外的一个团队,
- 将“下链”团队记录更改为“上链”,以及
- 记录分离度。
为了开始编写代码,我们为源团队设置了第一行数据:
然后,当一个团队被添加到“联系链”中时,我们可以通过日程数据迭代来查找游戏。请看一下我的实现:
我正在做的是查看游戏中每个团队的状态,首先是是否存在不匹配——如果两个团队都在链上,或者不在链上,则不需要采取任何行动。
然后,我更新联系的状态,然后对于不在链上的团队,数据被更新。联系的日期是基于比赛的日期,而分离的程度是加到对方球队的。
检查结果:
(我相对快速地浏览了一遍,如果您有任何问题,请告诉我)。结果看起来相当合理。让我们开始观想吧!
可视化分离度
直方图
首先,我们将绘制一个直方图,以查看团队与我们的随机来源团队的分离程度:
fig = px.histogram(teams_contacted_df, x='deg_sep', template='plotly_white')
fig.update_layout(bargap=0.5)
fig.show()
分离度直方图
有趣的是,它们中的大多数(29 个中的 19 个)只有 3 度或更少的分离度!哇!。
分离天数
同样,我们可以看看团队接触的天数。
在这里,我创建了一个名为 days 的numpy
数组,它是从链的起点开始的天数。
然后,我用 Plotly Express 调用一个横条图。应该比较直截了当。(Plotly.py 条形图文档如果不熟悉的话。)
days = (teams_contacted_df.date-min(teams_contacted_df.date)) / np.timedelta64(1, 'D')
teams_contacted_df = teams_contacted_df.assign(days=days)fig = px.bar(
teams_contacted_df, x='days', y='team',
orientation='h', template='plotly_white',
labels={'team': 'Team', 'days': 'Days until contacted.'}
)
fig.update_layout(bargap=0.2)
fig.show()
从 2020 年 3 月 10 日起,每支球队与(随机选择的)萨克拉门托国王队分开的天数
在这种情况下,一个团队离源团队最远只有 15 天,大约一半的联盟会在 9 天内联系。
我们可以在这个图中添加更多的细节——还记得我们是如何捕捉到将每个团队添加到链中的团队的吗?让我们添加数据。我们可以通过团队颜色来直观地做到这一点。在 Plotly Express 中,我们只需将列名(‘con_from
’)传递给参数’【T2 ')。
# Days of separation, grouped by source team
fig = px.bar(
teams_contacted_df, x='days', y='team',
orientation='h', template='plotly_white', color='con_from',
labels={'team': 'Team', 'days': 'Days until contacted', 'con_from': 'Contact source:'}
)
fig.update_layout(bargap=0.2)
fig.show()
与(随机选择的)国王分离的天数,按之前的链接分组
这就包含了更多的信息——尽管颜色是随意的,令人困惑。举例来说,我可能会认为湖人是被凯尔特人加入进来的(因为绿色)。让我们改变颜色。
有不同的方法可以做到这一点——例如,你可以在color_discrete_sequence
参数下传递一个颜色列表给px.bar
函数调用。
我在这里是通过循环遍历fig
对象下的数据来实现的:
for i in range(len(fig['data'])):
fig['data'][i]['marker']['color'] = teamcolor_dict[fig['data'][i]['name']]
再次渲染图形:
与(随机选择的)国王分离的日子,有“真正的”球队颜色。
它并不完美——它确实存在一些球队颜色相似的问题,但我认为它工作得很好,把你的目光吸引到正确的地方。
很有趣,不是吗?可以预见的是,大部分传播是由原始团队(国王)完成的,但实际上只占很小的比例。大部分工作由其“子”节点完成——这就是网络传播的力量。
我们能把这个标在地图上吗?是的,我们去吧。
描绘未来
我们首先需要竞技场坐标——在我刚才完成的地方加载这个文件,并创建一个新的’teamupper
’列,以使球队名称格式与我们的其他数据帧保持一致。
arena_df = pd.read_csv('srcdata/arena_data.csv', index_col=0)
arena_df = arena_df.assign(teamupper=arena_df.teamname.str.replace(' ', '_').str.upper())
竞技场位置
作为第一个练习,让我们简单地标出这些位置来检查:
# Load mapbox key
with open('../../tokens/mapbox_tkn.txt', 'r') as f:
mapbox_key = f.read().strip()
# Plot a simple map
fig = px.scatter_mapbox(arena_df, lat="lat", lon="lon", zoom=3, hover_name='teamname')
fig.update_layout(mapbox_style="light", mapbox_accesstoken=mapbox_key) # mapbox_style="open-street-map" to use without a token
fig.update_traces(marker=dict(size=10, color='orange'))
fig.show()
这段代码使用 Plotly Express 创建了一个新的“散点 _ 地图框”类型的绘图,在每个纬度和经度绘制每一行arena_df
。我还在这里设置了一个标记的大小和颜色,这是可选的。
值得注意的是,因为这个调用使用了需要 Mapbox 标记的“light”样式。你可以用地图框得到一个免费的,这是我有的。或者,用mapbox_style=”open-street-map”
代替,不用钥匙。它会工作得很好,虽然我不认为它看起来很好。(如果你感兴趣的话,这篇精彩的文档会有更详细的介绍。)
NBA 赛场位置
映射连接
我们有一个数据框架(teams_contacted_df
),它记录了每个团队何时被添加到连接链中,以及由谁添加的。
扩展这些数据,我们将添加出发团队和目的团队的位置。这些数据并不表明团队的旅行,更多的是连接的路径。例如,如果洛杉矶湖人队被圣安东尼奥马刺队加入到链条中,但是比赛在洛杉矶,那么“起源”位置将仍然在圣安东尼奥。
然后,有了这些数据,我们就可以创建一个新的图——在这个图中,从一个团队到另一个团队的每一行都用一条线表示。
同样,有多种方法可以做到这一点。我选择这样做,为每个连接创建一个新的数据序列。(有一种观点认为,应该为每一天或每一个团队创建一个新的系列。我将演示我所做的,但请随意尝试您自己的变化!)
所以我在这里做的是使用经典的情节性(plotly.graph_objects
),并且:
- 初始化一个新图形
- 添加第一个轨迹,这是所有的竞技场
- 对于
teams_contacted_df
数据帧的每一行,添加一条连接“起点”团队竞技场和“终点”团队竞技场的新轨迹。 - 每个轨迹都有连接日期的名称,以及“起点”和“终点”团队名称(您可以在图例中看到)
在地图上代表每个团队的联系
你可能已经注意到了一些事情——首先,地图以非常低的缩放级别加载,我们没有显示任何国家边界,也没有标题。让我们解决所有这些问题:
这导致了这个图:
团队在地图上的联系,有更多格式
我认为它信息量很大,但是仍然缺少一些信息。我更愿意看着地图,立即知道是哪个竞技场(我是澳大利亚人,仍然会把休斯顿/达拉斯/圣安东尼奥弄混),也知道每个城市的分隔程度。
点睛之笔-地图上的文字
该图允许我们直接将文本和标记一起添加到地图中。让我们添加文本来显示团队名称,并在下一行显示该团队与我们的源的分离程度。
文本只需要作为列表传递;我们可以通过以下方式构建它:
txt_list = list()
for i in range(len(arena_df)):
teamupper = arena_df.iloc[i].teamupper
temp_row = teams_contacted_df[teams_contacted_df.team == teamupper]
temp_txt = (
temp_row.team.values[0].split('_')[-1]
+ '<BR>' + str(temp_row.deg_sep.values[0]) + ' degrees of sep.'
)
txt_list.append(temp_txt)
然后,每个团队的文本变成类似于:‘【T0]’
基于D3.js
,像<BR>
这样的简单 HTML 标签将被呈现在页面上,这很简洁。
所以现在对竞技场的需求可以包括这个列表:
fig.add_trace(go.Scattergeo(
mode="markers+text",
lon=arena_df['lon'], lat=arena_df['lat'], marker=dict(size=8, color='slategray'),
hoverinfo='text', **text=txt_list**, name='Arenas'
))
还要注意的是,Scattergeo
调用中的mode
参数值已经更改为“markers+text”
。这告诉 Plotly 也在屏幕上呈现文本数据。
最终结果如下所示:
地图上团队的联系,地图上有文字
就这样,我们可以将所有 30 个团队的位置,到“源”的“网络连接”路径,以及连接的详细信息绘制到交互式地图上!
由于源代码在我的 GitLab repo 中,请随意使用不同的日期和团队。当然,它不需要太多的修改就可以应用到不同的联赛,这将是很酷的。(MLB,NFL…EPL 怎么样?)
这是同样的模拟,从犹他爵士开始:
从 2020 年 3 月 10 日开始的与爵士的联系日,期待
和网络图。
从 3 月 10 日起,球队与犹他爵士队的联系
从上面的两个例子可以看出,连接所有三十个团队真的不需要很长时间,或者说不需要那么多跳。
反过来,暂停联盟肯定是显而易见的——在短短几天内,一半的联盟将被连接,并且在两周内,所有的球队都将与一个“来源”球队联系。
我将在 Plotly Dash 中创建一个仪表板,允许人们使用不同的输入日期和来源位置,但现在—自己使用数据,让我知道你还发现了什么。我很快就把这些放在一起了,所以我不知道你是否能循环所有可能的日期和团队组合——但我肯定这不会很难。
将这一数据与其他联赛进行比较也很有趣——无论是 MLB,球队打更多的比赛,NFL,不是所有球队都互相比赛,每周只打一场,还是欧洲冠军联赛,欧洲冠军联赛纵横交错。我也很想知道这些数据是什么样的。
不过,对我来说就这样了。正如我提到的,我可能会把它变成一个 Dash 仪表板,然后回来分享它。在那之前——保持安全,互相照顾。帮大家把曲线拉平!
如果你喜欢这个,比如说👋/关注推特,或点击此处获取更新。ICYMI:我还写了这篇关于用 Plotly Dash 构建 web 数据仪表板的文章。
[## 使用 Python 在几分钟内构建一个 web 数据仪表板
通过将您的数据可视化转换为基于 web 的仪表板,以指数方式提高功能和可访问性…
towardsdatascience.com](/build-a-web-data-dashboard-in-just-minutes-with-python-d722076aee2b)
这是关于视觉化隐藏的关系:
[## 如何用 Python 可视化数据中的隐藏关系 NBA 助攻分析
使用交互式快照、气泡图和桑基图操纵和可视化数据,使用 Plotly(代码和数据…
towardsdatascience.com](/how-to-visualize-hidden-relationships-in-data-with-python-analysing-nba-assists-e480de59db50)
回头见!😃
用张量流 2 和张量流概率实现 VAE 的 6 种不同方式
自从在 2013 到本文中引入以来,变分自动编码器(VAE)作为一种生成模型,随着其在广泛领域的应用,已经席卷了贝叶斯深度学习的世界。Kingma 和 Welling 的原始论文被引用超过 1 万次;同时,乍一看,它的构造可能不容易理解,因此有许多很好的文章解释了该模型的直觉、架构和其他不同的组件。
然而,VAE 的实现通常是作为那些文章的补充,代码本身较少被谈论,尤其是在一些特定的深度学习库(TensorFlow,PyTorch 等)下被上下文化。)—这意味着代码只是放在代码块中,没有足够的注释说明一些参数是如何工作的,为什么选择这个函数而不是其他函数,等等。此外,由于这些流行库的灵活性,您可能会发现这些演示 VAE 实现看起来都各不相同。此外,一些版本可能会被错误地实现,即使是 TensorFlow 自己的教程中的(我将在后面处理这个帖子,主要在我的实现的版本 a. 下),但如果不与其他版本进行比较,这些错误可能不会被发现。最后,遵循一个有效的版本当然很好,但是我几乎没有看到一篇文章比较横向不同的实现方式。所有这些促使我写这篇文章。
我假设读者已经对 VAE 的工作原理有了一定程度的了解,并且想知道更多关于实现方面的东西。
我打算把这篇文章分成两个部分,这两个部分共同构成了标题:
- 使用 TF 2 和 TFP实现一般 VAE时需要特别注意的事项
- 如何用不同的方式实现 VAE ,使用 TF 2 和 TFP
在开始深入每一部分之前,我想用下面两段话来分享一下我学习这个模型的亲身经历:
在我开始实现它之前,我一直认为我在读了这篇论文之后对这个模型有了很好的理解。当阅读报纸时,通常有太多关于模型的细节,以至于人们很可能会忘记需要额外注意的部分。有时,论文用一个简短的句子描述的模型的一个组成部分可能需要我花几个小时才能完全掌握,并在实现过程中使其工作。在我看来,如果你想很好地理解一个模型是如何工作的,尽管尽可能彻底地阅读这篇文章肯定是好的,但最好还是自己去实现它。
当你开始实现模型时,我会说选择一个社区已经知道模型将如何表现的基准数据集,而不是试图提出你自己的数据集,特别是如果你是第一次实现模型。这一点尤其重要,因为你对结果会是什么样子有一个非常明确的目标——可以说是一个参考。因为仅仅使代码运行无误,并看到成本下降,还远远不能称之为实现工作;我们至少需要看看它是否以其他人已经在特定数据集上观察到的特定方式表现。
第 0 部分:阐明实现目标
根据上一节的讨论,我将介绍数据集,以及 VAE 模型要完成的特定任务。在这篇文章中,我使用了手写数字的 MNIST 数据集,以及形状为(28,28,1)
的图像。我对它进行了预处理,将数据集归一化为介于 0 和 1 之间,并将值离散化为 0 或 1 ,使用 0.5 作为阈值。VAE 模型要在该数据集上完成的任务有:
(a)尽可能接近地重建输入数字图像
(b)使用来自先验分布的随机样本(而不是来自后验分布的样本,以数据为条件)作为解码器的输入,生成看起来逼真的新数字图像
任务 (a) 相对容易完成,然而任务 (b) 在我看来是指示实现是否工作的任务:它已经从训练数据中学习了不同数字的多模态,并且能够产生新的数字图像作为生成模型。
现在我们准备深入这篇文章的每一部分。
第一部分:实施 VAE 时的主要重点
两件事,都与每个实例的损失函数有关:
- 损失函数由两部分组成:反向 KL 散度(潜在变量 z 的先验和后验分布之间),以及期望的负对数似然(待重构数据上的解码器分布;也称为预期重建误差)。将这两部分相加,我们得到负的 ELBO,它将被最小化。对于每个部分的计算,我们需要额外注意我们需要在数据的每个维度上做什么操作(取和 vs .取均值)。
- 损失函数中 KL 散度的权重是一个我们根本不应该忽略的超参数:它调整了 z 的先验和后验分布之间的“距离”,对模型的性能起着决定性的作用。
这是损失函数:
这个损失函数的计算可以通过各种方式来完成,并且在实现过程中经常很容易出错,尤其是 w.r.t .第一个要点中提到的:对数据的每个维度的操作。我会在第二部分中详细阐述,每种实现方式都会单独介绍。
注意,它实际上应该是β-VAE 的损失函数,其中 ω 可以取除 1 以外的值。这个超参数是至关重要的,特别是对于任务 (b) 在第 0 部分中提到的时候:这个超参数的作用是决定我们想要惩罚 z 的先验分布和后验分布之间的差异的力度。很多时候,图像的重建看起来很完美,而从代码 z 采样得到的图像看起来很疯狂。如果 ω 设置得太小,我们基本上根本不正则化后验概率,因此训练后它可能与前验概率有很大不同——从某种意义上说,从前验概率采样的 z 经常会落入后验概率分布中密度非常低的区域。因此,解码器不知道如何处理这些样本 z ,因为它是根据后验分布(注意上面损失函数中负对数似然项的期望下标处的分布)对 z 进行训练的。以下是 ω=0.0001 时重构生成的数字:
重构位数 ω=1e-4
生成的数字 ω=1e-4
注意重构的数字可以清晰的分辨出来(也和它们的标签匹配),但是生成的数字基本都是深色的,无法识别。这是正则化不足的一个例子。
另一方面,如果 ω 太大,后验将被拉得太靠近先验,因此无论什么图像被输入到编码器,我们最终都会得到一个 z ,就好像它是从先验中随机采样的一样。以下是 ω=20 时重构生成的数字:
重构位数 ω=20
生成的数字 ω=20
请注意,所有数字看起来都一样,不管它是根据输入数字重建的,还是作为新数字生成的。这是过度正规化的一个例子。
第三,我们有当 ω 被设置为“恰到好处的量”时的场景——在某种意义上,后验与前验足够不同,可以对输入数字数据进行灵活的调节,因此重建看起来很棒;虽然两个分布的高密度区域有足够的重叠,因此来自先验的 z 样本对于作为其输入的解码器来说不会看起来太陌生。以下是 ω=3 时重构生成的数字:
重构位数 ω=3
生成的数字 ω=3
请注意,所有重建的和大多数生成的数字看起来都是可识别的,而一些生成的数字看起来不太真实。
**总之,虽然自动编码器设置对潜在变量 z 设置了信息瓶颈,迫使其仅保留在降维后重建 x 所需的最基本信息,但是 ω 有助于将 z 放置在能够使解码器从头生成看起来像真实的 x、的新 x 的空间,同时保持重建的质量。
有点题外话:张量流 2 和张量流概率
你可能会注意到,虽然我把这两个库放在了我的标题中,但是到目前为止,这篇文章只讨论了 VAE 模型及其在 MNIST 数据集上的应用。我最初想在构建帖子时将 TF 2 和 TFP 作为第三个组件来写,但后来我决定将它们放在上下文中,即在中讨论它们,而在第一部分和第二部分中讨论实现细节。然而,如果我没有给出这些库的一点背景知识就直接进入代码,这可能显得太草率了。所以他们来了。
TF2
TensorFlow 2.0.0 于 2019 年—9 月下旬发布,所以距离最初发布还不到一年。目前最新版本是 2.3.0 ,7 月发布, 2020 。去年 11 月,我开始从事一个研究项目,这个项目让我选择了 TF 2 ,因此到目前为止,我已经使用了所有四个版本,每个版本都用了一段时间。当时,我充分意识到 PyTorch 已经在研究界获得了很多关注;我选择 TF 2 主要是因为它是构建项目代码库的库。
我对 TF 2 的第一印象:开发深度学习模型确实比 TF 1 方便很多。急切执行是其将 TF 2 与 TF 1 区分开来的最显著特征之一,我不再需要在看不到任何中间结果的情况下构建整个计算图,这使得调试成为一场灾难,因为没有简单的方法来分解每个步骤并测试其输出。虽然急切执行可能会损害模型训练速度,但装饰器@tf.function
在某种程度上有助于恢复图形模式下的效率。此外,它与 Keras 的集成带来了一些很好的好处——顺序和功能 API 在堆叠神经网络(NN)层时带来了不同程度的灵活性,就像 PyTorch、torch.nn.Sequential
和torch.nn.functional
下的对等物一样;同样作为一个高级 API,它的接口看起来似乎很简单(以至于它会在 VAE 实现过程中造成麻烦——查看我在第二部分中的实现版本 a. 下的讨论),好像我正在训练一个 scikit-learn 模型。
与此同时,由于它第一次发布才不到一年,它肯定不像我希望的那样稳定。我仍然记得我被一些简单的张量索引程序卡住了:我在多个版本中实现了相同的功能,这都导致了相同的错误消息;然而,这是一个如此简单的步骤,没有人会想到它会导致错误。原来,今年 1 月初发布后将 TF 版本更新为 2.1.0 后,模型在不修改任何代码的情况下工作。最近的一个例子是在展平张量后添加一个Dense
层时,我得到了一个关于维度的错误信息,这也在将 TF 版本从 2.2.0 更新到 2.3.0 时消失了。
此外,它的用户和开发者社区并不像我预期的那样活跃。我在 Keras Github 问题页面下发布了多个问题,包括上面提到的那个——最后都是我回答了自己的问题并结束了这个问题。一些问题在几个月后获得了用户的评论,但 TensorFlow/Keras 团队没有解决任何问题。
最后,它的一些文档不够简单明了,也不够有条理。我花了很多时间试图弄清楚装饰器@tf.function
实际上是如何工作的,最终我得出结论,最好的方法就是试图模仿工作示例,而不要太在意目前的基本原理。它的一些教程也显得草率甚至误导(通过给出不正确的实现)——我将在后面给出例子。
全股骨假体
TensorFlow Probability 是在 2018 上半年推出的,作为一个专门为概率建模开发的库。它在幕后实现了重新参数化的技巧,这使得训练概率模型的反向传播成为可能。您可以在 VAE 论文和提出了通过反向传播算法的贝叶斯的本文中找到重新参数化技巧的很好演示——前者的潜在变量 z 的隐藏节点和解码器的输出节点是概率性的,而后者的可学习参数(每个 NN 层的权重和偏差)是概率性的。**
有了 TFP,我们不再需要为 z 的后验分布显式定义均值和方差参数,也不需要计算 KL 散度,这大大简化了代码。事实上,它可能会使实现过于简单,以至于不了解 VAE 也能实现,因为它的主要组件需要很好地理解模型,基本上都是由 TFP 抽象的。因此,在使用 TFP 实现 VAE 时也很容易出错。
我建议你从显式实现重新参数化技巧和定义 KL 术语开始,如果这是你第一次实现 VAE,并且你想很好地了解模型是如何工作的——我将在第二部分的第一个版本中以这种实现方式开始。
第二部分:实施 VAE 的不同方式
在深入每个实现版本的细节之前,我想先在这里列出它们。这份清单绝非详尽无遗,而是代表了我打算提出的观点。
实施 VAE 的各种方式是由于我们对以下每个 3 模块有不同的选择:
- 编码器的输出层
- 解码器的输出层
- 损失函数(主要是计算预期重建误差的部分)
每个模块都有如下选项:
编码器的输出层
tfpl.IndependentNormal
tfkl.Dense
输出 z 的后验分布的(串联)均值和(原始)标准差
解码器的输出层
tfpl.IndependentBernoulli
tfpl.IndependentBernoulli.mean
tfkl.Conv2DTranspose
输出逻辑
损失函数
negative_log_likelihood = lambda x, rv_x: -rv_x.log_prob(x)
tf.nn.sigmoid_cross_entropy_with_logits
tfk.losses.BinaryCrossentropy
tf.nn.sigmoid_cross_entropy_with_logits
+tfkl.Layer.add_loss
- PyTorch 式显式计算,通过
with tf.GradientTape() as tape
+tf.nn.sigmoid_cross_entropy_with_logits
+tfkl.Layer.add_loss
- 通过
with tf.GradientTape() as tape
+tf.nn.sigmoid_cross_entropy_with_logits
按历元进行 PyTorch 式显式计算
侧注:
我们有以下模块缩写:
将 tensorflow 作为 tf 导入
将 tensorflow_probability 作为 tfp 导入
tfd = TFP . distributions
tfpl = TFP . layers
tfk = TF . keras
tfkl = TF . keras . layers
还要注意,编码器和解码器的神经网络架构不太重要——我使用与本 TF 教程相同的架构来实现所有版本。
有人可能会想,既然 KL 散度的计算可以用不同的方式来完成(解析解 vs. MC 近似),那么它也应该是一个模块;但由于实现这一术语的方式或多或少取决于解码器输出层的选择,并且将其作为第四个模块添加可能会使演示过于复杂,因此我选择在其中一个实现版本(版本 a. )下讨论它。
实现只是来自每个 3 模块的不同选项的组合:
不同的 VAE 实现及其模块选项
现在让我们深入了解实现的每个版本。
版本 a.
这个版本可能是最广泛采用的一个版本——据我所知,我的所有同事都是这样写的:编码器输出节点,这些节点代表潜在变量 z 的后验分布的均值和(在ℝ范围内的一些变换)标准差。然后,我们使用重新参数化技巧对 z 进行如下采样(来自 VAE 论文的等式 (10) ):
从 z 的后验取样的重新参数化技巧
其中 ϵ 从标准多元高斯分布中采样,后验分布 q 的均值和标准差从编码器中确定性地输出。获得的 z 然后被用作解码器的输入。由于预处理后我们的图像数据 x 是二进制的,很自然地假设一个多变量伯努利分布(其中所有像素彼此独立),其参数是解码器的输出——这是在 VAE 论文的附录 C.1 伯努利 MLP 作为解码器中描述的场景。因此,解码器分布的对数似然具有以下形式(VAE 论文的方程 (11) ):
以伯努利 MLP 为解码器的图像重建分布的对数似然
其中 y 是解码器输出的每个像素的伯努利参数, D 是每个实例的像素数。 z 这里代表来自编码器的单个样本;由于损失函数中的预期负对数似然项无法解析计算,我们使用如下 MC 近似(来自 VAE 论文的方程 (10) ):
z 的 L 个样本下对数似然的 MC 逼近
其中 z 项(与上面的重新参数化技巧等式中的上标形式完全相同)表示第 i 个数字图像实例的第 l 个 MC 样本。实际上,通常设置 L=1 就足够了,即只需要一个 MC 样本。
损失函数中的另一项,反向 KL 散度,也可以通过 MC 样本来近似。由于我们假设编码器分布 q 为多元高斯分布,我们可以直接将编码器输出的均值和方差代入其密度函数:
反向 KL 散度的 MC 近似
其中 f 代表多元高斯密度。同样,我们也可以在实践中设置 L=1 。
此外,如果我们让 q 是具有对角协方差矩阵的多元高斯,则 KL 散度项可以如 VAE 论文的附录 B 所示解析计算:**
负反向 KL 散度的解析解
其中 J 代表 z 的维数。
在这个版本的实现中,我放了计算小批量图像数据成本的代码(注意, loss 函数是在单个实例上计算的;成本函数是所有实例的平均损失)到函数vae_cost
中,并通过函数train_step
定义每个时期的优化步骤。下面是它们在 TF 2 中是如何实现的:
这里需要解决几个问题:
- 预期重建误差的计算
由于伯努利分布的负对数似然性本质上是交叉熵损失的来源(如果你不能马上看到它,这篇文章给出了一个很好的评论),我们可以使用现有的函数——在这个实现版本中,我选择了tf.nn.sigmoid_cross_entropy_with_logits
:这个函数将伯努利参数的二进制数据和逻辑作为参数,所以我没有对最后一个解码器层tfkl.Conv2DTranspose
的输出应用 Sigmoid 激活。
注意,该函数保持其输入的原始维度:由于数字图像和解码器输出的每个实例都是形状为(28,28,1)
,tf.nn.sigmoid_cross_entropy_with_logit
将输出形状为(batch_size, 28,28,1)
的张量,每个元素是该特定像素的伯努利分布的负对数似然。由于我们假设每个数字图像实例具有独立的伯努利分布,因此每个实例的负对数似然性是所有像素的负对数似然性之和,因此是上面代码块中的函数tf.math.reduce_sum(…, axis=[1, 2, 3])
。
如果您计划使用 Keras API,这就是需要采取额外预防措施的地方:Keras API 最大的好处之一是它大大简化了训练神经网络的代码,只有三行代码: (1) 通过定义网络的输入和输出来构建一个tfk.Model
对象; (2) compile
通过指定loss
功能和optimizer
得到模型; (3) 通过调用fit
方法训练模型,其参数包括输入输出数据、小批量、历元数等。对于步骤 (2) ,自变量loss
取一个正好有两个自变量的函数,并通过取该函数输出的所有 维度 的平均值来计算训练期间该批数据的成本,不管它是什么形状。因此,在我们的例子中,你可能很想根据你看过的所有 Keras 教程来编写loss=tf.nn.sigmoid_cross_entropy_with_logits
,但这是不正确的,因为它对每个实例的所有像素的交叉熵损失取平均值,而不是将它们相加——由此产生的成本将不再拥有任何统计解释。但是不用担心,你仍然可以将tf.nn.sigmoid_cross_entropy_with_logits
与 Keras API 结合起来——在c 版本下。我会详细说明如何做。
还记得在帖子的最开始,我提到了 TensorFlow 自己的教程之一有不正确的 VAE 实现吗?现在是时候仔细看看了:它犯的第一个错误是对预期重建误差的计算。它应用mse_loss_fn = tfk.losses.MeanSquaredError()
作为损失函数:首先,对我来说,选择均方误差已经是有问题的——不仅它隐含地假设重建分布是具有实值数据的独立高斯分布,而我们预处理后的图像数据是二进制的,这使得独立伯努利分布的假设成为更自然的选择,而且 MSE 计算高斯分布的缩放和偏移的负对数似然,这意味着你将使用贝塔-VAE 损失而没有意识到它;(更)重要的是,tfk.losses.MeanSquaredError()
没有明确定义自变量reduction
也会计算所有维度的 MSE *的平均值。同样,我们需要取平均值的唯一维度是实例维度,对于每个实例,我们需要对所有像素取和**。如果想要应用tfk.losses
模块,在实施版本 d 下,我将演示如何使用tfk.losses.BinaryCrossentropy
,这是一个更适合我们的情况的选择,用于计算预期的重建误差。***
- KL 散度的计算
出于与上面类似的原因,需要额外注意:我们需要对数据的每个维度进行操作,特别是取平均值或总和。
注意,对于 KL 散度的解析解,我们取所有 J 维度上的元素的 z 的后验分布的参数之和。然而,在同一个 TensorFlow 教程中,它的计算方式如下:
kl_loss = -0.5 * tf.reduce_mean(
z_log_var - tf.square(z_mean) - tf.exp(z_log_var) + 1
)
这是他们在指南中犯的第二个错误,因为他们在所有维度上取平均值。
也可以使用一个 z 样本的 MC 近似来计算 KL 散度——在analytic_kl=False
时检查代码。如果你想验证你的实现是否正确,你可以用下面的方法来近似 KL 散度,把 L 设为某个大整数,比如说 10,000:
其中每个 z 被采样通过
看看结果是否和你用解析解得到的结果相似。
最后,如果您不想手动计算 KL 散度,您可以使用 TensorFlow 概率库中的函数,该函数直接计算两个分布之间的 KL 散度:
prior_dist = tfd.MultivariateNormalDiag(loc=tf.zeros((batch_size, latent_dim)), scale_diag=tf.ones((batch_size, latent_dim)))
var_post_dist = tfd.MultivariateNormalDiag(loc=mu, scale_diag=sd)
kl_divergence = tfd.kl_divergence(distribution_a=var_post_dist, distribution_b=prior_dist)
既然我们刚刚提到了 TFP,现在是时候进入下一个版本的实现了,这就是关于这个库的。
版本 b.
通过将 TFP 与 TF2 的 Keras API 相结合,代码看起来比版本 a 中的代码简单得多这实际上是我最喜欢的版本,并且由于其简单性,将是我将来使用的版本。
在这个版本中,编码器和解码器的输出都是来自tensorflow_probability.distributions
模块的对象,这些对象有许多你期望从概率分布中得到的方法:mean
、mode
、sample
、prob
、log_prob
等。为了从编码器和解码器获得这样的输出,你只需要用一个tensorflow_probability.layers
对象替换它们的输出层。
实现如下:
就是这样!代码重新格式化后的 62 行代码,包括注释。这种简化的主要原因之一是对 z 的采样,因为重新参数化技巧的所有步骤都通过编码器输出 TFP 层tfpl.IndependentNormal
进行了抽象。此外,KL 散度计算是通过概率编码器输出层中的activity_regularizer
参数完成的,其中我们指定先验分布为标准多元高斯分布,以及 KL 散度权重 ω ,以创建tfpl.KLDivergenceRegularizer
对象。此外,可以通过简单地调用解码器输出的log_prob
方法来计算预期的重建误差,该方法是一个tfp.distributions.Independent
对象——这是它所能得到的最简洁的方法。
一个警告是,有人可能认为既然解码器的输入需要是一个张量,但是 z 是一个tfp.distributions.Independent
对象(参见第 53 行),我们需要改为编写z = encoder(x_input).sample()
来显式采样 z 。这样做不仅没有必要,而且不正确:
- 不必要,因为我们已经将
convert_to_tensor_fn
设置为tfd.Distribution.sample
(这实际上是默认值,但我明确地写了出来,以便您可以看到):该参数的作用是,每当该层的输出被视为tf.Tensor
对象时,就像在我们的情况下,当我们需要来自该分布的样本时——outputs=decoder(z)
在第 56 行,它将调用由convert_to_tensor_fn
指定的方法,因此它已经在做outputs=decoder(z.sample())
。 - 不正确,因为随着
.sample()
被显式调用,应该由tfpl.KLDivergenceRegularizer
计算的 KL 散度将不会作为成本的一部分被提取。可能是.sample()
被调用后,我们在神经网络的计算图中不再有 z 作为tfp.distributions.Independent
对象,也就是包含tfpl.KLDivergenceRegularizer
作为其activity_regularizer
的对象类型。因此,在实现 VAE 的这个版本中对编码器输出进行.sample()
将会给我们一个仅包含预期重建误差的损失函数——经过训练的 VAE 将不再充当生成模型,而是仅重建其输入的模型。**
这个版本的实现非常类似于 TensorFlow 的本教程,它比版本 a. 下显示的要好得多——既可以重建现有数字,也可以生成新数字。在这篇文章中,我只想说几件事:
- 他们应用
tfpl.MultivariateNormalTriL
而不是tfpl.IndependentNormal
作为编码器输出概率层,该概率层本质上训练下三角矩阵的非零元素,该下三角矩阵在概念上从正定矩阵的乔莱斯基分解导出。这样的正定矩阵本质上是 z 的后验分布的协方差矩阵,可以是任意正定矩阵,而不仅仅是 VAE 论文中假设的对角矩阵。这将给予我们更灵活的后验分布,但也包含更多的参数来训练,并且 KL 散度计算起来更复杂。 - 他们在
tfpl.KLDivergenceRegularizer
中将 KL 散度weight
设置为默认的 1.0 ,但是就像我在第一部分中讨论的那样,这个超参数对于 VAE 实现的成功至关重要,并且通常需要进行显式调整以优化模型性能。
最后,对于这个实现版本,我想展示应用 TFP 层作为解码器输出的一个好处:我们能够获得更灵活的预测。对于原始 VAE,解码器输出是确定的,因此在采样 z 之后,解码器输出被设置。但是,由于输出是一个分布,我们可以调用mean
、mode
或sample
方法来输出一个tf.Tensor
对象作为数字图像预测。以下是调用不同方法进行重建和生成时的结果:
用于数字图像重建的解码器分布的一个样本
数字图像重建中解码器分布的意义
数字图像重建的解码器分布模式
用于新数字图像生成的解码器分布的一个样本
用于新数字图像生成的解码器分布的平均值
用于新数字图像生成的来自解码器分布的模式
注意,对于重建和生成,平均值似乎比模式更模糊(或不如模式清晰),因为伯努利分布的平均值是在 0 和 1 之间的值,而模式是 0 (当参数小于 0.5 时)或 1 (否则);该样本比其他两个样本显示出更多的粒度,同时看起来也很清晰,因为每个像素都是随机样本(与模式不同,模式在训练后基本上知道所有像素作为一个整体将取什么值来形成一个数字),它也取 0 或 1 作为其值。这就是概率分布所能提供的灵活性。
以下两个版本的实现侧重于在应用 Keras API 简化代码的同时,如何定制损失函数以正确计算期望的重构误差;由于版本 a.** 中的讨论已经为这两个版本奠定了基础,所以我可以将重点放在演示代码上。**
c 版。
在版本 a.** 中,我们讨论了当compile
对象tfk.Model
会导致预期重建误差的不正确计算时,如何直接使用tf.nn.sigmoid_cross_entropy_with_logits
作为loss
参数;一个快速解决方案是基于tf.nn.sigmoid_cross_entropy_with_logits
实现一个定制的损失函数,如下所示:**
其中我们对每个实例取所有像素维度上的交叉熵损失的总和。当编译模型时,我们写道
model.compile(loss=custom_sigmoid_cross_entropy_loss_with_logits, optimizer=tfk.optimizers.Adam(learning_rate))
注意,解码器与版本 a.** 中的解码器相同,它确定性地输出独立伯努利分布的参数的逻辑值。同时,我们使用tfpl.IndependentNormal
作为编码器输出层,就像在版本 b. 中一样,因此 KL 散度计算由其参数activity_regularizer
负责。**
类似地,我们有以下实现版本:
版本 d。
我们基于tfk.losses.BinaryCrossentropy
建立另一个定制损失函数,如下所示:
注意,与使用确定性解码器输出层的版本 c.** 不同,该版本应用了概率层,就像版本 b. 中一样;但是,我们需要先取这个分布的平均值(上面代码块的第 2 行),因为tfk.losses.BinaryCrossentropy
对象的一个参数是伯努利分布的参数,与其平均值相同。还要注意初始化tfk.losses.BinaryCrossentropy
对象时的参数reduction
,该参数被设置为tfk.losses.Reduction.NONE
:这防止程序对与小批量数字图像张量形状相同的结果张量进行进一步操作,该张量的每个元素包含一个特定像素的交叉熵损失。然后,我们对实例级别的维度求和,就像我们在版本 c. 中的自定义损失函数中所做的那样**
值得指出的是,当compile
模型必须接受两个参数时,我们为loss
参数定义的任何函数都必须接受两个参数,一个是模型试图预测的数据,另一个是模型输出。因此,每当我们想要应用 Keras API,同时拥有更灵活的损失函数时,我们就会遇到问题。幸运的是,我们在编码器输出 TFP 层中有activity_regularizer
参数,这有助于将 KL 偏差合并到成本计算中,这给了我们版本 b .;但是如果我们没有呢?剩下的两个版本介绍了一种实现更灵活的损失函数的方法,而不仅仅是针对 VAE 的特殊情况——这要归功于tfkl.Layer
类的add_loss
方法。
版本 e。
我将从直接演示这个版本的代码开始:
请注意,当compile
为tfk.Model
(行 70 )时,我使用了与版本 c.** 完全相同的loss
功能。通过调用add_loss
类方法(行 49 )将加权 KL 散度合并到成本的计算中。以下内容直接引自其文档😗*
这个方法可以用在子类层或模型的
call
函数中,在这种情况下losses
应该是一个张量或张量列表。
除了是“一个张量或一列张量”之外,对格式没有任何要求,我们可以建立一个更加灵活的损失函数。棘手的部分来自这段引文的前半部分,它指定了这个方法应该在哪里被调用:注意,在我的实现中,我在从tfk.Model
类继承而来的VAE_MNIST
类的call
函数中调用了它。这与实现版本 b.** 不同,后者没有类继承。对于这个版本,我最初也是从编写没有类继承的VAE_MNIST
类开始,在名为build_vae_keras_model
的类函数中为tfk.Model
对象调用compile
方法,就像我在**版本 b 中所做的一样。tfk.Model
对象model
编译后,我直接调用model.add_loss(self.kl_weight * kl_divergence)
——我的理由是,由于我们模型的输出层,类tfkl.Conv2DTranspose
的对象,继承自tfkl.Layer
,我们应该能够进行这样的操作。然而,训练结果是,如果我把 KL 权重调低到大约 0.01 ,我会得到“更亮”的生成图像;如果我开始增加 KL 的重量,我会得到几乎完全黑暗的图像。总的来说,生成的图像质量很差,而重建的图像看起来很好,但在不同的 KL 权重值下不会有任何变化。只有在我从tfk.Model
类继承了VAE_MNIST
,并将调用add_loss
的类方法的名称改为call
之后,模型才能正常运行。****
版本 f.
我将这个版本作为最后一个实践版本来实现,想象如果有一天我需要实现一些太复杂而无法使用 Keras API 的模型,这样的框架可能会派上用场。代码如下:
我想强调将调用add_loss
方法的类方法命名为call
的重要性:注意这个方法最初被命名为encode_and_decode
(第 70 行)——如果我在重命名类方法之前为train_step
方法添加@tf.function
装饰器(第 94 行),我会得到
TypeError: An op outside of the function building code is being passed a “Graph” tensor. It is possible to have Graph tensors leak out of the function building context by including a tf.init_scope in your function building code.
在我相应地修改了类方法名之后,错误消失了。拥有@tf.function
装饰器很重要,因为它显著提高了训练速度:在重命名之前,最后一个历元运行了 1041 秒(并且每个历元的时间流逝随着历元的增加而增加;第一个纪元“只”跑了 139 秒,这又是一个奇怪的现象);重命名后,每个历元的运行时间在 34.7 秒和 39.4 秒之间。
此外,在重命名之前,我需要为add_loss
方法添加lambda
参数(第 78 行),因为没有lambda:
我会得到以下错误:
ValueError: Expected a symbolic Tensors or a callable for the loss value. Please wrap your loss computation in a zero argument lambda.
简而言之,当您计划应用add_loss
方法来实现一个更灵活的损失函数时,一个好的实践是子类化tfk.Model
类,并在名为call
的类方法中调用add_loss
方法。
结论
在这篇文章中,我介绍了实现在 MNIST 数据集上训练的 VAE 模型的不同方法,并从实践的角度对 VAE 进行了详细的评述。总的来说,我会推荐一个首次 VAE 实现者从版本 a.** 开始,然后尝试应用 Keras API 来简化代码,用自定义损失函数来计算期望的重建误差就像版本 c .****版本 d .;在对模型有了一个像样的了解后,最好采用**b .版本,这是最简洁的版本,也是 IMHO 最优雅的版本。如果想为将来实现一个非常灵活的损失函数做准备,版本 e、T29 或版本 f、T31 可能是一个很好的起点。
参考
[1] Diederik P. Kingma 和 Max Welling,自动编码变分贝叶斯 ( 2013 ),第 2 届国际学习表征会议论文集(ICLR)
[2] Charles Blundell,Julien Cornebise,Koray Kavukcuoglu 和金奎大·威斯特拉,神经网络中的权重不确定性 ( 2015 ),第 32 届国际机器学习大会(ICML)会议录
[3] 通过子类化 ( 2020 )制作新图层&模型,TensorFlow Guide
[4] 卷积变分自动编码器 ( 2020 ),TensorFlow 教程
[5] Ian Fischer,Alex Alemi,Joshua V. Dillon 和 TFP 团队,具有张量流概率层的变分自动编码器 ( 2019 ),介质上的张量流
6 个用于算法分析的数学函数
理解计算时间复杂度所需的基本函数
unspalsh.com上的 Aron 视觉效果图
设计和实现算法时需要考虑的最重要的因素之一是算法分析期间计算的时间复杂度。
时间复杂度对应于算法在所提供的输入上运行以生成所需输出所需的时间量。在本文中,我们将讨论算法分析中最常用的函数。此外,还提供了一些代码示例,以帮助读者理解这些功能如何与计算机执行的常见操作相关联,作为算法执行的一部分。
常值函数
这可能是最简单的函数,对于任何参数 n *,*常量函数赋值 c 。
常数函数
当我们需要计算一个算法执行的基本操作的数量时,常量函数是很有用的。一些例子可以是整数加法或减法以及变量赋值或比较。
# Examples of basic operationsx = 10
name = 'Andrew'
is_verified = True
线性函数
另一个在我们的上下文中很重要的简单函数是线性函数,它非常类似于常数函数,但是线性函数不是给函数分配一个常数值,而是简单地分配给它自己的输入。
线性函数
当分析需要在所有 n 个元素上执行的操作时,线性函数非常有用。一个例子是读取未存储在计算机内存中的 n 个元素序列的过程(即,要读取所有元素,我们需要执行 n 操作)。
复杂度为 N 的操作示例:
my_list = [1, 2, 3, 4, 5]for i in my_list:
print(i == 2)
对数函数
对数函数是算法分析中最常用的函数之一。
对数函数
如何近似对数
为了计算任何整数的精确对数,我们需要应用微积分。然而,在算法分析的上下文中,我们不一定需要精确的值,因为一个好的近似值就足以满足我们的目的。为了做到这一点,我们通常使用上限,即大于或等于对数的最小整数。例如,log16 的 ceil 是 4,因为((((16/2)/2)/2)= 1。同样,log 18 的 ceil 是 5,因为((((((18/2)/2)/2)/2)= 0.5625≤1。
通常,在每次迭代中将问题分成两半的算法对应于时间复杂度的对数级。这样的例子可能是下面显示的流行的二分搜索法算法。
def binary_search(numbers, item):
first_index = 0
last_index = len(numbers)-1
while first_index <= last_index:
mid_index = (first_index + last_index)//2
if numbers[mid_index] == item:
return True
else:
if item < numbers[mid_index]:
last_index = mid_index - 1
else:
first_index = mid_index + 1
return False
注意:在计算机科学中,我们通常使用以 2 为基数的对数,这是因为计算机的本质是用来存储二进制的。这可能有点令人困惑,因为在数学中“默认”基数是 10,而大多数计算器都假定基数为 10。在算法分析中,当底数被省略时,我们通常用底数等于 2 来解析对数函数。
二次函数
另一个在复杂性分析中常见的函数是二次函数,它将输入 n 的平方指定给自己。
二次函数
在算法分析中,用二次函数来描述嵌套循环的复杂度,即执行 n 次的 n 次运算序列。下面提供了一个例子,在给定一个列表的情况下,该算法试图找到并报告重复项。请注意,这绝对不是解决此类问题的最佳方法(就时间复杂性而言)。
# Example with n^2 time complexityn = [1, 2, 3, 4, 5]for i in n:
for j in n:
if i != j and n[i] == n[j]:
print(f'{n[i]} is a duplicate')
立方函数
与二次函数类似的一个函数是三次函数,它给自己分配输入 n 的立方。
三次函数
三次函数在算法分析中非常罕见,通常表示算法的设计性能很差。
常数、线性、二次和三次函数属于形式为的多项式函数的更大家族
多项式函数
其中 α 是系数,而 d 对应于**多项式的次数。**显然,次数较少的多项式的时间复杂度代表比次数较多的多项式更有效的实现。
指数函数
指数函数是衡量算法时间复杂度的另一个有用的函数。
指数函数
该函数由基数 b 和指数 n 组成,后者被赋予输入值。与对数函数类似,我们假设指数函数的默认基数等于 2。
指数时间复杂度算法的一个非常常见的例子是下面给出的计算斐波那契数的递归函数(即调用自身的函数)
def fibonacci(n):
if n <= 1:
return n return fibonacci(n-1) + fibonacci(n-2)
为什么我们需要时间复杂性?
现在让我们说,对于同一个问题,已经实现了许多不同的算法,我们需要决定哪一个更好(至少在时间复杂度方面)。测量每种算法的时间复杂度可以帮助我们决定哪种算法是最有效的,从而在性能方面更好。
下表说明了输入大小和描述算法复杂性的函数对时间复杂性的影响。
+---------+-----+-------+---------+-------+-----------+------------+
| input n | n | log n | n log n | n^2 | n^3 | 2^n |
+---------+-----+-------+---------+-------+-----------+------------+
| 8 | 8 | 3 | 24 | 64 | 512 | 256 |
| 32 | 32 | 5 | 160 | 1024 | 32768 | 4294967296 |
| 128 | 128 | 7 | 896 | 16384 | 2097152 | 3.4*10^38 |
| 512 | 512 | 9 | 4608 | 262144| 134217728 | 1.34*10^154|
+---------+-----+-------+---------+-------+-----------+------------+
现在很清楚,算法的设计应该确保它尽可能高效地完成工作,否则,时间复杂度会迅速增加,从而使实现效率低下,并且在许多情况下不可用。
结论
在本文中,我们讨论了在计算算法的时间复杂度时最有用的基本函数。我们引入了许多多项式函数和 Log 函数,并研究了一些与上述每个函数相对应的代码示例。
选择增长率尽可能低的算法很重要。以线性或 n 次登录时间运行的算法被认为是非常高效的,而诸如二次或三次之类的更高多项式阶的算法通常表示具有高增长率的低效算法,即,当它们需要在大型数据集上运行时,它们可能成为噩梦。
要避免的 6 个隐藏的 SQL 错误
尤金·希斯蒂科夫在 Unsplash 上拍摄的照片
他们在雷达下飞行,给你带来麻烦
SQL 很棒。它是人类可读和高效的。这很容易掌握。
不幸的是,也很容易犯令人讨厌的 SQL 错误。那些不突出的,不会被你的编辑发现的,会让你头疼的。
在这篇文章中,我将强调一些隐藏的错误,当你浏览数据分析时要注意。
1.操作中的空值
SQL 有各种各样的常见和有用的运算符,用于算术(例如,+,-),比较(例如。>,
Use them, enjoy them, but don’t forget that they won’t do anything with null values. 对空值的操作将返回空值。
下面是几个例子:
a .添加列
假设我们有一个 2019 年销售额的列和一个 2020 年销售额的列。在 2019 年的一行中有一个空值。
当我们把它们加在一起时,我们得到一个空值:
作者图片
这是个坏消息。我们可能知道将空值视为 0,但是 SQL 不知道。
b .“不在”运算符
现在,假设我们有一个关于产品的调查结果表。我们只想排除非常差或非常好的评论。
当我们查询评级不在(“非常好”、“非常差”)时,我们得到以下结果:
作者图片
我们可能期望返回空值(毕竟,null 不在我们提供的列表中),但是 SQL 会将它们排除在结果集中。
解决方法: 每当我们执行操作时,我们都应该确保知道列中的任何空值。如果我们希望它们被视为不同的值,我们可以使用“coalesce”语句轻松实现:
coalesce(rating, ‘’)
2.聚合中的空值
这是与上一个问题相反的问题。当我们运行聚合函数时,SQL 忽略空值。在许多情况下,这是可取的。
但是如果空值真的是 0 呢?
例如,让我们计算 2020 年的平均销售额:
作者图片
在这种情况下,SQL 排除了空值,并计算出 410 / 4 = 102.5,而不是 410 / 5 = 82。
这很容易被忽略——102.5 听起来是一个真实的、完全合理的值。
修复: 同#1。让我们合并空值,如果它们真的表示 0。
3.错误的连接
连接是一个关键的 SQL 功能,它可以帮助我们组合两个表中的数据。
但是当我们使用错误的连接类型时,我们可能会丢失我们需要的数据。
例如,假设我们有一个地理表和一个销售表,我们希望将所有联系人的州和销售额列表发送给我们的营销团队。
左联接为我们提供所有联系人及其销售额,但内联接会删除所有没有任何销售额的联系人:
作者图片
如果我们在这种情况下使用内部连接,我们会丢失可能很重要的数据(也许市场营销想要锁定潜在客户!).
解决方法: 注意我们使用的连接类型。
要了解更多信息,请查看我关于连接数据的介绍文章:
左接合。内部联接。外部联接。啊?
towardsdatascience.com](/a-beginners-guide-to-joining-data-935c8e579fb7)
顺便说一下,如果我们真的执行左连接,我们应该确保将我们的销售列合并为 0,否则,我们可能会遇到上面的问题#1 或#2!
4.右表中的重复键
当我们连接数据集并且我们的右表在连接键中有重复项时,我们会得到比开始时更多的记录。
有时候这就是我们想要的。但是其他时候,我们可能会在右边的表中出现令人惊讶的重复数据——这可能是由于数据质量问题(真实世界的数据是混乱的,你没听说过吗?).
例如,假设我们想在一个“增强的”城市表中用更多的信息来丰富我们的联系人/地理表。
如果我们加入 on state,我们会得到重复的联系人:
作者图片
**解决方法:**确保我们知道我们的右连接键列是否不同。一种简单的检查方法是运行计数和非重复计数,并确保它们相同:
#these will be equal if there are no duplicates
select count(state), count(distinct state) from mytable;
5.运算符优先级问题(注意你的 and 和 or!)
当创建复杂的条件语句时,很容易犯操作符优先的错误。
最常见的例子:当我们编写 SQL 查询时,“And”在“Or”之前被处理。
假设我们有一个包含客户销售额和细分市场的表,我们希望返回细分市场 A 或 B 中销售额也必须大于 100 的客户。
如果我们在编写查询时不注意优先级,我们会得到:
作者图片
请注意,即使 client 1 记录的销售额低于 100,它也会被返回。这是因为查询首先解析“and”语句。
当我们在适当的位置添加括号时,我们得到了我们想要的:
作者图片
解决方法: 当我们使用多个操作符时,总是使用括号。它防止错误,使我们的代码更具可读性。
6.删除逗号
这可能会因我们使用的数据库管理系统而异。
对于 Postgres,我们在命名列时不需要包含“as”关键字。
这意味着,如果我们从查询中删除一个逗号,SQL 将使用列后面的列名重命名逗号前面的列:
作者图片
这是一个双重打击——我们不仅丢失了我们要寻找的一个列,而且我们的一个列也留下了不正确的名称。
修复: 在运行之前仔细检查我们的 select 语句,确保我们没有遗漏任何逗号。
结束语
在这篇文章中,我们介绍了运行 SQL 查询时需要注意的几个场景。当有疑问时,放慢速度,进行测试,并确保你没有成为这些常见错误的受害者总是有帮助的。
P.S. →如果你想了解更多关于 SQL、Python、数据科学的知识,订阅我的 免费邮件列表 。
学习高级 SQL 的 6 大资源
如何将您的 SQL 技能从初级提升到高级
图片由皮克斯拜的 Gerd Altmann 提供
注意,我不隶属于这些公司中的任何一家。这只是我分享我的知识和资源!😃
对于那些对 SQL 有所涉猎的人来说,您可能知道编写基本的查询非常容易,这也是它如此出色的原因!
选择 FROM WHERE GROUP BY ORDER BY。
但是 SQL 比这强大得多。不幸的是,大多数资源只涉及 SQL 的基础知识,很难提高您的 SQL 技能。
也就是说,我已经整合了一些 SQL 资源,您可以利用它们将您的 SQL 技能提升到一个新的水平。我从来没有结构化学习过 SQL——这是我自己学的。这些资源真的帮助我把我的技能提高到了一个新的水平。它们从最有帮助到最没有帮助进行排序,如果你以前从未见过这些资源,你应该会学到很多新的技巧。
我强烈建议您浏览这些资源,因为它们涵盖了许多基本的技能和技术,可以让您作为数据科学家的生活变得更加轻松。例如,如果你从来没有利用过窗口函数,现在是时候了!
也就是说,这里有六个资源可以用来提升你的 SQL!
1.扎卡里·托马斯的妙语
链接 此处 。
我先分享一个扎卡里·托马斯的妙语。这是一个了不起的资源,它提供了一些关于一些最基本的 SQL 概念的练习题。
您将从中了解到的一些内容包括:
- 自连接
- 窗口功能
- 交叉连接
2.Leetcode
链接 此处 。
Leetcode 是最好的资源之一,它帮助我学会了我从来不认为可能的技巧。这是我在找工作时充分利用的东西,也是我会经常回去查阅的资源。
Leetcode 很棒,因为他们有解决方案和一个讨论板,在那里你可以了解更有效的解决方案和技术。
通过 Leetcode,您将了解到以下内容:
- 自连接
- 嵌套的 WHERE 语句
- 创造性地使用 HAVING 语句
- 旋转表格
3.方式
链接 这里 。
模式提供了广泛的 SQL 指南,从初级 SQL 到中级 SQL 再到高级 SQL。这是一个伟大的资源,看看你不知道什么,并挑选你需要学习的东西。这也是一个很好的资源来温习生锈的技术。
另外,他们还有三个实用的 SQL 案例研究,您可以用它们来获得实际经验。查看 这里 。
您可以学习的一些内容包括:
- 字符串函数
- 子查询
- 窗口功能
- 性能调整
- 透视数据
4.SQL Server
链接 此处 。
如果您想真正了解技术,SQL server 有关于技术的深入资源,我个人从未见过!
您将学习的一些内容包括:
- 索引
- 存储过程
- 用户定义的函数
- 扳机
5.使用索引路加
链接 此处 。
说到索引,如果您想深入了解它的大量细节,这是一个必不可少的资源!我不打算撒谎,它很密集,可能令人望而生畏,但如果你需要参考任何子主题,它非常有用。
您将学习的一些内容包括:
- 什么是指数
- 聚类数据
- WHERE 语句*(详细冗长)*
6.黑客银行
链接 此处 。
与 Leetcode 类似,Hackerrank 提供了几十个练习题,你可以用它们来学习新技能。如果你想专注于难题,跳过任何简单的问题!
感谢阅读!
我希望这些资源对您的数据科学之旅有所帮助。具体来说,您应该能够极大地提高您的 SQL 技能,这在执行深度挖掘、创建您自己的视图、执行 ETL 等等时将非常重要。
特伦斯·申
- 每周查看 我的免费数据科学资源 的新资料!
- 如果你喜欢这个, 在 Medium 上关注我 获取更多
- 我们来连线上 LinkedIn
新时代商业智能的 6 个关键领域
图片来自 Pixabay (CC0)
早在 1958 年,IBM 的研究员 Han Peter Luhn 就提出了商业智能(BI)的概念,他使用了《韦氏词典》中的定义:理解呈现的事实之间的相互关系,从而指导行动实现预期目标。根据其定义,商业智能确实是一种愿景。它不应该由在某个给定时间设计的工具或技术来表示。换句话说,它应该被视为公司的战略愿景,用于将数据资产转化为业务洞察力,以做出数据驱动的决策。
从历史上看,有两个时代彻底改变并普及了商业智能的概念。第一次是在 20 世纪 80 年代,当时关系数据库被发明出来,并成为数据收集和数据存储的主流工具。数据库和 SQL 使企业能够更快地访问信息,以便根据当前事实和历史趋势做出业务决策。第二个时代是在数据仓库诞生的 20 世纪 90 年代。数据仓库从各种关系数据库系统收集数据,并进一步转换和聚合它们以供 BI 工具使用,这导致了大量信息的可访问性的飞跃。结果,数据仓库刺激了新技术,通过更好的可视化让业务用户更快地访问更多信息,使他们的生活更简单。
从数据中获得业务洞察力是一个迭代过程。记住一个给定的问题,从数据中获得的新发现很容易引出另一个问题。一个报告或仪表板可能会有许多结果,这取决于您从哪里开始以及找到了什么。业务用户通常需要一套不同粒度的报告,但最终仍然需要数据分析师的帮助来运行定制查询,这可能需要几天甚至几周才能得到答案。也就是说,一个理想的工具应该具有以下功能来完全满足商业智能的需求:
- 从最精细的级别到最高的聚合级别,访问每个级别的所有数据。
- 快速访问数据,响应时间只需几秒钟
- 无需编程即可进行任何分析和报告
- 用通用语言或视觉效果与其他决策者分享见解,这样既容易理解,又可操作。
没有一种工具可以同时在上述所有领域做得很好。许多公司不仅购买多种工具来相互补充,还构建自己的报告来填补这些工具无法填补的空白。此外,每个公司都非常需要业务和数据分析师来帮助分析调查、故障排除和手动生成 BI 工具无法完成的报告或仪表板。
大数据、云平台、机器学习和数据管理方面的最新进展将商业智能推向了第三个时代,对信息的访问更快、更容易,同时还有前所未有的可视化和机器智能选择。例如,NoSQL 数据库提供非结构化数据的快速访问;Tableau 等可视化工具允许业务用户在不编写代码或查询的情况下进行快速分析;云平台允许流技术和更快的数据管道发布数据,从以前的每周/每月到现在的几天/几小时/几分钟。最后,机器学习帮助用户从各个角度找到正确的信息,检测异常值,并预测未来。
在新的商业智能时代,企业如何充分利用新的机遇并取得成功?下面列出了六个关键领域,应该通过战略路线图仔细考虑,以确保最终的成功。
- 了解你的客户
识别你的客户,知道他们想要什么,对于你的商业智能之旅的成功至关重要。一般来说,有两种类型的用户:
商业用户
- 制定数据驱动型决策的高管和经理
- 需要详细报告以确保业务成功的业务分析师
- 寻找新商机的营销和产品经理
- 使用数据运行预测模型的数据科学家
操作用户
- 确保收入和利润报告准确的财务分析师
- 成功支持生产环境的 IT 运营人员
- 监控数据质量并捕捉数据异常的数据质量人员
这些用户的技能差别很大,从报表分析,到使用 Excel,到使用 BI 工具,以及编写 SQL 查询和程序。因此,它需要提供不同类型的数据输出和工具来满足不同用户的需求。在了解客户之后,公司可以制定正确的战略和策略来实施商业智能解决方案。不成功的 BI 计划通常源于忽视一组用户的需求或交付他们不想要的工具,这导致客户满意度低和数据利用率低于预期。
2。标准化数据管道
正如我在之前的文章数据处理和数据访问中的大数据架构中所述,由于不同的用户组可能会有不同的 BI 工具,因此标准的数据管道对于确保单一来源的真实性至关重要。它还通过防止不必要的数据重复来提高组织的效率和生产力。任何公司都不想面对的最后一件事是,从多个仪表板或报告中以不同的数字报告给定的度量,并且不知道哪个是正确的。
任何数据,无论是由应用程序还是从外部来源收集的,都需要在被商业智能应用程序使用之前进行清理、标准化和转换。根据数据源的不同,一个组织中可能有多个标准的数据管道,这些管道可能需要相互排斥,每个管道专注于自己的数据源和负责的数据区域。
3。为不同的用例设计数据访问层
在过去的二十年中,数据仓库已经成为将所有有用信息存放在一个地方供商业智能工具访问的首选方法。这种方法有几个明显的局限性:
- 单个数据仓库在处理和数据访问之间引入了冲突,这使得很难同时实施数据处理的服务级别协议(SLA)和 BI 报告的快速响应时间。
- 大多数数据仓库存储高度结构化和转换的数据,但不存储原始或非结构化的数据。
- 当需要进行更改时,关系数据库会导致僵化和高影响。
现代 BI 工具现在可以从多个结构化或非结构化的数据库或来源访问数据。它们中的许多还支持数据建模、数据转换、数据分析和数据采样,以便用户确定哪些数据是可用的,并在工具中准备数据,而无需编程或开发人员的帮助。换句话说,数据集中化功能已经逐渐从数据仓库转移到 BI 工具,为用户提供了从不同系统访问各种类型数据的能力和灵活性。
鉴于上述趋势,组织应该根据用例以及相应的数据检索模式,为其 BI 工具选择合适的数据库技术。NoSQL 数据库以及大数据平台的最新进展提供了许多不同的选择。要做出正确的技术选择和投资,需要进行仔细的测试和概念验证。
4。增强自助服务的能力
BI 用户总是同时过度依赖于提供信息的开发人员,并对他们之间的不断交流感到沮丧。今天的技术和工具可以让用户更加自主地滑动和切割数据,查看更细粒度或非结构化的数据,调查数据问题,以及自己创建报告和故事。
随着 BI 工具消耗越来越多的数据,业务用户将面临他们应该选择什么数据以及在哪里找到正确信息的问题。集中式数据管理,配备使用数据目录的强大元数据管理,将解决这一问题,并成为企业中成功的商业智能之旅的关键。好处是:
- 让商务智能用户能够自信地快速找到正确的数据
- 允许 BI 工具以一致的方式使用相同的变量、度量和显示名称
- 因此,提供语义层的单一事实,提高整个公司的效率和生产力
总之,现代商业智能通过提供用户自己查找数据的能力,赋予了用户更大的权力。这将最大限度地增加用户高效利用数据的机会。它还使 It 能够将资源集中在构建强大的数据管道和基础设施上,从而提供可扩展的解决方案来处理更多数据,如物联网和流数据。
5。借助高级分析实现现代化
BI 一直被称为报告过去和当前,而数据科学负责预测未来。这是一种过时的观点,受到以前的 BI 工具的限制,但不是商业智能最初的定义。任何有智能的东西都应该能够根据过去的事实预测未来。因此,越来越多的 BI 工具能够与用其他语言(如 R 或 Python)开发的预测模型集成,并提供数据科学功能来实现开箱即用的更多智能,例如:
- 内置于报告或仪表板中的机器学习功能,可自动检测异常值、趋势突破,并同时发送警报。
- NLP 能够讲述故事,并从一系列报告中自动得出结论,而不是让人类查看每个报告来得出结论。
这是一个新的但令人兴奋的领域,具有很高的商业智能潜力,它将把工具和服务带到决策智能的下一个级别。
6。监控持续改进的使用情况
商业智能服务于商业需求。当业务环境或要解决的问题发生变化时,特定的报告、数据板和数据资产可能会过时。应该有一个严格的流程来监控 BI 工具的使用及其输出。任何过时的都应该有组织地淘汰。这对于公司内部的整体有机增长以保持效率、成本效益和生产力是很重要的。因此,任何 BI 工具和产品都应该从一开始就建立跟踪机制。例如,它应该将用户的访问统计记录到最精细的级别,如访问了哪个报告、哪个表和哪些列。这些统计数据还为技术团队提供了数据访问模式的概念,以便他们能够提高数据访问性能。
结论
商业智能的概念出现在关系数据库发明之前。在过去的二十年里,商业智能技术所带来的效率和结果已经发生了两次革命,我们现在正处于第三次革命中。我们有时会听到商业智能正在消亡的说法,但这不是真的。这种说法将愿景与限制商业智能能力的工具混为一谈——任何企业和公司仍然比以往任何时候都更需要商业智能。随着第三个时代的到来,商业智能正随着许多新功能而再次现代化,包括具有用户友好功能的更多自助服务、数据科学和预测能力的数据建模。此外,可以开发更强大的数据管道来提供大量数据,这将有助于新的 BI 工具提高智能。企业应该充分了解其用户群体,选择正确的技术范围,构建一致的数据管道,实现数据管理,并增强整体基础设施,以享受成功的商业智能之旅。
6 个鲜为人知的熊猫绘图工具
使用这些绘图工具加快您的 EDA 进程
艾萨克·史密斯在 Unsplash 上拍摄的照片
Pandas 是数据分析和操作的首选 Python 库。它提供了许多加快数据分析过程的功能和方法。
说到数据可视化,pandas 并不是主要的选择,因为已经有了很好的可视化库,比如 matplotlib、seaborn 和 plotly。
话虽如此,我们不能忽视熊猫的绘图工具。它们有助于发现数据帧或序列中的关系,语法非常简单。只用一行代码就可以创建非常丰富的图表。
在本帖中,我们将介绍 pandas 的 6 种绘图工具,它们无疑为探索性数据分析过程增加了价值。
创建一个伟大的机器学习模型的第一步是探索和理解数据中的结构和关系。
这 6 个绘图工具将帮助您更好地理解数据:
- 散点图
- 密度图
- 安德鲁斯曲线
- 平行坐标
- 滞后图
- 自相关图
我将使用 kaggle 上可用的糖尿病数据集。让我们首先将数据集读入熊猫数据帧。
import pandas as pd
import numpy as npimport matplotlib.pyplot as plt
%matplotlib inlinedf = pd.read_csv("/content/diabetes.csv")
print(df.shape)
df.head()
该数据集包含 8 个数字特征和一个指示该人是否患有糖尿病的目标变量。
1。散布矩阵图
散点图通常用于探索两个变量(或特征)之间的相关性。使用笛卡尔坐标显示数据点的值。
散点图矩阵只用一行代码就能生成散点图网格。
from pandas.plotting import scatter_matrixsubset = df[['Glucose','BloodPressure','Insulin','Age']]scatter_matrix(subset, figsize=(10,10), diagonal='hist')
出于演示目的,我选择了具有 4 个功能的数据框架子集。对角线显示每个变量的直方图,但是我们可以通过将对角线参数设置为“ kde ”来改变它以显示 kde 图。
2。密度图
我们可以在序列或数据帧上使用 kde() 函数生成密度图。
subset = df[['Glucose','BloodPressure','BMI']]subset.plot.kde(figsize=(12,6), alpha=1)
我们能够用一行代码看到特性的分布。 Alpha 参数用于调整线条的暗度。
3。安德鲁斯曲线
安德鲁斯曲线以统计学家大卫·f·安德鲁斯命名,是一种用大量曲线绘制多元数据的工具。使用样本的属性(特征)作为傅立叶级数的系数来创建曲线。
我们通过对属于每一类的曲线进行不同的着色来得到不同类的聚类的概述。
from pandas.plotting import andrews_curvesplt.figure(figsize=(12,8))subset = df[['Glucose','BloodPressure','BMI', 'Outcome']]andrews_curves(subset, 'Outcome', colormap='Paired')
我们需要传递保存类信息的变量的数据帧和名称。 Colormap 参数是可选的。基于子集中的特征,两个类别之间似乎有明显的区别(有一些例外)。
4。平行坐标
平行坐标是绘制多元数据的另一种工具。我们先来创造剧情,再来说说它告诉我们什么。
from pandas.plotting import parallel_coordinatescols = ['Glucose','BloodPressure','BMI', 'Age']plt.figure(figsize=(12,8))parallel_coordinates(df,'Outcome',color=['Blue','Gray'],cols=cols)
我们首先从熊猫绘图工具中导入平行坐标。然后创建要使用的列的列表。然后创建 matplotlib 图形。最后一行创建平行坐标图。我们传递一个数据帧和类变量的名称。颜色参数是可选的,用于确定每个类别的颜色。最后,使用 cols 参数选择要在绘图中使用的列。如果未指定,则使用所有列。
每列用一条垂直线表示。水平线代表数据点(数据帧中的行)。我们大致了解了如何根据特性来划分类。“葡萄糖”变量似乎是区分这两个类别的良好预测指标。另一方面,不同类别的线在“血压”上重叠,这表明它在分离类别方面表现不佳。
5。滞后图
滞后图用于检查数据集或时间序列的随机性。如果一个结构显示在滞后图上,我们可以断定数据不是随机的。
from pandas.plotting import lag_plotplt.figure(figsize=(10,6))lag_plot(df)
我们的数据集中没有表明随机性的结构。
让我们看一个非随机数据的例子。我将在熊猫文档页面使用合成样本。
spacing = np.linspace(-99 * np.pi, 99 * np.pi, num=1000)data = pd.Series(0.1 * np.random.rand(1000) + 0.9 * np.sin(spacing))plt.figure(figsize=(10,6))lag_plot(data)
我们可以清楚地看到滞后图上的结构,所以数据不是随机的。
6。自相关图
自相关图用于检查时间序列的随机性。它们是通过计算不同时间滞后的数据值的自相关而产生的。
滞后就是时差。如果所有时滞的自相关都非常接近于零,那么时间序列就是随机的。
如果我们观察到一个或多个显著的非零自相关,那么我们可以得出结论,时间序列不是随机的。
让我们先创建一个随机时间序列,看看自相关图。
noise = pd.Series(np.random.randn(250)*100)noise.plot(figsize=(12,6))
这个时间序列显然是随机的。该时间序列的自相关图:
from pandas.plotting import autocorrelation_plotplt.figure(figsize=(12,6))autocorrelation_plot(noise)
正如所料,所有的自相关值都非常接近于零。
我们来做一个非随机时间序列的例子。下图显示了一个非常简单的上升趋势。
upward = pd.Series(np.arange(100))upward.plot(figsize=(10,6))plt.grid()
该时间序列的自相关图:
plt.figure(figsize=(12,6))autocorrelation_plot(upward)
这种自相关清楚地表明一个非随机的时间序列,因为有许多明显的非零值。
直观地检查简单的上升和下降趋势的非随机性是非常容易的。然而,在现实生活的数据集中,我们很可能会看到高度复杂的时间序列。我们可能看不到这些系列的趋势或季节性。在这种情况下,自相关图对于时间序列分析非常有帮助。
熊猫又提供了两个绘图工具,分别是bootsap plot和 RadViz 。它们也可以用于探索性的数据分析过程。
感谢您的阅读。如果您有任何反馈,请告诉我。
熊猫的 6 个鲜为人知却令人敬畏的把戏
图片来源: Unsplash
我希望我能早点知道的技巧,以便从熊猫身上获得更多的价值
作为最流行的用于分析的 Python 库,Pandas 是一个提供各种数据操作和处理能力的大项目。毫不夸张地说,包括我在内的数据科学家在我们的日常工作中都会用到熊猫。
这个博客是我致力于分享熊猫十大鲜为人知但最受欢迎的特征的迷你系列的第一部分。希望您可以带着一些灵感离开,使您自己的代码更加健壮和高效。
这个迷你系列的数据集来自食物营养成分表,这是一个维基百科页面,包含 16 个按食物类型分类的基本食物及其营养成分的列表。在这个演示中,我们将使用乳制品表的一个子集,如下所示。
来源:维基百科
1。用 **read_html(match)**
从 HTML 中抓取表格
说到 Python 中的 web 抓取,我的首选库曾经是BeautifulSoup
,直到我发现了熊猫中的read_html()
。没有解析 HTML 页面的麻烦,我们可以直接提取存储为 HTML 表的数据,
注意到参数。match = ‘Fortified milk’
在码?它仅用于选择包含指定字符串或正则表达式的表,在我们的例子中,就是 dairy 表。match
arg。当我们的 HTML 页面变大时将会非常方便。
然而,查看输出显示,我们意识到相当多的行和列被截断了!
2。自动加载定制的**options**
和熊猫一起工作一段时间,你可能知道它允许用户在它的选项系统中配置显示相关的选项。例如,设置pd.options.display.max_rows = 1000
解决了上面的显示问题,这简直让我回到了第一次学习熊猫的时候!
然而,我的挫折越积越多,因为我不得不重写相同的配置。选项,每次我开始一个新的 IPython 会话。我不知道这些选项可以编译到 IPython 启动文件中,
然后我们只需设置PYTHONSTARTUP
环境变量指向这个启动文件,所有方便的设置都会在 Python 启动时自动加载。这是启动文件执行后的打印输出,
****** * 更新 2022:加入我们的 YouTube 社区🎦** 【数据说话带吉】 😄**
3。从 **.iterrows()**
切换到 **.itertuples()**
正如我们刚刚看到的,由于“Food”列中的子类别,该数据包含缺失值,
来源:维基百科
直觉上,我们的下一步是通过删除带有 NA s 的行或者用所需的值填充它们来删除丢失的值。不管我们决定使用哪一个选项,我们首先需要连接“Food”列,因为它们都包含唯一的信息。众所周知,这可以通过用.iterrows()
方法循环遍历行来实现。
然而,一个更好的循环熊猫的方法是.itertuples()
,顾名思义,它返回一个元组而不是一个 pd。系列如.iterrows()
所示。
我经常发现.itertuples()
比.iterrows()
运行得快,因为前者消除了调用.iterrows()
方法的一些开销,例如检查数据类型。更多细节可以在这里[找到](http://Since this is beyond the scope of this blog, I will not discuss it here, however, more details regarding how to (create ODBC or JDBC connections) can be found here.)如果你有兴趣的话。
现在,让我们探索如何将我们的“食物”价值观与.itertuples()
联系起来,
该语法中的技巧包括(1)初始化两个全局变量以存储当前的“Food”值和行索引,该行索引恰好是“row”元组中的第一个元素;(2)通过分配回新的串联“食物”值来修改原始的 dairy 表。
这里显示了我们预想的输出,
4。用 **.fillna(method)**
输入缺失值
正如我们简要提到的,处理缺失值的另一种方法是用所需的值填充它们,在我们的例子中,这些值是下一个连续行中的值。现在fillna()
函数派上了用场,
只用一行代码,我们丢失的值就被估算出来了,
这里我们指定参数。method = ‘bfill’
:反向填充,反向传播第一个非空值。另一个选项是 ‘ffill’ :向前填充,在时序数据中特别有用。关于该参数及其多值选项的更多详细信息,请点击链接。
事实上,当我第一次学习.fillna()
时,我非常喜欢它,因为它允许我估算 NA s,而无需首先用 NA s 对行进行子集化。method
这个功能很快成为我最喜欢的熊猫功能之一。
****5。用和**cumsum()**
处理布尔值
随着 NA 被填充,现在我们采取不同的方法来连接“食物”值怎么样?第一步,让我们创建一些关键变量来指示哪些行将被合并**,即,两个连续的行在除“食物”之外的变量上具有相同的值,**
这里有两个技巧:(1)使用shift(1)
选择前一行,然后与当前行进行比较;(2)调用cumsum()
对于转换成整数向量的布尔值(即 1 =真,0 =假)如果两行不同时进行“计算”。
因为我们比较了数据集中的所有 3 列,所以从cumsum()
创建了 3 个额外的关键变量(例如,Measure_)。一旦我们将它们与 dairy 表合并,我们将看到下面的输出,对于要合并的行,所有 3 个关键变量保持不变,
6。用 **.get_group()**
自省 **GroupBy**
对象
有了关键变量,我们可以继续使用另一个有利的技巧连接“Food”值:.groupby() + .apply()
,下面的代码返回与第 3 项相同的输出,
类似于 SQL 中的 GROUPBY 操作,Pandas 中的.groupby()
将我们的数据分成由关键变量定义的组。但是它到底是如何工作的呢?为了自省对象.DataFrameGroupBy
,我们可以利用较少使用的.groups
和.get_group()
,
从下面的部分打印输出中,我们可以看到,每个组都是由原始数据集拼接而成的微小数据帧,当我们调用apply()
时,相同的操作(例如,在我们的例子中是 join)将迭代通过单个组,直到到达末尾。****
因此,显式可视化GroupBy
对象非常有助于确保我们对正确的子数据集应用操作。
你有它!提高熊猫编程水平的 6 个不常用技巧,我希望这个主题对你有所帮助。在这个迷你系列的第二部分,我将分享我最喜欢的熊猫的另外四个特征,所以请密切关注🙂一如既往,所有代码都可以在我的 Github repo 这里找到,快乐学习!
想要更多数据科学和编程技巧?使用 我的链接 注册 Medium,获得我所有内容的全部访问权限。
还订阅我新创建的 YouTube 频道 【数据与 Kat 会谈】
更多有趣的数据科学博客:
*** [## 每个数据科学家都应该知道的 6 个 SQL 技巧
提高分析效率的 SQL 技巧
towardsdatascience.com](/6-sql-tricks-every-data-scientist-should-know-f84be499aea5) [## SQL、R 和 Python 中的数据整形
从 Python vs. R 到 Python & R
towardsdatascience.com](/data-reshaping-in-sql-r-and-python-d44ca19e71b8)***
面向初学者的 6 个机器学习概念
机器学习新手?从这里开始…
机器学习是一种将传统数学与现代强大的计算处理相结合的技术,以学习数据集中固有的模式。在机器学习中,目标是产生一种算法,可以使用这些模式来执行一些指定的任务。
在监督机器学习的情况下,目标可能是开发一个模型,该模型可以识别一组输入属于哪个类别或类,或者预测连续值,例如房屋的价格。
在这篇文章中,我将介绍机器学习中的一些关键概念。如果你是机器学习的新手,这会让你很好地理解这个领域中使用的一些术语和技术。
1.特征
在机器学习中,我们上面谈到的输入被称为特征。特征是分配给数据点的一组属性。
下面的示例数据集是一个著名的数据集,通常用于被称为“波士顿房价”的机器学习实践问题。它由一组与房屋相关的特征(下图中以红色突出显示)组成,如年龄、平均房间数、财产税值以及相应的房价。
为了使机器学习模型成功执行其任务,至少需要在这些特征中的一些和房屋价格之间存在统计关系。
波士顿房价数据集-要素高亮显示为红色
2.特征选择和工程
开发机器学习模型的一个重要步骤是优化。我们开发的模型需要以最佳状态运行,确保这一点的一种方法是使用最佳功能来训练模型。
包含每个特性并不总是有用的。一些特征可能与我们试图预测的变量没有有意义的统计关系,而另一些特征可能彼此密切相关。这两种情况都会在训练阶段引入噪声,从而降低模型性能。特征选择是选择最佳特征以包括在训练阶段的过程。
类似地,原始形式的特征可能无法提供足够有意义的数据来训练性能模型。此外,有些功能根本不能以原始形式使用,基于日期/时间的功能就是一个很好的例子。机器学习模型不能使用日期或时间戳作为特征,我们需要首先从日期中导出有意义的特征,以便能够包含这些信息。我们可以使用整数形式的部分日期,如月、日或周数,或者计算两个日期之间的差异,以提供算法可以理解的模式。这就是所谓的特征工程。
3.标签
受监督的机器学习需要被称为标签数据的东西。这意味着数据中的每组要素都有相应的标签。这些标签可以是类别或类型,如猫或狗,或者是连续值,如波士顿房价数据集中的标签是价格的情况。
在开发机器学习模型时,这些特征通常被称为 X ,标签被称为 y 。
波士顿房价数据集-标注高亮显示为红色
4。培训
监督机器学习需要带标签的数据,因为算法使用这些示例特征值及其相应的标签来“学习”模式,如果成功,将使模型能够准确预测新的无标签数据上的标签。
在机器学习过程中,这个学习阶段被称为训练阶段。在这个阶段的最后,您有了一个模型,可以用来预测新的未标记数据的标签或值。训练阶段通常被称为拟合模型。
5.调谐
在这篇文章的前面,当我描述特性选择的时候,我曾经讨论过一个优化过程。该过程的另一部分称为调整,包括优化算法的参数,以找到特定数据集的最佳组合。
所有机器学习模型都包含具有各种选项的参数。例如,随机森林模型有许多可调参数。一个例子是确定森林中树木数量的 n_estimators。通常情况下,树的数量越多,结果越好,但是在某一点上(这取决于数据集),随着添加更多的树,改进会减少。为数据集找到最佳的树数是调整随机森林算法参数的一种方法。
每个算法都有许多可调参数,并且每个参数都有潜在的大量选项。幸运的是,有自动的方法找到这些参数的最佳组合,这就是所谓的超参数优化。
6.确认
一旦模型建立起来,我们需要确定它执行给定任务的能力。在我们的示例数据中,我们希望了解模型预测房屋价格的准确性。在机器学习中,建立最佳性能指标是很重要的,这将根据我们正在解决的问题而变化。
通常,当开始一个机器学习项目时,我们会首先将我们正在处理的数据集分成两部分。一个用于训练模型,另一个用于测试阶段。
机器学习中的测试通常被称为验证。我们使用该模型对保留的测试数据集进行预测,并测量所选的性能指标,以确定该模型执行给定任务的能力。
本文概述了讨论机器学习时使用的一些最常见的术语和概念。如果你刚刚开始学习,它应该有助于你理解机器学习教程中使用的一些术语。如果你想用 python 创建你的第一个模型,你可以阅读我的教程“如何创建你的第一个机器学习模型”这里。
感谢阅读!
我每月发一份简讯,如果你想加入请通过这个链接注册。期待成为您学习旅程的一部分!
处理日期和时间时你必须知道的 6 种方法
迄今为止最混乱的数据类型
日期和时间对于任何编程应用都是不可或缺的——它是运动的驱动力,也是我们在宇宙巨大时间线上所处位置的稳定指示器。计算机科学中的每个子领域——从数据科学和人工智能到设计网页——都需要理解处理日期。
因为它们太混乱了(简单的任务:尝试编写一个程序,在没有任何外部库的情况下找到 date n 之后 64 天的日期),并且非常复杂——日期的长度、闰年、嵌套在父对象中的子对象——当处理 datetime 对象时,您必须知道这 6 个函数和方法。
注意:本文讨论 Python 中的 datetime。
dateutil.parser.parse
将字符串转换成日期很常见——要访问一个datetime
对象的属性,代表日期的字符串必须转换成日期。不幸的是,数据集或其他数据源几乎从来没有能够方便访问的datetime
对象。将字符串转换为日期最好的库是dateutil
,它可以自动推断日、月、年的位置,这需要用其他库来指定。
dateutil
可以适应各种各样的日期,其中每一行的每一个命令自动推断物体的位置并产生相同的结果(datetime.datetime(2040, 7, 3, 0, 0)
):
如果一个人能从字符串中分辨出日期,那么dateutil
也能。使用这个库,您可以避免通过传统的日期时间转换方法执行的烦人的日期对象映射。当并非所有日期都以相同的格式出现时,这一点尤其有用,现实世界的数据通常就是这种情况。
datetime.datetime.now()
要访问当前时间,使用datetime.datetime.now()
。这将返回一个 datetime 对象,返回您所在地区的时间,精确到微秒。
另一种方法是datetime.datetime.today()
,它返回相同的信息,但是精度较低。这可能更适合于高流量的情况,在这种情况下,计算时间的微小改进可能证明是有价值的。
日期时间.时间增量
当您找到两个 datetime 对象之间的差异时,将返回 timedelta 对象。例如,要返回 1938 年 7 月 3 日到 2020 年 5 月 30 日之间的差值,将运行以下代码:
简单地在两个 datetime 对象之间使用减号操作符交互将创建一个 timedelta 对象,在本例中,该对象被保存到变量delta
。
timedelta 对象有几个属性:
您甚至可以将 timedelta 对象添加到常规 datetime 对象中:
日历。Calendar.itermonthdates()
Calendar 是一个建立在 datetime 之上的库,它提供了方便的日历相关函数,有助于避免手动跟踪闰年和一个月中的天数。为了访问迭代函数,必须首先创建一个Calendar
对象。
参数firstweekday
设置为 0,表示星期一,但也可以设置为 6(星期日)或两者之间的任何一天。
考虑.itermonthdates()
,它接受一个月和一年,并返回一个迭代器,该迭代器包含该月中的所有日期,包括完成一周所需的任何前后日期。
输出如下所示:
Calendar 还有许多其他函数来返回各种各样的迭代器,以及其他功能,如打印 HTML 或文本日历,这些可以在文档页面访问:
[## 日历-通用日历相关函数- Python 3.8.3 文档
源代码:Lib/calendar.py 这个模块允许你像 Unix cal 程序一样输出日历,并提供…
docs.python.org](https://docs.python.org/3/library/calendar.html)
箭头。Arrow.humanize()
Arrow 是一个 Python 库,它的humanize()
属性非常突出。这种方法允许人们更无缝地与日期对象交互和解释日期对象。首先必须创建一个 Arrow 对象(可以容纳 datetime 对象并转换成Arrow
对象)。
调用time.humanize()
将产生一个字符串,其中包含一条人类可读的消息,描述time
是从多久以前到现在。
可以想象,这个特性对 UI 设计开发人员特别有帮助,他们可以用它来显示像“Josh 两分钟前发送了这条消息”或“你一年前编辑了这个文档”这样的消息。Arrow 也可以处理未来的日期。
德罗林
为了纪念回到未来而命名,Delorean 主要是因为其方便的自然语言理解而被使用,这意味着通过日期操作人类导航的简易性。首先,创建一个 Delorean 对象,它可以容纳datetime
对象:
如果您想获得下周、下周五、上周二的日期,或者任何数量的可理解的命令,只需调用适当的函数:
这可以为您和阅读您代码的人提供更容易、更直观的日期操作。
感谢阅读!
希望这些库和方法可以帮助您处理日期和时间!
6 个月的机器学习/计算机视觉工程师
Clem Onojeghuo 在 Unsplash 拍摄的照片
经验
在一个我几年前都没有涉足的领域呆上半年是什么感觉
介绍
我不敢相信已经六个月了,我已经写了一篇文章,详细描述了我在目前职位的第一天。
时间过得真快。
再次欢迎来到我作为计算机视觉工程师的在线日志。
在这篇文章中,你可以期待一个在创业公司工作的计算机视觉工程师的日常活动的许多细节。也期待回忆我犯过的一些错误和我庆祝过的成就。
对于你来说,这篇文章将介绍当你在一家初创公司中担任机器学习/计算机视觉角色时会有什么期望,以及当前机器学习从业者的典型角色和职责。
我认为这是一个足够好的介绍。
让我们直入主题,用 4000 字或更少的篇幅总结六个月的经历。
机器学习/计算机视觉/深度学习
Vladyslav Ociacia 的混血儿。(作者持有图像许可)
让我们从我的角色分解开始,同时附上工作角色描述。
在这一部分,我还将向您展示对计算机视觉工程师的确切期望。
机器学习简单来说就是开发能够从数据中学习和改进的系统。
计算机视觉是机器或系统通过调用一个或多个作用于所提供信息的算法来生成对视觉信息的理解的过程。这种理解被转化为决策、分类、模式观察等等。
深度学习是利用深度卷积神经网络来解决计算机视觉任务,如图像分类、姿态估计、语义分割等。
我的主要职责是研究和实施计算机视觉技术,如姿势估计、语义分割、手势识别和面部特征检测。所有列出的技术都在移动设备上实现。
技术
以下是我在过去六个月中使用深度学习解决方案实现的各种计算机视觉技术。
在某些情况下,我包括了我使用过的模型:
- 姿态估计:这是对图像或视频中呈现的人体内关键关节位置的估计。我通过利用研究设计的解决方案来实现姿态估计,例如堆叠沙漏、卷积姿态机器(CPM) 和 Posenet 。
- 手势识别:对一个人所采取的动作的分类可以称为活动或手势识别。我实现这一技术的过程是通过迁移学习利用 MobileNetV2 网络(在 imagenet 上训练),并使用定制的分类头对图像中的手势进行适当的分类。
- **手部检测/跟踪:**这是一个简单的计算机视觉任务,主要关注图像或视频中手部的检测和定位。
- **语义分割:**这可以被认为是在像素级别上进行的粒度分类,因为我们正在将图像中的每个像素分类为一个对象。实现这一点很有趣,它涉及到 TensorFlow 的 DeepLabV3 分段示例的逆向工程。
- **人脸检测/跟踪:**这是一个可以跟踪和定位图像或视频中人脸位置的系统的实现。
工具
如果你是一个机器学习实践者,你可能知道下面提到的一些工具。对于那些刚刚进入人工智能领域的人来说,列出的工具被数据科学家、ML 研究人员和 ML 工程师等使用。
这些是我日常使用的工具。
- tensor flow:机器学习模型的实现、训练、部署的开源平台。
- Keras:一个开源库,用于实现运行在 CPU 和 GPU 上的神经网络架构。
- tensor flow Lite:开源框架,旨在智能手机等边缘设备上部署机器学习模型。
其他值得注意的工具:
Jupyter Lab,Anaconda,CoreML, 视觉框架 ,
**小贴士:**不要执着于工具、技术和流程。关注你快速学习和适应新环境的能力。
软件工程
凯文·Ku 在 Unsplash 上拍摄的照片
以前我认为软件工程是一种技能,但是随着我职业生涯的发展,我已经接受了软件工程更像是一种实践的事实。
软件工程不是一项你可以在三个月内获得的技能,而是一种你通过多年的软件应用开发经验而形成的方法。
所以,作为一名机器学习工程师,我每天都在实践软件工程。更具体地说,我将软件工程原则的各个方面融入到我的开发工作流程和过程中。
大多数现代机器学习工程师都精通 3+编程语言。这可能看起来很多,但是用集成的学习系统和 ML 技术构建现代应用程序需要各种平台和工具之间的协同作用——所有这些都利用不同的编程语言来编写可执行指令。
以下是我在过去六个月中使用的主要编程语言:
- Swift :用于 iOS 应用开发
- Python :用于 ML 模型的实现、训练和评估
- JavaScript :用于 ML 模型的实现,也写自定义脚本。
我也有 HTML,CSS,SQL,Kotlin,NodeJS,Flask 等实用知识。所有这些工具和语言都是在三年的通用软件工程中发展起来的。
**提示:**学习 OOP(面向对象编程)的基本原理。面向对象的知识在广泛使用的编程语言中是可应用和可转移的。
如果你理解 OOP,学习编程语言就是熟悉特定于语言的语法。
冠状病毒
engin akyurt 在 Unsplash 上拍摄的照片
没人能预测到 2020 年全球疫情会让世界各国陷入瘫痪。卫生纸在西方国家成为一种商品;肘式问候取代了握手,远程工作现在成为了大多数科技行业的新常态。
当疫情号抵达英国时,我担任目前的角色才一个月,然后我们就进入了封锁状态。
远程工作并没有改变初创公司的目标、团队动力和我完成工作的雄心。作为一名计算机视觉工程师,一个高度科技化的角色意味着我可以在任何有网络连接的地方工作。
有助于远程工作的事情:
- 买台灯 :这是我最近买的,很满意。我读了很多书,深夜的编码/写作会议变得越来越频繁。所以有一个好的人造光光源对阅读时的能见度和整体生产力非常有帮助。
- 缩放 :这可能是 2020 年最受关注的视频会议工具了。Zoom 创造了一个无缝的虚拟延伸,这是它的对手所没有的。我的一天以与同事的 zoom 会议开始,以与朋友的 zoom 会议结束。
- TeamViewer :当我不在家时,TeamViewer 让我可以从我的 GPU 机器上访问计算资源。
- 我遇到的任何问题都只是一个远离解决方案的松弛信息。
有人说远程工作将成为员工的永久选择。很明显,公司自己在办公空间上节省了大量资金,并且公司团队提供的生产力或结果也没有明显的缺乏。
提示:在你的家里有一个指定的工作区域。
此外,如果你需要改变环境,附近的合作空间或咖啡馆也是一个选择
五金器具
当我写我作为计算机视觉工程师的第一个月时,我包括了分配给我的一个具体任务,那就是购买一个 GPU 工作站。
经过艰苦的研究和与美国和英国的 GPU 供应商公司的一些来回,我终于购买了一个。
在过去的五个月里,我连续几天利用 GPU 计算资源来训练定制模型。由于工作站拥有 14 个 CPU 内核,我还执行了并发运行的脚本,没有出现任何问题。
提示:确保你购买了一个带有多个 GPU 插槽的 GPU 工作站,即使你可能只购买了一个真正的 GPU。在可预见的未来,你可能需要扩展你的 GPU 能力,所以最好做好准备。
我对 GPU 的历史以及它们是如何产生的有点兴趣。作为深度学习实践者,你我都知道,随着 AlexNet 的引入和深度卷积神经网络的出现,用 GPU 训练 CNN 变得流行起来。
我可能会写一篇关于 GPU 的历史和其他关于它们的使用和专长的很酷的事实的文章。
学习/研究
在与 ML 相关的职业生涯中学习永远不会结束。人工智能领域本身正在以一种速度前进,总是有新的发展需要了解( 目前是 GPT-3 的发布)或新的技术需要实现。
回想过去的六个月,我真的感觉自己又回到了大学时代。完成“朝九晚五”的工作后,我回到家里阅读研究论文、写论文和实现 ML 模型。
对于那些希望进入人工智能职业的人来说,你必须意识到有一个不言而喻的期望,在那里你应该被告知最新的人工智能发展。大多数人期望你比一般人更了解新的人工智能应用程序发布。
目前,我正在获取尽可能多的实践和理论知识,然后才能着手实施我的神经网络体系结构或修改 DCNNs 的子组件。
无论我要实施什么样的简历技巧,我都不是 100%了解。在我考虑任何形式的实现之前,通常会有一个广泛的研究阶段。对于我正在研究或实施的每项新技术,大约 70%的内容对我来说都是新的。
学习从未停止。
提示:不要害怕后退一步,以确保你正在建立一个坚实的学习基础。最近,与深入阅读最新的神经网络架构相反,我回到了深度学习早期发表的研究论文。
害怕
aaron Blanco Tejedor 在 Unsplash 上拍摄的照片
如果我告诉你在过去的六个月里我没有质疑过自己的能力,那我就是在撒谎。
这是我第一个与 ML 相关的角色,更可怕的是,我是公司第一个机器学习雇员。
你听说过冒名顶替综合症吗?
这是一种无能和不足的感觉,即使你做得很好。它是自我怀疑、缺乏自信和虚假的智力欺诈的混合物,从你的成功和成就中偷走。
在过去的六个月里,我发现自己问了以下问题:
我走得够快吗?我够好吗?我够聪明吗?我知道的足够多吗?够好吗?如果我失败了呢?如果我错了呢?
这是关于冒名顶替综合症的事情;它可以是一件消极或积极的事情,这完全取决于你采取的行动和你选择如何解决你的自我怀疑。
我用我的冒名顶替综合征的感觉来确保我在我的游戏中处于领先地位,我不会被它削弱,也不会被它削弱。
冒名顶替综合症比你想象的更普遍;即使是最伟大的人也深受其害。
阿尔伯特·爱因斯坦,图片来自biography.com
“我一生的工作被过分推崇,这让我很不自在。我觉得把自己想象成一个无意识的骗子是完整的。”——阿尔伯特·爱因斯坦
**提示:**你够了!
ML 社区
安妮·斯普拉特在 Unsplash 上拍摄的照片
我在工作之外所做的和我在工作中所做的一样重要。
在过去的六个月里,我意外地开始在 AI 社区内建立个人品牌。通过几个不同的在线平台,我每天可以接触到成百上千的人。
我认为你可以,也应该这样做。
下面是我用来在 ML 社区中建立存在的平台的总结。
中等
图片来自媒体设计
在我的学术研究和现在的职业生涯中,Medium 上与人工智能相关的内容一直是一个很好的信息来源。
我看过文章,简化复杂的神经网络架构的研究论文;和文章,就如何在人工智能行业内进行工作选择或薪资谈判提供了有用的建议。
2019 年夏天,我决定不仅要成为 Medium 上内容的消费者,还要成为创作者。我不知道该期待什么,但我心中有一个目标。
我的目标是将媒体作为一种工具来强化我通过学习和项目获得的知识和信息。对我来说,媒介是一种知识保留的形式。
现在,媒体对我来说是一个平台,使我能够每天接触到成千上万的人。我已经写了 70 多篇人工智能和人工智能相关的文章,我可以看到很多人受到了我的写作的启发,并且正在学习和学习一个可行的项目。
由于某种原因,我()被认为是人工智能、技术和教育领域的顶尖作家之一。事实上,这是一项荣誉,我希望尽可能长久地保持下去。
提示:在你的学习过程中融入媒体。就你目前正在学习的概念和想法写文章。这有助于知识的保留,还有提供在线作品集的额外好处。
商务化人际关系网
我不记得我第一次创建 LinkedIn 账户是什么时候,但我可以说的是,与其他任何年份相比,我在 2020 年使用 LinkedIn 的次数都要多。
相当多的人阅读我的作品,一些读者对我文章的内容有疑问。LinkedIn 是联系我的传统方式之一。
我非常乐意回答任何问题,并就我技术专长范围内的话题给出任何建议。迄今为止,我已经回答了大约 50 多个通过 LinkedIn 联系我的人提出的问题。我还抽出一些时间与个人进行视频电话会议。我收到的一些问题需要更详细的答案。
我被问到的大多数问题都围绕着学习机器学习的最佳方法,或者走哪条职业道路。虽然我不是专家,但我很乐意分享我通过学习、研究和经历获得的一点点经验。
如果你想给我发信息或者讨论与 ML 有关的事情,我可以在这里找到。
咨询公司
在过去的六个月里,我和一些寻求项目建议的人坐在一起,在一些情况下,我的时间和专业知识得到了回报。现在,我得到的报酬不会改变我的生活,我也不会很快成为一名全职顾问。但事实上,个人只看重我的专业技能,这对我来说仍然是疯狂的。
除了咨询工作之外,我最近还受邀成为一本计算机视觉书籍的技术作者,这本书将在未来发行。再说一次,这个机会似乎好得不像是真的,但是今天我在这里,这本书还没发行几章。
除了我的学习和职业生涯,我无法预测我可能会遇到什么机会。每个月都不一样。
油管(国外视频网站)
由 Gianandrea Villa 在 Unsplash 上拍摄的照片
我很欣赏 AI/ML YouTube 频道,那里的主持人教授机器学习相关主题,或者解释和实现研究论文中提出的技术。
当然,我是亚历克斯·弗里德曼的播客和 YouTube 频道的粉丝。
在 YouTube 上,我是一个消费者,我关注 ML 相关频道如两分钟论文、丹尼尔·伯克、森德克、深蜥蜴、 3Blue1Brown 、扬尼克·基尔彻、阿布舍克·塔库尔等。
我已经决定开始在 YouTube 平台上构建。很快,我将发布我认为对那些开始学习机器/深度学习的人有用的内容。
随意订阅我的频道这里 ( 不要脸塞)。
提示:不要害怕拓展你的触角。让世界知道你的存在。
我犯过的错误
来自iemoji.com的眼睛表情符号
在过去的六个月里,我犯了数不清的错误。
下面是几个“不太”尴尬的错误。
- 没有推进我的 git 回购,失去了两个星期的工作。
- 对我的工作没有耐心,这导致了很多错误和错误。
- 在我真正需要帮助的时候没有寻求帮助。
- 将水洒满了团队放有电子设备的桌子。
- 在周五投入生产。然后花了一个周末修复漏洞。
- 我在网上开会迟到了,尽管我在家工作(这个错误需要一定的技巧 lol )。
每个人都会犯错;错误不可避免。重要的是你从你犯的错误中学习,记住你的错误并不能定义你。
我确信在接下来的六个月里我会犯更多的错误。
年度愿景
简单来说,就是六个月。
作为六个月的总结,在今年剩下的时间里,我将与你分享我为自己设定的目标。
这些目标主要是让我在职业生涯、个人和学术发展上保持正轨。一些列出的目标是模糊的,我很可能会在以后完善它们。
- 在年底前阅读 10 篇研究论文
- 在线发布两个基于人工智能的应用
- 在边缘设备上实施更多计算机视觉技术
- 在 ML 社区中建立更强大的存在
- 建立稳固的个人品牌
- 获得人人都在谈论的张量流证书
提示 : 关注我了解更多 AI/ML 相关内容
我们仍然是人工智能中代表最少的种族之一,然而我们可能会因为它的利用和滥用而遭受最大的痛苦。
towardsdatascience.com](/are-there-black-people-in-ai-fb6928166d73) [## 根据吴恩达的观点,如何在机器学习的职业生涯中导航
了解如何在机器学习领域取得成功
towardsdatascience.com](/how-to-navigate-a-career-in-machine-learning-according-to-andrew-ng-stanford-lectures-9e10f09047f0)*
作为一名数据科学家,我在 6 个月里学到了什么
我从训练营开始,然后找到了我梦想中的机器学习工作。以下是一些关键要点。
arXiv | 播客 | GitHub 问题 | 算法&硬件 | 社会科学 | 商业成果 |图片由 Artem Beliaikin 在 Unsplash
自从六个月前我的头衔从顾问变成了数据科学家,我体验到了比我想象的更高的工作满意度。为了庆祝我在这个引人入胜的领域的第一个半年,这里是我一路上收集的六个教训。
#1 —阅读 arXiv 白皮书
您可能已经意识到,回顾 arXiv 是一个好主意。这是非凡想法和最先进进步的源泉。
不过,我在平台上遇到的大量可操作的建议让我感到惊喜。例如,我可能无法获得 16 个 TPU 和 7k 美元来从头开始训练 BERT,但是 Google Brain 团队推荐的超参数设置是开始微调的好地方(查看附录 A.3 )。
希望您最喜欢的新包能够在 arXiv 上有启发性的阅读,为它的文档增添色彩。例如,我学会了在 ktrain 上使用非常可读和非常有用的文章来部署 BERT,ktrain【】是一个位于 Keras 之上的库,为文本、图像和图形应用程序提供了一个简化的机器学习接口。
# 2——听播客,获得巨大的情境意识
播客不会提高你的编码技能,但会提高你对机器学习的最新发展、流行的包和工具、该领域未回答的问题、解决老问题的新方法、整个行业普遍存在的潜在心理不安全感等的理解。
我每天收听的播客让我感受到了数据科学领域日新月异的发展。
以下是我现在最喜欢的播客
通过这个有用的期刊、视频和讲座的集合,推进你对机器学习的理解。
towardsdatascience.com](/supercharge-data-science-5bb7376d8572)
最近我特别兴奋地了解到的进展,跟踪了 在 GPU和 云计算 ,并对人工神经网络和神经生物学的进展之间的 潜在共生 提出了质疑。
#3 —阅读 GitHub 问题
根据我在巨大的智慧金枪鱼投诉海洋中的经验,这里有三个潜在的胜利:
- 我经常从其他人使用和/或误用包的方式中获得灵感
- 了解在什么样的情况下一个包会破裂也是很有用的,这样可以培养你对自己工作中潜在故障点的意识
- 由于您正处于设置环境和进行模型选择的前期工作阶段,在将开源工具添加到您的管道之前,您最好考虑一下开发人员和社区的反应
#4 —理解算法与硬件的联系
最近半年做了很多 NLP,再来说说 BERT。
2018 年 10 月,伯特崭露头角,震撼世界。有点像超人一跃跃上高楼后(最初推出时疯狂认为超人不会飞!)
BERT 代表了机器学习处理文本处理任务能力的一个阶跃变化。它最先进的成果是基于在谷歌的 TPU 计算机芯片上运行的变压器架构的并行性。
第一次在 GPU 上训练的感觉。通过 GIPHY
理解 TPU 和基于 GPU 的机器学习的含义对于提升你作为数据科学家的能力非常重要。这也是加深你对机器学习软件和运行它的硬件的物理约束之间不可分割的联系的直觉的关键一步。
随着摩尔定律在 2010 年左右逐渐消失,将需要越来越多的创新方法来克服数据科学领域的限制,并继续朝着真正智能的系统前进。
来自 Nvidia 展示的图表显示了每年每平方毫米的晶体管数量。这凸显了 2010 年左右晶体管数量的停滞和基于 GPU 的计算的崛起。
我看好 ML 模型的兴起——计算硬件协同设计 ,对 稀疏性的依赖增加和修剪 ,甚至 “非专用硬件”机器学习 ,看起来要颠覆当前以 GPU 为中心的范式的统治地位。
#5 —从社会科学中学习
我们年轻的领域可以从 2010 年代中期发生的社会科学可复制性危机中学到很多东西(在某种程度上,这种危机仍在发生)
数据科学家的“p 值黑客”。xkcd 的兰德尔·门罗的漫画
2011 年,一项学术众包合作旨在复制 100 项已发表的实验和相关心理学研究。但它失败了——只有 36%的复制报告了有统计学意义的结果,相比之下,97%的原件报告了有统计学意义的结果。
心理学的再现性危机揭示了将“科学”与不可靠的方法联系在一起的危险和责任。
数据科学需要可测试、可复制的方法来解决问题。为了消除 p-hacking,数据科学家需要限制他们如何调查数据的预测特征,以及他们为评估指标而运行的测试的数量。
有许多工具可以帮助实验管理。我有处理 ML 流程—Ian Xiao的这篇优秀文章提到了另外六个领域,以及机器学习工作流的其他四个领域的建议。
我们还可以从近年来数据科学领域的大量失误和算法弊端中吸取许多教训:
例如,利益相关方只需看看加深现状的社会工程推荐引擎、歧视性信用算法和刑事司法系统。我已经写了一些关于这些社会弊病以及如何用有效的以人为中心的设计来避免它们。
好消息是,有许多聪明且积极的从业者正在努力应对这些挑战,并防止未来违背公众信任。查看谷歌的一对、哥伦比亚的 FairTest 和 IBM 的 explability 360。与社会科学家研究人员的合作可以产生丰硕的成果,比如这个关于审计歧视的算法的项目。
当然,我们还可以从社会科学中学到很多其他的东西,比如如何进行有效的演讲
研究社会科学以理解人类关于数据推断的直觉可能会失败是至关重要的。人类非常擅长在特定情况下从数据中得出结论。我们推理的方式是高度系统化和可预测的。
我们对人类心理这一方面的许多理解都在丹尼尔·卡内曼的优秀作品《T21 思考的快慢》中得到了体现。这本书应该是任何对决策科学感兴趣的人必读的。
卡尼曼研究中可能与你的工作直接相关的一个元素是他对锚定效应的处理,这种效应“发生在人们考虑未知量的特定值时。”
传达建模结果时(即代表准确度、精确度、召回率、f-1 等的数字)。),数据科学家需要特别注意管理预期。在“我们仍在解决这个问题,这些指标可能会改变”到“这是最终产品,这是关于我们期望我们的 ML 解决方案如何在野外执行”的尺度上提供一定程度的手动波动可能是有用的
如果你展示的是中间结果,Kahneman 建议为每个指标提供一个数值范围,而不是具体的数字。例如,“f-1 分数代表了本表中其他指标(精确度和召回率)的调和平均值,大约在 80–85%之间。这表明还有改进的余地。”这种“手动波动”的沟通策略降低了听众将锚定在你分享的特定价值上的风险,而不是获得关于结果的方向正确的信息。
#6 —将数据与业务成果联系起来
在你开始工作之前,确保你正在解决的问题值得去解决。
你的组织并没有付钱给你去建立一个 90%准确的模型,给他们写一份报告,在 Jupyter 笔记本上闲逛,或者甚至在 图形数据库 上启发你自己和其他人。
您的职责是将数据与业务成果联系起来。
我希望这些建议至少对你有所帮助——在评论中留言,让我知道你是如何使用它们的。当然,如果你喜欢这篇文章,请在 Medium 、 LinkedIn 和 Twitter 上关注我。
免责声明 :我正在为书籍推荐添加附属链接。通过这个链接在亚马逊上购买有助于支持我的数据科学写作——提前感谢。
为您的数据科学之旅撰写更多文章
图论是对图形的研究,图形是用来模拟对象之间成对关系的数学结构…
towardsdatascience.com](/an-intro-to-graph-theory-centrality-measurements-and-networkx-1c2e580adf37) [## 你从未听说过的最好的数据科学认证
数据策略最有价值培训实用指南。
towardsdatascience.com](/best-data-science-certification-4f221ac3dbe3) [## 像我五岁一样解释计算机科学
了解互联网,编程,机器学习和其他计算机科学的基础知识,通过清晰和…
medium.com](https://medium.com/coderbyte/eli5-computer-science-f8dfd7910311) [## 型号选择综合指南
选择正确算法的系统方法。
medium.com](https://medium.com/atlas-research/model-selection-d190fb8bbdda) [## 面向临床文本的命名实体识别
使用 pandas 将 2011 i2b2 数据集重新格式化为用于自然语言处理(NLP)的 CoNLL 格式
medium.com](https://medium.com/atlas-research/ner-for-clinical-text-7c73caddd180)*