结束销售
通过正则化线性回归预测房价
在今年秋天完成我的数据科学沉浸式学习时,我们的第一个“真正的数据科学项目”之一是分析艾奥瓦州的一组样本住房数据T1 】,这些数据是通过埃姆斯评估办公室收集的,用于计算 2006 年至 2010 年在艾姆斯出售的个人住宅物业的评估值。具体来说,我们被要求创建一个模型来预测预期的房屋价值,并最小化均方根误差(RMSE) 。
这个数据集已经在一个非常受欢迎的 Kaggle 竞赛系列中使用,并作为一个很好的学习工具来练习应用完整的数据科学模型工作流:从导入/清理到模型预测。
对于这一挑战,我们的队列仅限于使用线性回归来寻找预分割测试数据子集的期望值。这在几个方面很重要:
- 因为整个数据集已经被分割成一个测试集,这减少了我们的模型可以训练的实例的数量。虽然建议您通常在建模时执行训练/测试分割,但进一步减少训练集可能会限制整体性能。
- 如数据描述中所述,有五个观察值被认为是异常值:“三个…真正的异常值(可能不代表实际市场价值的部分销售)和两个…简单的不寻常销售(价格相对合理的非常大的房子)。”这很有帮助,因为我们可以很容易地量化/识别在我们的训练和测试数据集中有多少离群值。因为我们的线性回归不太可能预测这些异常值,并且评分是基于 RMSE 的,所以我们的模型从训练数据归纳到测试数据的能力将受到这些异常值的数量是否在训练集内的更大影响。
- 由于销售价格的广泛分散和正偏差,部分由于上述异常值,该模型将倾向于低估多于高估。这可以通过记录目标要素(和/或任何其他非正态分布的要素)来归一化值的范围来解决。然而,结果很难解释(以对数或平方根美元表示的销售价格),我们无法预测哪个训练或测试集中有哪些异常值。
然而,作为数据科学家,我们必须做出某些假设,并在当前可用数据的范围内工作。
导入、数据清理和 EDA
清理和 EDA 对于这项挑战非常重要,因为该数据集包含许多在分类中可能很重要的有序/分类特征,并且需要转换为数值。
作为基线,我导入了以下库来清理、探索和建模训练数据。
我的第一个预处理步骤是将所有对象类型转换成可用于线性回归的数字特征。根据数据字典,有几个本质上是有序的分类特征。根据我个人的判断,我将对潜在购房者来说很重要的值从 0(如果 n a 是一个选项)或 1(如果 NA 不是一个选项)向上转换(取决于功能的数量)。
虽然我可以使用get_dummies
方法,但通过使用一系列值(然后可以缩放)可以得到更多细微差别,并减少总体特征的数量。
Converting some of the categorical features
此外,该数据集中有许多需要估算的缺失/空值。对于具有大量缺失值的要素(如“地块临街面”),更希望使用“真实”值而非“虚拟”值(如 0)来估算这些要素。这可以通过使用均值、中值、众数或其他相关函数来实现。
为了简单和节省时间,我没有使用计算来估算所有缺失的值。相反,我关注的是空值比例最大的变量。对于所有其他特性,我使用了.fillna(0)
。使用一个基本的、有点随意的假设,我通过以下方式估算了地段临街面的缺失值:
我通过将某些数字特征转换成字符串,准备了通过.get_dummies
转换的非序数分类特征:
Converting numerical features to string types
最后,为了证实我对功能重要性的最初假设,我创建了一个 Seaborn heatmap,它计算了与我的目标功能:销售价格相关的 Pearson 系数。
特征工程和选择
所有数据科学家的一项关键技能是特征选择的艺术和科学。这需要严格的统计测试和专业知识(或直觉)来从噪音中过滤信号。在进行最初的数据探索时,我发现了一个有趣的现象,即包裹 ID 和销售价格之间存在明显的相关性。通过散点图,我们可以发现宗地 ID 中的分歧(5 对 9)以及 PID 以 9 开头的房屋聚集在较低值的趋势。虽然这可能具有统计学意义,但我没有进行假设检验来验证。结果,我考虑到这种噪音,去掉了 PID 列。
由于该数据集的特征(多个相关特征),存在冗余和多重共线性的可能性。虽然我们可以使用某些正则化技术(如套索)来补偿,但我也决定创建特征交互,希望隔离/放大最有影响力的特征。
因为我生成的要素使用不同的比例,所以在拟合模型之前,我应用了StandardScaler
作为预处理集进行归一化。
拟合和交叉验证模型
为了验证我的线性回归模型的性能,我实例化并交叉验证了四个变量:多元线性回归、Lasso、Ridge 和 ElasticNet。虽然我的训练数据包含 350 多个特征,但通过使用正则化函数,我能够更准确地微调我的预测。最终,《套索》在 RMSE 和 R。
结论
虽然我非常具体的 Lasso 线性回归在我的训练数据和 Kaggle Challenge(不到 2 万美元 RMSE)的 30%测试数据中表现得相当好,但当该模型应用于其余 70%的测试数据时,我最终失败了。由于存在显著的异常值(我在训练集中去掉了这些异常值),我的模型没有一般化,而是过度拟合了。
尽管如此,我希望我在这篇文章中展示的一些技术对其他有志于学习回归建模的数据科学家有用。
RMSE for Training and Test Data
云计算机视觉
测试概述
我的目标
有时我会把照片上传到像 Shutterstock 或 Depositphotos 这样的网站上。为了更好地被发现,照片应该包含适当的关键字和标题。Depositphotos 没有关键字的建议工具。Shutterstock 在手机应用程序中可以根据图片上的内容神奇地建议关键词。我很感兴趣,并决定创建一个脚本,可以为我所有的照片做同样的事情(我将能够使用它与存款照片)
为什么是云
起初,我尝试使用 OpenCV——它是一个用于计算机视觉的开源库。这个库是这样工作的:你需要提供一些参数(矩阵),这些参数定义了搜索一个图片的内容和图片本身。我开始搜索这些参数,但我发现的只是简单的几何图形和人脸的识别。在哪里找到合适的矩阵或者如何自己创建它还不清楚。那么,为什么是云呢?这样更方便快捷。
微软认知服务
我召回微软服务是因为https://how-old.net网站。比方说,病毒效应是成功的。因此,微软将牛津实验项目更名为认知服务,现在他们提供付费服务。除了计算机视觉,还有一批不同的 API,如文本到语音转换、搜索、人脸检测。注册非常顺利,几分钟后我就可以测试我的照片了。MS Cognitive Service 的一个很好的功能——它可以为图片创建一个标题。
谷歌云愿景
谷歌还提供计算机视觉服务,作为大型谷歌云平台的一部分。意味着更严重更复杂。注册真的很长,需要信用卡。谷歌云的一个很好的功能是地标探测——它可以在图片上找到著名的地方并命名。
克拉里菲
这是一家成立 4 年的纽约公司。他们主要也是唯一的服务是云计算机视觉。他们在 ImageNet 竞赛中获得了 5 个名次(这是一种计算机视觉的奥林匹克竞赛)。真正流畅的注册和完美的用户体验。除此之外,他们有真正准确的识别引擎。
我是如何测试的
所有这 3 个服务都有一个在线演示,你可以把你的图片放在那里,并立即得到结果。我用 4 种不同类型的图像进行了测试:特写建筑、城市景观、自然和倒影。以下是微软的一些结果:
Microsoft Computer Vision
所以,微软对大部分图片都做得很好。它为除了有灯笼的图片之外的所有图片提供了一些漂亮的标题和少量的或多或少相关的标签。接下来是谷歌:
Google Cloud vision
你可以在这里看到更多与图片密切相关的标签。没有地标,但是这个服务也可以提供它(像罗马圆形大剧场或者埃菲尔铁塔)。谷歌也有一个用提灯检测图片的问题。接下来是 Clarifai:
Clarifai API
Clarifai API 显示了这几组照片的最佳结果。正如你所看到的,它提供了大量强相关的标签,也很好地识别了灯笼照片。
с对照表
由于复杂的注册和信用卡要求,以及不明确的配额行为,我决定不使用谷歌云视觉。我处理地理相关的标签只是使用免费的地理编码 API。官方 SDK 的缺乏很容易被非官方的掩盖。而且一般来说这只是一个简单的 HTTP 请求。
附加服务
我没有试过亚马逊 Rekognition,因为它需要注册和信用卡,没有在线演示。IBM Alchemy 没有通过我最初的测试。它提供了非常少量的标签,有时标签是不相关的。
还有一堆不同的提供计算机视觉的网络服务,我在 Mashape 博客上发现了几个列表,大多数都已经死了,或者需要复杂的注册而没有在线演示,或者只提供付费服务。
结论
现在用计算机视觉开始工作真的很容易。大多数情况下,它只需要注册,然后发布带有特殊标题的请求。带有 JSON 响应格式的 REST API。但遗憾的是,并不是 100%正确。我想甚至不是 90%。在我的情况下,结果应该由人来审查。对于其他情况,如人脸检测或成人内容,它的效果要好得多。
我希望你喜欢这篇小评论。如果是这样,请不要犹豫,按下心脏按钮。谢谢!
有用的链接
- 计算机视觉国际竞赛—【http://image-net.org/
- 【http://opencv.org/】OpenCV 官方页面— 官方
- 微软计算机视觉(在线试用、定价、文档)——https://www . Microsoft . com/cognitive-services/en-us/Computer-Vision-API
- 谷歌云视觉(在线试用、定价、文档)——https://cloud.google.com/vision/
- Clarifai API(在线试用、定价、文档)——https://www.clarifai.com/demo
- IBM 视觉识别(在线试用、定价、文档)——https://www . IBM . com/Watson/developer cloud/Visual-Recognition . html
- 亚马逊 Rekognition(无在线演示)——【https://aws.amazon.com/ru/rekognition/
- 原料药市场—【https://www.mashape.com/
云计算 AWS #1:简介和 EC2 实例创建(通过控制台)
大家好!欢迎来到 AWS 教程。如果你还不认识我,我是 NYU 大学的一名研究生,我冒险进入了写作的世界,与你们分享我有限的知识。我目前正在 NYU 学习“云计算”课程,我认为分享我所学到的东西是值得的。我也在写关于机器学习的文章,所以也来看看这些文章吧!
在这个系列中,我将主要关注实现部分,较少关注理论部分。我知道有许多与 AWS 相关的文章,但它们分散在不同的文章中,我觉得有必要将它们“捆绑”在一起。此外,我计划在接下来的文章中写一些关于使用 AWS 创建 web 应用程序和聊天机器人的内容。
来源
本文的灵感来自各种材料,包括但不限于:
- Amazon Web Services in Action 由 Michael Wittig 和 Andreas Wittig ,
- AWS 官方文档,
- Sambit Sahu 教授的讲座、笔记和幻灯片,以及
- 互联网
什么是云计算?
让我们从 NIST(美国国家标准与技术研究院)的官方定义开始:
云计算是一种支持对可配置计算资源(例如,网络、服务器、存储、应用程序和服务)的共享池进行无处不在、方便、按需的网络访问的模型,可配置计算资源可以通过最少的管理工作或服务提供商交互来快速供应和释放。
你脑子进水了,是吗?只要记住这一点:
云计算提供了对随需应变资源的访问,例如计算能力、数据库存储、应用程序和其他一些 IT 资源。
详细定义参见本。
云可以分为三种类型:
- Public -由组织管理的云,对公众开放使用
- 私有云 -在单个组织内虚拟化和共享 IT 基础设施的云
- 混合云——混合了公共云和私有云的云
云服务也可以分为三种类型:
- 基础设施即服务(IaaS) -使用 Amazon EC2 等虚拟服务器提供计算、存储和网络功能等基础资源
- 平台即服务(PaaS) -提供将定制应用部署到云的平台,例如 AWS Elastic Beanstalk 和 Heroku
- 软件即服务(SaaS)——结合基础设施和运行在云中的软件,包括办公应用程序,如谷歌办公应用程序和微软 Office 365
为什么 AWS 优于其他云平台?
有几个原因:
- 它是最成熟的云平台
- 它支持最多的 SDK 语言
- 社区支持比任何其他云平台都大
AWS 入门
注册过程主要包括五个步骤:
- 提供您的登录凭证
前往https://aws.amazon.com,点击创建免费账户/创建 AWS 账户按钮。按照屏幕上的步骤创建您的帐户。
2.提供您的联系凭据
只需在必填字段中填写您的联系信息。
3.提供您的付款详情
是的,您必须提供您的付款详情才能创建 AWS 帐户。请注意,AWS 支持万事达卡和维萨卡。
4.验证您的身份
完成上述步骤后,您将会接到 AWS 的电话。你的屏幕上会显示一个密码,你必须通过电话向机器人语音提供这个密码。
5.选择您的支持计划
选择基本计划,因为它是免费的。
恭喜你!您成功创建了一个 AWS 帐户。您现在可以在https://console.aws.amazon.com登录您的 AWS 管理控制台
**注意:**强烈建议您按照 AWS 的建议设置计费警报:http://mng.bz/M7Sj
EC2 实例
创建 EC2 实例类似于用编程语言编写“Hello World”程序。理解创建该实例所涉及的各种过程是至关重要的。
EC2 是弹性计算云的缩写。它是一种服务,为我们提供了一个叫做实例的虚拟服务器。使用 Amazon EC2,您可以设置和配置操作系统,并在这个实例上安装应用程序。
启动 Amazon EC2 实例的架构如下所示:
实例是一个 Amazon EBS 支持的实例,即 root 是一个 EBS 卷。Amazon EBS(弹性块存储)提供持久的块存储卷供实例使用。亚马逊 EBS 提供以下内容:
- 保护实例免受组件故障的影响
- 提供高可用性和耐用性
- 提供一致的低延迟性能
- 在几分钟内增加或减少您的使用
您可以为您的实例指定可用性区域(它应该在那里运行),或者由 AWS 自动为您指定。
要启动您实例,您需要通过指定一个密钥对和一个安全组来保护它。
一个密钥对由一个私钥和一个公钥组成。公钥将被上传到 AWS 并插入到虚拟服务器中。你应该保存私人钥匙;它就像一个密码,但更安全。当您想要连接到实例时,您需要验证您的身份。这是通过使用私钥的认证来完成的。
安全组是 AWS 的一项基本服务,像防火墙一样控制网络流量。当实例启动时,一个或多个安全组与其相关联。有关安全组的更多信息,请参考 AWS 官方文档:https://docs . AWS . Amazon . com/AWS C2/latest/user guide/using-network-security . html
理论说够了!现在,我们将研究以两种方式启动实例:
- 通过控制台
- 通过命令行
通过控制台创建 EC2 实例
我们将为 Linux 创建一个 EC2 实例,因为这样做很容易。这一过程包括三个主要步骤:
- 启动实例
- 连接到您的实例
- 终止您的实例
1.启动实例
- 登录控制台:https://console.aws.amazon.com/
- 在继续下一步之前,请确保您在美国东部(N. Virginia)地区(这只是出于一致性目的)
- 导航至服务 - > EC2
- 点击启动实例
- 现在,选择一个亚马逊机器图像(AMI) 推出了。AMI 充当您的实例的基本模板。选择第一个 AMI(HVM 版)。
- 选择 t2.micro 实例类型。这是唯一符合*“符合自由层条件”的实例类型。* T2 实例为您的虚拟实例提供基线硬件配置。接下来,点击查看并启动。
- 在这个页面上,您将看到 AWS 为您自动创建了一个安全组。如果要使用现有的安全组,导航到编辑安全组->-配置安全页面->-选择一个现有的安全组。在本教程中,我们将使用自动为我们创建的安全组。点击发射。
- 将弹出一个密钥对。因为我们没有现有的密钥对,所以选择创建新的密钥对选项。写下密钥对的任意名称。我将称它为*‘我的钥匙对’*。点击下载密钥对。私钥文件将被下载到您的系统中。保管好它。接下来,点击启动实例。
- 您的实例现在将开始运行。导航至页面底部,点击查看实例。
- 现在,您可以看到正在运行的实例的详细信息。花些时间探索和谷歌出某些术语,如“实例 ID”、“公共 DNS (IPv4)”、“IPv4 公共 IP”等。因为如果你理解它们的意思,它会很好地为你服务。同样,等待状态检查栏从 初始化 变为 2/2 检查通过。
2.连接到您的实例
有两种方法可以连接到实例:
- 通过浏览器(在这种情况下,您需要安装 Java)
- 通过独立的 SSH 客户端
官方 AWS 文档提供了通过浏览器连接实例的指南。然而,我们将通过独立的 SSH 连接我们的实例。还要注意,我将通过 Mac 连接实例,但我会尽可能为 Window 用户提供说明。
对于 Linux(和 Mac)用户:
- 大多数 Linux 机器默认安装了 ssh 客户端。您可以通过在终端上键入 ssh 来检查您是否有 ssh 客户端。如果你的电脑不能识别这个命令,那么去http://www.openssh.com/portable.html并按照那里的指示去做。
- 接下来,安装 AWS CLI。现在并不真的需要这样做,但是稍后当我们尝试以编程方式创建实例时会用到。如果安装了 pip,请键入以下命令:
- 验证您已经通过该命令安装了 awscli :
- 如果您在安装 awscli 时遇到任何错误,请参考 AWS 官方文档:https://docs . AWS . Amazon . com/CLI/latest/user guide/installing . html
- 从控制台获取(记下)实例 ID、公共 DNS 名称和 IPv4 地址。
- 在步骤 1 中,我们下载了一个扩展名为’的密钥。pem。找到密钥并记下其路径。我的道路是:
downloads/我的密钥对. pem
- 使用 chmod 命令确保您的私钥不会被公开。该命令如下所示:
- 现在,使用 ssh 命令连接到实例。 ssh 命令的语法如下:
ssh-I[私钥路径]用户名@[公共域名或 IPv4 地址]
- 亚马逊 Linux 的用户名是ec2-用户。 public_dns_name 或 IPv4_address 就是您之前记下的那个。写完 ssh 命令后,提示您输入是或否。输入是。
恭喜你!您现在已经连接到 Amazon Linux AMI。
对于窗口用户:
Window 用户日子有点不好过。默认情况下,他们没有 SSH 客户端,所以他们需要安装免费的 SSH 客户端。如果你有旧版本的 PuTTy,建议安装最新版本。我不会提供一步一步的指示;相反,我会把你重定向到你可以自己做这件事的链接。
- 从这里下载 PuTTy:【http://www.chiark.greenend.org.uk/~sgtatham/putty/】
- 为您的 Linux 实例启用入站流量:https://docs . AWS . Amazon . com/AWS C2/latest/user guide/authoring-access-to-an-Instance . html
- 使用 PuTTYgen 转换私钥: PuTTYgen 会在您安装 PuTTy 时安装。PuTTy 不支持。pem 扩展名,但它可以将。pem 扩展到。使用 PuTTYgen 的 ppk。
- 启动一个 PuTTY 会话:打开 PuTTY 。从类别窗格中,选择会话并完成主机名 (ec2-user@[public_DNS_name 或 IPv4_address])。然后在连接类型下,选择 SSH 。最后,确保端口号为 22 。
- 接下来,在类别窗格中,展开连接->-SSH->Auth。选择浏览 - >选择**。你生成的 ppk 文件**->-打开。如果这是您第一次连接到实例,将显示一个安全警告对话框,询问您是否信任该连接。选择是。一个窗口打开,您现在连接到您的实例。
最后三条说明,参考 AWS 官方文档:https://docs . AWS . Amazon . com/AWS C2/latest/user guide/putty . html
3.终止您的实例
使用实例后将其终止是很重要的。由于您使用的是实例的 AWS 自由层版本,如果您只是让实例闲置,您将会产生费用。下面是实现它的步骤:
- 在 EC2 控制台中,单击 Instances 并选择实例。
- 选择动作->-实例状态->-终止
- 当提示确认时,点击是,终止。
- 该实例将需要一些时间来终止。等待它关闭。实例状态应该从关闭到终止。
唷!那是一把!我们终于学会了如何创建一个实例,通过 SSH 访问该实例,并终止它。
对这些人来说就是这样!下周,我们将学习做同样的事情,即以编程方式创建一个 Amazon Linux 实例。敬请期待!
cLPR:一个用于学习姿态和旋转的 3D 数据集
如果你仍然在媒体上阅读这篇文章,我已经把我的博客搬到了 http://yvanscher.com/blog.html
今天我将发布 cLPR 数据集,一个用于在 3D 机器学习中工作的数据集。该名称代表立方体用于学习姿势和旋转**。目标是为测试机器学习算法提供许多不同位置的彩色 3D 立方体的良好基线数据集,这些算法的目标是学习姿势和旋转。**
在此下载数据集:
数据
数据集包含立方体的 32x32、64x64、128x128、256x256 jpeg 图像(3d 对象的 2d 投影)。jpegs 没有任何质量损失。数据看起来像这样:
The cube in 3 different positions. The first and third image are showing 2 of the same sides (red and cyan).
标签
标签在二进制 numpy 文件中提供。该文件被称为cube1–1.14.3–2018–06–10–12–30–10.npy
,通常为cubeN-x.xx.x-datetime.npy
,其中x.xx.x
是用于转储文件的 numpy 版本,N
是该数据文件的多维数据集。它包含数据集中所有图像的立方体中节点的每个位置和旋转。对于这个数据集,结构是 250047 x 8 x 6,它的位置 x 节点 x 6 numpy 数组,其中最后一个维度(0,1,2)的前 3 个值是 x,y,z 位置,最后一个维度(3,4,5)的后 3 个值是以弧度表示的 x,y,z 旋转。您也可以通过修改脚本在rotation_positions
数组中存储的内容来创建您想要的任何标签(projector.py
,第 90 行)。
所以结构看起来像:
制作数据集
数据集是使用名为pygame
的包生成的,该包最初是为制作 python 游戏而设计的。这个包很不错,因为它让你可以轻松地绘制和渲染 2d 或 3d 对象。我使用 pygame 是因为我希望代码足够简单,能够让图形经验和矩阵乘法基础知识有限的人理解。
用于生成数据集的代码在 github 上。让我们来看看这些代码是如何在高层次上工作的。
创建一个线框
首先,我们创建一个立方体的线框。这个线框由节点、边和面组成。节点是空间中的点,每个用 x,y,z 坐标表示。我们将所有节点存储在一个 8x3 的 numpy 数组中。边是两个节点(numpy 数组中节点的索引)。面是连接在一起的 4 个节点(也是 numpy 数组中节点的索引)。
您可以像这样创建一个线框:
我用它来创建 8 个节点,6 个面。您实际上不需要指定边,只需要指定节点和面。您可以测试立方体线框创建;运行存储库中包含的python wireframe.py
脚本:
对于这个线框类别,wireframe.py
唯一的外部依赖是numpy
。这个脚本将创建一个立方体并打印节点、边和面。
产生旋转
然后,我生成一组旋转,我想在三维应用到立方体的节点(立方体的角落)。为了生成旋转,我只需遍历 0-6.3 弧度范围内所有可能的旋转组合(接近 2π弧度,但不完全完美)。
上面的代码片段将生成大约 360 度,2π弧度的旋转。然后在 pygame 的每一帧/迭代中,我们将抓取其中一个旋转并显示出来。
步骤 3 渲染线框
我使用 pygame 的函数绘制多边形来渲染线框。该函数获取一系列边(2 个点,[(x,y,z),(x,y,z)])并在屏幕上以给定的点和边的顺序用该颜色绘制一个多边形。下面是我的代码的快速和肮脏的版本;实际的脚本要复杂一些。
第 4 步应用一个旋转和重新中心立方体
为了对这个立方体进行旋转,我对适当的轴使用了一个旋转矩阵。所以要绕着 x 轴旋转,我会用wireframe.py
的create_rot_x
。该函数返回一个矩阵,用于在 x 轴上旋转我们需要的弧度数。然后我在transform
函数中在线框的节点和我们创建的旋转矩阵之间做一个点积。所有这些只是将我们节点的 x,y,z 位置乘以矩阵中正确的数字,这样新的位置就会沿着 x 旋转任意多的弧度。我对这次旋转的 x 、 y 和 z 弧度重复上述过程。完成后,重新调整立方体的中心,使它的中间在屏幕的中心。
步骤 5 将立方体节点重置到它们的初始位置
我存储初始位置,并在每次旋转+重定中心+立方体快照后重置它。这使得推理立方体在每次迭代中做什么变得更容易,移动到我给它的旋转。从一个旋转运动到另一个旋转运动也可能会有万向节锁的问题。这有点令人迷惑,所以我想完全避免它。
重复第 3-5 步
当我这样做时,我在每次旋转后截屏 pygame 屏幕,并将位置信息存储在一个 numpy 数组中。在这个过程中,我将图像写入磁盘,最后保存一个包含所有节点位置和旋转的 numpy 数组。
最后一步
标签的目视检查和程序测试。我回放了 numpy 文件(projector.py
的-t
输入选项回放了 npy 文件),看到旋转看起来不错。还通过test_npy_positions
功能(输入到projector.py
的-n
输入)运行它,该功能将它与每个部分位置的已知正确值进行比较。上面的解释旨在让你了解代码是如何工作的,更多细节见 github 上的代码。代码并不完美,数据集也不完美,还有很大的改进空间(例如,为标签添加颜色映射以使跟踪更容易)。请随时提出拉请求或自己动手。我真的很感激。
你能用这个数据集做什么?
你可以做的一件事是训练可变自动编码器。为了展示如何使用这个数据集,我提供了两个不同的自动编码器(一个经典的,一个传统的)。都有点,泛泛而谈…但重点只是展示一个例子,并不是要有一个完美的模型。
下面是一张图片,其中每个单元代表一个潜在空间的区域,我已经采样,然后通过我们的解码器网络生成一个立方体:
不是所有这些看起来都像立方体,但是嘿,有几个看起来像!代码在这个笔记本里。
不要气馁。生成模型是出了名的困难和挑剔,这里有一个我失败的模型输出的例子:
Failed (yet cool) cube outputs.
以下是我在上述数据子样本训练中制作的 vae 模型的必选 gif(每个时期的快照):
GIF of training VAE
如果你想要一个更好的例子,让自动编码器在 autoencoder 中尝试不同的发行版,请看看这篇文章(以及附带的 github 代码),作者是我在阿姆斯特丹大学的朋友 Tim Davidson 和他的几个同事。还有一篇关于 SO3 自动编码器的非常酷的论文使用了这个数据集的一个变种。
结论
谢谢你坚持到最后。如果您发现数据集或任何脚本有问题,请联系我;人们已经在研究论文和项目中使用这种数据(预发布),因此问题应该被了解、公布和调试。
如果您想引用该数据集,您可以这样做:
Yvan Scher (2018). cLPR Dataset. Brooklyn, NY: The InternetOR@misc{Scher:2018,
author = "Yvan Scher",
year = "2018",
title = "cLPR Dataset",
url = "[https://bit.ly/2yeeA15](https://bit.ly/2yeeA15)",
institution = "The Internet"}ORJust say you used the cLPR dataset and link back to this post :)
我要感谢彼得·科林里奇他有一些不错的 pygame 教程。如果你感兴趣的话,我用 pygame 写了其他的博客。如果你想了解图形和人工智能领域的最新项目和有趣的事情,你应该订阅我的时事通讯: 一代机器 。
干杯!
客户细分的聚类算法
上下文
在当今竞争激烈的世界,了解客户行为并根据其人口统计和购买行为对客户进行分类至关重要。这是客户细分的一个重要方面,它允许营销人员在促销、营销和产品开发策略方面更好地针对各种受众群调整营销工作。
目标
这篇文章展示了使用 python 中的 k-means 聚类对电子商务网站的客户数据集进行细分的概念。数据集包含大约 300 名客户的 年收入 和他们在电子商务网站上的 年支出 。我们将使用 k-means 聚类算法得出最佳聚类数,并根据提供的数据了解潜在的客户群。
关于数据集
数据集由 303 名客户的年收入(以 000 美元计)和他们一年内在电子商务网站上的总支出(以 000 美元计)组成。让我们使用 python 中的 numpy 和 pandas 库来研究这些数据。
#**Load the required packages**
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt#**Plot styling**
import seaborn as sns; sns.set() # for plot styling
%matplotlib inlineplt.rcParams['figure.figsize'] = (16, 9)
plt.style.use('ggplot')#**Read the csv file**
dataset=pd.read_csv('CLV.csv')#**Explore the dataset**
dataset.head()#top 5 columns
len(dataset) # of rows#**descriptive statistics of the dataset**
dataset.describe().transpose()
dataset.head()
dataset.describe().transpose()
数据集由 303 行组成。平均年收入为 245000 英镑,平均年支出为 149000 英镑。年收入和年支出的分布用 distplot 和 violinplot 表示。
可视化数据 disp plot 和 violinplot 显示收入和支出的数据分布。
**#Visualizing the data - displot**
plot_income = sns.distplot(dataset["INCOME"])
plot_spend = sns.distplot(dataset["SPEND"])
plt.xlabel('Income / spend')
Distribution plot of Income & Spend
**#Violin plot of Income and Spend**
f, axes = plt.subplots(1,2, figsize=(12,6), sharex=True, sharey=True)
v1 = sns.violinplot(data=dataset, x='INCOME', color="skyblue",ax=axes[0])
v2 = sns.violinplot(data=dataset, x='SPEND',color="lightgreen", ax=axes[1])
v1.set(xlim=(0,420))
聚类基础 聚类是一种无监督的机器学习技术,其中没有定义的因变量和自变量。数据中的模式用于识别/分组相似的观察结果。
Original Dataset
After Clustering
任何聚类算法的目标都是确保一个聚类中数据点之间的距离与两个聚类之间的距离相比非常小。换句话说,一个群体的成员非常相似,而不同群体的成员极其不相似。
我们将使用 are k-means 聚类来根据客户的收入和支出数据创建客户细分。
K-均值聚类
K-均值聚类是一种迭代聚类算法,其中聚类数 K 是预先确定的,并且该算法基于特征相似性迭代地将每个数据点分配给 K 个聚类之一。
k 均值算法的主要步骤
聚类的数学方法
聚类背后的数学原理,简单来说,就是最小化聚类质心与其相关数据点之间距离的平方和:
- K =集群的数量
- N =数据点的数量
- C=群集 j 的质心
- (xij—CJ)–数据点与其被分配的质心之间的距离
确定最佳聚类数“K” K-means 聚类的主要输入是聚类数。这是使用 最小化平方(WCSS) 内聚类和的概念导出的。创建一个 scree 图,它在 X 轴上绘制聚类数,在 y 轴上绘制每个聚类数的 WCSS。
Scree plot / Elbow method to determine optimum number of clusters
随着星团数量的增加,WCSS 不断减小。WCSS 的下降最初是陡峭的,然后下降的速率变慢,导致肘形图。弯头形成处的簇数通常给出了最佳簇数的指示。应该结合对业务需求的具体了解来决定最佳集群数量。
对于我们的数据集,我们将使用肘方法得出最佳聚类数:
**#Using the elbow method to find the optimum number of clusters**
from sklearn.cluster import KMeans
wcss = []
for i in range(1,11):
km=KMeans(n_clusters=i,init='k-means++', max_iter=300, n_init=10, random_state=0)
km.fit(X)
wcss.append(km.inertia_)
plt.plot(range(1,11),wcss)
plt.title('Elbow Method')
plt.xlabel('Number of clusters')
plt.ylabel('wcss')
plt.show()
Scree plot of given datatset on customer Income & Spend
根据肘图,我们可以选择 4、5 或 6 个集群。让我们尝试集群的数量和可视化集群,以决定集群的最终数量。
将 k 均值拟合到 k=4 的数据集
**##Fitting kmeans to the dataset with k=4**
km4=KMeans(n_clusters=4,init='k-means++', max_iter=300, n_init=10, random_state=0)
y_means = km4.fit_predict(X)**#Visualizing the clusters for k=4**
plt.scatter(X[y_means==0,0],X[y_means==0,1],s=50, c='purple',label='Cluster1')
plt.scatter(X[y_means==1,0],X[y_means==1,1],s=50, c='blue',label='Cluster2')
plt.scatter(X[y_means==2,0],X[y_means==2,1],s=50, c='green',label='Cluster3')
plt.scatter(X[y_means==3,0],X[y_means==3,1],s=50, c='cyan',label='Cluster4')plt.scatter(km4.cluster_centers_[:,0], km4.cluster_centers_[:,1],s=200,marker='s', c='red', alpha=0.7, label='Centroids')
plt.title('Customer segments')
plt.xlabel('Annual income of customer')
plt.ylabel('Annual spend from customer on site')
plt.legend()
plt.show()
Cluster plot : k=4
该图显示了 4 个集群的分布。我们可以将他们理解为以下客户群:
- 第 1 类:中等年收入和低年支出的客户
- 第 2 类:年收入高、年支出中等偏高的客户
- 第三类:年收入低的客户
- 第 4 类:年收入中等但年支出高的客户
集群 4 是一个潜在的客户群。然而,群 2 和群 3 可以被进一步细分以达到更具体的目标客户群。现在让我们来看看当 k=6 时,集群是如何创建的:
**##Fitting kmeans to the dataset - k=6**
km4=KMeans(n_clusters=6,init='k-means++', max_iter=300, n_init=10, random_state=0)
y_means = km4.fit_predict(X)**#Visualizing the clusters**
plt.scatter(X[y_means==0,0],X[y_means==0,1],s=50, c='purple',label='Cluster1')
plt.scatter(X[y_means==1,0],X[y_means==1,1],s=50, c='blue',label='Cluster2')
plt.scatter(X[y_means==2,0],X[y_means==2,1],s=50, c='green',label='Cluster3')
plt.scatter(X[y_means==3,0],X[y_means==3,1],s=50, c='cyan',label='Cluster4')
plt.scatter(X[y_means==4,0],X[y_means==4,1],s=50, c='magenta',label='Cluster5')
plt.scatter(X[y_means==5,0],X[y_means==5,1],s=50, c='orange',label='Cluster6')plt.scatter(km.cluster_centers_[:,0], km.cluster_centers_[:,1],s=200,marker='s', c='red', alpha=0.7, label='Centroids')
plt.title('Customer segments')
plt.xlabel('Annual income of customer')
plt.ylabel('Annual spend from customer on site')
plt.legend()
plt.show()
Cluster plot : k=6
将聚类数设置为 6 似乎可以提供更有意义的客户细分。
- 第 1 类:中等收入,低年支出
- 第二类:低收入,低年度支出
- 集群 3:高收入,高年度支出
- 集群 4:低收入,高年度支出
- 第 5 类:中等收入,低年支出
- 集群 6:非常高的收入,高的年支出
因此,很明显,6 个聚类提供了更有意义的客户细分。
细分客户的营销策略
根据这 6 个集群,我们可以制定与每个集群相关的营销策略:
- 一个典型的策略是将某些促销努力集中于集群 6 和集群 3 的高价值客户。
- 集群 4 是一个独特的客户群,尽管他们的年收入相对较低,但这些客户倾向于在网站上花费更多,这表明他们的忠诚度。可能会有一些基于折扣价格的促销活动来吸引这一群体。
- 对于收入和年度支出都较低的第 2 组,可能需要进一步分析以找出支出较低的原因,并且可以引入对价格敏感的策略来增加该细分市场的支出。
- 尽管年收入不错,但第 1 类和第 5 类客户在网站上的花费并不多——对这些细分市场的进一步分析可能会导致对这些客户的满意度/不满意度的深入了解,或者降低电子商务网站对这些客户的可见性。策略可以相应地发展。
我们已经看到,我们如何通过使用聚类算法来生成客户细分,从而获得有意义的见解和建议。为了简单起见,数据集只使用了两个变量——收入和支出。在一个典型的业务场景中,有几个变量可能会产生更加现实和特定于业务的见解。
聚类和协作过滤——使用单词嵌入
第二部分,我训练了一些神经网络:
第 1 部分,我探索数据集并使用 t-SNE 算法对其进行可视化:
medium.com](https://medium.com/@gabrieltseng/clustering-and-collaborative-filtering-implementing-neural-networks-bccf2f9ff988)
内容:
- 理解和实现单词嵌入
- 训练一个“真正的”深而广的网络
动机:我在第二部分最后一点训练的深度和广度神经网络不是真正的深度和广度模型,因为神经网络的‘广度’部分没有使用任何额外的特征;该模型可以更好地描述为“宽浅”模型。
然而,MovieLens 提供了一组额外的信息,我还没有利用这些信息。每个用户都可以“标记”他们评价的电影。
An example of a tag. movieId 339 is for ‘While you were sleeping (1995)’.
挑战在于将这些标签转化为我的神经网络可以用来衡量用户对电影的感受的东西。
- 单词嵌入
1.1。单词嵌入简介
在第 2 部分中,我了解并实现了嵌入;这将一些输入转换成一个数组。例如,在实现电影的嵌入时,我将每个 movieId 转换成一个长度为 55 的数组。然后这个数组根据数据进行训练,因此它包含了用户对每部电影的感受信息;对于我的神经网络来说,这比随机分配的单个整数电影 ID 更能提供信息。
单词嵌入包括做同样的事情,除了单词。
就像在 ImageNet 的 150 万张图像上训练的 VGG 模型一样,存在大量的嵌入,这些嵌入在大量的文本语料库上训练,以识别单词的特征是什么。
这些单词嵌入是通过大量的句子来训练的。例如,单词表示的全局向量或 GloVe,来自维基百科和 Gigaword ,一个报纸文章的集合。然后替换每个句子中间的一个单词;这很可能使这个句子变得荒谬。嵌入被训练来识别句子是否有意义。
A comparison of superlatives, showing how GloVe captures the similar relationships between the words (credit to GloVe for this plot).
使用预先训练的单词嵌入不同于使用预先训练的模型进行图像识别。因为每幅图像略有不同,当使用 VGG 预训练模型进行图像识别时,我必须下载一个完整的模型,以及它的权重。然而,对于单词嵌入,我可以下载一个字典,将每个单词链接到某个维度的数组(GloVe 有 50、100、200 和 300 维向量)。
An example of a dictionary item in GloVe
1.2。将单词嵌入到 MovieLens 中
[链接到代码](http://LearningDataScience/Recommender_System/Word Embeddings.ipynb)
为了将标签添加到我的神经网络中,我将标签分解成它们各自的单词,并将这些标签附加到各自的用户和电影上。
The pandas Dataframe created
然后,我使用手套字典将这些标签转化为数组,使用 50 维单词嵌入。
由于神经网络的输入需要具有一致的大小,我取了最长标签的长度(19 个单词),并为每个用户和电影制作了一个 19 乘 50 的带有零的“标签数组”。然后,我根据需要用相应的单词 embedding from GloVe 填充尽可能多的行。这与使用 Keras 的填充没有什么不同。
2。训练一个神经网络
利用这个,我可以训练我的神经网络。
A graph of my neural network. Batch Normalization was implemented at each step, and dropout was used based on the values found in part 2.
不幸的是,这种神经网络的性能明显比没有标签时差:
The validation loss for this network was 1.1400, compared to a best of 0.7699 using the ‘deep only’ model.
我认为这种性能上的差异可以归因于标签的稀疏性;在分配的 100,004 个分级中,只有 1296 个具有标签。因此,从神经网络的大部分传来的绝大多数只是零的阵列(这也可以解释为什么模型对数据拟合不足)。
尽管性能令人失望,但这是对单词嵌入的一个很好的介绍,希望在进行更复杂的自然语言处理时会有用。
基于聚类的无监督学习
无监督机器学习是从“未标记的”数据(分类或归类不包括在观察值中)推断描述隐藏结构的函数的机器学习任务。使用无监督学习算法的常见场景包括:
-数据探索
-离群点检测
-模式识别
虽然有一个详尽的聚类算法列表(无论您使用 R 还是 Python 的 Scikit-Learn),但我将尝试涵盖基本概念。
k 均值
最常见和最简单的聚类算法是 K-Means 聚类。这个算法包括你告诉算法在数据集中有多少可能的聚类(或 K)。然后,该算法迭代地移动 k-中心,并选择聚类中最接近质心的数据点。
以 K=3 为例,迭代过程如下:
一个显而易见的问题是选择 K 值的方法。这是使用肘形曲线完成的,其中 x 轴是 K 值,y 轴是某个目标函数。一个常见的目标函数是数据点和最近质心之间的平均距离。
K 的最佳数值是“肘部”或扭曲区域。在这一点之后,通常认为添加更多的集群不会为您的分析增加显著的价值。以下是在 iris 数据集上使用 Scikit-Learn 的 K-Means 的示例脚本:
from sklearn.cluster import KMeans
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
%matplotlib inline
from sklearn import datasets#Iris Dataset
iris = datasets.load_iris()
X = iris.data#KMeans
km = KMeans(n_clusters=3)
km.fit(X)
km.predict(X)
labels = km.labels_#Plotting
fig = plt.figure(1, figsize=(7,7))
ax = Axes3D(fig, rect=[0, 0, 0.95, 1], elev=48, azim=134)
ax.scatter(X[:, 3], X[:, 0], X[:, 2],
c=labels.astype(np.float), edgecolor="k", s=50)
ax.set_xlabel("Petal width")
ax.set_ylabel("Sepal length")
ax.set_zlabel("Petal length")
plt.title("K Means", fontsize=14)
如上面的 3D 图所示,K-means 的一个问题是它做硬标签。但是,您可以看到紫色和黄色集群边界上的数据点可以是任意一个。对于这种情况,可能需要不同的方法。
混合模型
在 K-Means 中,我们做了所谓的“硬标记”,在这里我们简单地添加最大概率的标记。然而,存在于聚类边界处的某些数据点可能仅仅具有在任何一个聚类上的相似概率。在这种情况下,我们看的是所有的概率,而不是最大概率。这就是所谓的“软标签”。
from sklearn.mixture import GaussianMixture
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
%matplotlib inline
from sklearn import datasets#Iris Dataset
iris = datasets.load_iris()
X = iris.data#Gaussian Mixture Model
gmm = GaussianMixture(n_components=3)
gmm.fit(X)
proba_lists = gmm.predict_proba(X)#Plotting
colored_arrays = np.matrix(proba_lists)
colored_tuples = [tuple(i.tolist()[0]) for i in colored_arrays]
fig = plt.figure(1, figsize=(7,7))
ax = Axes3D(fig, rect=[0, 0, 0.95, 1], elev=48, azim=134)
ax.scatter(X[:, 3], X[:, 0], X[:, 2],
c=colored_tuples, edgecolor="k", s=50)
ax.set_xlabel("Petal width")
ax.set_ylabel("Sepal length")
ax.set_zlabel("Petal length")
plt.title("Gaussian Mixture Model", fontsize=14)
对于上面的高斯混合模型,数据点的颜色基于靠近聚类的高斯概率。RGB 值基于与红色、蓝色和绿色聚类的接近度。如果您查看蓝色和红色集群边界附近的数据点,您将看到紫色,表明数据点靠近任一集群。
主题建模
既然我们已经讨论了数值,让我们转向分类值。一个这样的应用是文本分析。解决这类问题的常用方法是主题建模,将文档或文档中的单词分类成主题。其中最简单的是 TF-IDF 模型。TF-IDF 模型根据单词的重要性对其进行分类。这取决于它们在特定文档中的出现频率(例如科学期刊中的特定科学主题)以及在所有文档中常见的词(例如停用词)。
我最喜欢的算法之一是潜在的狄利克雷分配或 LDA 模型。在这个模型中,文档中的每个单词都有一个基于整个文档语料库的主题。下面,我附上了华盛顿大学机器学习专业化课程的幻灯片:
LDA 模型本身背后的机制很难在这篇博客中解释。然而,人们的一个常见问题是决定主题的数量。虽然对此没有确定的答案,但我个人更喜欢实现每个文档的单词向量的 K 均值的肘形曲线。每个词向量的接近程度可以通过余弦距离来确定。
隐马尔可夫模型
最后,让我们介绍一些时间序列分析。对于聚类,我最喜欢的是使用隐马尔可夫模型或 HMM。在马尔可夫模型中,我们寻找状态和给定当前状态的下一个状态的概率。下面的例子是一只狗在马尔可夫模型中的生活。
让我们假设狗生病了。鉴于目前的状态,它有 0.6%的几率在下一个小时继续生病,0.4%的几率在睡觉,0.5%的几率在拉屎,0.1%的几率在吃东西,0.4%的几率会恢复健康。在 HMM 中,您提供时间序列数据中可能有多少个状态供模型计算。下面给出了波士顿房价数据集的一个示例,包含 3 个州。
from hmmlearn import hmm
import numpy as np
%matplotlib inline
from sklearn import datasets#Data
boston = datasets.load_boston()
ts_data = boston.data[1,:]#HMM Model
gm = hmm.GaussianHMM(n_components=3)
gm.fit(ts_data.reshape(-1, 1))
states = gm.predict(ts_data.reshape(-1, 1))#Plot
color_dict = {0:"r",1:"g",2:"b"}
color_array = [color_dict[i] for i in states]
plt.scatter(range(len(ts_data)), ts_data, c=color_array)
plt.title("HMM Model")
与每个聚类问题一样,决定状态的数量也是一个常见问题。这可以是基于域的。例如,在语音识别中,通常使用 3 种状态。另一种可能性是使用肘部曲线。
最后的想法
正如我在博客开始时提到的,我不可能涵盖所有的无监督模型。同时,基于您的用例,您可能需要算法的组合来获得相同数据的不同视角。至此,我想以 Scikit-Learn 在玩具数据集上著名的聚类演示结束您的演讲:
基于相似性传播的加密货币聚类
为了更好地理解硬币相关性,我们部署了一种相似性传播算法,并在市值表的顶端发现了三个不同的加密资产集群,它们协同移动。
介绍
几个月前,拉迪奇的研究团队开始研究区块链复合指数,不是作为一种投资工具,而是为了在评估加密经济中新的分散化项目时有一个清晰和公正的基准。本文讨论了一些初步的统计工作,帮助我们更好地理解硬币运动。简而言之,我们部署了机器学习来解决一场内部辩论——加密货币是独立的资产,根据其价值主张具有独特的运动,还是它们都完全与比特币动荡的新闻周期相关?
为什么这很重要?如果每一个代币都简单地跟随比特币的运动,那么综合指数就不是评估表现的有用机制。
当前的工具和最佳实践还不足以回答这个问题。在光谱的一端,您会发现带箭头的时间序列图意在传达关于世界的一些无可争议的事实,而在另一端,相关矩阵提供了一个很好的总体概念,说明加密资产在一段时间内协同移动的程度,但没有足够的粒度背景来得出决定性的结论。
幸运的是,这个问题的设置看起来几乎像一个标准的无监督聚类问题——我们有一些未标记的数据,我们希望通过相似性组织成组。我说几乎是因为,如果你是一名数据科学家,你应该注意到普通聚类任务的三个区别:(1)时间序列数据,(2)加密经济中的市值是幂律分布的,以及(3)我们不希望像 k-means 聚类那样预先指定返回的聚类数,因为那样会违背本练习的整个目的。
(Left) Time series plot of crypto market capitalizations since January, 2017. (Right) Estimated probability density function of crypto market caps using KDE.
随着问题的明确定义,我们部署了一个相似性传播算法来寻找三个不同的加密资产集群,它们位于市值表的顶端,具有相似的移动。本文的其余部分讨论了我们方法的理论和实践基础,详细说明了结果,并以一些简短的结论性意见结束。
在继续之前,必须一如既往地强调,统计方法,无论多么详尽,都只能提供一个关于世界的概率观点。他们不宣称因果关系,也不宣称绝对真理。尽管如此,这给了我们很多思考。希望你会同意。
为什么要亲和传播?
从一开始,我们就确定了算法需要维护的一些基本需求,以便产生科学勤奋的结果。总的来说,我们发现相似性传播不仅满足了我们所有的需求,而且在理论和实践上也是一个非常强大的算法。
Frey 和 Dueck 在 Science 上发表的 Affinity Propagation 将数据点之间的相似性度量作为输入,并在数据点之间交换实值消息,直到高质量的聚类自然出现。在交换消息时,算法识别样本,样本是很好地描述集群的观察结果。您基本上可以将样本视为质心,只是它们不是每个组中所有对象的平均值,而是描述其最近邻居的真实观察数据点。出于我们的目的,这意味着我们的样本将是一些真正的加密资产。也就是说,在运行算法后,我们仍然计算质心“趋势”线,并在下面的图中显示它们,以便于解释。
识别样本后,算法本身会推断出数据中存在多少自然聚类。根据创造者的说法,唯一真正需要仔细调整的超参数是阻尼因子,当信息在数据点之间传递时,它被设置为以避免数字振荡。创作者建议将阻尼系数设置为 0.9 。在我们的任务中,介于 0.5 和 0.83 之间的值导致识别出四个聚类。将其增加到 0.83 以上会产生三个聚类。更具体地说,设置较高的阻尼因子将组合来自较低阻尼集的第三和第四类,而前两类完全不变。最后,我们将阻尼因子设置在 0.83 以上,因为结果稍微更直观。
我们考虑了一些其他的算法,但是,没有一个能满足我们的一个或多个需求。我们知道,识别一年中只有几个月非常相似,但一年中其他时间完全不同的加密货币是不可取的。同样重要的是,我们想尽可能地测量并隔离新闻周期对市值的日常影响;忽略任何延迟效应。因此,需要在每个日期索引上专门评估相似性,但要跨整个数组。动态时间扭曲,这是一种流行的方法,用于测量具有不同长度和异相相似性的时间序列数据的相似性,但不会起作用,因为它试图找到异相相似性。我们有一个奢侈的问题,数据是有意同相的,长度相同。如上所述,k-means 聚类及其许多变体不会工作,因为我们不想告诉机器人应该有多少个聚类。
对于距离度量,如果我们可以标准化幂律分布数据,标准负欧几里得距离将很好地完成工作。为了做到这一点,每个向量首先进行对数变换,然后通过减去其平均值并除以其标准偏差进行标准化;产生一个干净的和可比较的数据集。
方便的是,以上所有暗示了 sci-kit learn 的相似性传播实现将会很好地满足我们的目的。2 月初,我们从 Coinmarketcap.com 获取了市值排名前 50 位的加密资产的历史数据。在这 50 家公司中,只有 26 家已经存在了足够长的时间,足以进行有效的聚类(至少一年)。
结果
下面的并排图对应于三个已识别的集群中的每一个。在左边,我们以时间序列的形式显示集群,样本为白色,集群中所有对象的质心线为亮黄色。空间中的其他成分显示为淡黄色。在右侧,我们展示了每个集群对应的方框图,这有效地从不同的角度提供了对相同数据的查看。相似性传播算法找到了三个样本:Ripple、Tether 和 DigixDAO。第一个集群主要由已建立的加密资产组成。
Note: The clusters start at index zero.
该集群中值得注意的资产是以太坊和 Ripple,分别是市值第二和第三大资产。集群中的其他应用包括平台(BitShares)、支付网络(Stellar)、货币(Litecoin、Nem、Bytecoin、Verge、Dogecoin)和去中心化应用(Siacoin)。所有这些资产都是在 2015 年或之前创建和推出的,远远早于加密热潮的到来。
下一个聚类包含比特币、Tether、Dash、Monero 和整个样本的总市值。这个集群中的资产都是货币,Dash 和 Monero 是关注隐私的匿名硬币。这是一个有趣的结果,因为有人认为 Tether 正在支撑比特币,从而支撑整个市场,代币据称与美元的比例为 1:1。 Tether 于 2017 年 12 月初被美国商品期货交易委员会传唤。
至于第三组,我们真的不知道它是什么。虽然我们预计比特币和以太坊之间可能会出现一些分歧,但这一集群表明,加密领域的异质性比我们预期的要多。我们的密码分析师注意到,这些趋势是 dApp 平台,它们似乎是稍微新的资产。像往常一样,我的观点是,现实世界比我们通常假设的要复杂得多,如果我们增加加密资产的样本,我们可能会发现更多像这样的集群。
结束语
从上面的图表中可以推断出许多值得注意的见解。第一个是显而易见的,我们发现了不止一个集群,这意味着,不,加密资产并不完全遵循比特币不稳定的新闻周期。也就是说,似乎确实存在一前一后移动的自然硬币群,我们预计随着加密样本的增加会有更多。
总的来说,这项研究帮助我们得出结论,评估加密资产的基础框架是一种适当的方法。
其他视角
企业家对硬数据的访问是有限的,这些数据可以帮助他们在试图建立一个…
medium.com](https://medium.com/radicle/how-much-runway-should-you-target-between-financing-rounds-478b1616cfb5) [## 按阶段剖析启动失败率
几周前,在一篇题为“在两轮融资之间,你应该瞄准多少跑道?”,我们发现…
towardsdatascience.com](/dissecting-startup-failure-by-stage-34bb70354a36)
法律免责声明 : Radicle 不是投资顾问,并且 Radicle 不就投资于任何证券、资产、代币、基金或其他投资工具的合理性做出任何陈述。拉迪奇不是税务顾问。radic e 在 radic e 复合材料或任何 radic e 分析中包含证券、资产或代币并不是 radic e 购买、出售或持有此类证券的建议,也不被视为投资建议。复合材料的过往表现并不代表或保证未来的结果。所有的胚根材料都是基于公众普遍可获得的信息和据信可靠的来源,仅为信息目的而准备的。所示的综合数据和分析并不代表可投资资产/证券的实际交易结果。Radicle 维护综合数据并计算显示或讨论的综合水平和绩效,但不管理实际资产。
用 K-means 聚类用电曲线
Photo by Fré Sonneveld on Unsplash
机器学习在能源领域有广泛的应用。一个非常令人兴奋的是提取对电力消费行为的见解。个人或家庭一天中使用能量的方式也被称为“能量指纹”。
在本文中,我们将介绍如何使用 K-means 聚类算法来发现单个家庭的日常负载模式。
该数据集包含 2006 年 12 月至 2010 年 11 月(47 个月)期间收集的 2075259 个测量值。你可以在这里找到。
首先,让我们准备好数据
上面的图显示了 1456 天的所有日负荷曲线。通过观察较暗的区域(这里集中了更多的曲线),我们可以看到两种清晰的消费行为模式。
K-均值聚类
K-means 是一种无监督机器学习算法,其中必须事先定义聚类的数量。这就留下了选择多少个集群的问题。
解决这一问题的常用方法是使用轮廓值。这是一个衡量点与自己的聚类相比与其他聚类相似程度的指标。其范围从-1 到 1,其中高值表示某个点与其所属的聚类匹配良好。
我们对所有负载曲线的轮廓取平均值,以便对算法的执行情况有一个全面的了解。
我用一系列的集群数(从 2 到 30)进行实验。重要的是在相同的范围内缩放每个周期,以便能量负载的大小不会干扰群集的选择。
最大平均轮廓出现在只有 2 个聚类时,但是为了更好地说明这个例子,我选择 3 个。让我们看看它们是什么样子:
正如我们所看到的,K-means 发现了三组独特的负载曲线。
绿色集群包含在整个下午保持稳定能源使用的负载。也许这些天居住者呆在家里,像周末和特殊的日期。
蓝色集群在早上有一个高峰,在下午使用量下降,在晚上再次达到高峰。这种模式似乎适合居住者上班和/或上学的工作日。
最后,红色聚类显示全天消费量较低的日子。也许是假日里只有几个电器开着的情况?
用 t-SNE 验证结果
我们可以验证聚类算法结果的一种方法是使用一种形式的维度缩减并在 2D 平面中绘制点。然后,我们可以根据它们所属的集群给它们上色。
为此,一种流行的算法叫做 t-SNE 。算法的内部工作超出了本文的范围,但是可以在这里找到一个很好的解释。
需要记住的是,SNE 霸王龙对 K-means 发现的聚类一无所知。
在上面的图中,每个点代表一个每日的负载曲线。它们从 24 维减少到 2 维。理论上,高维空间中的点之间的距离保持不变,因此相互靠近的点指的是相似的载荷分布。大多数蓝色、红色和绿色点相互靠近的事实表明聚类效果良好。
结论和进一步的工作
本文提出了一种利用 K-means 算法发现用电量聚类的方法。我们使用剪影分数来寻找最佳的聚类数,并使用 t-SNE 来验证结果。
至于下一步,我们可以尝试不同的聚类算法。Scikit-learn 有很多值得探索的地方。一些不需要先验地选择聚类的数量。
另一个有趣的应用是将这个模型扩展到不同的家庭,并找到家庭中相似能源消耗行为的聚类。
我希望你喜欢它!如果您有任何意见和/或建议,请随时联系我。
群集以太坊地址
使用交易活动中的模式对地址进行分类
介绍
以太坊用户可能是匿名的,但他们的地址是唯一的标识符,在区块链上留下了公开可见的痕迹。
我建立了一个基于交易活动的聚类算法,将以太坊用户划分为不同的行为子群。它可以预测某个地址是属于 exchange、miner 还是 ICO wallet。
数据库使用 SQL 构建,模型用 Python 编码。源代码可以在 GitHub 上获得。
3D representation of Ethereum address feature space using T-SNE
背景
以太坊区块链是一个名为**智能合约的去中心化应用平台。**这些合同通常用于代表其他资产。这些资产可以代表现实世界中的物理对象(如房地产所有权),也可以是纯粹的数字对象(如公用令牌)。
执行智能合同所需的计算是用生态系统的本地货币 ether 支付的。
以太存储在被称为地址的加密账户中。
动机
许多人认为加密货币提供了数字匿名,这种想法有一定的道理。其实匿名是 Monero 和 ZCash 的核心使命。
然而,以太坊的应用更加广泛,其广泛的灵活性产生了丰富的、公开的交易行为数据集。因为以太坊地址是唯一的标识符,其所有权不会改变,所以可以跟踪、汇总和分析它们的活动。
在这里,我试图通过有效地集群以太坊地址空间来创建用户原型。这些原型可以用来预测未知地址的所有者。
这开启了一系列广泛的应用:
- 了解网络活动
- 增强交易策略
- 改进反洗钱活动
结果
以太坊生态系统中的参与者可以通过他们交易活动中的模式来区分。已知属于交易所、矿商和ico的地址定性地表明聚类的结果是准确的。
技术细节
请随意跳到下面的解读结果。
特征工程
以太坊交易数据集托管在 Google BigQuery 上。使用具有最高以太网余额的 40,000 个地址,我创建了 25 个特征来表征用户行为的差异。
Features derived for each address
选择适当数量的集群
使用剪影分析,我确定聚类的最佳数量大约为 8。
这种选择最大限度地减少了具有负轮廓分数的样本的数量,负轮廓分数表明样本可能被分配到错误的聚类。
但是我们怎么知道它是否有效呢?
通过从ethers can . ioblock explorer 抓取数据,我在我的数据集中收集了 125 个地址的众包标签。
大多数标签分为三类:
交易所、矿工和 ICO 钱包。
聚类是一种无监督的机器学习技术,所以我不能使用标签来训练我的模型。相反,我使用它们将用户原型分配给集群,基于每个集群的最高标签密度。结果可以在这里找到。
2D visualization of initial clustering. Known addresses on the left.
重新聚类
Exchange 和 miner 的地址一开始是混在同一个集群里的。为了将它们分开,我执行了第二轮聚类,只使用该聚类中的地址。
通过将相异度从欧几里德距离改为*余弦距离,*我极大地改善了交易所和矿工之间的分离。
Improved separation of exchanges and miners. Known addresses on the left.
通过将重新聚类的结果代入原始分析,我们最终得到 9 个聚类。
2D visualization of final clustering results. Known addresses on the left.
解释结果
我们可以根据相应的聚类质心得出关于用户行为的结论。
Radar plot — cluster centroid address features
交换
- 高乙醚平衡
- 高流入和流出交易量
- 交易之间的时间非常不规则
交易所是加密空间的银行。这些结果是直观的。
矿工
- 低乙醚平衡
- 小平均交易规模
- 更有规律的交易间隔时间
矿工通过消耗计算能力来保护区块链,并获得以太奖励。矿工团体经常“集中”他们的资源以减少支出的差异,根据贡献的资源来分配收益。
ICO 钱包
- 高乙醚平衡
- 少量大额交易
- 交易之间最有规律的时间
ico(首次公开募股)是加密初创公司常用的融资方式。这些初创公司会有大量的资金,并定期出售大量资金来支付日常业务开支,这是有道理的。
其他类别
- 交易所和矿业集群高度相似,因为它们是在第二轮集群中创建的。
- 集群 7 中的地址具有大量智能合约活动。
- 聚类 2 和聚类 5 是高度不同的。
你能识别这些用户群吗?
后续步骤
扩展这项工作将允许对以太坊区块链数据更细致的观察。以下是一些特别有趣的领域:
- 基于图论和网络分析添加特征
- 区分机器人和人类
- 扩展智能合同分析
- 重复分析 ERC-20 令牌交易活动
有问题吗?建议?
你可以在 Twitter 或者 LinkedIn 上找到我。
参考
感谢 Brandon Martin-Anderson、Alex Cuevas、John Braunlin 和 Eric Bragas 审阅本文草稿。
日常生活中的聚类——第 1 页,共 2 页
让我们来考虑这个场景:我喜欢步行,所以当我游览一个城市时,我想尽可能多地步行,但我想优化我的时间来观看尽可能多的景点。现在我想计划我的下一次哥谭市之旅,去参观一些蝙蝠侠的地方。我找到了 1000 个蝙蝠侠出现的地方,我最多还有 4 天。我需要把这 1000 个地方分成 4 个桶,这样这些点就可以靠近我可以停车的中心,来计划我的每一天旅行。我该怎么做?
这类问题可以归为聚类问题。但是什么是集群呢?聚类或聚类分析的任务是将一组数据分组到同类或相似的项目中。同质或相似的概念就是这样定义的。所以解决这类问题是必要的:
- 定义元素之间的“相似性”度量(相似性的概念)
- 根据所选的度量,找出元素的子集是否“相似”
该算法确定哪些元素形成一个聚类,以及在一个聚类中它们的相似度。参考我的上一篇文章,聚类是一个可以用属于无监督方法的算法来解决的问题,因为算法不知道任何关于聚类的结构和特征的信息。
特别是,对于这个问题,我将使用 k-means 算法:k-means 是一种在给定数据集上查找 k 个组(其中 k 是定义的)的算法。每个组由一个质心来描述,该质心代表每个聚类的“中心”。中心的概念总是指我们为特定问题选择的距离的概念。
对于我们的问题,距离的概念很简单,因为两点之间的真实距离是由一个纬度和一个经度定义的。为此,不能用欧几里得距离而是有必要引入球面余弦定律来计算从到地理点的正确距离。
但是 k-means 算法是如何工作的呢?它遵循一个迭代过程:
这种算法的流行来自于它的:
- 收敛速度
- 易于实施
另一方面,该算法不能保证达到全局最优。最终解决方案的质量在很大程度上取决于初始集群集。由于该算法非常快,所以可以应用几次并选择最佳解决方案。
该算法从 k 个聚类的定义开始,其中 k 由用户定义。但是用户如何知道 k 是否是正确的数字呢?他如何知道这些集群是否是“好”集群?测量聚类质量的一个可能的度量是 SSE(误差平方和),其中误差是从聚类质心到当前点的距离。因为这个误差是平方的,所以它更强调远离质心的点。
在下一篇文章中,我将展示一种在 TensorFlow 中解决这个问题的可能方法。
原载于 2017 年 5 月 14 日【devklaus.wordpress.com。
日常生活中的聚类—第 2 页,共 2 页
在我的上一篇文章中,我写了关于聚类和 k-means 算法的内容。在这篇文章中,我想用这些概念和 TensorFlow 写一个简单的例子。(并帮助自己计划下一次去哥谭市的旅行)。
对于这个实现,我们需要 Python(我使用 3.7,但 2.x 也可以)和一些包:
- matplotlib
- 张量流
- numpy
- 熊猫
安装这些软件包很简单:
- 对于 python 2.x: pip 安装<包名>
- 对于 python 3.x: pip3 安装<包名>
在任何情况下,您都可以遵循每个软件包文档中的安装说明。
到目前为止还好吗?好了,让我们深入代码:
首先,我定义了问题的参数:
- 点数:1000
- 集群数量:4
- 计算步骤数:100
在这个特殊的例子中,我使用了一组随机生成的 1000 个 GPS 位置作为训练集[从第 27 行到第 36 行]关于位置:45.7±9.1。如果你有一个坐标正确的文件,你可以加载并使用正确的坐标。第 34 行到第 36 行显示了训练集:
在第 42 行中,向量值被转换成张量流可用的常数。
在随机建立了训练集之后,我们需要质心[从 44 到 50 的线]并将其转换为将由 TensorFlow 操纵的变量。这是 K-means 算法的关键,我们需要一组质心来开始迭代。
K-means 的代价函数是点和质心之间的距离,该算法试图最小化该代价函数。正如我在以前的帖子中所写的,两个 GPS 点之间的距离不能用欧几里德距离来计算,有必要引入一种更精确的方法来计算 di 距离,这种方法之一是球面余弦定律。对于这个例子,我使用了近似的球面余弦定律。这种近似对于像城市距离这样的距离非常有效,并且在计算上比整个算法的实现更有效。要了解更多关于这个近似值和误差的信息,请阅读这篇有趣的帖子。[第 53 至 63 行]
最后,更新质心[第 65 行]
第 68 行到第 75 行初始化所有变量,实例化评估图,运行算法并可视化结果:
结论:
我的前两篇文章关注的是聚类问题的一种算法:K-means。该算法对数据做了一些假设:
- 每个属性分布的方差是球形的
- 所有变量都有相同的方差
- 每个聚类的先验概率是相同的
如果违反了这些假设,那么算法就失败了。
这种算法的一个可能的缺点是必须事先定义聚类的数量。如果您不知道您的聚类如何,您可以选择另一种聚类算法,如 DBSCAN 或 OPTICS(这些算法基于密度模型而不是质心模型)。或者,您可以在 K-means 中引入后处理步骤,聚合(或分割)两个或更多质心,然后在相同的训练集上重新启动整个算法,但使用新的质心集。
从计算的角度来看,K-means 算法对数据对象的数量是线性的,其他聚类算法具有二次复杂度。所以这是需要记住的重要一点。
原载于 2017 年 5 月 25 日【devklaus.wordpress.com】。
欧盟国家集群
欧盟国家的细分,包括基于消费者的聚类分析&商业信心指标
在本文中,我使用了一个公开的欧盟统计局数据集,来对欧盟国家进行细分。该数据集由 5 个置信度指标组成:
- 消费者信心指数
- 建筑业信心指数
- 工业信心指数
- 零售信心指数
- 服务信心指标
这些指标是通过每月在以下领域进行的定性调查形成的:制造业、建筑业、消费者、零售业、服务业和金融服务业。这些调查始于 1980 年,并逐渐包括所有欧盟新成员。目前,整个欧盟每月都有大约 137,000 家公司和超过 41,000 名消费者接受调查。
所使用的指标是余额,即肯定答案和否定答案之间的差异(占总答案的百分比),作为指标,作为置信度指标(余额的算术平均值)。
有关这些调查的更多信息,请点击此链接
欧元区由 19 个国家组成:奥地利、比利时、塞浦路斯、爱沙尼亚、芬兰、法国、德国、希腊、爱尔兰、意大利、拉脱维亚、立陶宛、卢森堡、马耳他、荷兰、葡萄牙、斯洛伐克、斯洛文尼亚和西班牙。
用于获取原始数据集的欧盟统计局包。
关于 ETL 步骤的更多细节可以在实际代码中找到,在文章结尾的链接中。
ETL 和探索性分析
原始数据集包含 11,340 个观察值,其中包括欧盟国家每月的这些指标。在处理过的数据集中,我使用了 2014 年以后的观察值& ii)每个州的每个变量的中值,因此最终数据集总共由 28 个观察值组成。通过对所有商业相关的信心指标(建筑、工业、零售和服务信心指标)进行平均,创建了另一个变量,以使用通用的商业信心指标。
看到信心指数的地图会很有趣。下面是消费者和平均商业信心指标的图表。
- 很明显,各国之间存在显著差异。
- 北欧国家往往有更高的消费者信心指数。
- 这里有一些异常值。希腊的信心指数明显低于其他国家。
下面是一个散点图,带有标记标签,表明每个国家在消费者和企业信心指标方面的定位。
我们可以从上面的图中看出一些模式,类似于之前的发现:
- 有一些异常值,比如希腊(左下角)和瑞典(右上角)
- 有一组国家位于图的中间,表明消费者和企业的平均信心
- 在所有国家,商业信心都大大高于消费者信心
分割
由于各国之间在信心指标方面存在相当多的差异,因此开发一个细分市场来检查各国组建团队的情况将会非常有趣。
k-means聚类算法用于分割。这是最广泛使用的无监督学习算法。该过程遵循一种简单且容易的方式,通过预先确定的固定数量的聚类(假设 k 个聚类)对给定数据集进行分类。主要思想是定义 k 个中心,每个聚类一个。这些中心应该被巧妙地放置,因为不同的位置会导致不同的结果。因此,更好的选择是将它们放置在尽可能远离彼此的地方。下一步是获取属于给定数据集的每个点,并将其与最近的中心相关联。当没有分数悬而未决时,第一步完成,早期小组年龄结束。在这一点上,我们需要重新计算 k 个新的质心作为上一步得到的聚类的重心。在我们有了这 k 个新的质心之后,必须在相同的数据集点和最近的新中心之间进行新的绑定。已经生成了一个循环。作为这个循环的结果,我们可以注意到 k 个中心一步一步地改变它们的位置,直到不再发生变化,或者换句话说,中心不再移动。
指出合适的集群数量
下面的肘形图(scree)用于检查簇的合适数量。所以我们要寻找的是曲线开始变平的点。
具体而言,计算类内平方和的总和(每个观察值和对应于该观察值被分配到的类的质心之间的欧几里德距离的总和)。
剪影分析
一般而言,轮廓分析确定每个观察值与相应聚类的吻合程度(值越高越好)。
它包括计算每次观察的轮廓宽度:
- 接近 1 的值表明该观察值与其当前聚类非常匹配。
- 值为 0 表示它位于两个集群的边界上,并且可能属于其中任何一个集群。
- 接近-1 的值表示观察值更适合其最近的相邻聚类。
总之,我从两个方面着手,因为从技术和实践的角度来看,这两个方面都更合适。
下面是一个图表,其中包含关于所有集群的信息,指示集群中每个置信度指标的平均值
- 在建筑信心指标、消费者信心指标和服务信心指标上,A 类往往比 B 类具有更高的值
- 这两个集群在工业信心指数和零售信心指数上的值相似
主成分
最好能画出这些聚类结果并直观地检查出来。但是不可能想象如此多的变量,因为需要不同的维度。克服这一点的一种方法是使用某种降维技术。特别地,使用 PCA(主成分分析)。它在特征中找到结构并帮助可视化。特别是:
- 它会找到一些变量的线性组合来创建主成分(新特征)
- 维护数据中的大部分差异
- 主成分(新特征)是不相关的(即彼此正交)
下图(双图)显示了绘制在前两个主成分上的所有原始观察值。
- 集群 A 明显地从集群 B 中脱颖而出
- 只是有一点重叠
- 总的来说,北欧国家往往有较高的信心指数,将其归入 A 类
- 聚类结果可以证实双速欧盟理论(各国在生活水平等许多方面存在显著差异。)
下面是所有欧盟国家的表格,显示了它们的集群和中值信心指标(自 2014 年以来)
混合类型数据的聚类
Which methodology to group individuals based on their common patterns and similarities when expressed in multiple data types?
一种使用 R
关于;在…各处 ;大约
聚类 无监督数据 并不是一件容易的事情。事实上,在这种情况下,数据处理和探索通常是由领域知识驱动的,如果不是纯粹的直觉,并且由于没有方法来测量所得分割的准确性(与监督学习相反),因此变得很困难。
此外,无监督学习的入门课程相当经常地讨论理想的用例,比如 k-means 教程,它只适用于数字特征。
然而,真实的业务情况往往会偏离这些理想的用例,需要分析由混合类型数据、构成的数据集,其中数值(两个值的差是有意义的)、名义(分类的,不排序的)或序数(分类的,排序的)特征共存。
在这篇文章中,我将关注这种情况,在使用 R 的无监督分类练习的背景下。
- 第一部分包括方法论:我正在讨论使用距离的数学概念来衡量个体之间的相似性的问题。然后,我将介绍 PAM 聚类算法(围绕 medoids 进行划分)以及一种选择最佳聚类数(轮廓系数)的方法**。我最后用一句话来结束对的解读。**
- 在第二部分中,我将使用 uci 的机器学习库上的银行营销数据集以及来自
cluster
和Rtsne
包的一些有用的函数来说明方法**。该数据集与葡萄牙银行机构的直接营销活动(电话)相关,传统上用于监督学习讨论(分类目标是预测客户是否会认购定期存款)。但是,它包含一些关于银行客户的信息,我们将尝试对这些信息进行“先验”聚类。**
我们开始吧!
第一部分:方法
如何度量相似度
Data Scientists aiming at clustering ‘unknown’ data, sometimes without business knowledge, use distance to avoid subjectivity and ensure consistent approach to all features
距离是个体之间距离的数值度量,即用于测量个体之间的接近度或相似度的度量。存在许多距离度量,其中一个实际上对破解我们的案例非常有用,那就是高尔距离 (1971)。
高尔距离被计算为个体间部分差异的平均值。每个部分不相似性(以及高尔距离)在[0±1]范围内。
Gower distance’s formula
部分相异 ( d_ij^f
) 计算取决于被评估变量的类型。这意味着将对每个特征应用特定的标准化,并且两个个体之间的距离是所有特征特定距离的平均值。
- 对于一个数字特征
**f**
,偏相异度是 1)观察值x_i
和x_j
的绝对差值与 2)从所有个体观察到的最大范围:d_ij^f = |x_i — x_j| / |(max_N(x) — min_N(x))|
,N 是数据集中个体的数量。
Partial dissimilarity computation for numerical features (R_f = maximal range observed)
- 对于一个定性的特征
f
,只有当观测值y_i
和y_j
具有不同的值时,偏相异度才等于 1。否则为零。
注:使用cluster
包中的daisy()
功能,可在 R 中获得更高的距离。特征首先自动标准化(即重新调整至[0 1]范围内)。
聚类算法:MEDOIDS 周围划分(PAM)
高尔距离非常符合 k-medoids 算法。k-medoid 是一种经典的聚类划分技术,它将 n 个对象的数据集聚类成 k 个先验已知的聚类**。**
与 k-means 算法非常相似,PAM 具有以下特征:
- 优点:与 k-means 相比,它直观、对噪声和异常值更鲁棒(由于所使用的距离属性),并且它为每个聚类产生一个“典型个体”(对解释有用)。
- 缺点:耗时耗机(运行时间和内存是二次的)。
评估数据集群内的一致性
除非你有一个很好的先验原理来强制一个特定的数量的簇 k** ,否则你可能会对向计算机询问一个基于统计的推荐感兴趣。存在几种方法来限定所选数量的聚类的相关性。在第二部分中,我们使用轮廓系数。**
轮廓系数将到同一簇中元素的平均距离与到其他簇中元素的平均距离进行对比。具有高轮廓值的对象被认为是良好聚类的,具有低值的对象可能是异常值。该指标适用于 k-medoids 聚类,并且也用于确定最优聚类数。请阅读维基百科页面,了解关于计算和解释的更多细节。
解释
基本上有两种方法来研究这种聚类工作的结果,以便得出一些与业务相关的解释。
- 1.每簇的汇总,使用 r 中的
summary()
函数 - 2.低维空间中的可视化,使用 t-SNE ,使用 r . t-分布式随机邻居嵌入(t-SNE)中的
Rtsne()
函数是一种降维技术,特别适合于高维数据集的可视化。
我们在用例(第二部分)中涵盖了这两种情况。理论够了,来应用和举例说明吧!
第二部分:用例
在这个用例中,我们将尝试根据以下特征对银行客户进行聚类:
- 年龄(数字)
- 工作类型(分类):‘行政’、‘蓝领’、‘企业家’、‘女佣’、‘管理’、‘退休’、‘个体户’、‘服务’、‘学生’、‘技术员’、‘失业’、‘未知’
- 婚姻状况(分类):“离婚”、“已婚”、“单身”、“未知”
- 教育(分类):“初级”、“中级”、“高级”、“未知”
- 违约:有信用违约?(分类):“否”、“是”、“未知”
- 余额(数字):年平均余额,单位为欧元
- 住房:有住房贷款?(分类):“否”、“是”、“未知”
#' Load useful packages
library(cluster)
library(dplyr)
library(ggplot2)
library(readr)
library(Rtsne)#' Load data
df <- read_csv2("../data/001_unsupervised_mixed_types_data/bank.csv")
根据高尔距离,最相似和最不相似的客户:
#' Compute Gower distance
gower_dist <- daisy(df, metric = "gower")gower_mat <- as.matrix(gower_dist)#' Print most similar clients
df[which(gower_mat == min(gower_mat[gower_mat != min(gower_mat)]), arr.ind = TRUE)[1, ], ]# A tibble: 2 x 7
age job marital education default balance housing
<int> <fct> <fct> <fct> <fct> <int> <fct>
1 **52 technician married secondary no 196 yes **
2 ** 52 technician married secondary no 195 yes**#' Print most dissimilar clients
df[which(gower_mat == max(gower_mat[gower_mat != max(gower_mat)]), arr.ind = TRUE)[1, ], ]# A tibble: 2 x 7
age job marital education default balance housing
<int> <fct> <fct> <fct> <fct> <int> <fct>
1 ** 60 retired married primary no 71188 no **
2 **26 admin. divorced secondary yes -3 yes**
在商业环境中,我们通常寻找一些既有意义又容易记忆的聚类,例如最多 2 到 8 个。轮廓图有助于我们确定最佳选择。
sil_width <- c(NA)
for(i in 2:8){
pam_fit <- pam(gower_dist, diss = TRUE, k = i)
sil_width[i] <- pam_fit$silinfo$avg.width
}plot(1:8, sil_width,
xlab = "Number of clusters",
ylab = "Silhouette Width")
lines(1:8, sil_width)
7 clusters has the highest silhouette width. 5 is simpler and almost as good. Let’s pick k = 5
解读
- 每个集群的摘要
k <- 5
pam_fit <- pam(gower_dist, diss = TRUE, k)
pam_results <- df %>%
mutate(cluster = pam_fit$clustering) %>%
group_by(cluster) %>%
do(the_summary = summary(.))
pam_results$the_summary
Clusters’ scorcard
在这里,我们可以尝试为集群中的客户端导出一些通用模式。例如,集群 1 由“管理 x 三级 x 无违约 x 无住房”客户组成,集群 2 由“蓝领 x 二级 x 无违约 x 住房”客户组成,等等。
- 低维空间中的可视化
tsne_obj <- Rtsne(gower_dist, is_distance = TRUE)tsne_data <- tsne_obj$Y %>%
data.frame() %>%
setNames(c("X", "Y")) %>%
mutate(cluster = factor(pam_fit$clustering))ggplot(aes(x = X, y = Y), data = tsne_data) +
geom_point(aes(color = cluster))
Clients observed in a lower dimensional space
虽然不完美(尤其是聚类 3),但颜色大多位于相似的区域,这证实了分割的相关性。
结论
这篇文章是我在尝试对混合类型的无监督数据集进行聚类练习时的想法的总结。我认为这可能对其他数据科学家有附加价值,因此分享。
然而,仍存在一些挑战,包括:
- 如何处理海量数据集(cf 内存密集)?
- 一种热编码可能是一种解决方案;这两种方法的优缺点是什么?
请不吝评论并分享您对如何应对这一挑战和改进这一拟议方法的看法。
来源
- R 中混合数据类型的聚类 | Daniel P. Martin | 2016
- 当属性为名义属性时,个体的最优距离函数是什么?|ttnphns| stats.stackexchange.com
- 分类上升等级|约瑟夫·拉玛兰吉| 2018(法语)
用变换的文档向量聚类文本
距离度量不能跨变换空间进行比较。本文还提出了一种度量方法来测试文档的变换,以提高文档的聚类能力
机器学习中分类的一个姐妹任务是聚类。虽然分类需要用类信息预先标记训练数据,但聚类是无监督的。无人值守的磁盘文本分组有很大的好处,我们想知道单词嵌入是否有帮助。事实上,一旦被识别,这些聚类就可以继续充当类似的未来传入文本的目标分类桶。如果我们成功做到了这一点,我们就不需要预先贴标签了!有价值的目标,但稍后会更多。
单词嵌入产生了从n-长( n 是组成文本语料库的词汇的大小)稀疏文档向量到p-长密集向量的线性变换,其中 p < < n 。在文档向量分类的背景下,我们得出结论,使用 tf-idf 向量和朴素贝叶斯分类器是一个很好的起点。虽然我们不能一概而论,但用预先训练/定制的数字向量替换单词似乎对分类质量没有太大帮助。这篇文章(以及下一篇文章)的总体目标是为一个集群任务重复这个练习。在这篇文章中,我们关注以下几点。
- 比较和对比文档的距离/相似性度量
- 变换如何影响向量的可聚集性
- 如何比较不同转换在集群中的有效性?
1.文档的聚类与分类
聚类依赖于对象之间距离的概念,而分类依赖于对象相似性的概念。这里的对象是按照经过测试和尝试的单词袋方法及其变体(包括单词嵌入)表示为数字向量的文档。我们可以选择使用欧几里德距离度量进行聚类,使用余弦相似性进行分类。直觉上,我们期望相似的文档彼此距离很近。但是这并不能保证,除非我们在实现中明确要求它。在对文档向量进行分类时,我们不必担心的事情对聚类任务很重要。其中一些如下。
- 在任何给定的空间中,长度归一化对于聚类文档向量是重要的,但是对于分类它们却不是
- 不同变换空间中的距离和相似性不能直接在数量上进行比较以得出任何结论
- 转换不需要保持距离或相似性,我们实际上希望它们变得更好,因为首先应用转换是没有意义的。
让我们更详细地看看这些,主要集中在向量之间的距离。
2.长度标准化
用于文档的向量空间模型的核心假设是,如果两个文档包含具有相同相对频率的相同单词,那么它们很可能在谈论相同的事情。因此,建立在该前提上的向量通过产生单位余弦相似性来反映它。我们也希望在聚类练习中得到相同的最终结果。也就是说,我们想要构建文档的聚类,其中每个聚类中的文档彼此之间的相似度要高于它们与其他聚类中的文档的相似度。有道理对吗?
但是聚类通常是基于特征空间中向量之间的距离和基于余弦相似性的而不是。也许我们可以使用余弦相似性本身作为距离度量。大多数 K-means 聚类的实现(例如 scikit-learn )不允许自定义距离函数。因此,如果我们想要使用 scikit 中的 K-means 实现对文档进行聚类,我们需要文档的距离度量与其余弦相似性表现相同,以获得对文档进行聚类的良好结果。余弦相似性不受向量大小的影响,而向量之间的距离则不受影响。因此,我们要求在执行聚类任务之前,所有的文档向量都被归一化为具有相同的长度。
为了说明,考虑下面图 1 中的向量 OP 、 OA 、 OB 和 OQ 。 OA 就是简单的 OP 但是幅度更大。同样,OB 是 OQ的放大版。但是 OA 、 OB 与 OP 和 OQ 之间的角度相同,因此它们的余弦相似性不受影响。
Figure 1. (A) Magnitude of vectors affects their difference but not their cosine similarity. So we need to normalize document vectors for clustering (B) Linear transformation of vectors does not in general preserve angles or lengths. So once again the document vectors should be normalized after a transformation if clustering is the objective.
Equation 1
让我们非常清楚,我们需要在聚类文档向量的上下文中进行长度归一化,我们希望距离度量表现得像余弦相似性度量一样…长度归一化不是对任何向量集进行聚类的一揽子建议…事实上,它会破坏我们在以前的帖子中获得的完美聚类,其中距离需要是原始向量之间的良好距离…
3.转换
考虑长度为 n 的两个向量 X 和 Y ,词汇量的大小。我们通过使用单词嵌入将它们转换成更短的 p 维向量 X 和 Y 。我们知道(例如参见单词嵌入和文档向量:第 2 部分。分类)变换与 X’ = WX 和 Y’ = WY 是线性的其中 W 是 pxn 矩阵其中 p 是字向量的长度。余弦相似度和新空间中的距离可以如下导出。
Equation 2
显然,在 p 空间中的向量之间的角度和距离是 W 的函数。当且仅当 W 正交时,它们才是不变的。
Equation 3
但是没有理由期望 W 是正交的,因为单词向量是根据底层算法以各种方式从摘要文本中导出的,并且不要求它们是正交的。当我们在这里处理文档时,根据第 1 节中的论点,我们需要,
在进行聚类任务之前,对转换后的文档向量的长度进行归一化
4.距离测量
我们希望向量的线性变换将使我们能够更好地解读数据中的潜在聚类。每次转换都将文档向量带到不同的空间。虽然我们可以在一个空间内比较距离,但我们不能在不同的空间内进行比较。参见下面的图 2,其中 2A 的聚类数据通过线性变换 W_1 和 W_2 进行了变换,分别产生了我们在 2B 和 2C 中看到的聚类。
Figure 2. The relative changes in inter/intra cluster distances are the key. W2 is a preferable transformation than W1 even while it reduces the intercluster separation in absolute terms. The ratio inter/intra cluster distances is larger with W2
图 2B 显示了集群之间距离的较大绝对值。但是图 2C 更好地划分了集群。原因很清楚。在图 2B 中,星团内和星团间的距离都变大了。在图 2C 中,虽然总距离被挤压,但是簇内距离比簇间距离被挤压得更多。这是关键。为了更好地描绘集群,我们需要各个集群尽可能紧凑,同时尽可能远离其他集群。常识对吗?我们可以这样来形式化这一点
我们更喜欢增加集群间距离与集群内距离之比的线性变换……事实上,我们应该期望产生最高比率的变换能够显示集群任务的最佳结果
由于有许多聚类内和聚类间的距离,这里有一个合理的程序来比较聚类任务的不同降阶线性变换。
- 选择一个转换
- 对于每个聚类 C_i 找到其成员到其质心的中间距离。计算这些中间值的平均值。这是该坐标系的“代表性”距离度量。
- 用这个从 1 开始的代表性距离度量值除以每个集群间距离。求这些比值的平均值。
- 对每个转换重复 1–3。在 3 中产生较大值的转换应该更适合执行聚类任务
5.一个例子
我们用一个例子来结束这篇文章,这个例子巩固了我们在前面章节中的观察。考虑如下图 3A 所示的具有可识别聚类的 2-d 特征空间。重现这些结果的代码可以从 github 下载。
Figure 3. Cluster detection with transformed vectors. The ratio of intercluster to intracluster distance measures is the metric to evaluate and compare across transformations. (A) Original vectors that show two clusters. (B) The clusters are better separated than in A © The transformation did not help with improving cluster detection here (D-E) Distribution of intracluster distances upon transformation. The whiskers are at 5 and 95 percentile values. The intracluster cluster distances got blown up in 3E as expected from 3B. The intracluster distances got squished in 3D agreeing with 3C.
对这些数据进行简单的线性变换,我们得到了如图 3B 所示的聚类。图 3B 中观察到的正交性并不令人惊讶,因为“我们作弊”并选择了与图 3A 中这些簇的主导方向有些一致的线性变换。我们一般没有这种奢侈,但这只是为了放大变换对聚类检测的影响。应用不同的随机变换会产生如图 3C 所示的挤压星团。根据这些变换,簇内距离(距簇的质心)的实际分布已经改变。3C/3D 中距离的压缩和 3B/3E 中距离的扩展是显而易见的。
很明显,在图 3B 中获得的聚类比图 3A 或 3C 中的聚类分离得更好。对于图 3B,簇间距离与平均簇内中值距离的比值也具有最高值。这就是我们在这篇文章的第 2 到第 4 部分所要建立的观点
6.结论
这个帖子有点短,但也差不多了。我们已经为使用降阶转换对文档进行聚类打下了基础。进入细节和结果会使这个太长。我们将在下一篇文章中讨论这个问题,并结束这个系列。
…
原载于 2018 年 11 月 26 日【xplordat.com。
美国人口聚类:观察加权 k-均值
感谢 Chris Decker 提供以下信息:
对于最近几年发现这个帖子的人: scikit learn 在 2018 年 0.20.0 的 KMeans 中实现了一个“sample_weight”参数。再也不用自己卷了。
———
在这篇文章中,我详细介绍了一种 k-means 聚类形式,其中权重与个体观察值相关联。
k 均值聚类近 60 年来一直是机器学习的主力。它简单、有效、直观。我喜欢它的原因之一是,你可以随着时间的推移绘制集群任务,并看到它学习。
From: https://datasciencelab.wordpress.com/2013/12/12/clustering-with-k-means-in-python/
但是,它的伸缩性不是特别好。在笔记本电脑上,你能聚集 10,000 个点吗?当然,没问题。一百万?也许吧,但是会很慢。一亿分?Fuhgeddaboutit!
假设我们想对美国人口进行聚类。为什么?我们可以设置 k=48,并根据当前的人口中心来确定较低的 48 个州的情况。或许,我们想在全国设立 k=1000 个配送中心。也许我们要设置 k = 1000 万个星巴克位置。
美国人口有 3 亿多人。你如何使用 k-means 对它们进行聚类?忽略并行 k-means,让我们限制它在一台笔记本电脑上运行不到 3 分钟。想法?
你可以做的一件事是对数据进行采样;也就是说,用减少的、有希望是代表性的数据子集来运行。另一种方法是聚合数据,大大减少点的数量,但将每个点与每个聚合点代表的原始样本大小相关联。换句话说,对每一点进行加权。
我们可以从哪里获得这样的数据集?美国人口普查局。它们提供了一个非常方便的数据集,其中包含每个邮政编码的居民数量。美国大约有 43,000 个邮政编码,这个数字我们可以轻松地在笔记本电脑上聚集起来。想象一下,我们有一个由邮政编码、经纬度对(k-means 使用的 x-y 坐标)和该邮政编码中的居民数量(体重)组成的数据文件:
“zip”,”state”,”latitude”,”longitude”,”population”
“00601”,”PR”,18.180103,-66.74947,19143
“00602”,”PR”,18.363285,-67.18024,42042
.
.
.
99929,”AK”,56.409507,-132.33822,2424
99950,”AK”,55.875767,-131.46633,47
履行
当然,我们可以去 scikit-learn 或 R 或其他主要的机器学习库运行一些加权 k-means 算法。可惜不是。在一些库中有加权 k-means,但是它们不是我们想要的那种。它们不是为观察值而是为特征提供权重。
也就是说,使用特征权重,我们可以指定纬度应该比经度更影响质心。然而,我们想要指定观察值-权重,使得邮政编码=10012(一个密集的曼哈顿邮政编码)对质心的吸引力远远大于 59011(蒙大拿州一个广阔的低密度区域)。
核心思想非常直观。取(x,y)平面上的四个等权点,质心为(mean(x),mean(y))。
如果我们应用权重,比如说 w=(13,7,4,4),那么权重为 13 的点具有大得多的引力,应该会将聚类中心拉得更靠近它。加权质心现在是:(加权平均(x,w),加权平均(y,w))
距离度量可以是我们通常的欧几里德距离。然而,当我们处理纬度-经度对时,正确的直线距离度量被称为 H 反正弦距离,所以我们将使用它。
我无法在主要的库中找到实现。就连 stackoverflow 都让我失望了。来自那里的一个建议是复制数据点。也就是说,如果加权数据如图所示(上图),将会创建等效的未加权数据集(下图):
显然,这存在扩大数据规模的问题——这正是我们想要解决的问题——而且这只适用于小整数权重。
相反,我从 stackexchange 中找到了一个不错的“常规”k-means 示例(感谢 Gareth Rees !)我将其剥离并修改为观察加权:
import random
import numpy as np
import pandas as pd
import scipy.spatial
from haversine import haversinedef distance(p1,p2):
return haversine(p1[1:],p2[1:])def cluster_centroids(data, clusters, k):
results=[]
for i in range(k):
results.append( np.average(data[clusters == i],weights=np.squeeze(np.asarray(data[clusters == i][:,0:1])),axis=0))
return resultsdef kmeans(data, k=None, centroids=None, steps=20):
# Forgy initialization method: choose k data points randomly.
centroids = data[np.random.choice(np.arange(len(data)), k, False)] for _ in range(max(steps, 1)):
sqdists = scipy.spatial.distance.cdist(centroids, data, lambda u, v: distance(u,v)**2) # Index of the closest centroid to each data point.
clusters = np.argmin(sqdists, axis=0) new_centroids = cluster_centroids(data, clusters, k) if np.array_equal(new_centroids, centroids):
break centroids = new_centroids
return clusters, centroids#setup
data = pd.read_csv(“us_census.csv”)
data = data[~data[‘state’].isin([‘AK’,’HI’,’PR’])]
vals = data[[‘population’,’latitude’,’longitude’]].values
k = 3
random.seed(42)#run it
clusters,centroids=observation_weighted_kmeans(vals,k)#output
data[‘c’]=[int(c) for c in clusters]
lats = [centroids[i][1] for i in range(k)]
data[‘clat’] = data[‘c’].map(lambda x: lats[x])
longs = [centroids[i][2] for i in range(k)]
data[‘clong’] = data[‘c’].map(lambda x: longs[x])
data.to_csv("clustered_us_census.csv", index=False)
在旧的 Macbook Air 上,运行时间从 2 秒(k=1)到 160 秒(k=48)不等。
结果
美国人口的质心在哪里(即 k=1)?似乎是在密苏里州东南部。
对于 k=10,
最后,如果我们根据人口密度“重新划分”我们的州,那么我们会看到一个非常不同的画面。至少 5 个状态将被划分给邻居,并且 CA 和 TX 被分成四个或五个区域。
更新(2017–05–09):以下是完整源代码:https://github . com/leaping llamas/medium _ posts/tree/master/observation _ weighted _ k means
更新(2018–06–10):上面显示的中 post 代码存在一些 bug。然而,github 代码工作得很好。为了明确起见,请确保您正在运行:https://github . com/leaping llamas/medium _ posts/blob/master/observation _ weighted _ k means/medium . py
P.S .如果您要对数据的某个子集进行聚类,比如说对一个州内的地区进行聚类,您需要确保调整质心初始化。也就是说,确保初始质心随机分布在感兴趣的区域内(而不是像示例代码中那样分布在更大的范围内),否则它们将在单个聚类中结束。
聚类——无监督学习
机器学习
什么是聚类?
“聚类”是将相似的实体组合在一起的过程。这种无监督机器学习技术的目标是找到数据点中的相似性,并将相似的数据点分组在一起。
为什么使用聚类?
将相似的实体分组在一起有助于描述不同组的属性。换句话说,这将让我们深入了解不同群体的潜在模式。对未标记的数据进行分组有许多应用,例如,您可以识别不同的客户群/细分市场,并以不同的方式营销每个客户群,以最大化收益。另一个例子是将属于相似主题的文档分组在一起。当你处理大量的变量时,聚类也被用来减少数据的维数。
聚类算法是如何工作的?
有许多算法被开发来实现这一技术,但对于这篇文章,让我们坚持机器学习中最流行和最广泛使用的算法。
- k 均值聚类
2.分层聚类
k 均值聚类
- 它以 K 作为输入开始,这是你想要找到的聚类数。将 K 个质心放置在空间中的任意位置。
- 现在,使用数据点和质心之间的欧几里德距离,将每个数据点分配给与其接近的聚类。
- 将聚类中心重新计算为分配给它的数据点的平均值。
- 重复 2 和 3,直到没有进一步的变化发生。
现在,你可能会想,我如何在第一步决定 K 的值。
其中一种方法叫做肘法,可以用来决定一个最优的聚类数。这里,您将对 K 值范围运行 K 均值聚类,并在 Y 轴上绘制“解释的方差百分比”,在 X 轴上绘制“ K ”。
在下面的图片中,你会注意到,当我们在 3 之后添加更多的集群时,它并没有给出更好的数据建模。第一个集群增加了很多信息,但在某个点上,边际增益将开始下降。
Elbow Method
层次聚类
与 K 均值聚类不同,分层聚类从将所有数据点指定为自己的聚类开始。顾名思义,它构建层次结构,在下一步中,它组合两个最近的数据点,并将其合并为一个集群。
1.将每个数据点分配给自己的聚类。
2.使用欧几里德距离找到最接近的聚类对,并将它们合并到单个聚类中。
3.计算两个最近的聚类之间的距离,并进行组合,直到所有项目都聚集到一个聚类中。
在这种方法中,您可以通过注意哪些垂直线可以被水平线切割而不与聚类相交并覆盖最大距离来决定最佳聚类数。
Dendogram
使用聚类算法时要记住的事情:
- 将变量标准化,以便所有变量都在相同的范围内。这在计算距离时很重要。
在形成聚类之前处理离群数据,因为它会影响数据点之间的距离。
如果你从这篇文章中学到了什么,那么请❤点击下面,这样其他人会在媒体上看到它。
集群:为什么要使用它
作为一名没有编程背景的数据科学新生,我喜欢用简单的方式解释复杂的主题。好像在我的节目开始前自言自语。好吧,我希望你们都准备好了一些集群。
让我们从什么是集群开始?事实上,你已经做过很多次了。这是寻找相似之处并将这些相似点放入一个组(或集群)的行为。让我们都回想一下上次出去吃饭的情形。你首先要弄清楚的是你想要什么类型的食物,墨西哥的、中国的、意大利的等等。你正在制造具有这些属性的多个餐馆的集群。
现在来看一个更加数据科学的例子,我将观察种子的不同属性,看看对这些属性进行聚类是否有助于预测种子是否属于某个物种。
直接进入代码,我们需要导入库来执行下面几行。我还将在底部读取我的数据集
%matplotlib inline
**import** **pandas** **as** **pd**
**import** **numpy** **as** **np**
**from** **sklearn** **import** cluster
**from** **sklearn** **import** metrics
**from** **sklearn.metrics** **import** pairwise_distances
**import** **matplotlib.pyplot** **as** **plt**
**import** **matplotlib**
matplotlib.style.use('ggplot')
**import** **seaborn** **as** **sns**seeds = pd.read_csv("../assets/datasets/seeds.csv")
看看我的数据框的前几行,这就是它的样子。使用 pandas 查看这一点的代码是 seeds.head(),它将显示前 5 行
seeds.species.nunique()
然后,我查看了我的“物种”列中独特值的数量,这是“目标值”列(我们试图预测的东西)。我们的数据集中有三个物种
*# Plot the Data to see the distributions/relationships*
cols = seeds.columns[:-1]
sns.pairplot(seeds, x_vars=cols, y_vars= cols, hue='species')
这是一个散点图,显示了我们不同的变量是如何相互联系的,颜色(或我上面设置的色调)是每个不同的物种。因此,你可以开始看到,一般来说,对于我们的大多数变量(预测),种子往往与它们自己的物种聚集在一起。
因为我们有一个目标值,所以我们可以在这里停止聚类,但是很多时候我们会在没有目标值的时候使用聚类。因此,我将放弃我们的目标,看看我们的聚类是否会发现差异,并很好地预测哪些种子应该聚集在一起。
X = seeds.drop("species", axis = 1)**from** **sklearn.metrics** **import** pairwise_distances
**from** **sklearn** **import** cluster, datasets, preprocessing, metrics
X_scaled = preprocessing.normalize(X,axis=0)
我放弃了目标值,我还从 sklearn 导入了几个库,这样我就可以规范化我的数据。规范化数据是组织数据库的属性和关系以缩放范围[0,1]内的所有数值变量的过程。我们这样做是为了使 permiter 等值为 15 的列不会比紧致度等值低于 1 的列更重要
**from** **sklearn.cluster** **import** KMeans
k = 3
kmeans = cluster.KMeans(n_clusters=k)
kmeans.fit(X_scaled)
我使用 kmeans 集群来解决这个问题。它设置随机质心(每组的中心点),这些质心将不断移动,直到它们位于一组点的中心,以使所有点的平均距离尽可能小。
inertia = kmeans.inertia_
**print** 'Silhouette Score:', metrics.silhouette_score(X_scaled, labels, metric='euclidean')
我在上面所做的是查看两个不同的指标来分析我们的聚类方法做得有多好。惯性是每个聚类的误差平方和。因此,惯性越小,集群越密集(所有点越靠近)
轮廓分数从-1 到 1,显示了聚类之间的距离以及聚类的密度。你的轮廓分数越接近 1,你的聚类就越明显。如果你的分数是 1,把你的集群想象成完美的小球,它们彼此远离,没有分类失误。
聚类可以用在很多问题上,不管你有没有目标值,都有助于寻求洞见,看到关系。
CDN —内容交付网络
什么,为什么,怎么做?
什么?
什么是 CDN?Well 是一个专注于传递内容的复杂网络。什么内容?你从一个流行的网络服务上下载的几乎所有内容都会通过 CDN 传送。例如,FaceBook、网飞和 YouTube 使用内容交付网络来服务数十亿从其服务器请求数据的用户。CDN 背后的主要思想是以改善空间(基于位置)和时间(基于访问时间)位置的方式分发内容。
举个例子 通常网飞会在世界各地不同的 ISP 为服务器用户安装冗余服务器。这些服务器被称为开放连接设备,根据访问权限在本地保存内容。任何到达网飞核心的新东西都会被推送到这些网站上,这样当地用户就能及时了解最新的展览目录。
为什么?
想想网飞或 FaceBook 的故事。世界各地的大量用户不断请求内容,显然,由于许多原因,拥有一个庞大的服务器群不是一个解决方案。
- 单点故障(SPOF)
- 网络延迟
- 成本(ISP 必须跳过许多 BG——连接不同 ISP 的边界网关。这要花费!!)
- 需要故障安全冗余
此外,如果您检查 FaceBook 的 DOM(文档对象模型),您可以看到以下内容。
Content Loaded over CDN
FaceBook 的图像通常使用 Akamai CDN 渲染。这里 可以找到更多使用 Akamai 的人。
怎么会?
cdn 大多是相互对话的分布式系统。根据分布式系统的定义,整个系统对任何到达它的人来说都是一个端点。
简化过程
How CDN get updates
全局重定向器
在 cdn 上讨论全局重定向器的概念很重要。这些是 ISP 级别或区域级别的重定向,用于到达具有所请求内容的最近的服务器。
键入www.google.com,你将被重定向到 www.google.lk (因为我是在斯里兰卡写的)。这是全局重定向。
为什么打开 Connect Appliances
为什么ISP没有一个单独的服务器机架来缓存所有的东西,为什么cdn把他们自己的设备推到 ISP 的场所?如果互联网服务提供商知道你的请求,他们将不得不打开并通过互联网查看你请求的内容。现代网络实施 HTTPS,这使得这不可能。如果他们要打开你的请求,他们必须是一个中间人,这将再次在浏览器中失败,因为这将使 SSL 证书验证失败。因此 CDN 发布自己的设备,以更安全可靠的方式完成任务。
对于互联网服务提供商来说,这听起来可能是一项令人讨厌的任务,因为他们需要在自己的场所安装一些机顶盒。嗯**不是!!**这是因为拥有这样的设备将使他们能够减少通过 ISP 并到达 WWW 的请求数量。这是一个巨大的成本降低。最终 CDN 和 ISP 都很开心,我们也是。
感谢您的阅读。希望你学到了新东西。干杯!😃
CNN 在结构化数据中的应用——自动特征提取
Deep Learning based Automated Feature Engineering
作者:2018 年 8 月 13 日作者:酸溜溜的 Dey
T3【https://www.linkedin.com/in/sourish-dey-03420b1a/】T5
重要特征工程:
在我的上一篇文章中,我讨论了从有限的特性中创造丰富特性的重要性。事实上,机器学习/深度学习模型的真正质量来自广泛的特征工程,而不是建模技术本身。虽然特定的机器学习技术可能最适合特定的业务问题/数据集,但功能是任何建模项目的通用驱动因素/关键组件。从可用数据集中提取尽可能多的信息对于创建有效的解决方案至关重要。
在这篇文章中,我将讨论一种在行业中不太流行的特征工程方法(至少对于结构化数据而言),即使用 CNN(是的,你没听错,卷积神经网络)从结构化数据中生成特征,这是一种现代深度学习模型,广泛用于计算机视觉问题领域。我们还将在一个小数据上测试这种方法,以实际操作来创建特征——就好像它没有运行,它没有完成。
为什么要进行自动化特征工程:
传统上,分析师/数据科学家使用来自领域/业务知识的手动过程来创建特征。通常它被称为手工特征工程。虽然在数据科学中,我们不能否认领域知识的重要性,但这种类型的特征工程有一些缺点:
1.**繁琐:**手工特征工程可能是一个繁琐的过程。从父变量列表中可以创建多少个新特征?例如,从日期变量中,数据科学家可以创建 4 个新特征(月、年、小时和星期几)。然而,另一位数据科学家可以创建 5 个附加功能(周末指示器、节日指示器、X-mass 月指示器、季节性指数、一个月中的第几周等等)。与其他变量有关系/交互作用吗?因此,人工特征工程受到人类时间限制和想象力的限制:我们无法设想每一个可能有用的特征。
2.**人类偏见的影响:**通常,任何从事特定领域/建模项目的人,都会对某些特性产生深刻的偏见(尤其是如果这些特性是由分析师早先创建的话!),不管它是否给模型增加了价值。
自动化特征工程的力量来了。这里可以创造的特征实际上是无限的,没有任何人为的偏见。此外,这捕获了特征之间所有可能的复杂非线性交互。当然,我们可以在任何时间点应用降维/特征选择技术来去除冗余/零重要性特征。
商业问题和 CNN 的相关性
这里的业务目标是根据信用卡所有人的支付状态、余额和过去几个年份(预测期的最后 6 个月)监控的支付历史来预测信用违约的概率。为了简单起见,让我们忽略滞后期(通常在客户信息提取和数据上传到系统进行分析之间存在滞后)。这个业务问题和数据准备的动机来自https://medium . com/@ guai sang/credit-default-prediction-with-logistic-regression-b 5 BD 89 f 2799 f。
我没有使用跨部门的组成部分(如性别、教育等。)中,并且只保留时间序列变量(余额、支付历史等。)来介绍一下 CNN 这个商业问题。本文的目标是在这种结构化数据上概念化和实现 CNN,并使用 CNN 模型从这种数据中生成 100 个新特征。你可以在这里得到的数据和全部代码。
关于数据:
数据集使用二元变量“下个月的默认付款”(Yes = 1,No = 0)作为响应变量。该集合中有 18 个特征(不包括 ID ):
- 1:6 =X1 预测期最后一个月的还款情况;。。。;X6 =预测期前第 6 个月的还款情况。还款状态的衡量标准是:-1 =按时支付;1 =延迟一个月付款;2 =付款延迟两个月;。。。;8 =付款延迟八个月;9 =付款延迟 9 个月及以上。0 表示没有交易
- X7 =参考时间范围最后一个月的账单金额;….X12 =参考时间范围之前第 6 个月的账单金额;
- X13 =参考时间范围最后一个月的账单金额;….X18 =参考时间框架前第 6 个月的支付金额;
CNN 格式的数据表示:
深度学习方法,特别是 CNN,已经在基于图像的数据领域取得了很多成功,其中数据在规则的像素网格中提供了清晰的结构化拓扑。虽然关于卷积神经网络(CNN,或 ConvNet)的详细讨论超出了本文的范围,但让我们来看看是什么让 CNN 如此受欢迎?
深度学习方法,特别是 CNN,已经在基于图像的数据领域取得了很多成功,其中数据在规则的像素网格中提供了清晰的结构化拓扑。虽然关于 CNN 或 ConvNet 的详细讨论超出了本文的范围,但是让我们来看看是什么让 CNN 如此受欢迎?
缩减参数(参数共享):在卷积运算(层)时,每个输出值(图中卷积特征)不需要连接到前一层(图中图像)的每个神经元,只需要连接到当前应用卷积核的那些被称为感受野的神经元。卷积层的这种特性称为局部连通性。同样,相同的权重应用于卷积,直到参数的下一次更新。卷积层的这种特性称为参数共享。与通常的 ANN(人工神经网络)结构相比,这些大大减少了所需的参数数量,在 ANN 结构中,每一对输入/输出神经元之间都有一个连接。
移位/平移方差:表示当输入移位时,输出也移位,否则保持不变。具体到一幅图像,你可以把一个物体识别为一个物体,即使它的外观以某种方式变化。
因此,简而言之,要对任何数据应用 CNN,需要以某种方式准备数据,以便存在局部模式,并且相同的局部模式在任何地方都是相关的。具体到我们的数据,我们有时间序列的事件范围(平衡,支付等。)对于单个客户,这使得数据充满了她本地的模式,因此这些参数可以在客户之间共享。我们只需要准备适合馈入个人客户的 CNN 特征矩阵的数据,与 d * w * n 的图像帧矩阵相同(d、w 和 n 是图像帧的深度、宽度和通道号)。
详细说明我们是否有 m 个特征的 N 个客户(这里是余额/付款等。)跨越 t 个时间范围(此处为第 1 个月、第 2 个月等。)对于 p 不同的交易(交易是不同的信用额度,如零售卡、抵押贷款等。).因此,单个客户的 m 个特征、t 个时间范围和 p 个交易类似于图像特征阵列的宽度、深度和通道数。准确地说,对于我们的数据,每个客户的维度将是 m * t * p,整个数据的维度将是 Nmt*p。现在,这使得原始结构化数据成为图像帧类型的数据,非常适合应用 CNN 通过卷积运算提取客户间复杂的非线性局部模式。
数据准备:
原始数据集由一张贸易-零售卡组成。为了使它更相关和更具挑战性,我为一个额外的交易——抵押贷款创建了虚拟数据集(将目标变量状态标记为原始数据)。数据比零售卡数据稀疏,值可能不是 100%符合逻辑。最终数据集( CreditDefault.csv )保存在这里。
因此,我们有 30k 个不同的客户 id 和总共 60k 个观察值,前 30k 个观察值是零售卡的,接下来 30k 个是抵押贷款的。
包含数据准备代码的详细解决方案在https://github . com/nitsourish/CNN-automated-Feature-Extraction/blob/master/CNN _ Feature _ Extraction . ipynb。这是这个问题的棘手部分是准备格式(像图像格式)的数据,以便我们可以应用 CNN。准确地说,对于我们的数据,每个客户的维度将是 3(特征数量)* 6(时间范围)* 2(交易),并且将有 30000 个该维度的框架。因此,对于整个数据,它将是一个 30000 * 3(宽度)* 6(深度)* 2(通道数)的数组。所以这些数据对于训练一个卷积网络来说是完美的。
Pipeline- CNN Feature Extraction
准备好特定于渠道的数据后,我们可以看到维度:
shape of channel1(retail)data: (30000, 3, 6, 1)
shape of channel2(mortgage)data: (30000, 3, 6, 1)
在合并这两个阵列之后,数据适合于馈入 CNN 作为输入体,以提取具有非线性交互的复杂特征。
shape of input volume(layer)data: (30000, 3, 6, 2)
现在数据看起来像图像帧数据图像像数据(体积 362 的 30000 个图像帧)。现在,我们需要以一种热编码格式将目标变量(下个月的默认付款)映射到客户 ID。
X = np.concatenate((retail, mort),axis=3)Y = event_id[['default payment next month']].valuesY = to_categorical(Y,2)
In our data we have payment default rate is: 28.402671 percent
在数据中,我们有 28.40%的付款 _ 违约率。虽然事件发生率不是 50%,但我们可以说这是一个相当平衡的数据。所以不需要做任何重量校正
CNN 的特征提取
为了从 CNN 模型中提取特征,首先我们需要用最后的 sigmoid/logistic 密集层(这里是维度 2) w.r.t .目标变量来训练 CNN 网络。训练网络的目标是通过多次向前和向后迭代来识别网络的正确权重,最终尝试最小化二进制交叉熵(误分类成本)。这里我将使用 keras 框架,后端为 TensorFlow(tf)。对于我们的业务问题,AUC 是评估指标,我们将通过最大化每个时期的 AUC 值来进行优化(Keras 没有默认的 AUC 指标。但是,我们可以利用 tf 为 AUC 创建定制的评估函数。)
CNN 架构
在到达最后一个 sigmoid 输出层之前,我们用 4 个 conv 层(conv +激活+池化(可选))和 2 个 FC(全连接层)构建了以下 CNN。
我们利用早期停止来训练 epochs = 100 的模型,以防止过度拟合。使用我的 NVIDIA GTX GeForce 1060 GPU(val _ AUC = 0.8317)进行训练用时不到 10 分钟。
特征提取方法
现在,通过使用预训练的模型,我们可以直接将这些权重应用于数据,去除最后的 sigmoid/logistic 层(在这个问题中,直到 100 维的密集层)。我们可以用这一点来计算任何新数据的相同商业问题的这些特征。我们只需要前馈网络,它将直接映射最终权重来计算某个中间层的要素,而无需再次构建网络。这是一种迁移学习。基于我们对特征数量的要求,我们可以在任何具有期望维度的中间密集层提取特征。对于这个问题,我们将使用一个中间模型来提取特征,直到 CNN 的“特征密集”层。
*#Preparing Indermediate model-removing last sigmoid layer*
intermediate_layer_model = Model(inputs=model.input,outputs=model.get_layer('feature_dense').output)
intermediate_layer_model.summary()
输出层的维度是 100,所以如果我们预测用这个网络对一个新的数据用同样的输入维度,我们可以创建 100 个新的复杂特征。
*#predict to get featured data*
feauture_engg_data = intermediate_layer_model.predict(X)
feauture_engg_data = pd.DataFrame(feauture_engg_data)
print('feauture_engg_data shape:', feauture_engg_data.shape)
feauture_engg_data shape: (30000, 100)
- 我们成功地捕捉了原始变量之间的 100 个复杂的相互作用。
对 feauture _ engg _ data 的进一步探讨
让我们偷偷看看这些特性是否有价值。尽管有一些更好的方法,但为了简单起见,让我们捕捉这些新特性与目标变量“下个月的违约付款”之间的一些二元关系。虽然对于分类目标变量相关性不是 100%正确的方法,但我们将计算所有新值与目标变量的相关性,作为变量的近似值,这对最终模型可能很重要。
*#Sorting correlation values in decsending order*
new_corrs = sorted(new_corrs, key = lambda x: abs(x[1]), reverse = True)
*#Let's see top 10 correlation values*
new_corrs[:10]
[('PAY_1', 0.32479372847862253),
('PAY_2', 0.26355120167216467),
('PAY_3', 0.2352525137249163),
('feat_78', -0.22173805212223915),
('PAY_4', 0.21661363684242424),
('PAY_5', 0.20414891387616674),
('feat_86', -0.20047655459374053),
('feat_6', -0.19189993720885604),
('PAY_6', 0.1868663616535449),
('feat_3', -0.17394080015462873)]
我们可以看到 4 个新创建的变量(feat_78,feat_86,feat_6,feat_3)在与“下个月违约付款”的相关性(伪)方面排名前 10。虽然在此基础上没有什么具体的可以说这些变量的预测强度,但至少这些变量值得进一步研究。
我们还可以根据绝对幅度相关性来查看最高相关变量的 KDE(核密度估计)图。
强调 CNN 用于特征提取
现在关键的问题是为什么 CNN/深度学习方法只用于特征提取。为什么不用它作为分类器呢?有两个主要原因:
局部模式:我们在这个商业问题中使用的数据(适用于我们使用结构化数据的大多数场景),也包括横截面(静态)变量,在这里我们不会发现任何局部模式。所以我们不能用 CNN 对整个数据做分类器。当然,对于具有平移/平移不变性的数据,我们可以使用 CNN 作为最终分类器。
基础设施挑战:构建大规模工业数据并投入生产需要大量基础设施支持(GPU、AWS 等)。),这可能并不适用于每个组织。
模型运行中的延迟:即使有适当的基础设施,相当复杂的深度学习模型的前向传播也要比 XGBoost、RF、SVM 等高效分类器花费更长的时间。事实上,在某些需要超快的实时预测的应用中,最好的解决方案是使用自动技术(如 CNN 特征提取)提取特征,然后添加相对简单的分类器。
Automated Feature Extraction + Classifier
监管挑战:尽管对机器学习/人工智能有着巨大的关注,但在实施预测模型之前,特别是进入银行/保险/金融领域的组织必须通过内部/外部监管流程,这可能需要艰苦的劝说才能在生产系统中使用这些最新技术。相反,如果最终分类器是传统模型,则从建模方法的角度来看,可能不存在挑战。
改进和前进的道路:
作为现代人工智能和深度学习大师,吴恩达准确地说,“……应用机器学习基本上是特征工程。”创建有意义的特征空间的重要性不能被夸大,并且自动化特征工程技术旨在帮助数据科学家解决特征创建的问题,从原始数据集无缝地构建成百上千的新特征。但是,目的不是取代数据科学家。相反,这将使她能够专注于机器学习管道中其他有价值的部分,如功能选择、探索新方法、将健壮的模型交付到生产中等。我们刚刚讨论了自动化特征工程的一种潜在方法。当然还有一些其他类似的技术。我喜欢在未来探索这些。同时渴望听到 CNN 在结构化数据(关系数据库)上的其他应用,在任何其他商业问题上的应用。
基于 CNN 的人脸检测器
Image Source: Google Images
如果你对任何类型的图像处理、计算机视觉或机器学习感兴趣,你很有可能在旅途中的某个地方遇到/使用过 dlib。
根据 dlib 的 github 页面介绍,dlib 是*一个用 C++制作真实世界机器学习和数据分析应用的工具包。*虽然这个库最初是用 C++编写的,但它有很好的、易于使用的 Python 绑定。
我主要使用 dlib 进行 面部检测 和 面部标志检测 。dlib 中的正面人脸检测器效果真的很好。它很简单,开箱即用。
该检测器基于梯度方向直方图(HOG) 和线性 SVM。(解释这个检测器如何工作超出了这篇博文的范围。可能是改天讨论的话题)
虽然基于 HOG+SVM 的人脸检测器已经存在了一段时间,并聚集了大量的用户,但我不确定我们中有多少人注意到了 dlib 中基于 CNN(卷积神经网络)的人脸检测器。老实说,我没有。我是在浏览 dlib 的 github 资源库时偶然发现的。
我当时的想法是,
哇。是否优于现有的检测器?有多准确?它能全方位检测人脸吗?它能在实时视频上运行吗?
嗯,这就是这篇文章的内容。试图找出上述问题的答案。
如果你曾经在 dlib 中使用过基于 HOG 的人脸检测器,你可能知道它不会检测奇数角度的人脸。它应该是一个很好的"正面"人脸检测器,它确实是。
它可以检测到人脸,即使它们的正面并不十分突出。这对于正面人脸检测器来说非常有用。但是你只能期待这么多。
同时,基于 CNN 的检测器能够检测几乎所有角度的人脸。不幸的是,它不适合实时视频。它应该在 GPU 上执行。为了获得与基于 HOG 的检测器相同的速度,您可能需要运行强大的 Nvidia GPU。
然而,这不应该阻止我们在静止图像上尝试它。
在这篇文章的剩余部分,我将向你展示如何在图像上使用基于 CNN 的人脸检测器,并将结果与基于 HOG 的检测器和现成的 Python 代码进行比较。
让我们直接开始编码吧。
入门指南
让我们从导入必要的包开始。如果您尚未安装这些软件包,您可以通过在终端中键入以下命令来安装它们。
pip install opencv-python dlib argparse time
(argparse 和 time 更有可能预装在 Python 中)
如果您没有使用 Python 的虚拟环境,我强烈建议您开始使用它。需要起点的可以查看我之前的帖子。
命令行参数
这个脚本需要两个命令行参数。
- 输入图像
- 模型重量
您可以通过在终端中键入以下命令来获取模型权重文件。
wget [http://arunponnusamy.com/files/mmod_human_face_detector.dat](http://arunponnusamy.com/files/mmod_human_face_detector.dat)
默认情况下,如果您没有提供任何特定的路径,代码会在当前目录中查找模型文件。
例如,您可以通过键入以下命令来运行
python cnn-face-detector-dlib.py -i input.jpg
(如果input.jpg和模型权重文件都在与 python 脚本相同的当前目录中,这将起作用)
或者你可以通过输入,
python cnn-face-detector-dlib.py -i <path-to-image-input> -w <path-to-weights-file>
(python CNN-face-detector-dlib . py-I ~/Downloads/input . jpg-w ~/Downloads/mmod _ human _ face _ detector . dat)
**( 我假设你已经安装了最新版本的 Python。必须是 3.0+)
初始化
*读取提供的输入图像,并检查其类型是否为*无。如果是,打印错误声明并退出程序。
初始化基于 HOG 和基于 CNN 的人脸检测器,我们将应用于输入图像。
对于基于 HOG 的,我们不需要提供任何文件来初始化。它是预先构建在 dlib 内部的。只需调用方法就足够了。
对于基于 CNN 的,我们需要提供权重文件来初始化。
应用猪脸检测
让我们在输入图像上应用检测器。
faces_hog = hog_face_detector(image, 1)
1 是对图像进行向上采样的次数。默认情况下,1 适用于大多数情况。(对图像进行上采样有助于检测较小的面部)
time.time()
可以用来测量以秒为单位的执行时间。
一旦检测完成,我们可以在检测到的人脸上循环。要在检测到的人脸上绘制方框,我们需要向 OpenCV 提供(x,y) —左上角和(x+w,y+h) —右下角。
dlib 和 OpenCV 中的矩形格式有点不同。我们可以在这里使用 skimage 将 dlib 矩形对象直接叠加在图像上。但是当我们用 OpenCV 处理实时视频时,熟悉 dlib 和 OpenCV 之间的转换将会很有帮助。
**cv2.rectangle(image, (x,y), (x+w,y+h), (0,255,0), 2)**
上面的线将在输入图像上检测到的人脸上绘制一个矩形。(0,255,0)代表 BGR 顺序中盒子的颜色(本例中为绿色)。2 代表线条的粗细。
应用 CNN 人脸检测
除了检测器返回矩形对象之外,这个过程与前面的检测器几乎相同。让我们用红色来区分 CNN 检测到的人脸。
显示结果
为了区分 HOG 和 CNN 检测器的检测,让我们在图像的右上角写下哪种颜色是哪种颜色。
cv2.imshow()
将显示运行脚本时的输出图像。
cv2.waitKey()
指定显示窗口关闭前应等待的时间。例如cv2.waitKey(500)
将显示 500 毫秒(0.5 秒)的窗口。如果你不传递任何数字,它会一直等到你按下任何键。
cv2.imwrite()
将输出图像保存到磁盘。
一旦我们完成了显示,释放所有的窗口是一个好的习惯。
完整的代码可在这里获得。
执行时间
给你一个执行时间的概念,对于一个 620x420 的图像, HOG 花费大约 0.2 秒,而 CNN 花费大约 3.3 秒在 CPU 上( Intel i5 双核 1.8GHz )。
Execution time on CPU (in seconds)
根据您的硬件设置和映像的大小,确切的数量可能会有所不同。底线是 HOG 需要不到一秒钟,而 CNN 只需要几秒钟。
检测奇数角度的人脸
重要的部分来了。
基于 CNN 的检测器可以检测到基于 HOG 的检测器可能检测不到的奇数角度的人脸吗?
嗯,答案是“ 差不多 ”。(我还没有经过严格的测试来给出一个自信的“是”。但是据我测试,它对非正面的图像非常有效。
让我们看一些例子,其中基于 HOG 的检测器失败,但 CNN 能够检测。
****
这样的例子不胜枚举。
这并不是说基于 HOG 的检测器对非正面图像完全不起作用。事实上,它确实检测到一些非正面图像,如下图所示。
All the images above are taken from Google Images. I do not own the copyright.
摘要
在这篇文章中,我们研究了 dlib 的基于 CNN 的人脸检测器,并与广泛使用的基于 HOG+SVM 的人脸检测器进行了比较。
我们观察到,基于 CNN 的检测器对于非正面人脸在奇数角度下工作得非常好,而基于 HOG 的检测器很难工作。
不幸的是,基于 CNN 的检测器计算量很大,目前不适合实时视频。如果您已经注意到检测器函数调用(dlib.cnn_face_detection_model_v1()
),它显示 v1 是版本 1。这意味着作者很有可能会推出轻量级的、可用于实时应用程序的下一个版本。
让我们期待 dlib 下一个版本中的轻量级版本。
好了,暂时就这些了。欢迎在下面的评论中分享你的想法,或者你可以在 twitter 上联系我,电话:@ ponnum Samy _ arun。
如果你对这篇文章感兴趣,你可以订阅我的博客来获得新文章上线的通知。(别担心,我每个月只发表一两篇文章)
干杯。
更新:
如果你关心实时性能,检查一下 cvlib 中的人脸检测器。它可以检测(几乎)所有角度的人脸,并能够处理实时输入。
Udacity 驾驶模拟器中的 CNN 模型比较
对于 Udacity 的自动驾驶汽车 Nanodegree 项目 3,他们创建了一个驾驶模拟器,可用于训练和测试自动驾驶模型。我使用模拟器中车辆的前向图像和转向角度,训练并比较了两个架构差异很大的卷积神经网络(CNN)模型。结果表明,对于这种类型的任务,CNN 架构的选择不如所使用的数据和增强技术重要。在结果中可以看到模拟器中模型的并排视频。
方法
我对这个项目的一般方法是使用 Udacity 提供的训练数据和尽可能多的必要的数据增强技术来产生可以在模拟器中成功绕过不同轨道的模型。我尝试了两种不同的 CNN 模型:第一种是他们论文中公认的 NVIDIA 模型:
第二个是我为 Udacity 的开源挑战#2“使用深度学习预测转向角度”开发的类似模型:
https://github . com/Chris gundling/自驾车/树/主/转向模型/社区模型/cg23
这些模型非常不同,因为 NVIDIA 只使用了大约 25 万个参数,而我尝试的原始 VGG 风格模型有近 3400 万个参数。
我试验了各种数据预处理技术、7 种不同的数据扩充方法,并改变了我测试的两个模型中每一个的压差。最后我发现,虽然 VGG 风格的模型驾驶稍微平稳,但需要更多的超参数调整。NVIDIA 的架构在推广到测试轨道(Track2)方面做得更好,付出的努力更少。最终的 NVIDIA 模型没有使用 dropout,并且能够在轨道 1 和 2 上行驶。我在 CPU 上的模拟器中测试时,遇到了较大的 VGG 风格模型的转向延迟问题。我最终将这个模型的图像尺寸从 128X128X3 缩小到 64X64X3,并将全连接层的尺寸减半。这使得 VGG 风格的模型可以在赛道 1 和 2 上行驶。
承认
我要感谢 Vivek Yadav 在这个项目上的精彩帖子。实现的一些数据增强技术是他在这篇文章中描述的想法:
https://chatbotslife . com/using-augmentation-to-mimic-human-driving-496 b 569760 a9 # . yget 03 t5g
我还要感谢 Udacity 的 Yousuf Fauzan 对旋转透视变换的实现。我在“线外”活动中遇到了优素福,他在 Udacity 的挑战#2 中运用了这一技术。该脚本使用旋转矩阵对图像进行不同程度的透视变换。
数据探索
Udacity 提供的数据由 8036 个中心、左侧和右侧组成。jpg 图片,总数据量为 24109 个例子(只有 323 MB 的数据!).这些训练图像都来自轨道 1。这些图像宽 320×高 160。下面的示例显示了从汽车上以一个时间步长拍摄的左/中/右图像。
Left, Center and Right Camera Images Respectively from the Simulator Vehicle on Track 1
Udacity 数据集驾驶日志中提供的转向角绘制如下。转向角以 1/25 的因子进行预缩放,因此它们在-1 和 1 之间(模拟器产生的最大/最小转向角为+/- 25 度)。
Udacity Provided Training Data
我知道模型训练需要一个评估指标,所以我分离出 480 个中心摄像机图像和它们对应的转向角度,用于验证集。这是一个比我通常使用的验证集更小的验证集,但是我不想放弃太多的训练数据。我考虑实现 k-fold 交叉验证来开发一个更好的验证误差度量,但是我发现单个验证集与实际驾驶能力相当一致。我没有使用专门的“测试集”来计算均方根误差,而是将第 2 轨的性能作为我的测试集。
数据预处理
我密切关注了关于收集培训数据的 Slack 的讨论。似乎很多人很难只用他们的电脑键盘来收集“平稳”的驾驶数据。Udacity 的数据在一定程度上解决了这个问题,但基于使用 Udacity 挑战#2 中真实人类转向数据的经验,所提供的模拟器转向数据仍然看起来更像是阶跃。
指数平滑
我通过对驾驶训练数据应用指数平滑来解决这个问题。指数平滑(布朗的方法)有助于产生更平滑的转向过渡,但也会截断和移动数据。我应用了一个缩放比例来恢复一些转向幅度,并将数据移动了几个时间步长,这样转向就不会被延迟。对于前 1200 个训练示例,可以在下面看到指数平滑的结果。
Exponential Smoothing of Udacity Steering Data
正常化
我使用等式(x-128)/128 将所有图像像素值标准化。这会将值规范化为介于-1 和 1 之间。我这样做是为了训练数据、验证数据,并在模拟器驾驶脚本中实现它来测试模型。
裁剪
在增强后,我从每张图像中剪掉了底部的 20 个像素和顶部的 40 个像素。这从图像中移除了汽车的前部和地平线以上的大部分天空。
调整规模
对于 NVIDIA 型号,我与他们的方法保持一致,使用高度为 66 像素、宽度为 200 像素的图像。对于 VGG 风格的模型,我使用了 64 高 64 宽的图片来缩小来自 Udacity 挑战#2 的原始模型。
数据增强
使用了七种不同的增强技术来增加模型在训练期间可以看到的图像数量。这大大降低了模型过度拟合数据的趋势。
增量的另一个主要好处是它们可以模拟恢复。视点变换、图像移位和使用左/右图像都添加了模拟汽车恢复到中心的训练数据,而实际上不必收集任何恢复数据。使用定制的生成器/产量方法在运行中执行扩增。实施的数据扩充技术如下:
- 透视/视点变换 —与 NVIDIA 论文中描述的类似,旋转透视变换应用于图像。我必须对透视变换的转向角度调整做一些调整,因为我发现一对一的透视变换角度对转向角度调整太大了。我决定在-80 到 80 度之间均匀地旋转图像透视。然后,我将视角除以 200,以调整转向角度。这提供了+/- 0.4 单位或 10 度的最大/最小转向角调节。
- 图像翻转 —由于训练数据中的左转弯和右转弯不均匀,因此图像翻转对于模型泛化到轨迹 2 非常重要。当图像翻转时,我也翻转了转向角的符号。
- 左/右摄像机图像 —我使用了来自汽车的左/右摄像机图像,这立即使训练数据的大小增加了三倍。在仔细检查左/右图像并寻找中心图像的共同特征后,我估计左/右图像从中心摄像机水平偏移了大约 60 个像素。基于这些信息,我为这些左/右图像选择了+/- 0.25 单位或+/- 6.25 度的转向角校正。
- —我对图像进行了水平和垂直移动。我的最大/最小水平和垂直位移是每个方向 40 像素。我在模型训练时调整了这个值。考虑到我估计左/右图像会偏移 60 个像素,我对最大水平偏移应用了稍微小一点的转向角校正。垂直移动没有转向角校正。
- 图像亮度 —我通过转换到 HSV 色彩空间和将 V 像素值从 0.5 缩放到 1.1 来调整图像的亮度。这主要是为了帮助推广到轨迹 2,那里的图像通常更暗。
- 图像模糊 —我不确定这种技术对模拟器有多大用处,但这种技术应该有助于模型在使用更多“真实世界”类型的数据时进行归纳,这些数据有时会出现模糊。我使用了可变高斯平滑来模糊图像。
- 图像旋转——与透视变换不同,我对图像进行了小旋转,以模拟相机的抖动。同样,不确定这对模拟器有多大用处,但对自动驾驶汽车上的真实摄像头会有用。
对于视点变换、图像偏移和左/右图像,我还尝试实现了基于速度的转向角校正。我的直觉是,在更高的速度下,转向校正应该更小或更平缓。我惊讶地发现,我不能让这个工作,以及有一个恒定的转向角校正。随着进一步的调整和对左/右相机图像位置的更好的了解,我认为这个方法会起作用。
基于速度的转向调整是通过定义汽车返回中心的 2 秒响应时间来实现的。随着车速的增加,在 2 秒钟内返回中心所需的转向角减小。下图显示了转向角校正的计算方法:
Speed Based Steering Adjustment
数据生成程序
所实现的数据生成器在左/中/右图像之间随机选择,并且还随机选择要应用的增强技术。我发现仅提供增强的训练数据不如用非增强的原始图像和增强的图像的组合来训练模型有效。
首先用较大的转弯训练模型,然后让较小转弯的数据慢慢漏入训练中。这个想法直接归功于其他几个在 Medium 上发布这个想法的学生。如果该模型最初是用低转向角训练的,它将偏向于更直的驾驶,我发现它在最尖锐的弯道中表现不佳。使用数据生成器,下图显示了数据生成器在训练运行期间为前 30 个训练示例生成的图像和增强选项。这些图像已经被裁剪和调整大小。图像标题如下所示:
- ang:图像的转向角度标签
- 凸轮:相机选择(左/中/右)
- 8 月:1 是不增加,2 是增加
- opt:数据扩充选项为: 1。翻转、抖动、模糊、亮度、 2。移动图像和 3。旋转视点变换
Image Augmentation Examples
模型设置和超级参数
我的目标是训练这两个模型中的每一个。NVIDIA type 和 2。具有尽可能多的相似超参数的 VGG 类型。我使用以下参数来训练这两个模型。
- 最大历元数— 8 (5 或 6 个历元的训练通常为 NVIDIA 提供最佳模型,而 VGG 风格只有 1-3 个历元)
- 每个时期的样本数— 23040
- 批量大小— 64
- 优化器—学习率为 1e-4 的 Adam
- 激活—VGG 风格的 Relu 和 NVIDIA 型号的 elu
在 Keras 中实现的 NVIDIA 模型如下所示:
**# Layer 1x = Convolution2D(24, 5, 5, activation=’elu’, subsample=(2, 2), border_mode=’valid’, init=’he_normal’)(img_input)# Layer 2x = Convolution2D(36, 5, 5, activation=’elu’, subsample=(2, 2), border_mode=’valid’, init=’he_normal’)(x)# Layer 3x = Convolution2D(48, 5, 5, activation=’elu’, subsample=(2, 2), border_mode=’valid’, init=’he_normal’)(x)# Layer 4x = Convolution2D(64, 3, 3, activation=’elu’, subsample=(1, 1), border_mode=’valid’, init=’he_normal’)(x)# Layer 5x = Convolution2D(64, 3, 3, activation=’elu’, subsample=(1, 1), border_mode=’valid’, init=’he_normal’)(x)# Flatteny = Flatten()(x)# FC 1y = Dense(100, activation=’elu’, init=’he_normal’)(y)# FC 2y = Dense(50, activation=’elu’, init=’he_normal’)(y)# FC 3y = Dense(10, activation=’elu’, init=’he_normal’)(y)# Output Layery = Dense(1, init=’he_normal’)(y)model = Model(input=img_input, output=y)model.compile(optimizer=Adam(lr=1e-4), loss = ‘mse’)**
模型建筑
这两个模型的模型架构如下所示。如简介中所述,这些模型的主要调整参数是压差。对于 NVIDIA 型号,令人有些惊讶的是,该型号在轨道 1 和 2 上都表现最佳,没有掉线。任何掉线都会导致赛车在弯道中转向不够有力。对于 VGG 型模型,最后一个 conv 层和全连接层中的一些丢失提高了性能。
NVIDIA 型号结构和参数
这使得每个图像向前传递 0.6 MB,向后传递 1.2 MB。使用 64 的批处理大小,在向后传递期间最大内存使用量将是 75 MB。
VGG 型号结构及参数
这使得每个图像向前传递 1.2 MB(约 0.3MB * 4 字节),向后传递 2.4 MB。使用 64 的批处理大小,在向后传递期间最大内存使用量将是 150 MB。将结构和参数与 NVIDIA 的模型进行比较,在近 430 万个参数中,该模型的参数明显多于 NVIDIA 的。
结果
以下视频显示了路线 1 和路线 2 的两种型号的并排比较。虽然 VGG 风格的车型似乎驾驶稍微顺畅,但英伟达的车型在赛道 2 上表现更好。我在使用 VGG 风格模型过度拟合轨道 1 时遇到了麻烦,驾驶行为高度依赖于模型训练的下降和时代数。
以 0.2 节气门开度在轨道 1 上行驶
Track 1 Driving — NVIDIA Model on Left and VGG Style Model on Right
在 0.3 节气门开度的轨道 2 上行驶
Track 2 Driving — NVIDIA Model on Left and VGG Style Model on Right
结论
自从 Udacity 首次发布 Nanodegree Term 1 项目以来,我最期待的就是参与这个项目。由于在道路上收集高质量和高数量的真实世界数据存在困难,因此能够在模拟器中用看似无限的数据训练这些模型可能会在自动驾驶方面取得重大突破。正如在这个项目中所看到的,即使使用相对少量的数据和相当简单的 CNN 模型,车辆也能够成功地通过这两个过程。
我期待着继续这项工作,并一直致力于实施 RNN/LSTM 和强化学习方法来控制转向,油门和刹车。我也很好奇使用真实世界和模拟器数据的组合来训练这些模型,以了解如何在模拟器中训练的模型可以推广到真实世界,反之亦然。
硬件/测试设置
我使用 Udacity 的 CarND AWS AMI 的修改版和 g 2.2x 大 GPU 来训练这些模型,并在我带 CPU 的 Macbook Pro 笔记本电脑上测试这些模型。模拟器被设置为“最快”的设置,屏幕分辨率为 640 X 480。
密码
这个项目的所有代码都是用 Python 实现的,可以在我的 github 档案中找到:
**【https://github.com/chrisgundling **