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

原文:TowardsDataScience Blog

协议:CC BY-NC-SA 4.0

方差差异

原文:https://towardsdatascience.com/differences-in-variance-an-unappreciated-source-of-insight-in-our-data-f9cb0de520c0?source=collection_archive---------49-----------------------

我们数据中一个不受重视的洞察力来源

数据人喜欢平均值。他们喜欢平均值,他们喜欢中间值。平均而言,哪些国家最幸福?患有罕见疾病的人的平均寿命是多少?一个国家的收入中位数是多少?订婚戒指的平均价格是多少?

均值和中位数很棒,因为它们告诉我们数据的总体情况。如果你的数据是正态分布的(通常不是正态分布的),那么平均值会告诉你大部分你需要知道的东西。因此,我们的大多数统计测试,如 t-test、ANOVA 等,都是为了查看平均值,以及它们在不同组之间的差异。但是还有另一个变量,就在我们面前,却没有得到同样多的爱:方差。它有很多东西可以教给我们!

群体差异的两种方式

这里有两组人,给定一些虚构的测试。我绘制了它们的分布图:

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

我只是在 R 中生成了一些随机的、虚假的数据,并用 ggplot 包绘制出来(图片由作者提供)

我们看到各组的均值不同。这种差异可以通过 t 检验或回归分析清楚地发现。但是还有另一种方式可以区分不同的群体:

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

作者图片

这里,组 1 比组 2 具有更宽的分布。它有更大的方差。t-检验或回归不能捕捉到这一点;他们只会告诉你平均而言,这些群体没有什么不同*。但是正如你所看到的,这并不意味着这些群体没有什么不同!下面我将向您展示如何测试这一点。*

你可能认为你以前没有遇到过这个概念。但是你可能听说过 GINI 系数,对吧?它衡量一个社会的财富不平等。概念大致相同:一些社会可能拥有相同的平均财富,但在一个社会中,财富可能分配不均。一个所有人工资完全相同的社会,其方差终究是 0!

真实数据的含义:性别和智商的例子

对方差差异进行研究的少数领域之一是智商领域。研究普遍发现,虽然男女之间的智商差异很小或不存在,但男性的智商差异始终高于女性。下面我用数据来说明这一点,这些数据是我用一项超过 80,000 名苏格兰青少年的研究的真实方差模拟的(多么大的数据集啊!).我还给出了 R 代码,这样你就可以自己做了:

set.seed(140293)male = rnorm(5000,100,14.9)
female = rnorm(5000,100,14.1)

我们设置了一个特定的种子,这样你就能得到和我一样的随机数,结果也能得到相同的随机生成的数据。然后,我创建了两组智商数据,5000 名男性和 5000 名女性,均以 100 为均值呈正态分布。男性数据的标准偏差为 14.9,女性为 14.1。记住标准差是方差的平方根。

接下来,我们将数据放入一个tible中,并对其进行重新格式化,以便于使用,使用 tidyverse R 包很容易做到这一点:

install.packages('tidyverse')
library(tidyverse)IQ_data = tibble(male, female) %>% 
  pivot_longer(cols = c(male, female), 
               names_to = 'sex',
               values_to = 'IQ') %>%
  mutate(sex = factor(sex))

然后我们做一个频率多边形来比较男性和女性的分布:

IQ_data %>% ggplot( aes(x = IQ, colour = sex) )+
  geom_freqpoly(size = 1)

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

作者图片

女性分布的峰值高于男性,表明接近 100 分的女性较多。男性分布在尾部略高,表明有更多的男性智商得分极高和极低。但是差别似乎很小。

t.test(IQ ~ sex, IQ_data)

进行 t 检验,平均智商没有性别差异( p = 0.38)。然而,这些组可能在尾部有所不同。我们来调查一下。

尾比

我们可以通过取高于或低于某个阈值的雄性与雌性的比例来计算出一个尾比。我们将所有智商为 130 或更高(一般认为非常聪明)的个体,统计男女数量。对于智商 70 或更低的人(一般认为不聪明),我们也是这样做的。

IQ_data %>% filter(IQ >= 130) %>% group_by(sex) %>% countIQ_data %>% filter(IQ <= 70) %>% group_by(sex) %>% count

运行代码,你会看到在我们的数据集中有 95 个非常聪明的男性和 66 个非常聪明的女性(59%是男性)。这使得男女比例为 1.44:1。
同样,我们的数据中有 104 名非常不聪明的男性和 84 名女性(55%为男性),男女比例为 1.24。因此,尽管男性和女性平均来说没有什么不同,但在最聪明和最不聪明的群体中,男性更多。

更进一步:Levene 的测试

比率都很好,但我们可能想知道差异是否有统计学意义。对此有一些测试,但最常见的是方差相等的 Levene 测试,这是我从 car R 包中得到的:

install.packages('car')
library(car)
leveneTest( IQ ~ sex, IQ_data)

我们得到的 F 值为 5.54,显著性 p 值为 0.02,证实了我们的结果,即男性的智商比女性高。

含义

通过比较方差,我们还能回答哪些问题?

  • 如果一种药物增加了患者的平均健康水平,但也增加了服药者之间的健康差异,这可能表明该药物对一些人有帮助,但对另一些人没有帮助。
  • 也许你有两种产品在许多商店出售。平均而言,每家商店销售的产品数量可能相同,但一种产品的销售数量差异可能更大,这表明一些商店销售很多,而其他商店销售很少。这可能对理解你的客户和在哪里销售你的产品有所暗示。
  • 不影响一个国家人民平均幸福的政策,如果能减少幸福的方差,可能对社会仍然是好的,我们可以称之为“幸福不平等”。
  • 通常,特别低的方差可能是好产品的标志。罗里·萨瑟兰喜欢争辩说,最好的卫星导航是最小化旅行时间差异的卫星导航,不一定是能找到最短平均旅行时间的卫星导航。当你去机场赶飞机时,你不想要一条可能需要 30 分钟到 2 小时的路线,即使它是平均最快的路线。
  • 在调查妇女和少数民族的代表性时。例如,在所有公司中,女性在高层管理职位中的平均比例可能是 50%,有些人会将其解释为实现了性别平等。然而,如果公司之间的这一比例差异非常大,这可能表明许多公司的女性经理远远超过 50%,而其他公司的女性经理可能会少得多。

结论

我们在这里已经看到,不同的组可以有不同的方差和均值,这可以在我们的数据中产生新的见解。根据我的经验,这确实是一个被忽视的领域,所以很酷的结果可能相对容易找到。它也不需要比你已经有的更多的数据,这很好。如果你发现任何有趣的方差差异,请务必在 Twitter 上给我加标签,这样我就可以看到它们了。我很期待你的发现!

不同的色彩空间作为 CNN 的输入

原文:https://towardsdatascience.com/different-colorspaces-as-inputs-to-cnns-406ae62d1bd6?source=collection_archive---------28-----------------------

通过自定义数据生成器找出在 CNN 中使用不同的色彩空间是否会导致更好的结果,并最终创建一个集合模型。

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

Unsplash 上由鲁维姆·诺加拍摄的照片

我刚刚在另一篇文章中发完一篇牢骚,我忘记了 OpenCV 使用 BGR 格式,CNN 的输出是以 RGB 格式检查的,这浪费了我很多时间,当我有了一个想法,如果将不同色彩空间的图像传递给 CNN 会怎么样,它会如何影响模型?这就是我们要在这篇文章中发现的。

目录

  1. 要求

2.使用的色彩空间

3.代码和结果

  • 导入和加载数据集
  • 创建图像数据生成器
  • 正常 CNN 的结果
  • 迁移学习的结果
  • 创建集合模型

如果你对这个过程不感兴趣,只想知道结果,你可以直接跳到正常的 CNN 部分的结果。

要求

如果你想编码,那么你需要 Tensorflow 和 OpenCV。你可以使用下面显示的代码进行 pip 安装,或者像我一样使用 Google Colab,不需要安装免费的 GPU。

pip install tensorflow
pip install opencv-python

使用的色彩空间

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

照片由埃菲社Unsplash 拍摄

决定使用哪种色彩空间是一项相当简单的任务。我只是打开了 OpenCV 的文档,并选择了所有可以转换的独特文档。我会把它们列出来,并提供额外的阅读链接,如果有人有兴趣了解更多的话。

代码和结果

在开始之前,我想澄清一下,我的目的不是创造一个非常高科技的 CNN 架构来获得最好的准确性,而是比较所有的色彩空间。

导入和加载数据集

选择的数据集是猫对狗的数据集。首先,我们开始导入所有需要的库。

import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv2D, MaxPooling2D, Dropout, Flatten, Dense, Activation, BatchNormalization
import os
import numpy as np
import matplotlib.pyplot as plt
import re
import random
import cv2

下一步是加载数据集并存储所有文件名,然后将这些文件名传递给图像数据生成器,并定义将使用的所有常数。

创建图像数据生成器

创建一个普通的定制数据生成器,带有一个额外的 colorspace 参数,它定义了要转换到哪个 colorspace。cv2.cvtColor用于那个目的。除了 HSV 的色调矩阵被除以 180 之外,所有的图像都被调整到它们需要的尺寸,并通过除以 255 进行归一化。为图像和标签创建 NumPy 数组,并生成它们。

使用 Conv2D、max pooling、batch normalization 和 dropout 层创建基本的 CNN,这些层最终被展平,密集层给出具有 sigmoid 激活函数的输出。该模型是使用 Adam 编译的。如果你想创建更好的 CNN,你可以参考我之前的文章。只要用所需的值来拟合模型,我们就完成了。

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

正常 CNN 的结果

如果我们观察训练精度和损失,除 HSV 之外的所有色彩空间给出了非常相似的更好的结果。然而,也可以观察到我们的模型是过度拟合的,所以 HSV 不能直接被怀疑。此外,对于验证集,HSV 中的图像可以比它们的对应图像学习得更快,但是对于大量的时期,结果是均匀的,并且选择特定的一个是非常困难的。

迁移学习的结果

如上所述,迁移学习模型非常简单。使用预训练的 MobileNetV2,其层被设置为不可训练的,并且全局平均池层之后是用于输出的密集层。

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

迁移学习中不可训练层的结果

只有 BGR 和 XYZ 色彩空间给出了好的结果,而 HSV 给出了最差的结果。但是为什么会这样呢?我们使用预先训练好的层,这些层习惯于看到 RGB 风格的输入,XYZ 与 RGB 非常相似,所以只有它们给出了好的结果,而 HSV 是一个圆柱形系统,在相似性方面离 RGB 最远,因此给出了最差的结果。

因此,我们通过改变base_model.trainable = True使整个预训练网络可训练,让我们看看现在会发生什么。

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

所有可训练层的迁移学习的结果。

即使现在 BGR 和 XYZ 色彩空间从一开始就表现很好,然而,他们被所有其他色彩空间赶上了,除了 HSV,它再次表现最差。除了 HSV 之外,几乎没有太多颜色空间可供选择,所以让我们创建一个集合模型,看看它是否能提高性能。

创建集合模型

如果我们可以实现性能的提高,那么我们也将知道不同的色彩空间得到不同的分类为正确或错误的图像,这将意味着改变色彩空间对模型有一些影响。我们将创建一个非常简单的集合模型,取所有模型的预测概率的平均值,将其转换为整数,并根据真实标签对其进行评估。

accuracy for bgr  : 0.9596773982048035
accuracy for ycrcb  : 0.9536290168762207
accuracy for lab  : 0.9415322542190552
accuracy for luv  : 0.9546371102333069
accuracy for xyz  : 0.9546371102333069
Ensemble accuracy: 0.966

因此,可以说,改变色彩空间可能会也可能不会提高准确性,特别是如果你是随机检查,并且没有分配随机种子来重复结果,因为有很多起伏。然而,如果你想要更精确一点,你可以尝试其他色彩空间,甚至是整体模型。

如果你想玩的话,你可以在这里和这里找到 gist 链接到 colab 文件的链接。

张量流中不同类型的归一化

原文:https://towardsdatascience.com/different-types-of-normalization-in-tensorflow-dac60396efb0?source=collection_archive---------22-----------------------

了解 Tensorflow 中的批次、组、实例、层和权重标准化,以及解释和实现。

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

来源

当规范化被引入深度学习时,它是下一件大事,并大大提高了性能。对你的模型来说,做得正确是一个至关重要的因素。曾经有过这样的疑问,不管批处理规范化是什么,它是如何提高性能的。还有什么替代品吗?如果你像我一样有这些问题,但从来没有烦恼,只是为了在你的模型中使用它,这篇文章将澄清它。

目录

  • 批量标准化
  • 群体规范化
  • 实例规范化
  • 图层规范化
  • 权重标准化
  • Tensorflow 中的实现

批量标准化

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

Kaspars UpmanisUnsplash 上拍摄的照片

最广泛使用的技术为表演带来奇迹。它是做什么的?嗯,批量标准化是一种标准化方法,通过小批量标准化网络中的激活。它计算小批量中每个特征的平均值和方差。然后减去平均值,并将该特征除以其最小批量标准偏差。它还有两个额外的可学习参数,激活的平均值和幅度。这些用于避免与零均值和单位标准偏差相关的问题。

所有这些看起来很简单,但是为什么会对社区产生如此大的影响?它是如何做到的?答案还没有完全想出来。有些人说它改善了内部协变量的转移,而有些人不同意。但我们确实知道,它使损失表面更平滑,一层的激活可以独立于其他层进行控制,并防止重量到处乱飞。

既然如此,为什么我们还需要别人呢?当批量较小时,小批量的均值/方差可能远离全局均值/方差。这引入了大量噪声。如果批量大小为 1,则不能应用批量标准化,并且它在 RNNs 中不起作用。

群体规范化

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

照片由哈德逊·辛慈Unsplash 上拍摄

它计算每个训练示例的通道组的平均值和标准偏差。所以它基本上与批量大小无关。在 ImageNet 数据集上,组规范化与批处理大小为 32 的批处理规范化的性能相当,并且在较小的批处理大小上优于它。当图像分辨率很高并且由于内存限制而不能使用大批量时,组归一化是一种非常有效的技术。

对于图像识别任务,实例规范化和层规范化(我们将在后面讨论)都不如批量规范化,但不是组规范化。层规范化考虑所有通道,而实例规范化只考虑导致其崩溃的单个通道。所有的通道并不同等重要,就像图像的中心到它的边缘,同时也不是完全相互独立的。因此,从技术上来说,组规范化结合了两者的优点,并消除了它们的缺点。

实例规范化

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

照片由埃里克·沃德Unsplash 拍摄

如前所述,它计算每个训练图像的每个通道的平均值/方差。它用于风格转换应用,也建议作为 GANs 批量标准化的替代。

图层规范化

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

照片由免费使用声音Unsplash

批次归一化是对各批次维度的输入进行归一化,而图层归一化是对各要素地图的输入进行归一化。再次像组和实例标准化一样,它一次对单个图像起作用,即它的平均值/方差是独立于其他示例计算的。实验结果表明,该算法在 RNNs 上表现良好。

权重标准化

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

Kelly SikkemaUnsplash 上拍摄的照片

我认为描述它的最好方式是引用它的论文摘要。

通过以这种方式重新参数化权重,我们改进了优化问题的条件,并且我们加速了随机梯度下降的收敛。我们的重新参数化受批处理规范化的启发,但不会在小批处理中的示例之间引入任何依赖关系。这意味着我们的方法也可以成功地应用于循环模型,如 LSTMs,以及噪声敏感的应用,如深度强化学习或生成模型,批量归一化不太适合这些应用。尽管我们的方法简单得多,但它仍然大大提高了整批规范化的速度。此外,我们的方法的计算开销更低,允许在相同的时间内采取更多的优化步骤。

Tensorflow 中的实现

如果我们不能实现它,理解理论又有什么用呢?所以我们来看看如何在 Tensorflow 中实现它们。使用稳定 Tensorflow 只能实现批量规范化。对于其他人,我们需要安装 Tensorflow 附加组件。

pip install -q  --no-deps tensorflow-addons~=0.7

让我们创建一个模型,并添加这些不同的规范化层。

import tensorflow as tf
import tensorflow_addons as tfa**#Batch Normalization** model.add(tf.keras.layers.BatchNormalization())**#Group Normalization** model.add(tf.keras.layers.Conv2D(32, kernel_size=(3, 3), activation='relu'))
model.add(tfa.layers.GroupNormalization(groups=8, axis=3))**#Instance Normalization** model.add(tfa.layers.InstanceNormalization(axis=3, center=True, scale=True, beta_initializer="random_uniform", gamma_initializer="random_uniform"))**#Layer Normalization** model.add(tf.keras.layers.LayerNormalization(axis=1 , center=True , scale=True))**#Weight Normalization** model.add(tfa.layers.WeightNormalization(tf.keras.layers.Conv2D(32, kernel_size=(3, 3), activation='relu')))

当在组规范化中指定组的数量时,确保其值是当时存在的特征映射数量的完美除数。在上面的代码中是 32,所以它的约数可以用来表示要分成的组的数量。

现在我们知道如何使用它们,为什么不试一试呢?我们将使用具有简单网络架构的 MNIST 数据集。

model = tf.keras.models.Sequential()
model.add(tf.keras.layers.Conv2D(16, kernel_size=(3, 3), activation='relu', input_shape=(28, 28, 1)))
model.add(tf.keras.layers.Conv2D(32, kernel_size=(3, 3), activation='relu'))
#ADD a normalization layer here
model.add(tf.keras.layers.Conv2D(32, kernel_size=(3, 3), activation='relu'))
#ADD a normalization layer here
model.add(tf.keras.layers.Flatten())
model.add(tf.keras.layers.Dense(128, activation='relu'))
model.add(tf.keras.layers.Dropout(0.2))
model.add(tf.keras.layers.Dense(10, activation='softmax'))
model.compile(loss=tf.keras.losses.categorical_crossentropy,
optimizer='adam', metrics=['accuracy'])

我用 5 种不同的批量大小,即 128、64、32、16 和 8,尝试了所有的标准化。结果如下所示。

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

培训结果

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

测试精度

由于数据集偏差和运气等差异,我不会深入研究这些结果!再训练一次,我们会看到不同的结果。

如果你想更详细地了解这些或者发现更多的标准化技术,你可以参考这篇文章,它对我写这篇文章有很大的帮助。如果您想进一步改善您的网络,您可以阅读以下内容:

[## 超越 Tensorflow 2 中的标准 CNN

使用复杂的架构生成更深层次的模型,并了解不同的层,从而使模型更好。

towardsdatascience.com](/beyond-the-standard-cnn-in-tensorflow-2-a7562d25ca2d)

不同类型的时间序列分解

原文:https://towardsdatascience.com/different-types-of-time-series-decomposition-396c09f92693?source=collection_archive---------4-----------------------

以及为什么你可能用错了。

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

照片由在 Unsplash 上拍摄

介绍

布拉哈姆·马斯洛写道,“我想,如果你唯一的工具是一把锤子,那么把一切都当成钉子是很诱人的”。

这是有抱负的数据科学家在分析时间序列数据时发现自己所处的情况。Python 的 Statsmodels 库中的 seasonal _ decompose 函数就是锤子,每一个时间序列数据都只是另一个钉子。

分解我们的时间序列是提高预测准确性和创造因果洞察力的重要一步。

seasonal_decompose 函数可以用于时间序列分解,但是还有其他更好的方法。而且,作为数据科学家,我们总是希望使用好的东西。

亚伯拉罕·马斯洛写道,“我想,如果你唯一的工具是一把锤子,那么把一切都当成钉子是很有诱惑力的”。

本文有以下目标:

  1. 解释时间序列分解的重要性。
  2. 解释季节性分解函数的问题。
  3. 介绍时间序列分解的替代方法

为什么要分解我们的时间序列数据?

时间序列分解是指我们将时间序列数据分解为以下四个部分的方法:

  1. 趋势[ T
  2. 循环[ C ]
  3. 季节性
  4. 余数[ R

1)趋势

时间序列的趋势是指时间序列移动的大致方向。时间序列可以有正趋势或负趋势,但也可以没有趋势。

例如,美国(和许多发达经济体)的 GDP 增长率没有趋势,因为经济力量使增长率保持相对稳定。

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

来自世界银行的数据。

2)循环

时间序列数据的周期是指其以不一致的频率上升和下降的趋势。我们经常使用时间序列的周期部分来讨论经济数据中的商业周期。

3)季节性

时间序列的季节性成分与其周期成分相似,除了一个重要的区别:季节性成分指的是以一致的频率上升和下降的数据。

旅游业对季节性因素非常熟悉。一个国家的旅游业在温暖的月份里收入很高,然后当第一次有下雪的迹象时,它的收入慢慢地向悬崖的边缘移动。

4)余数

剩余部分是去除趋势、周期和季节成分后的时间序列数据。是上述成分无法解释的时间序列数据中的随机波动。

在预测时,使用“季节性调整”时间序列是有利的,这只是一个去除了季节性因素的时间序列。这使得预测者可以专注于预测数据的总体趋势。

使用时间序列分解的第二个原因是为了识别季节成分中任何有趣的行为。然后,我们可以研究为什么我们的数据以这种方式移动。

时间序列分解常用方法的问题是

有趣的是,Statsmodels 知道有比通常的季节性分解函数更好的方法来分解时间序列数据。

他们警告我们(强调是我自己的):

这个[季节性 _ 分解]是一个天真的分解。应首选更复杂的方法— Statsmodels 文档

季节性分解使用经典的分解方法,有两种类型:加法和乘法。

加法分解

加法分解认为时间序列数据是其组成部分之和的函数。因此,

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

其中 Y 是时间序列数据,T 是趋势周期分量,S 是季节分量,R 是余数。

重新排列给了我们,

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

乘法分解

乘法分解认为时间序列数据是其组成部分的乘积的函数,而不是总和。因此,

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

重新排列给了我们,

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

我们通常可以从其变化中识别出一个加法或乘法时间序列。如果季节分量的大小随时间变化,那么这个序列就是乘法序列。否则,该系列是可加的。

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

图片来自尼古拉·考伦茨

请注意,从 2011 年开始,在加法时间序列中,季节性成分的大小(序列的最大值与红线之间的差值)相对恒定。

然而,在乘法序列中,季节性成分的大小随着时间的增加而增加。

注意:识别一个数列是加法还是乘法比上面的图片显示的要复杂。通常,时间序列的一个部分可能是相加的,而其他部分是相乘的。

例如,你可以合理地拥有一个时间序列,其中

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

和,因此,

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

时间序列分解的经典方法有几个问题:

  1. 它使用双边移动平均线来估计趋势周期。因此,前几个观察值和后几个观察值在趋势周期中是不存在的。
  2. 它假设季节成分在整个系列中是恒定的。虽然这对于短期来说可能是一个准确的假设,但是对于长期来说,这种假设就站不住脚了。例如,航空旅行和其他交通方式的创新为许多经济体的旅游业带来了根本性的变化;因此,假设它的季节变化在历史上一直保持稳定是不正确的。
  3. 趋势线过度平滑了数据。因此,它对剧烈波动没有反应。这导致了大的剩余分量。

幸运的是,有解决上述问题的时间序列分解方法。

传统方法的替代方法

X11 分解

X11 分解为所有观察值创建了一个趋势周期。同样,X11 分解允许季节性成分缓慢变化。

我不知道任何实现 X-11 过程的 Python 库。然而,这可以通过 R 的季节性软件包中的 seas 函数相对容易地完成。您也许可以使用 rpy2 库来复制 Python 中的 R 代码。(一旦我找到解决办法,我将在本周晚些时候更新这篇文章)。

seas(data, x11 = "")

让我们比较 X11 分解和经典分解的结果。

在 R 中:

library(forecast)
library(ggplot2)
autoplot(AirPassengers)

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

国际航空旅客人数时间序列(千人)

因为季节成分随时间增加,所以我们知道应该使用乘法分解。

mfit <- decompose(x = AirPassengers, type = "multiplicative")
autoplot(mfit)

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

航空乘客数据的乘法分解

请注意,季节性成分是不变的,余数成分有许多大值,趋势线在数据集的开始和结束处缺少一些观察值。

现在,如果我们使用 X11 分解,

fit <- seas(x = AirPassengers, x11 = "")
autoplot(fit)

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

X11 分解

您应该注意到三件事:

  1. 季节性因素随着时间的推移而增加,从而反映了自 1950 年以来航空业的根本变化。
  2. 余数部分比我们进行经典分解时的情况要小。这是因为我们的趋势线非常适合原始数据。
  3. 趋势线中没有遗漏的观察值。

STL 分解

X11 的一个问题是它只处理月度和季度数据。

另一个原因是它对异常值不够稳健。

因此,在 1990 年,密歇根大学和贝尔实验室的研究人员发表了“STL:基于黄土的季节趋势分解过程”。

与 X11 方法相比,STL 时间序列分解方法具有以下优势:

  1. 它处理任何类型的季节性。
  2. 用户可以控制季节性成分的变化率。
  3. 它对异常值是鲁棒的。

我们可以用 Python 中的 STL 函数实现 STL。

from statsmodels.tsa.seasonal import STL

我们可以通过向 STL 函数中的趋势季节性参数传递一个整数来改变趋势周期和季节性成分的平滑度。默认情况下,季节参数设置为 7(也建议您使用大于或等于 7 的季节平滑器)。

如果未指定趋势值,则 Statsmodels 会使用大于的最小奇整数来计算趋势值

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

季节性平滑的选择取决于你。整数越大,季节性因素就越“平滑”。这使得数据中较少的变化归因于季节性因素。因此,您必须确定数据中有多少变化可以合理地归因于季节性因素。

STL 方法的创始人建议使用季节性诊断图,然后用不同的平滑值进行试验,以确定哪个值似乎是正确的。不幸的是,Python 中没有这种实现(但是 R 中有)。

用 Python 实现 STL:

from statsmodels.tsa.seasonal import STL
import matplotlib.pyplot as plt
import pandas as pddf = df[:len(df) - 1] # Removes the last row in the data setcolumns = ['Month', 'Passengers']
df.columns = columns
df.head()

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

df = df.set_index('Month') # Set the index to datetime object.
df = df.asfreq('MS') # Set frequency# Set robust to True to handle outliersres = STL(df, robust = True).fit() 
res.plot()
plt.show()

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

季节成分的变化比我们使用 X11 分解时变化更快。因为 STL 分解对异常值也是稳健的,所以它对季节分量的估计可能比 X11 的估计更准确。

请随意在 STL 函数中试验季节性参数。请确保您使用的是奇数整数。

如果你想对数据进行季节性调整,那么从原始数据中减去季节性因素。

也就是说,

df['Seasonally Adjusted'] = df['Passengers'] - res.seasonal
df.head()

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

结论

现在你知道季节分解的其他方法了。与 Statsmodels 的 seasonal_decompose 函数相比,这些替代方法可以更好地估计时间序列的季节性和趋势周期成分。

您还可以使用这些方法获得更准确的预测,并更好地识别数据集中的有趣模式。

文献学

[1] Hyndman,R.J .,& Athanasopoulos,G. (2018) 预测:原则与实践,第二版,OTexts:澳洲墨尔本。OTexts.com/fpp2.

[2]https://www . stats models . org/stable/generated/stats models . TSA . seasonal . seasonal _ decompose . html

[3]安德鲁·萨特克利夫。(1993)“X11 时间序列分解和抽样误差”,澳大利亚统计局:澳大利亚墨尔本。

[4] Cleveland,R.B .,Cleveland W.S .,McRae J.E .,& Terpenning,I. (1990 年)“短期负荷预测:基于黄土的季节性趋势分解程序”,《官方统计期刊》。

[5] Gardner,Dillon r .(2017)《STL 算法讲解:STL 第二部分》

笔记

  1. 趋势项可以是非线性的。还有,有两种趋势:随机的和确定的。我将在以后的文章中讨论这些。
  2. seasonal_decompose 函数还可以估计单边移动平均值;然而,这导致在序列开始时比使用双边方法时有更多的缺失观测值,而在序列结束时没有缺失观测值。

资料组

【https://www.kaggle.com/rakannimer/air-passengers

将数据导入 R 的不同方式

原文:https://towardsdatascience.com/different-ways-of-importing-data-into-r-2d234e8e0dec?source=collection_archive---------32-----------------------

如何在 R 中处理不同类型的数据

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

卡斯帕·卡米尔·鲁宾在 Unsplash 上拍摄的照片

我在 DataCamp 完成了两门课程,这两门课程向我介绍了将数据导入 r 的概念。我想详细讨论一下我在课程中学到的一些方法。让我们开始吧。

数据可以来自许多来源。一些最常见的是

  • 平面文件— CSV、txt、tsv 等
  • 来自 Excel 的数据
  • 数据库— Postgresql、Mysql 等
  • 统计软件——SAS、SPSS、STATA

平面文件

什么是平面文件?

根据维基百科,平面文件数据库是存储在一个名为平面文件的文件中的数据库。记录遵循统一的格式,并且没有用于索引或识别记录之间关系的结构。文件很简单。平面文件可以是纯文本文件或二进制文件。

下面列出的一些包将帮助您在 r 中处理平面文件。

实用工具

默认情况下,当您加载 r。

  • read.table():主功能。读取表格格式的文件并从中创建数据框。它提供了许多参数来对输入的数据进行分类。
  • read.csv():read . table()的包装函数。用于读取逗号分隔(CSV)文件。
  • read.delim():用于读取制表符分隔文件的包装函数。如果文件中的数字使用句点(。)作为小数。
  • read.csv2() : read.csv()和 read.csv2()是相同的。唯一的区别是,它们是根据您在数字中使用句点还是逗号作为小数点来设置的。
  • read.delim2():当文件中的数字使用逗号(,)作为小数时,使用 read.delim2。

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

read.csv() 功能的输出

专业包

readr

这个包让我们的生活更轻松。它比 utils 包更快、更方便、更高效。我总是倾向于使用这个。

read_r 支持七种文件格式,具有七种功能:

  • [read_csv()](https://readr.tidyverse.org/reference/read_delim.html):逗号分隔(CSV)文件
  • [read_tsv()](https://readr.tidyverse.org/reference/read_delim.html):制表符分隔的文件
  • [read_delim()](https://readr.tidyverse.org/reference/read_delim.html):通用分隔文件
  • [read_fwf()](https://readr.tidyverse.org/reference/read_fwf.html):定宽文件
  • [read_table()](https://readr.tidyverse.org/reference/read_table.html):表格文件,其中各列由空格分隔。
  • [read_log()](https://readr.tidyverse.org/reference/read_log.html):网络日志文件

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

read_csv() 功能的输出

Tibbles 的 readr 包工作。根据文档,Tibbles 数据帧,但是它们调整了一些旧的行为以使生活变得更简单。打印输出还显示了 read.csv 输出中缺少的列类。

数据表

作者 Matt Dowle & Arun Srinivasan 的 data.table 的关键指标是速度。这个包主要是关于数据操作的,但是它还有一个非常强大的功能,可以将数据读入 R: fread()。

如果你有很大的文件要导入到 R 中,你可以使用 data.table 包。

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

fread() 功能的输出

Fread()可以自动处理名称。它还可以推断列类型和字段分隔符,而不必指定这些。它是 read.table()的改进版本,速度非常快,更加方便,并增加了更多功能。

擅长

数据分析中最常用的工具是 Microsoft Excel。excel 文件的典型结构包含带有表格数据的不同工作表。

我们需要浏览这些文件,然后从中导入一些数据。r 提供了两个函数来处理这个问题。

  • **excel_sheets()** : 探索不同的工作表

结果是一个简单的字符向量,它返回 excel 文件中工作表的名称。

  • **read_excel()**:将数据导入 R

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

read_excel()函数的输出

默认情况下,第一个工作表作为 tibble 导入。我们可以通过使用索引或设置工作表参数来显式指定要导入的工作表。下面的两个调用做同样的工作。

然而,手动加载每一个工作表,然后将它们合并到一个列表中会非常繁琐。幸运的是,您可以使用[**lapply()**](http://www.rdocumentation.org/packages/base/functions/lapply) 来自动执行这个操作。这个函数返回一个相同长度的列表。

XL 连接

由马丁·斯图德开发。它充当了 R 和 Excel 之间的桥梁。它允许用户执行任何活动,如编辑工作表、格式化数据等。在 R 内部的 Excel 上,它可以处理 XLS 和 XLSX 文件。XLConnect 工作在 Java 之上。确保您已经安装了所有的依赖项,如 Java 开发工具包(JDK ),并在 r

在使用软件包之前安装它,下面的命令将为您完成这项工作:

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

XLConnect 载入工作区

**loadWorkbook()**:该函数将一个 Microsoft Excel 文件加载到 R 中,可以对其进行进一步操作。将 create 参数设置为 True 将确保在文件尚不存在时创建该文件。

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

loadWorkbook() 函数的结构

这个对象实际上是 R 和 Excel 之间的桥梁。在 R 中构建工作簿后,您可以使用它来获取它所链接的 Excel 文件的信息。一些基本功能是

  • get_Sheets() :蒂耶函数从 excel 文件中以列表形式返回工作表。

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

getSheets() 的输出

  • readWorksheet() :允许用户从指定的工作表中读取数据,只需在函数的工作表参数中给出工作表的名称。

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

readWorksheet() 的输出

这个函数最好的部分是你可以指定从哪一行和哪一列开始读取信息。

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

readWorksheet() 的输出

PS:在对数据集执行任何操作之前,确保数据集被导入到工作目录中。

关系数据库

关系数据库是数据项之间具有预定义关系的集合。这些项目被组织成一组具有列和行的表格。表用于保存关于要在数据库中表示的对象的信息。

开源 : MySQL,PostgreSQL,SQLite

专有 : Oracle 数据库,微软 SQL Server

根据您想要连接的数据库类型,您必须在 r 中使用不同的包。

MySQL: RMySQL

PostgreSQL: RPostgreSQL

Oracle 数据库:ROracle

DBI 为 R 和关系数据库管理系统之间的通信定义了一个接口。这个包中的所有类都是虚拟的,需要通过各种 R/DBMS 实现来扩展。

用更专业的术语来说,DBI 是一个接口,RMySQL 是实现。

像往常一样,让我们先安装包并导入库 DBI。安装 RMySQL 将自动安装 DBI。

第一步是创建到远程 MySQL 数据库的连接。你可以这样做

现在我们已经连接到数据库,可以访问其中的内容了。以下函数帮助我们读取、列出、查询和执行数据库上的其他操作。

  • dbListTables :这个函数让用户列出数据库中的表格。这个函数需要连接对象作为输入,并输出一个带有表名的字符向量。

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

  • dbReadTable :读取所需的表格,并将结果显示为数据帧。

选择性导入

我们可以用两种方法做到这一点

  • 读取整个表并使用 subsetting 函数对数据进行子集化。
  • **dbGetQuery()**:这个函数发送一个查询,检索结果,然后清除结果集。这里的字符串是一个常见的 SQL 查询。
  • dbFetch() :这个函数有助于从以前执行的查询中获取记录,并允许我们指定每次获取的最大记录数。

注意:dbSendQuery() 将查询发送到数据库,要获取它,我们应该使用 dbFetch()。它的工作与 dbGetQuery()相同。当您想要逐块加载大量记录时,这可能会很有用。

不要忘记断开它。

从互联网上下载文件意味着发送一个 GET 请求并接收你所请求的文件。

读取 CSV、TSV 或文本文件时,我们可以在函数中以如下方式将 URL 指定为字符串。

Excel 文件

r 不知道如何处理直接来自网络的 excel 文件,所以我们需要在导入之前下载它。文件下载后,我们可以使用read_excel功能读取和导入文件。

JSON 数据

JavaScript Object Notation (JSON)是一种非常简单、简洁且结构良好的数据形式。此外,它是人类可读的,也很容易为机器解释和生成。这就是为什么 JSON 被用于与 API(应用程序编程接口)通信。

jsonlite 包

它是一个健壮的、高性能的 JSON 解析器和生成器。

让我们先安装软件包。成功安装后,我们将使用fromJSON函数从 URL 获取数据。

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

包含 JSON 数据的 r 列表

软件包的另一个有趣的功能是美化和缩小。它们主要用于格式化 JSON 数据。

  • 美化/缩小:美化给 JSON 字符串增加缩进;minify 删除所有缩进/空白。

统计软件包

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

  • 避风港

这个包用来读取 SAS,STATA,SPSS 数据文件。它通过包装 Evan Miller 的 ReadStat C 库来实现这一点。这个软件包使用起来非常简单。

让我们先安装包并加载库。

  • read_sas:该函数读取 SAS 文件。

同样,对于其他类型的文件,我们可以使用read_stata()read_dta()read_por()read_sav()

  • 国外

由 R 核心团队编写。它在命名和使用上不太一致,但它支持许多外来数据格式,如 Systat、Weka 等。我们还可以将数据导出为各种格式。

让我们安装软件包并加载库。

SAS

这个包的缺点是不能导入. sas7bdat 。它只能导入 SAS 库(。xport)

STATA

这个包裹可以阅读。STATA 版本 5 到 12 的 dta 文件。

convert.factors :将带标签的 STATA 值转换为 R 因子。

convert.dates :将 STATA 日期和时间转换为 Date 和 POSIXct。

缺失类型:

如果为 FALSE,则将所有类型的缺失值转换为 NA。

如果为真,存储属性中值是如何丢失的。

SPSS

use.value.labels :将带标签的 STATA 值转换为 R 因子。

to.data.frame :返回 dataframe 而不是 list。

结论

这是关于将基本数据导入 r 的。加载数据是任何过程的第一步,比如分析、可视化和操作。

有很多方法可以将数据导入 r。

我主要使用 read_excel 和 read_csv。

你用什么?评论下来。

感谢阅读!

使用 pandas 创建、子集化和组合数据框的不同方式

原文:https://towardsdatascience.com/different-ways-to-create-subset-and-combine-dataframes-using-pandas-e7227330a7f1?source=collection_archive---------21-----------------------

熊猫中一些最有用的方法和功能的非常需要的简明指南

介绍

在最近 5 年左右的时间里,python 是新的最热门的编码语言,每个人都在努力学习和研究它。其中一个最大的原因是程序员和数据科学家的庞大社区,他们不断地使用和开发语言和资源,使更多人的生活变得更容易。然而,为了有效地使用任何语言,在进入该语言的广阔世界之前,通常需要了解某些框架。对于 python 来说,有三个这样的框架或者我们称之为库,它们被认为是基石。它们是熊猫、Numpy 和 Matplotlib。在这篇文章中,我们将探讨熊猫的一些有用的方法或功能,以了解熊猫是如何做事情的。

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

克里斯里德在 Unsplash 上的照片

由于 pandas 具有广泛的功能,我将只介绍一些最重要的功能。在本文中,我们将试图回答以下问题:

  • 什么是包?
  • 如何安装包和调用包?
  • 熊猫是什么?
  • 什么是 dataframe 和 series?
  • 如何用多种方式初始化一个 dataframe?
  • 如何选择/子集化/切片数据帧?
  • 如何组合两个数据帧?

python 新手,想在继续学习之前先学习基础知识吗?你可以看看我写的另一篇文章,这篇文章解释了数据科学的 python 基础。

[## 数据科学的 Python 基础

用 Python 实现数据科学所需的构件

medium.com](https://medium.com/analytics-vidhya/basics-of-python-for-data-science-7c165c76123f)

知道 python 的基础,但不确定所谓的“包”是什么?别担心,我会掩护你的。如果你已经知道什么是软件包,你可以跳到“熊猫数据框架和系列”部分来看看直接覆盖的主题。

什么是包裹?
在大多数现实世界的应用程序中,实际需求需要一个人做大量的编码来解决一个相对常见的问题。例如,机器学习是一个真实世界的应用程序,世界各地的许多人都在使用,但大多数情况下可能有一个非常标准的方法来解决问题。为了节省编码人员和那些想开发这种代码的人的大量时间,所有这种应用程序或代码片段都被编写并在线发布,其中大多数通常是开源的。这些代码的集合被称为包。这个定义是我想用简单的术语让你理解什么是包,它绝不是一个正式的定义。

如何安装包和调用包?
熊猫就是这样一种包装,它无疑是世界上使用最多的包装之一。个人必须先下载这些软件包,然后才能使用它们。使用终端输入 pip 命令可以很容易地做到这一点。一旦下载,这些代码就存在你的电脑里,但不能直接使用。必须做一些被称为“导入”包的事情。简单来说,我们用这个语句告诉计算机“嘿,计算机,我将在这个文件/笔记本中使用这个名字的下载代码”。有了这个,计算机就会明白它必须在下载的文件中查找该包中所有可用的功能。

使用 pip 命令格式化安装包:pip 安装包名
调用包:导入包名作为别名

什么是熊猫?
Pandas 是多个函数和自定义类的集合,称为 dataframes 和 series。它无疑是最常用的软件包之一,世界各地的许多数据科学家都使用它进行分析。这也是大多数数据科学学生学习的第一个包。让我们详细看看使用这个软件包可以做些什么。

**注意:**我们不会查看 pandas 提供的所有功能,而是查看一些人们在日常工作中经常使用和可能需要的有用功能。

熊猫数据框和系列

在 Pandas 中,主要有两种数据结构,称为 dataframe 和 series。把 dataframes 想象成你常规的 excel 表格,但是在 python 中。基本上,它是一个二维表,其中每一列都有一种数据类型,如果一列中有多个值,很有可能会转换为 object 数据类型。对于 series,它相当于数据帧中的一列信息,有点类似于列表,但它是 pandas 的原生数据类型。

注意:每个包通常都有其对象类型。这可以在尝试打印类型(对象)时找到

让我们看下面的例子来更好地理解它们的区别。

正如我们在上面看到的,series 创建了一系列列表,但实际上创建了 2 个一维值。另一方面,dataframe 根据需要在二维空间中创建了一个表格样式值。

既然我们已经有了基础知识,现在让我们开始深入学习吧。

创建基本数据框架

在进入任何奇特的方法之前,我们应该首先知道如何初始化数据帧和不同的方法。让我们首先看看如何使用不同的方法创建一个简单的 dataframe,其中一列包含两个值。在这样做之前,确保有进口熊猫作为“进口熊猫作为 pd”。请注意,这里我们使用 pd 作为熊猫的别名,大多数社区都使用它。

如上所示,声明或初始化数据帧的基本语法是 pd。DataFrame()和括号中给出的值。因为在括号内只能输入一个变量,所以使用了可以一次保存多个值的数据结构。在上面显示的例子中,列表、元组和集合被用于启动数据帧。如图所示,它们都给出相同或相似的结果。现在让我们看看如何使用字典声明数据帧。

当试图使用简单的字典初始化数据帧时,我们得到如上给出的值错误。我们得到的错误声明该问题是由于字典中的标量值引起的。我们可以通过使用 from_records 方法或使用字典中的值列表来解决这个问题。还要注意,当试图从 dictionary 初始化 dataframe 时,dictionary 中的键被视为单独的列。

注意将值初始化为字典还有什么不同吗?这是本文中我们第一次控制列名。你问还有没有其他方法可以控制列名?是的,我们可以,让我们看看下面的例子。

正如我们在上面看到的,我们可以在 DataFrame 方法中使用 column 关键字初始化列名,语法为 pd。DataFrame(值,列)。我们可以在同一个语句中创建多个列,方法是利用列表列表、元组列表。我们还可以使用列名列表同时为多个列指定名称。

选择或索引数据

既然我们知道了如何从头开始创建或初始化新的数据帧,接下来的事情就是查看特定的数据子集。在 python 中,这在某些情况下被指定为索引或切片。让我们看一下我们将在本节中使用的数据帧。

请注意这里是如何指定索引值的。如果没有给定索引值,索引的顺序将从 0 开始到 9 结束。这将有助于我们更好地理解方法之间的差异。如果您想知道代码的 np.random 部分是做什么的,它会创建随机数并输入到数据帧中。

人们主要使用三种不同的方法来选择数据。它们是:

  • 通信线路(LinesofCommunication)
  • iloc
  • 切片— []

让我们来看看它们,了解它们是如何工作的

通信线路(LinesofCommunication)

loc 方法将使用数据帧和/或序列中的索引信息提取数据。这意味着,对于子集化数据,loc 会查找每一行的索引值,以获取所需的信息。让我们看看下面的例子来更好地理解它。

请注意,当我们将 0 作为 loc 输入传递时,结果输出是对应于索引值 0 的行。这就是从 loc 中提取信息的方式。这种方法的主要优点是,可以仅基于索引值从数据集中检索信息,因此我们可以确定每次提取的内容。

iloc

iloc 方法将使用数据帧和/或序列中的位置信息提取数据。这意味着,对于子集化数据,iloc 不会查找每行的索引值来获取所需的信息,而是根据位置获取所有信息。让我们看看下面的例子来更好地理解它。

注意,这里与 loc 不同,获取的信息来自第一行,对应于 0,因为 python 索引从 0 开始。如果你还记得最初看 df 的时候,指数从 9 开始,到 0 结束。因此,我们现在清楚了,使用 iloc(0)获取第一行,而不考虑索引。

切片— []

python 中的切片是使用方括号— []完成的。有多种方法可以根据需要对数据进行切片。让我们看看如何最有效地利用切片。

让我们首先看看数据帧中的行切片。

在这里,我们可以看到括号中输入的数字对应于行的索引级别信息。上面给出的三个不同的例子应该涵盖了行切片的大部分内容。

现在让我们看看数据帧中的列切片。

我们可以看到,对于按列切片,语法是 df[[“col_name “,” col_name_2”]],我们将需要关于列名的信息,因为这将非常清楚我们正在提取哪些列。上述方法在某种程度上类似于 loc,因为它试图匹配精确的列名(loc 匹配索引号)来提取信息。使用这种方法,我们还可以添加多个要提取的列,如上面的第二个示例所示。

最后,如果我们必须按照某种条件进行切片,那该怎么办呢?嗯,那些也可以容纳。让我们看一个例子。

正如我们所看到的,切片的语法是 df[condition]。这里的条件不必仅仅是一个条件,也可以是多个条件的叠加或分层。在上面的第一个例子中,我们想要查看 A 列有正值的所有列。类似地,我们可以将多个条件相加,就像上面的第二个例子一样,以获得所需的信息。

这 3 种方法或多或少涵盖了使用 python 可能需要做的大部分切片和/或索引。

组合两个数据帧

我们现在将研究如何以多种方法组合两个不同的数据帧。你问我们为什么一定要这样做?有很多原因可以解释为什么人们会对这样做感兴趣,比如将多个数据源放入一个表中。

有多种方法可以帮助我们做到这一点。它们是:

  • 串联
  • 附加
  • 加入
  • 合并

让我们逐一研究一下。

串联

Concat 是 method 中最强大的方法之一。在某种程度上,我们甚至可以说所有其他方法都是 concat 的派生方法或子方法。让我们首先看一个简单直接的 concat 例子。

它看起来像一个具有默认设置的简单 concat,只是将一个数据帧添加到另一个数据帧之下,而不考虑索引,同时考虑列的名称,即 df2 的列 A 被添加到 df1 的列 A 之下,以此类推。现在让我们探索一些我们可以在 concat 中调整的附加设置。

让我们首先看看如何在 concat 语句中更改轴值,如下所示。

正如我们所看到的,当我们将 axis 的值更改为 1(默认值为 0)时,数据帧的添加是并排进行的,而不是从上到下。此外,现在不是以列名作为添加两个数据帧的指导,而是以索引值作为指导。

现在,让我们尝试使用另一个附加参数 join。join 参数用于指定我们想要的连接类型。如果您不确定什么是连接,那么在继续阅读文章之前快速阅读一下是个好主意。现在让我们看看下面的例子。

正如我们在上面看到的,当我们使用轴值为 1 的 inner join 时,得到的数据帧由具有公共索引的行(如果轴=0,则为公共列)组成,并并排添加两个数据帧(如果轴=0,则为一个在另一个下面)。让我们看一个 axis=0 的例子来理解这一点。

输出与我们预期的一样,其中只显示了公共列,并且数据帧一个接一个地添加。

Ignore_index 是 concat 方法中另一个经常使用的参数。让我们看看它是做什么的。

正如我们在这里看到的,这里的主要变化是索引值不是连续的,与 df1 和 df2 的索引值无关。因此,这是通过忽略原始数据帧的索引,将现有索引值替换为新的顺序索引。

concat 的最后一个参数是 keys。该参数通过输入自定义键名帮助我们跟踪行或列的来源。让我们看一个例子来更好地理解它。

正如我们所看到的,根据值是如何添加的,keys 标记说明了所提到的键以及列和行中的信息。

附加

Append 是 pandas 中的另一种方法,专门用于将数据帧一个接一个地相加。可以说这种方法的功能相当于 concat 方法的子功能。让我们看一个例子。

正如我们从上面看到的,如果我们在 axis=0 的情况下使用 concat,这就是我们将得到的确切输出。然而,因为这个方法是特定于这个操作的,所以 append 方法是 pandas 用户所知道的著名方法之一。让我们看看如何将多个数据帧追加到单个数据帧中。

正如我们在上面看到的,第一个给了我们一个错误。这可以通过使用括号和插入我们想要添加的数据帧的名称来解决。这是因为 append 参数只接受一个用于追加的输入,它可以是一个数据帧,也可以是一组数据帧(在本例中为 list)。concat 中有一个 ignore_index 参数,其工作方式类似于 ignore_index。我们可以看一个例子来更好地理解它。

正如我们所看到的,它忽略了数据帧中的原始索引,并给它们新的顺序索引。

加入

Join 是 pandas 中的另一种方法,专门用于将数据帧添加到另一个旁边。可以说这种方法的功能相当于 concat 方法的子功能。让我们看一个例子。

正如我们所看到的,如果我们在 axis=1 的情况下使用 concat,这就是我们将得到的确切输出。尽管大多数人更喜欢使用 merge 方法而不是 join 方法,但 join 方法是 pandas 用户所知道的著名方法之一。现在让我们来看看对于具有不同索引的数据帧,随着参数“how”值的改变,join 将如何表现。

因此,从上面可以确认,当使用 axis=1 并使用指定的 how 参数时,join 方法的行为类似于 concat。

合并

Merge 类似于 join,只有一个重要的区别。也就是说,在 join 中,数据帧仅基于索引值添加,但在 merge 中,我们可以根据合并的发生来指定列名。所以,说 merge 比 join 更有用、更强大一点都不会错。让我们看一个例子来更好地理解它。

注意我们在 merge 语句中是如何使用参数“on”的。On 是使用 merge 时必须指定的强制参数。只有当两个数据框架中有相同的列和相同的名称时,这种方法才能很好地工作。如果我们想要合并基于不同名称的列的数据帧呢?还是基于多列合并?Merge 自然也包含所有类型的联接,可以使用“how”参数访问这些联接。让我们看一些例子来了解如何使用它们。

正如我们在上面看到的,我们可以将多个列指定为一个列表,并将其作为 on 参数的输入。如果数据帧有不同的列名,我们可以使用 left_on 和 right_on 参数合并它们,而不是使用 on 参数。

我们将关注的最后一个参数是指标。默认情况下,这是 False,但是当我们将它作为 True 传递时,它将创建另一个附加的 column _merge,该 column _ merge 在行级别通知进行了什么类型的合并。

正如我们在上面看到的,它将通知 left_only,如果该行只有来自左边数据帧的信息,它将说 right_only,如果它有关于右边数据帧的信息,最后如果它有两个数据帧的信息,它将显示两者。

结论

在本文中,我们研究了多种情况,包括完成以下任务的多种方法:

  • 以多种方式初始化数据帧
  • 使用 loc、iloc 和切片子集化数据帧
  • 使用 concat、append、join 和 merge 组合多个数据帧

总之,每个人都知道实践使人完美。这句话也适用于技术领域,对吗?为了让你更容易实践我们在本文中讨论的多个概念,我已经创建了一个 Jupiter 笔记本,你可以在这里下载。练习的好时光!!!

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

如果有任何疑问、建设性的批评和任何反馈,请随时联系我这里的。

从头开始的可微分编程

原文:https://towardsdatascience.com/differentiable-programming-from-scratch-abba0ebebc1c?source=collection_archive---------24-----------------------

去年,我有一个很好的机会,在脸书人工智能研究中心参加了与 Yann Lecun 的谈话。

作为一名数学爱好者,在他的演讲中给我留下深刻印象的是其对深度学习作为可微分编程的重新思考。Yann Lecun 在《脸书邮报》上详述了他的想法:

越来越多的人以数据依赖的方式(用循环和条件)程序化地定义网络,允许它们随着输入数据的变化而动态变化。它真的非常像一个常规程序,除了它是参数化的、自动微分的、可训练/可优化的。

——雅恩·勒村,博览会主任

微分编程的总体目标是计算:

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

为什么我们需要能够区分一个程序?

即量化程序及其输出对某些参数的敏感性。

在本文中,我们将通过从头开始开发这种令人兴奋的新型编程所需的所有工具来解释什么是可区分编程

大局

让我们从一个简单的玩具示例开始,展示我们如何使用传统的、与数据无关的代码编写一个程序来估计乘坐出租车的持续时间:

在此代码中,我们使用预计算的纽约市平均速度(约 30km/h)来计算出租车行程持续时间。这是编制程序的传统方式,即数据不会影响其参数。

我们使用预定义的参数,这里是由专家估计的平均速度,将这个速度的倒数乘以行程距离,我们得到预期的行驶持续时间。

无论我们运行多少次,它都不会改进。它永远不会从错误中吸取教训。

可区分编程提供的恰恰相反:每次运行都可以用来微调应用程序参数。让我们看看这是如何实现的。

利用反馈

对计算机和人类都适用的一点是,要想进步,你需要反馈。理想情况下,你需要一种方法来量化你的错误。

在计算机世界中,通过在我们的初始代码中引入一个计算相对常见的误差度量的新函数:平方误差可以很容易地做到这一点。

增加了误差计算的代码

一旦你知道了误差,你需要一种方法来知道你需要在哪个方向修改你的参数来减少误差。

让我们分析一个具体的例子。考虑一次持续时间为 12 分钟、距离为 6 公里的旅行。为了用我们的模型精确地预测这个值,模型的正确参数应该是 30 km/h。任何其他值都会导致此行程的错误。

让我们看一下相对于我们的参数,平均速度的平方误差图,以获得一些见解。整个代码很简单:

得到的曲线是:

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

平方误差总是正的,更重要的是,在正确的平均速度下达到最小值。图片作者。

蓝色曲线显示了行程持续时间相对于速度的演变。更快的行程显然导致更短的行程持续时间。

橙色曲线将误差显示为实际持续时间(此处为 12 分钟)与给定速度的行程持续时间之间的简单差异。对于实际平均速度:30km/h,该误差为零。

绿色曲线是误差的平方。与误差类似,平均速度为 30 公里/小时时,误差为零。

下山

我们现在有了一种方法来量化我们的误差,关于我们程序的输入参数。我们现在需要的是如何减少错误的一些指示。

假设我们的参数,平均速度是 35 公里/小时。平方误差在 2.95 左右。问题是,我们应该降低速度还是提高速度来减少误差?由于我们知道最佳值 30 公里/小时,我们显然知道速度必须降低。但是对于一个真正的问题,我们必须发现它。

再一次,让我们从绘制平均速度为 35 km/h 的平方误差曲线和曲线切线的图表中获得洞察力。

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

平均速度的误差 wrt,以及平均速度为 35 公里/小时时曲线上的切线。图片由作者提供。

观察切线,很明显我们需要跟随它的斜率来减少误差。在这种情况下,这意味着我们应该降低平均速度。这种方法叫做梯度下降法。

分化

有效地知道如何更新我们的参数的方法是清楚的:我们需要计算我们的误差函数的正切并估计它的斜率。这意味着我们必须对误差函数求导以得到它的梯度。

计算函数的导数有多种方法。现在,我们将只考虑两个:

  • 数值微分,使用基于极限的微分定义
  • 形式微积分,通过推导平均速度的误差公式。

在本文的后面,我们将看到第三个非常通用和健壮的选项。

下面是用于绘制上述曲线的代码:

函数 speed_error_num_diff 使用导数定义来估计相对于误差的误差梯度:

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

使用导数定义允许简单有效的计算

如您所见,代码很简单,但是不方便的是数值不稳定,并且需要一个额外的参数: delta 。根据误差的绝对值,必须调整增量

另一种方法需要平方误差公式的符号推导:

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

平均速度误差的形式微分。图片作者。

这两种方法都有效,可用于优化平均速度参数。我们可以绘制梯度下降法的迭代图,并观察到该方法如预期收敛到 30 km/h:

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

当我们在梯度方向上移动参数时,误差减小。图片作者。

梯度下降通过一个循环和一个指定步长的常数、任意系数来实现:

用于使用梯度下降优化平均速度参数的代码

自动微分

如上所示,这两种方法都有效,但是它们并不总是容易处理的。形式上的一个意味着误差公式的符号推导,一般不像我们例子中那么简单。

有时使用数值法,但由于舍入误差,数值不稳定。

这两种方法都需要人工构建坡度。

幸运的是,有一种方法可以自动构造所有需要的导数:自动微分。

这种方法利用了两个事实:

  • 在任何程序中,我们最终都会进行简单的算术运算(±*/),并调用一些基本函数,如 sin、cos、exp、log、…
  • 链式法则可以用来区分复杂的数学表达式

为了说明这种方法是如何工作的,我们将开发一个仅支持算术运算的基本实现。提醒一下,下面是四种算术运算的推导规则列表:

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

(±*/)运算的派生规则。图片作者。

自动微分有两种主要的实现方式:正向和反向模式。由于前向模式实现起来更简单,我们选择这种模式。

原则是用一个额外的浮点数来增加数字,这个浮点数存储导数。如果数是常数,它的导数是零,而如果数是变量,它对自身的初始导数是 1.0。这一对浮点数被称为对偶数,从数学上来说,构成了一个代数,我们可以在其上执行标准运算。

我们所要做的就是为 DualFloat 创建一个类,重载算术运算符,并使用上面的派生规则:

现在,让我们以多项式 f(x)=3x 为例,手动使用自动微分计算其对 x=4 的导数。

3 是常数,用(3,0)初始化,变量 x 用(4,1)初始化。使用新定义的双数乘法计算,我们得到:

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

双数计算

而且的确, f(x) 的导数是 6x ,因此当 x = 4f’(x)=24

使用 python 和 DualFloat 类,我们得到:

我们现在有工具使用自动微分重写梯度下降:

请注意,我们不必再为微积分费心了。所有必要的计算都是使用双数秘密进行的。对误差调用 derivative() 自动提供梯度。

可微编程

在这篇文章中,我们已经开发了所有的数学和编程工具来进行差异化编程。如您所见,它基于简单的数学概念,可以很容易地引入任何程序。

注意,重写代码甚至是不必要的,因为存在可以替代 numpy 的库:例如,参见 Jax 。唯一剩下的问题在于识别影响程序性能的参数。

一旦你确定了这些参数并定义了一个误差,你就可以计算你的参数对这个误差的导数。然后,每次使用新数据时,您都可以从梯度的免费计算中受益,以改进您的参数。

使用可微分编程,任何程序都可以受益于可微分函数的所有数学工具,允许它们通过从数据中学习来改进自己。

微分方程作为神经网络层

原文:https://towardsdatascience.com/differential-equations-as-a-neural-network-layer-ac3092632255?source=collection_archive---------4-----------------------

向神经网络模型添加领域知识的第一步

人工神经网络(ANN)的主要思想是使用称为层的相对简单的函数的组合来建立复杂函数的表示。

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

一个深度神经网络是一个有许多层,或者许多功能组合在一起的网络。

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

虽然层通常是简单的函数(例如 relu( Wx + b )),但通常它们可以是任何可微分的函数。

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

该层由参数θ ∈ ℝᵖ.的某个有限向量来指定为了实用,我们需要能够使这一层(或多层)适合数据。这包括定义一个成本或损失函数来衡量模型预测与数据的接近程度。

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

如果我们的层是可微的,那么我们可以找到这个成本函数∇ C ( θ )的梯度,并使用它以有效的方式找到成本的局部最小值。

这里我考虑微分方程模型。这些系统使用包含当前状态导数的表达式来描述系统(x)的状态随时间的演化。一般来说,它们采取以下形式:

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

微分方程适合我们的神经网络框架,因为它接受一些参数并产生解作为输出,并且它是可微分的。

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

因此,我们可以使用微分方程作为神经网络中的一层。这真的很棒,有几个原因:

  • 微分方程是所有物理定律的基本语言。
  • 在物理学和化学之外,微分方程是描述复杂系统行为的重要工具。在我们的神经网络中使用微分方程模型允许这些模型与神经网络方法相结合。
  • 建立有效的神经网络包括为网络选择一个好的底层结构。通常更容易想到的是描述一个函数如何随时间变化,然后写下这个现象的函数。相对简单的速率法则可以变成非常复杂的行为(参见下面的洛伦兹系统!).

为了简单起见,在这篇文章中,我将集中讨论基于单个微分方程层的神经网络。然而,这些层可以很容易地作为一层嵌入到深度学习项目中。深度学习与微分方程形式的领域知识的结合是许多领域的游戏规则改变者。

洛特卡-沃尔泰拉捕食者猎物

为了演示如何将自己的微分方程层构建到神经网络中,我将使用朱莉娅通量微分通量微分方程库。在本文中,我将把代码保持为小片段,以允许开发直觉,但是这些示例的完整代码已经在 Github repo 中发布。

首先,我们将考虑拟合数学生物学中经典模型的参数。Lotka-Volterra 捕食者-食饵模型描述了在简单生态群落中可以观察到的种群振荡。

在哈德逊湾贸易公司 19 世纪的毛皮贸易数据中可以观察到一个著名的例子。

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

该模型的方程由下式给出

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

Lotka-Volterra 捕食者-食饵方程

捕食者种群的振荡将会滞后于被捕食者种群的峰值。

现在让我们使用这个模型作为神经网络中的一层,有一组六个参数。两个用于猎物 x₀和捕食者 y₀的初始种群,四个速率参数α,β,δ,γ。

在 Julia 中,我们可以定义这个系统和一组默认参数。

现在,我们将微分方程层定义为输入参数的函数。参数数组将前两个条目作为初始条件。

接下来要做的是生成一些假数据来拟合(添加一些噪声),然后定义一个损失函数。我对我们的数据使用了一个简单的均方误差损失函数,尽管我们当然可以很容易地对损失函数添加一些正则化的参数。

最后,我们定义一个函数来实际执行模型拟合。这是 Julia 生态系统真正受益的地方,因为这个系统可以很容易地使用梯度方法来拟合参数。

正如你所看到的,我使用了 3000 次 Adams 迭代,然后调用 BFGS 来最小化成本。这是一个很好的组合,你可以直接跳到 BFGS,但收敛需要更长的时间。最好是让亚当斯迭代让你在附近,然后结束与 BFGS。

恢复的参数由下式给出:

The parameters are [0.9987532818277052, 0.9809616721237869, 1.5075095360807464, 1.009470157647888, 2.974936372236448, 0.993477599859459] with final loss value 2.1229151208653736The actual parameters should be: [1,1,1.5,1,3,1]

这是我们的数据与模拟时间序列数据的对比图。如你所见,最小化结果与数据非常吻合。

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

Lotka-Volterra 捕食者-食饵模型的参数使用最小二乘成本函数上的亚当和 BFGS 优化进行拟合。对于该合成数据集,参数恢复得非常接近精确。

当然,对神经网络的真正考验是它如何推广到验证数据。在这种情况下,我们可以很容易地测试系统的未观察到的初始条件,看看我们的神经网络是否捕捉到了动态。

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

推广到一组新的初始条件。当然,模型概括得很好,因为我们找到了几乎完全正确的参数。

太好了,它起作用了!

斯图尔特-朗道振子模型

现在让我们考虑一下在我的研究领域中经常出现的从动力系统中恢复参数的问题。 Stuart-Landau 方程描述了接近 Hopf 分叉(非线性系统中出现普通振荡)的非线性系统的动力学。我将考虑这种变化,它出现在对耦合振子群体的同步研究中。

使用这个模型的部分动机是由于我对这个模型的熟悉。然而,我还有另一个更深层的动机。Lotka-Volterra 捕食者-食饵模型是一个很好的开始模型,但对于数学生物学来说,这是一个奇怪的模型。这是一个保守系统,很像在物理系统中观察到的(没有摩擦)。这意味着 Lotka-Volterra 系统不是有一个孤立的吸引振荡(称为极限环),而是有一整类同心环。

这有可能扭曲我们对拟合微分方程模型的理解,因为保守系统保留了对初始条件的记忆。对于极限环振荡,我们会随着时间的推移丢失关于初始条件的信息(瞬态动力学衰减,时间箭头)。由于许多初始条件以相同的最终状态结束,这可能使参数恢复的问题更加困难。

该系统的方程由下式给出:

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

这些是用极坐标写的。因此,R 表示振幅,ψ表示弧度角度。动力学的定性形式为

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

斯图尔特-朗道动力学导致稳定的极限环振荡。

在 Julia 中,更新我们的捕食者-食饵模型来考虑这种类型的系统是一件简单的事情。

现在我们定义一个 ode 层生成一些数据并创建一个损失函数。

最后,下面的函数创建运行优化来恢复参数。

恢复的参数由下式给出:

The parameters are [0.02293619193779294, 0.08918144968755219, 0.08304049248335474, 6.275224626122101, 0.11589347566722544, 0.9019465183126854] with final loss value 0.7300967336849258The actual parameters are:
[0.0,0.08,0.1, 6.28, 0.1, 1.0]

训练数据的拟合如下所示:

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

蓝色表示训练数据的 Stuart-Landau 振荡器拟合,绿色表示模型预测。左图显示了相平面中的动态特性。右图显示了作为时间函数绘制的幅度 R(右上)和相位(右下)。

我们可以进一步测试我们的模型,看看它对新的初始值的推广程度。

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

使用未观察到的初始条件数据生成的验证数据的 Stuart-Landau 振荡器拟合显示为蓝色,模型预测显示为绿色。左图显示了相平面中的动态特性。右图显示了作为时间函数绘制的幅度 R(右上)和相位(右下)。

洛伦兹方程和混沌

现在是有趣的应用程序的时间了。让我们考虑使用混沌系统的时间序列数据进行参数恢复。为此,我们将使用著名的洛伦兹系统。

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

三维洛伦兹系统。最初用作大气流体动力学(对流)的简单模型。我们将选择给出混沌解的标准参数值(σ=10,ρ=28,β=8/3)。

在 Julia 中定义这个系统很简单:

作为演示,让我们看一下从稍微不同的初始条件值生成的 X 变量的一些时间序列数据。

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

x 变量作为时间的函数,三个初始条件非常接近。

该图显示了对初始条件的敏感依赖,这是混沌的标志。

通常,我们定义一个依赖于初始条件和参数的微分方程层。

生成一些数据,给时间序列添加一些噪声,并定义我们通常的误差函数。

现在使用 DiffEqFlux 库定义训练函数。

运行优化可以很好地拟合训练数据,当我们对训练样本之外的时间进行积分时,这种拟合可以很好地概括。

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

相空间绘制 t ∈ [0,30]的真实系统(蓝色)与模型预测(绿色)的关系图。

我们还可以查看适合时间序列图的训练模型。

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

蓝色显示的(扩展)训练数据的时间序列与绿色显示的拟合模型预测。在模型预测和数据出现分歧的 t ≈ 22 之前,它们一直非常接近。该模型仅针对 t ∈ [0,10]的数据进行训练。因此,该模型能够对大约两倍长度的训练数据进行准确预测。

由于该模型仅在 t ∈ [0,10]上训练,我们可以看到该模型对 t ∈ [10,20]的概括非常好,但在此时间之后很快偏离真实值。

The parameters are [0.9727986684296102, 0.034212291835795355, -0.001627150535904438, 9.99887680497206, 28.00267472723392, 2.666573010932292] with final loss value 1.7015586033442565The actual parameters are:
[1.0,0.0,0.0,10.0,28.0,2.6666666666666665]

所以我们找到了一个非常合适的。

结论

使用 Julia 生态系统(科学机器学习 sciml) 将微分方程模型包括到神经网络中是相对简单的。这使得我们能够通过经典的动态系统模型将整个知识分支纳入到我们的神经网络模型中,用于时序数据。下一步是将这些微分方程层结合到我们的深度学习模型中。

关于动力系统和人工神经网络的接口问题。我们从这里开始的三个可能的概括是:

  • 神经微分方程是一个术语,用来描述使用人工神经网络函数作为动力系统的右端。由于这些系统利用了一般的人工神经网络功能,它们可能在建模时间序列时表现出较差的收敛性。
  • 通用微分方程是一个用于混合数学模型和人工神经网络函数的术语。这里的想法是指定尽可能多的动态,然后让 ANN 填入未建模的动态、控制函数等。这些系统可以表现出更快的收敛速度,并允许我们将神经网络的能力与领域知识相结合来描述高维函数。
  • 混合动力系统用于将微分方程模型(或更一般的某种领域知识)与单独的机器学习方法相结合。存在这些类型的许多变体,但我会区分这个类,它将机器学习模型与领域模型分开。然后可以将它们组合起来或作为输入输入到另一个中。

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

此外,我应该提到,我们在本文中讨论的所有模型都可以很容易地转移到 GPU 进行训练。只需在 GPU 上声明初始条件。

提醒:本文的所有代码都可以在这里找到

快乐造型!

差分机器学习

原文:https://towardsdatascience.com/differential-machine-learning-f207c158064d?source=collection_archive---------26-----------------------

利用导数的新用途进行不合理的有效函数逼近

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

工作底稿

arxiv.org/abs/2005.02347](https://arxiv.org/abs/2005.02347) [## 差分机器学习概述

同伴回购

github.com/differential-machine-leanring-](https://github.com/differential-machine-learning)

为 2020 年 5 月 28 日彭博烧烤研讨会录制的 5 分钟视频概述

Brian Huge 和我刚刚发布了一篇的工作论文,这是在丹斯克银行进行了六个月的人工智能(AI)函数逼近的研究和开发之后。一个主要发现是,当训练标签相对于训练输入的梯度可用时,用于回归(即值的预测,而不是类的预测)的训练机器学习(ML)模型可以得到极大的改善。给定这些差分标签,我们可以编写简单但不合理有效的训练算法,能够以稳定的方式从小数据集以显著的速度和准确度学习精确的函数近似,而不需要额外的正则化或超参数优化,例如通过交叉验证。

在这篇文章中,我们以差分机器学习的名义简要总结了这些算法,强调了主要的直觉和好处,并评论了 TensorFlow 实现代码。所有细节都可以在工作文件、在线附录Colab 笔记本中找到。

在金融衍生品定价近似的背景下,训练集是用蒙特卡罗模型模拟的。每个训练示例都是在一个蒙特卡罗路径上模拟的,其中标签是交易的最终收益,输入是市场的初始状态向量。微分标签是对状态的收益 wrt 的路径梯度,并且用自动伴随微分(AAD) 有效地计算。由于这个原因,差分机器学习在金融中特别有效,尽管它也适用于所有其他可以获得高质量一阶导数 wrt 训练输入的情况。

模型不仅在输入和标签的扩充数据集上训练,而且在差异数据集上训练:

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

通过最小化值和导数的预测误差的组合成本:

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

给出了值和导数标签。我们通常通过推理计算预测的值,通过反向传播计算预测的导数。虽然这种方法适用于任意复杂的架构,但为了简单起见,我们在此讨论普通前馈网络。

回想一下普通前馈方程:

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

前馈方程

其中符号是标准的,并在论文中规定(索引 3 是为了与论文一致)。

本文中的所有代码都摘自演示笔记本,其中还包括注释和实际的实现细节。

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

标准进口

下面是前馈方程的 TensorFlow (1.x)实现。我们选择显式编写矩阵运算来代替高级 Keras 层,以突出代码中的等式。我们选择了 softplus 激活。ELU 是另一个选择。出于论文中解释的原因,激活必须是连续可微的,排除了例如 RELU 和 SELU。

代码中的前馈方程

用反向传播预测输出 wrt 输入的导数。回想反向传播方程是作为前馈方程的附件推导出来的,或者参见我们的教程了解一下:

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

反向传播方程

或者在代码中,回想一下 softplus 的导数是 sigmoid:

代码中的反向传播方程

我们再次明确地编写了反向传播方程来代替对 tf.gradients() 的调用。我们选择这样做,首先,再次突出代码中的方程,同时避免在训练期间嵌套反向传播层,如下所示。为了避免疑问,通过调用一次 tf.gradients() 来替换这段代码也是可行的。

接下来,我们在一个网络中结合了前馈和反向传播,我们称之为双网络,这是一个两倍深度的神经网络,能够以两倍的计算成本同时预测值和导数:

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

孪生网络

前馈和反向传播相结合的孪生网络

孪生网络在两个方面是有益的。训练后,在需要导数预测的应用中,它可以有效地预测给定输入的值和导数。例如,在金融领域,它们是价格对市场状态变量的敏感性,也称为希腊(因为交易员给它们取希腊字母),也对应于对冲比率

双生网络也是差异训练的基本构造。组合成本函数通过孪生网络的推理、预测值和导数来计算。成本函数的梯度通过 twin 网络反向传播来计算,包括由 TensorFlow 作为其优化循环的一部分静默进行的反向传播部分。回想一下神经网络的标准训练循环:

普通训练循环

差分训练循环实际上是相同的,对于成本函数的定义是安全的,现在结合了值和导数的均方误差:

差分训练循环

TensorFlow 在幕后无缝区分 twin 网络,以满足优化需求。网络的一部分本身就是反向传播,这无关紧要。这只是矩阵运算的另一个序列,TensorFlow 没有困难地进行微分。

笔记本的其余部分涉及标准数据准备、训练和测试,以及对金融教科书数据集的应用:Black & Scholes 中的欧式看涨期权和 correlated Bachelier 中的篮子期权。结果证明了差分深度学习的不合理有效性。

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

一些测试结果展示了差分深度学习的强大功能,可在笔记本电脑上重现

在在线附录中,我们探索了差分机器学习在其他类型的 ML 模型中的应用,如基函数回归和主成分分析(PCA),结果同样显著。

差分训练对不正确的导数施加惩罚,与常规正则化(如 ridge/Tikhonov)倾向于小权重的方式相同。与常规正则化相反,差分 ML 有效地减轻了过拟合*,而没有引入偏差*。因此,不存在偏倚-方差权衡或通过交叉验证调整超参数的必要性。它只是工作。

差分机器学习更类似于数据扩充,这反过来可以被视为一种更好的正则化形式。数据扩充一直被应用于例如计算机视觉中,并取得了成功。这个想法是从一个单独的图像产生多个标记的图像,例如通过裁剪、缩放、旋转或重新着色。除了以可忽略不计的成本扩展训练集之外,数据扩充教会了 ML 模型重要的不变性。同样,衍生品标签,不仅以非常小的成本增加了训练集中的信息量(只要它们是用 AAD 计算的),而且教会了 ML 模型定价函数的形状

工作论文:【https://arxiv.org/abs/2005.02347
Github repo:github.com/differential-machine-learning
Colab 笔记本:https://Colab . research . Google . com/Github/differential-machine-learning/notebooks/blob/master/differential ml . ipynb

安托万·萨维恩

深度学习中的差分隐私

原文:https://towardsdatascience.com/differential-privacy-in-deep-learning-cf9cc3591d28?source=collection_archive---------14-----------------------

关于如何将差分隐私集成到图像分类的深度学习架构中的实用指南

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

马太·亨利Unsplash 上拍照

我要感谢阿克谢·库尔卡尼先生在我发表我的第一篇文章的征途上指引我。

介绍

随着我们大量的日常活动被转移到网上,被记录的个人和敏感数据的数量也在增加。数据的激增也导致了机器学习和深度学习形式的数据分析工具的增加,这些工具正在渗透到每个可能的行业。这些技术也用于敏感用户数据,以获得可操作的见解。这些模型的目标是发现整体模式,而不是个人习惯。

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

凯文·Ku 在 Unsplash 上的照片

深度学习正在发展成为许多自动化程序的行业标准。但它也因学习训练数据集的微小细节而臭名昭著。这加剧了隐私风险,因为模型权重现在编码了更精细的用户细节,这些细节在恶意检查时可能会泄露用户信息。例如,弗雷德里克松等人演示了一种从面部识别系统中恢复图像的模型反转攻击[1]。给定大量可免费获得的数据,可以有把握地假设,确定的对手可以获得从模型权重中提取用户信息所需的必要辅助信息。

什么是差分隐私?

差分隐私是一种为我们提供用户信息隐私的某些数学保证的理论。它旨在减少任何一个人的数据对整体结果的影响。这意味着人们会对一个人的数据做出同样的推断,不管它是否出现在分析的输入中。随着数据分析数量的增加,暴露用户信息的风险也在增加。差分保密计算的结果不受各种隐私攻击的影响。

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

这里 X 是一个个体。图片作者。

这是通过在计算过程中添加精心调整的噪声(由ε表征)来实现的,使黑客难以识别任何用户。这种噪声的增加也导致计算精度的下降。因此,在准确性和提供的隐私保护之间存在权衡。隐私级别由ε来衡量,并与提供的隐私保护程度成反比。这意味着ε越高,数据的保护程度越低,泄露用户信息的可能性就越大。实现ε差分隐私是一种理想情况,在实际场景中很难实现,因此使用(ε,δ)-差分隐私。通过使用(ε,δ)-差分隐私,该算法是ε-差分隐私,具有概率*(1-δ)。因此,δ越接近 0 越好。Delta 通常被设置为训练样本数量的倒数。*

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

渐变操作。作者图片

请注意,我们的目标是保护模型而不是数据本身免受恶意检查。这是通过在模型权重的计算期间添加噪声来实现的,这具有模型正则化的额外优点。具体来说,在深度学习中,我们通过选择差分隐私优化器来集成差分隐私,因为这是大多数计算发生的地方。梯度首先通过获取损失相对于重量的梯度来计算。然后根据 l2_norm_clip 参数对这些梯度进行剪切,并添加噪声,这由 TensorFlow 隐私库中的噪声 _ 乘数参数控制。

我们的目标是通过以差分隐私—随机梯度下降(DP-SGD)优化器的形式应用差分隐私来保持模型权重的隐私性。这里尝试将差分隐私应用于深度神经网络 VGG19 ,其任务是对 CIFAR10 数据集进行图像分类,以了解对模型性能和隐私的影响。如果这样的模型被训练在敏感和私人的图像上,那么这些图像不被泄露将变得非常重要,因为它们可能被恶意使用。

DP-SGD 的实施

TensorFlow Privacy 库用于实现 DP-SGD 优化器和计算 epsilon。超参数不是非常精确地调整以获得基准的最大精度,因为我们只需要它进行比较研究,过度调整可能会扭曲预期的比较。计算ε的函数将’步数’作为输入,计算为(历元训练样本数)/批量步数是模型查看训练数据次数的度量。随着步数的增加,模型看到的训练数据越多,它会通过过度拟合将更好的细节纳入自身,这意味着模型有更高的机会暴露用户信息。*

*num_classes = 10# data loading
x_train, y_train), (x_test, y_test) = cifar10.load_data()
x_train = x_train.astype('float32')
x_test = x_test.astype('float32')
y_train = tf.keras.utils.to_categorical(y_train, num_classes)
y_test = tf.keras.utils.to_categorical(y_test, num_classes)# network params
num_classes  = 10
batch_size   = 128
dropout      = 0.5
weight_decay = 0.0001
iterations   = len(x_train) // batch_size# dpsgd params
dpsgd = True
learning_rate = 0.15
noise_multiplier = 1.0
l2_norm_clip = 1.0
epochs = 100
microbatches = batch_sizeif dpsgd:
   optimizer = DPGradientDescentGaussianOptimizer(
   l2_norm_clip=l2_norm_clip,
   noise_multiplier=noise_multiplier,
   num_microbatches=microbatches,
   learning_rate=learning_rate)
   loss = tf.keras.losses.CategoricalCrossentropy(
   reduction = tf.compat.v1.losses.Reduction.NONE)
   # reduction is set to NONE to get loss in a vector form
   print('DPSGD')else:
   optimizer = optimizers.SGD(lr=learning_rate)
   loss = tf.keras.losses.CategoricalCrossentropy()
   print('Vanilla SGD')model.compile(loss=loss, optimizer=optimizer, metrics=['accuracy'])
# where model is the neural network architecture you want to use# augmenting images
datagen = ImageDataGenerator(horizontal_flip=True,
          width_shift_range=0.125, 
          height_shift_range=0.125,        
          fill_mode='constant',cval=0.)datagen.fit(x_train)# start training
model.fit(datagen.flow(x_train,y_train,batch_size=batch_size), steps_per_epoch=iterations,epochs=epochs,validation_data=(x_test, y_test))if dpsgd:
   eps = compute_epsilon(epochs * len(x_train) // batch_size)
   print('Delta = %f, Epsilon = %.2f'(1/(len(x_train)*1.5),eps))
else:
   print('Trained with vanilla non-private SGD optimizer')*

基准使用 Keras 库提供的 SGD,学习率与 DP-SGD 相同。网络参数保持不变,以便进行公平的比较。

注意:由于 DP-SGD 将权重衰减作为一个参数,因此将权重衰减应用于神经网络的每一层都会出现错误。

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

作者图片

一些观察结果:

  • 使用 DP-SGD 的模型训练比基准慢。
  • 使用 DP-SGD 的模型训练比基准更嘈杂,这可能是由于梯度削波和噪声的添加。
  • 最终,与基准测试相比,具有 DP-SGD 的模型实现了相当不错的性能。

处理不平衡数据

我们试图通过制作不平衡的数据集,然后训练模型来模拟真实世界的场景。这是通过向每个类随机分配用户定义的权重来实现的。我们人为地制造了一个严重的不平衡,导致模型表现不佳。为了克服这种不平衡,我们采用数据级方法,而不是对模型本身进行更改。实例数量的减少导致ε增加。使用合成少数过采样技术(SMOTE)进行过采样后,我们看到精度有所提高。这使我们能够在不改变模型本身的情况下处理不平衡。

每个类的实例数(共 10 个类):
[3000 3500 250 2000 1000 1500 500 50 5000 2500]

*def imbalance(y, weights, x_train, y_train):
    random.shuffle(weights)
    indices = []
    for i in range(10):
       inds = np.where(y==i)[0]
       random.shuffle(inds)
       print(i,int(weights[i]*len(x_train)))
       indices += list(inds[0:int(weights[i]*len(x_train))])
       x_train = x_train[indices]
       y_train = y_train[indices]
    return x_train, y_trainweights = [0.01,0.05,0.1,0.2,0.3,0.4,0.5,0.6,0.7,1]
x_train, y_train = imbalance(y_train,weights,x_train, y_train)# Implementing SMOTE
from imblearn.over_sampling import SMOTE
smote = SMOTE(random_state=42)
x_train = x_train.reshape(len(x_train),32*32*3) 
# where shape of image is (32,32,3)
x_train, y_train = smote.fit_resample(x_train, y_train)
x_train = x_train.reshape(len(x_train),32,32,3)*

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

我们注意到:

  • 使用 SMOTE 对数据进行过采样后,模型性能比在不平衡数据集上训练的模型有所提高。
  • 基于原始平衡数据训练的模型取代了基于过采样数据训练的模型的性能。

从实验中,我们观察到数据级方法足以解决不平衡的问题,即使是有差别的私有优化器。

调整 NOISE_MULTIPLIER 参数

张量流隐私中对ε有直接影响的超参数是噪声乘数。

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

作者图片

噪声= 100.0,ε= 0.18
噪声= 10.0,ε= 0.36
噪声= 1.0,ε= 3.44

我们注意到:

  • 增加噪声会降低ε的值,这意味着更好的隐私保护。
  • 众所周知,隐私保护级别与模型性能成反比
  • 但是我们在实践中没有观察到这种关系,并且增加噪声乘数对性能几乎没有影响。

结论

在调整噪声乘数时发现的与理论的偏离可能归因于模型的深度较大,其中梯度操作无效。从 TensorFlow 隐私源中给出的代码中,我们看到ε的值独立于模型训练,仅取决于我们选择的噪声 _ 乘数*、批量 _ 大小时期增量值。Epsilon 有很好的理论支持来衡量隐私风险的大小。它考虑了在确定模型查看训练数据的次数时很重要的所有因素,并且直观地感觉到模型查看数据越多,用户信息暴露于模型权重的风险就越大。但它仍然缺乏实际测量模型重量对恶意检查的安全性。这是一个令人担忧的原因,因为现在我们不知道我们的模型权重是否对黑客攻击免疫。现在需要一个度量标准来衡量模型权重的不透明程度,即它们透露的用户信息有多少。*

未来的工作

正如结论中所讨论的,首先也是最重要的是提出一个衡量标准来判断模型的隐私性。它甚至可能是一个试图从模型权重中获取用户信息的攻击模型。模型能够正确识别的训练数据点的数量可以量化为隐私风险。一旦一个可靠的度量被形式化,我们就可以着手将不同的私有优化器扩展到计算机视觉和自然语言处理中更复杂的任务,以及其他架构。

参考

  1. 米(meter 的缩写))弗雷德里克松、s·贾和 t·里斯坦帕尔。利用置信度信息和基本对策的模型反转攻击见 CCS,第 1322-1333 页。2015 年 ACM
  2. Abadi,Martin 等.“深度学习与差异隐私2016 年 ACM SIGSAC 计算机与通信安全会议论文集。2016.
  3. 张量流隐私,https://github.com/tensorflow/privacy

Diffie Hellman 密钥交换

原文:https://towardsdatascience.com/diffie-hellman-key-exchange-f673d617137?source=collection_archive---------24-----------------------

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

克林特·帕特森在 Unsplash 上拍摄的照片

使互联网成为可能的技术

简而言之,Diffie Hellman 是一种广泛使用的技术,用于将对称加密密钥安全地发送给另一方。在继续之前,让我们首先讨论一下为什么要使用像 Diffie Hellman 这样的东西。当在互联网上以纯文本形式传输数据时,有人很容易使用某种数据包嗅探器(如 WireShark)来捕获数据包。一个恶意的人,可能会偷听你和你女朋友的谈话,或者更糟,窃取密码和信用卡信息。幸运的是,一些非常聪明的人想出了一种为交通信息编码的方法。我们将普通的纯文本转换成难以理解的东西,反之亦然的过程被称为密码术。密码学最基本的例子叫做凯撒密码。

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

https://commons . wikimedia . org/wiki/File:Caesar _ Shift _ Cipher _ wheel . png

本质上,双方都有一个对称密钥,它指定了什么字符映射到加密文本的什么符号。没有钥匙的人不能阅读这条信息。例如,在前面的图像中,字符“A”将被编码为加密消息中的“T”。然后,接收端的个人可以使用相同的凯撒密码来解码消息。

在计算机网络领域,对称加密算法的问题是,密钥必须不可避免地通过网络发送给另一方,以便他们可以解密传入的消息,并依次加密它们。如果恶意行为者碰巧在那个时间点监听网络,他们可以获得密钥,并将其用于邪恶的目的。

这就是不对称加密发挥作用的地方。不对称加密通过生成公钥和私钥对来工作。公钥只能用于加密消息,而私钥只能用于解密消息。例如,当您进行网上银行业务时,您将您的公钥交给银行,然后用它来加密发送给您的数据。如果一个坏人得到了公钥,他们不会造成任何真正的伤害,因为他们只有加密数据的能力。

今天,使用最广泛的非对称加密算法是 RSA。 RSA 代表Rivest–sha mir–ad leman之后,这些人在 1977 年首次描述了该算法。RSA 算法通过将消息提升到公钥的幂,然后取结果的模来加密消息。为了解密给定的消息,我们将它提升到私钥的幂,然后取结果的模。RSA 依赖于一种称为单向函数的数学概念。假设我们有以下等式:

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

现在,假设你得到了数字 8 并要求返回 2 。你能做到吗?

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

为了弄清楚 8 的所有因素,我们可以相对容易地逆向工作。

相反,模(与余数同义)运算是单向函数的一个例子。假设我们有以下等式:

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

如果让你从推导出 11 ,你会吗?

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

通过尝试所有不同的可能性(即 3 % 4 = 37 % 4 = 311 % 4 = 3) ,您可能能够获得正确的答案(*11))**,但是当分子非常大时,如 RSA 的情况(即 4096 位长),有很多排列,我指的是给出余数的很多排列鉴于这一特性,黑客将别无选择,只能使用蛮力(尝试各种可能性)来从加密消息和公钥中确定私钥。考虑到今天的密钥长度为 4096 位,传统的计算机要花上几个世纪才能遍历完所有可能的值。*

实际上,非对称加密比对称加密慢 3 到 5 个数量级。因此,我们不使用非对称加密来加密实际的有效载荷。相反,我们使用像 Diffie-Hellman 这样的技术安全地向另一方发送对称加密密钥,然后使用所述密钥加密/解密所有进一步的消息。

模运算(RSA) Diffie Hellman

我们已经在高层次上描述了 RSA。现在,让我们看一个具体的例子。假设,鲍勃想给爱丽丝发送一条消息。鲍勃将通过生成新的随机素数 N 和相应的生成器开始**

注意:g 不是随机的,但是我们如何选择它超出了本文的范围。

实际上,N 是一个很大的数字。然而,为了简单起见,我们将使用以下值:

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

两个 g & N 都以纯文本形式在网络上发送。Bob 然后生成一个密钥 a = 2 。接下来,鲍勃将生成器 g 提升到他的密钥 a 的幂,并取结果的模。最终产品 A = 5 被发送给爱丽丝。

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

**在另一端,Alice 执行相同的步骤—即,她生成一个密钥 **b,将生成器 g 提升到她的密钥 b 的幂,取乘积的模,并将最终结果 B = 3 发送给 Bob。

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

即使恶意的参与者想要窥探他们的流量。他们无法从 A 和 b 中推导出 Bob 或 Alice 的秘密密钥。

在从爱丽丝接收到 B 后,鲍勃将其提升到他的私钥 a 的幂,并取结果的模。

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

爱丽丝也一样。

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

在这种情况下,爱丽丝和鲍勃最后都得到相同的数字, 9 。然后他们使用 9 作为 AES 等对称加密算法的密钥。

椭圆曲线 Diffie Hellman

试图从椭圆曲线上的一点导出私钥比传统的 RSA(模运算)更难破解。因此,椭圆曲线 Diffie Hellman 可以用较少的比特实现相当的安全级别。

较小的密钥需要较少的计算步骤来加密/解密给定的有效载荷。当从本地机器建立安全连接时,您不会注意到太大的不同。然而,在类似于每秒执行成千上万次密钥交换的中型 web 服务器上,使用椭圆曲线 Diffie Hellman 可以节省大量资源。

**我们可以将 Diffie Hellman RSA 密钥交换中所有可能数字的定义域想象成一个圆(由于模函数的性质)。 **n 的值越大,圆圈越大,越难猜出正确的数字。

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

相反,顾名思义,椭圆曲线 Diffie Hellman 密钥交换的所有可能数字的定义域采用椭圆曲线的形式。

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

前述椭圆曲线的特征在于以下数学方程:

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

在野外,使用等式( mod n )是很常见的。

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

在实践中,你希望使用由专业数学家开发的曲线,并检查以确保它们是安全的。

椭圆曲线 Diffie Hellman 的工作方式不是像 RSA 那样进行幂运算,而是将点 G 多次添加到自身。

让我们看一个例子。假设 Bob 发起了与 Alice 的连接。Bob 选择一个生成器 G ( 曲线上的一点)和椭圆曲线方程的参数 abn ,并以明文形式通过网络发送它们。

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

Bob 和 Alice 各自生成一个私钥(数字)。为了简单起见,我们假设鲍勃选择了 b = 9爱丽丝选择了 a = 3 。鲍勃和爱丽丝分别负责计算 bG = 9GaG = 3G****。****

为了计算 xG (其中 x 为任意数),我们使用了点的加法和加倍公式。例如,为了确定 2G,我们使用一个点加倍的公式。

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

为了取分数的模,我们可以使用模乘逆计算器。

**[## 模乘逆

这个计算器计算给定整数 a 模 m 的模乘逆。理论是下面的…

planetcalc.com](https://planetcalc.com/3311/)**

**然后我们将答案乘以 **77 % 17 = 9,并取结果的模。

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

该点的 x 坐标可以计算如下:

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

然后我们用 x2G 来计算 y2G。

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

为了计算 3G,我们使用增加一个点的公式。

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

我们从计算斜率开始。

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

然后我们计算新点的 x 位置。

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

最后,我们使用 x 坐标的值来计算 y。

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

Bob 通过网络发送 bG = 9G = (7,6) 。同样,爱丽丝发送 aG = 3G = (10,6) 。在事件中,一个恶意的演员正在监听,从椭圆曲线上的点 (7,6)(10,6) 导出 aGbG 的值是不可能的。

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

一旦 Bob 从 Alice 接收到 aG = (10,6) ,他计算 abG = 9(3G) = 27G = (13,7) 。当 Alice 从 Bob 收到 bG = (7,6) 时,她计算 abG = 3(9G) = 27G = (13,7) 。然后,它们都使用 abG 的 x 坐标作为所有进一步数据传输的对称加密密钥。

挖得足够深

原文:https://towardsdatascience.com/dig-deep-enough-features-engineering-techniques-for-time-series-analysis-in-python-500c96aebade?source=collection_archive---------39-----------------------

以 Python 中时间序列分析的工程技术为特色。

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

照片由 Unsplash 上的 Dragos Gontariu 拍摄

在我们开始挖掘数据之前,对时间序列有一个概念是非常重要的。
基本上,一个时间序列是一个按连续顺序排列的数据点的序列,在大多数情况下,时间序列是一个变量在不同时间取值的一组观察值。

在这篇文章中,我将重点介绍一些特性工程的基本技术,这些技术可以随着时间的推移增强您的预测。很久没有在时间序列项目中合作了,所以我决定快速更新一下我用来提高预测的技术,并与大家分享。

特征工程

特征工程是使用领域知识来创建相关特征的过程,以便使您的机器学习算法更加准确。特征工程可以显著影响您的建模过程的性能,如果它做得正确,它可以帮助您的模型执行得非常好。

在进行这一步之前,您需要遵循解决数据科学问题的基本流程,即:

  • 明确你的目标;
  • 提取数据;
  • 清洗数据;
  • 探索数据和发现洞察力(探索性数据分析);
  • 特色工程;
  • 定义你的模型;
  • 训练和调整您的模型;
  • 部署模型。

特征工程是区分好模型和坏模型的重要步骤。在接下来的章节中,我们将讨论这些技术在时间序列分析中的应用。

让我们假设我们需要预测某个区域的能源消耗,那么我们得到了这个数据:

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

数据是不言自明的,它是一个单变量时间序列,我们有一些重复的模式,我们有两列日期和值,日期列被视为一个对象,因此我们需要将其转换为一个日期时间类型*,*这可以使用 Pandas 轻松完成:

现在我们的数据已经准备好了,让我们看看我们可以从这些变量中挖掘的东西,正如我所说的,数据集包含两列,一个与值相关联的日期,所以让我们讨论一些用于设计这类问题的技术。

日期相关功能

日期相关要素是一种特殊类型的分类变量,日期仅提供时间线上的特定点。如果我们有一些领域的知识或者对问题有深刻的理解,约会是可以被恰当地安排的。
既然我们想预测能源消耗,我们来问一些问题…

  • 日期/时间和消费有关系吗?
  • 数据中是否至少有一个趋势?

要回答第一个问题,如果我们的数据与一些个人使用有关,例如,我们知道晚上的能源使用量比白天低;因此,我们可以得出结论,如果我们从日期中提取小时,可能会有一些隐藏的模式,这也回答了第二个问题,因为我们知道在我们的数据中有一个重复的趋势。

提取周末和工作日有助于了解一周中是否有任何变化模式,而月/年也是一种非常有用的方法来查看季节是否有变化。

使用 Python 提取这些特征非常简单:

data['year']=data['Datetime'].dt.year 
data['month']=data['Datetime'].dt.month 
data['day']=data['Datetime'].dt.day
data['dayofweek']=data['Datetime'].dt.dayofweek  
data['dayofweek_name']=data['Datetime'].dt.day_name()
data.head()

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

从日期变量中提取的特征

我们可以提取更多信息,例如:

  • 四分之一
  • 学期
  • 是一个月的开始
  • 是一年的开始
  • 是月末
  • 是年末

一些日期提取的代码

基于时间的特征

同样,我们可以使用日期的时间戳部分提取更多的特征,例如,我们可以提取小时、分钟甚至秒,因为日期是每小时的,所以我们在这里可以提取的唯一特征是小时。

data['Hour'] = data['Datetime'].dt.hour 

我们可以使用日期列生成很多特性,如果你想探索更多关于基于日期/时间的特性,这里有文档链接

滞后特征

滞后特征基本上是目标变量,但随着一段时间而变化,它用于了解我们的目标值在过去的行为,可能是前一天,一周或一个月。

使用滞后特性有时可能是一把双刃剑,因为使用目标变量非常棘手,如果使用不当,有时会导致过度拟合

data["Lag1"] = data['AEP_MW'].shift(3) # Lag with 3 hours
data["Lag5"] = data['AEP_MW'].shift(5) # Lag with 5 hours
data["Lag8"] = data['AEP_MW'].shift(8) # Lag with 8 hours

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

滞后特征

滚动窗口功能

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

滚动窗口功能正在根据过去的值计算一些统计数据:

  • **预测点:**进行预测的时间点;
  • 特征推导窗口(FDW): 滚动窗口,相对于预测点;
  • 预测窗口(FW): 我们希望预测的未来值的范围,称为预测距离(FDs)。

我们可以使用这行代码来实现:

data['rollingMean'] = data['AEP_MW'].rolling(window=6).mean()

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

同样,我们可以生成许多不同的时间序列特征,这些特征可用于预测不同的预测距离:

扩展窗口统计

另一种类型的窗口,包括系列中所有先前的数据。

这可以通过使用 expanding() 函数在 Python 中轻松实现:

data['ExpandingMean'] = data['AEP_MW'].expanding(6).mean()

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

滚动平均值与膨胀平均值

当我们对问题有了很好的理解时,所有这些特性都是有用的,这将引导我们做出有意义的见解,并避免特性爆炸

对于非时间序列数据,还有一些其他有用的特征工程技术,我想和你们分享一下。

交互功能

还有一些其他类型的特征工程,涉及揭示特征之间的相互作用,一些特征可以组合起来提取一条特定的信息,所以基本上,我们可以对两个变量进行求和、相乘、求差或求商。

一个通用的技巧是查看每一对特征并问自己,“我能以任何可能更有用的方式组合这些信息吗?”

  • **T0 变量的总和:**假设我们有两个变量,selling_food_amountselling_gadgets_amount,如果我们只关心费用的总额,我们可以对它们求和。
  • **两个特征的区别:**假设我们有两个特征expiration_datemanufacturing_date,我们可以创建一个新特征,名为product_validity
  • **两个特征的乘积:**我们有一个在某个区域定义最佳房屋的问题,我们有这两个特征
    number_of_houses:该区域 10 公里内的房屋数量,median_houses:这些房屋的平均质量分数,
    重要的是,有许多房屋选择,但前提是它们足够好。为了创建这种交互,我们可以在这两个变量之间创建一个简单的乘积:house_score = number_of_houses x median_houses
  • **两个特征的商:**以疫情冠状病毒为例,我们可以通过mortality_rate = numberOfDeaths / numberOfCases生成死亡率特征。

结论

特征工程将你的输入转化为算法可以理解的东西。

生成太多的特征会混淆你的模型并降低性能,我们应该总是选择最有贡献的特征,并删除未使用的和多余的特征,最重要的是不要使用你的目标变量作为指标(这包括非常接近的滞后特征),这可能会给你非常误导的结果。

那都是乡亲们!顺便说一下,这是我的第一篇文章,希望你喜欢。

别忘了…相信数据,不要相信观点。

数据来源:https://www.kaggle.com/robikscube/hourly-energy-consumption

其他来源:

深入了解 YOLO V3 -动手指南第 1 部分

原文:https://towardsdatascience.com/digging-deep-into-yolo-v3-a-hands-on-guide-part-1-78681f2c7e29?source=collection_archive---------4-----------------------

深度学习/实时对象检测

让我们熟悉 YOLO v3 模型的尝试

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

https://www . good fon . com/wallpaper/zhivotnoe-gry Zun-zveriok-belka-priroda-mokh-voda-vodopoi . html

人工智能领域在过去几年里发生了巨大的变化,产生了许多新技术。计算机视觉就是这样一个领域,它的目的是训练机器阅读和解释视觉世界。

计算机视觉处理许多具有挑战性的用例,从图像分类到人脸识别。我今天要解决的一个挑战就是物体检测

什么是物体检测?

对象检测是一种包含两项任务的技术,即对象分类对象定位。它是一个被训练来检测多类对象的存在和位置的模型。这可以用于静态图像,甚至实时视频。

物体检测是如何工作的?

对象检测定位对象并将其分类为不同的类别,并通过在其周围绘制边界框来对其进行定位。对象检测有许多使用案例。例如,自动驾驶汽车需要能够在驾驶时识别道路上的其他物体。阅读 X 射线的 AI 放射科医生需要能够定位病变(异常组织)。为了解决这些用例,许多最先进的算法被用于检测对象,例如 R-CNN、快速 R-CNN、更快 R-CNN、掩蔽 R-CNN、SSD、YOLO 等。但是我对今天的 YOLO 特别感兴趣。

YOLO(你只看一次)被认为是最强大的对象检测算法之一。由约瑟夫·雷德蒙、桑托什·迪夫瓦拉、罗斯·吉斯克和阿里·法尔哈迪(2015)发明,迄今为止它已经有 4 个不同的版本,YOLO V4 是 2020 年 4 月发布的最新版本,但在这篇文章中,我们将重点关注 YOLOv3,并试图了解围绕它的所有宣传。除了 YOLO v3,我们还将使用最新版本的 Tensorflow,即谷歌在 2019 年 9 月发布的 TF 2.0。

这个帖子是给谁的?

由于被隔离,这些天我有额外的时间,我决定使用 YOLO V3 探索对象检测,并在跳到最新的 YOLO 版本之前了解它的动态。我看到了很多文章,但大多数都解释了这个非常复杂的 YOLO v3 模型的高级架构和直接实现,这让我感到困惑。我在寻找更多的东西,并决定要理解每一行代码以及后台发生的事情。我偶然看到了伊桑·颜佳·李、阿尤什·卡图里亚和拉赫马德·萨德里的精彩文章,这些文章帮助我更好地理解了。还有什么比试着向别人解释更好的方法来确保我真的理解了某事,因此我写了这篇文章。

这篇文章是我对 YOLO V3 的理解,一个复杂的算法,一个用简单的语言表达的天真的尝试。

先决条件

这篇文章假设你是:

熟悉 Python 3

很了解 TensorFlow

对卷积神经网络(CNN)和对象检测有基本的了解。

Streamlit 有一个基本的了解,以及它是用来做什么的。

本教程的关键要点

本教程分为 两个 部分。

第 1 部分 解释了理解 YOLO v3 如何工作的架构和关键概念。

第 2 部分 从理解配置文件到能够创建用户界面以从用户处获取输入图像并在其上执行对象检测,开始着手实施该算法。

让我们首先了解一下 YOLO 是什么。

YOLO——你只能看一次

许多对象检测模型多次接收和处理图像,以便能够检测图像中存在的所有对象。但是 YOLO,顾名思义,只看物体一次。它对整个图像应用单次向前传递,并预测边界框及其类别概率。这使得 YOLO 成为超快速实时对象检测算法。

太多行话了,嗯?让我们一步步来理解。

YOLO V3

Yolo V3 是对前两个 Yolo 版本的改进,前两个版本更强大,但比前两个版本稍慢。该模型具有多尺度检测、更强的特征提取网络和损失函数的一些变化。

网络体系结构

为了在高层次上理解网络架构,我们将整个架构分为两大部分: 特征提取器特征检测器(多尺度检测器)** 。图像首先被提供给特征提取器,该特征提取器提取特征嵌入,然后被传递给网络的特征检测器部分,该特征检测器部分吐出处理后的图像,该图像具有围绕检测到的类别的边界框。

让我们稍微深入一下这些组件。

特征提取器

以前的 YOLO 版本使用 Darknet-19(用 C 和 CUDA 编写的定制神经网络架构)作为特征提取器,顾名思义,它有 19 层。YOLO v2 在 Darknet-19 的基础上又增加了 11 层,使其架构达到 30 层。尽管如此,该算法在检测小对象时仍然面临着挑战,因为对输入图像进行了下采样,丢失了细粒度的特征。

YOLO V3 提出了一个更好的架构,其中使用的特征提取器是 YOLO v2、Darknet-53(在 ImageNet 上训练的网络)和残差网络(ResNet)的混合。该网络使用 53 个卷积层(因此被命名为 Darknet-53),其中该网络由个连续的 3×3 和 1×1 卷积层构建,后跟一个跳过连接(由 ResNet 引入,以帮助激活通过更深的层传播,而不会出现梯度递减)。

53 层暗网再叠加 53 层用于探测头,使得 YOLO v3 总共是一个 106 层全卷积底层架构。从而导致大的架构,尽管与 YOLO v2 相比,使其稍慢,但同时提高了精度。

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

这张图片是取自 YOLOv3 的 darknet-53 架构:一个增量改进

如果目标是像在 ImageNet 中那样执行分类,那么将添加平均池层、1000 个完全连接的层和 SoftMax 激活函数,如图所示,但是在我们的示例中,我们希望检测类和位置,因此我们将在提取器上附加一个检测头。探测头是多尺度探测头,因此,我们也需要在多个尺度上提取特征。

一旦我们熟悉了高层架构,我们将在下一节更深入地了解这些层是如何工作的。

为了形象化多尺度提取器的样子,我举了一个 416x416 的图像的例子。层的跨度定义为比率,通过该比率对输入进行下采样,,因此在我们的情况下,三个比例将是 **52x52、26x26、**和 13x13 ,其中 13x13 将用于较大的对象,26x26 和 52x52 将用于中等和较小的对象。

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

416x416 图像的多尺度特征提取器

多尺度检测器

YOLO v3 模型的一个重要特征是其多尺度检测器,这意味着对全卷积网络的最终输出的检测是通过在三个不同位置对三个不同大小的特征映射应用 1x1 检测核来完成的。内核的形状是1x1x*(B (5+C))。**

完整的网络架构

Ayoosh Kathuria 制作了一个非常精细的图表,完美地解释了 YOLO v3 的完整架构(结合了提取器和检测器)。

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

图来自https://towards data science . com/yolo-v3-object-detection-53 FB 7d 3 bfe 6 b

如上图所示,我们以 416x416 的图像为例,进行检测的三个比例分别为第 82 层、第 94 层和第 106 层。

对于第一次检测,前 81 层被下采样,使得第 81 层具有 32 的跨距(如前所述,层的跨距被定义为对输入进行下采样的比率),产生我们的大小为 13×13 的第一特征图,并且第一次检测是用 1×1 内核进行的,产生我们的大小为 13×13×255 的检测 3D 张量。

对于第二次检测,在向上采样到 26×26 的维度之前,第 79 层向前经过卷积层。该特征图然后与来自层 61 的特征图深度连接以形成新的特征图,该新的特征图在 1x1 卷积层的帮助下进一步与第 61 层融合。第二检测层在第 94 层,具有大小为 26×26×255 的 3D 张量。

对于最终(第三)检测层,遵循与第二检测相同的过程,其中第 91 层的特征图在与来自第 36 层的特征图深度连接和融合之前经历卷积层。在第 106 层使用大小为 52×52×255 的特征图进行最终检测。

多尺度探测器用于确保小物体也能被探测到,这与 YOLO v2 不同,后者一直受到批评。与先前层连接的上采样层最终保留了有助于检测小对象的细粒度特征。

下一节将详细描述这个内核在我们的模型中的样子。

YOLO v3 的工作

YOLO v3 网络旨在预测每个对象的**(候选对象的感兴趣区域)以及该对象所属类别的 概率

为此,该模型将每个输入图像分成一个由单元组成的 S x S 网格,每个网格预测中心落在网格单元内的对象的 B 边界框和 C 类别概率。该论文指出,每个包围盒可以专门用于检测某一种对象。

边界框**【B】*与正在使用的 锚点 的数量相关联。每个包围盒都有 5+C 属性,其中‘5’*是指五个包围盒属性(例如:中心坐标(bx,by)、高度(bh)、宽度(bw)和置信度得分) C 是类的数量。

我们将此图像传递到正向卷积网络的输出是一个三维张量,因为我们正在处理一个 S x S 图像。输出看起来像[ S,S,B(5+C) ]。*

让我们用一个例子来更好地理解这一点。

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

图片来自https://machine learning space . com/yolo v3-tensor flow-2-part-1/# NMS-unique

在上面的例子中,我们看到我们的输入图像被分成 13×13 个网格单元。现在,让我们来理解只取一个网格单元会发生什么。

由于 YOLO v3 的多尺度检测特征,在三个不同的地方应用三个不同大小的检测核,因此有 3 个盒子(即 B=3 )。YOLO v3 在具有 80 个对象类别或类的 COCO 数据集上被训练,因此 C=80

因此,输出是前面提到的具有维度(13,13,3(80+5))的 3d 张量。*

锚箱

在检测物体的早期,科学家使用滑动窗口的概念,并在每个窗口上运行图像分类算法。很快他们意识到这没有意义,而且效率很低,所以他们转而使用 ConvNets,在一个镜头中运行整个图像。由于 ConvNet 输出特征值的方阵(例如 YOLO 的 13x13 或 26x26),因此*“网格”*的概念出现了。我们将正方形特征矩阵定义为一个网格,但是当要检测的对象不是正方形时,真正的问题就来了。这些物体可以是任何形状(大部分是矩形)。因此,锚箱开始被使用。

锚定框是预定义的具有纵横比设置的框。甚至在训练之前,通过在整个数据集上运行 K-means 聚类来预先定义这些纵横比。这些锚定框锚定到网格单元并共享同一个质心。YOLO v3 每个检测秤使用 3 个锚箱,总共 9 个锚箱。

非最大抑制

在单次向前传递后,由于质心是相同的,预测的输出可能会有多个相同对象的边界框,但我们只需要一个最适合所有对象的边界框。

为此,我们可以使用一种称为非最大值抑制(NMS)的方法,该方法基本上在这些检测之后清除。我们可以定义一个特定的阈值作为这个 NMS 方法的约束,其中它将忽略置信度低于所述阈值的所有其他边界框,从而消除一些。但是这并不能消除所有的置信度,因此 NMS 的下一步将被执行,即按照降序排列包围盒的所有置信度,并选择得分最高的一个作为最适合该对象的置信度。然后,我们找到所有其他与具有最大置信度的边界框具有高并集交集(IOU)的框,并消除所有这些框。

现在我们已经知道了 YOLO v3 中使用的所有术语和架构,在下一部分 (第 2 部分) 中,我们将深入研究实现。

由于这是我第一次尝试写一篇中型文章,并试图阐明我的想法,我很乐意听到反馈的改进建议。

第二部即将上映……

参考

  1. 约洛夫 3:增量改进https://arxiv.org/pdf/1804.02767.pdf
  2. 伊桑李https://towards data science . com/dive-really-deep-into-yolo-v3-a-初学者指南-9e3d2666280e
  3. Ayoosh Kathuriahttps://towardsdatascience . com/yolo-v3-object-detection-53 FB 7d 3 bfe 6 b
  4. rahmad Sadlihttps://MC . ai/the-初学者-实施指南-yolo-v3-in-tensor flow-2-0-part-1/
  5. https://machine learning mastery . com/object-recognition-with-deep-learning/

使用 CNN 的数字识别器

原文:https://towardsdatascience.com/digit-recognizer-using-cnn-55c65ca7f9e5?source=collection_archive---------17-----------------------

使用 mnist 数据集建立一个简单的卷积神经网络来识别手写数字。

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

作者图片

数据集:

MNIST(“改进的国家标准和技术研究所”)是计算机视觉事实上的“Hello World”数据集。自 1999 年发布以来,这个经典的手写图像数据集已经成为基准分类算法的基础。随着新的机器学习技术的出现,MNIST 仍然是研究人员和学习者的可靠资源。

数据处理:

import tensorflow as tf
(x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data()

数据集包含 60,000 个训练图像和 10000 个测试图像。在这里,我将数据分别分为训练数据集和测试数据集。x_train & x_test 包含灰度代码,而 y_test & y_train 包含代表数字的从 0 到 9 的标签。

当您检查数据集的形状以查看它是否适用于 CNN 时。您可以看到我们将(60000,28,28)作为我们的结果,这意味着我们的数据集中有 60000 张图像,每张图像的大小为 28 * 28 像素。

要使用 Keras API,我们需要一个 4 维数组,但从上面可以看到,我们有一个 3 维 numpy 数组。

x_train = x_train.reshape(x_train.shape[0], 28, 28, 1)
x_test = x_test.reshape(x_test.shape[0], 28, 28, 1)
input_shape = (28, 28, 1)

因此,这里我们将三维 numpy 数组转换为四维数组,在我们将类型设置为 float 后,除法运算后会有浮点值。

x_train = x_train.astype('float32')
x_test = x_test.astype('float32')

现在到了正常化的部分,我们总是会在我们的神经网络中这样做。方法是将其除以 255(最大 RGB 码减去最小 RGB 码)。

x_train /= 255
x_test /= 255

建立模型:

from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Conv2D, Dropout, Flatten, MaxPooling2D
model = Sequential()
model.add(Conv2D(28, kernel_size=(3,3), input_shape=input_shape))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Flatten())
model.add(Dense(128, activation=tf.nn.relu))
model.add(Dropout(0.2))
model.add(Dense(10,activation=tf.nn.softmax))

我使用 Keras API 来构建模型,因此我有一个 Tensorflow 背景。我从 Keras 导入顺序模型,并添加 Conv2D、MaxPooling、Flatten、Dropout 和 Dense 层。

丢弃层通过在训练时忽略一些神经元来对抗过度拟合,而展平层在构建完全连接的层之前将 2D 阵列展平为 1D 阵列。

编译和拟合模型:

到目前为止,我们已经创建了一个非优化的空 CNN。然后,我设置了一个具有给定损失函数的优化器,该函数使用一个指标,并通过使用我们的训练数据来拟合模型。据说 ADAM 优化器比其他优化器更好,这就是我使用它的原因。

model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
model.fit(x=x_train,y=y_train, epochs=10)

在这里,我们仅用 10 个历元就获得了相当高的精度。由于数据集不需要很强的计算能力,所以你可以随意调整时段的数量,也可以随意调整优化器、损失函数和指标。

模型评估:

model.evaluate(x_test, y_test)

当评估该模型时,我们看到仅 10 个时期就以非常低的损失给出了 98.59%的准确度。

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

现在来验证它的预测:

image_index = 2853
plt.imshow(x_test[image_index].reshape(28, 28),cmap='Greys')
predict = x_test[image_index].reshape(28,28)
pred = model.predict(x_test[image_index].reshape(1, 28, 28, 1))
print(pred.argmax())

在这里,我们选择一个图像并运行它来获得预测,然后显示图像和预测,看看它是否准确。

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

作者图片

这就是你如何建立和实现一个简单的卷积神经网络。您可以将这个概念实现到各种不同类型的分类和其他类似的实现中。用你在什么上实现了这个概念来回应这篇文章。

机器学习中的数字意义

原文:https://towardsdatascience.com/digit-significance-in-machine-learning-dea05dd6b85b?source=collection_archive---------32-----------------------

追逐统计幽灵的终结

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

唉,机器学习中报告性能指标的标准很少被讨论。由于在这个主题上似乎没有一个明确的、广泛共享的协议,我认为提供我一直倡导的标准可能是有趣的,并且我试图尽可能地遵循这个标准。它来源于一个简单的前提,这个前提从中学开始就被我的科学老师灌输给我了:

科学报道的一般规则是,你写下的每一个数字都应该是“真实的”,不管“真实”的定义是什么。

让我们来看看这对统计量(比如测试性能)意味着什么。当你在科学出版物上写下以下陈述时:

测试准确率为 52.34%。

你说,就你所知,你的模型在从测试分布中提取的看不见的数据上成功的概率在 0.52335 和 0.52345 之间。

这是一个非常强烈的声明。

假设您的测试集由从正确的测试分布中抽取的 N 个样本组成。成功次数为 s 。成功率可以表示为一个二项式变量,它的平均概率 p 由样本均值估计:ps/n

其标准差为:σ=√p(1-p)

p = 0.5 时,其被限制在 0.5 以上。

在正态近似下,估计量的标准差为:δ=σ/√N

精度估计上的这个误差 δ 看起来是这样的,在大约 50%精度的最坏情况下:

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

换句话说,为了有把握地报告上面例子的 52.34%的准确性,您的测试集的大小应该至少在 3000 万样本的数量级!这种粗略的分析很容易转化为除准确性之外的任何可计数的量,尽管不能转化为像可能性或困惑这样的连续数字。

以下是一些常见机器学习数据集的插图:

在 ImageNet 上可以合理地报告多少位数的准确度?准确率在 80%左右,测试集为 15 万张图片:

√( 0.8 * 0.2/150000)=0.103%

也就是说你可以差点举报 XX。X%的数字,实际上每个人都这样做。

MNIST 怎么样,准确率在 99%以内

√( 0.99 * 0.01/10000)=0.099%

pf first,报 XX 就可以了。X%也是!

然而,最大的警告是,在大多数情况下,性能数据不是孤立地报告的,而是用于在相同的测试集上比较多种方法。在这种情况下,实验的两臂之间的采样差异相互抵消,即使样本量更小,它们之间的差异也可能具有统计学意义。估计图形方差的一个简单方法是进行自举重采样。一个更加严格的测试包括进行成对差异测试或者更一般的方差分析

报告超出其内在精度的数字可能很有诱惑力,因为性能数字往往在基线比较的上下文中更有意义,或者当人们认为测试集是固定的而不是从测试分布中抽取的样本时。当在生产中部署模型时,这是一个导致惊奇的实践,突然固定的测试集假设消失了,伴随着无关紧要的改进。更一般地说,这是一种直接导致过度适应测试集的实践。

那么,在我们的领域中,一个数字为“真”意味着什么呢?嗯,这很复杂。对于工程师来说,很容易认为尺寸不应超过公差。或者对物理学家来说,物理量不应该超过测量误差。对于机器学习实践者来说,我们不仅要应对测试集的采样不确定性,还要应对独立训练运行、不同初始化和训练数据混洗下的模型不确定性。

按照这个标准,很难确定机器学习中哪些数字是“真”的。解药当然是尽可能报告置信区间。置信区间是一种更精细的报告不确定性的方式,可以考虑所有的随机性来源,以及简单方差之外的显著性测试。它们的出现也向你的读者发出信号,表明你已经考虑了你所报告的内容的意义,而不仅仅是你的代码所给出的数字。正如这篇博文所解释的,一个用置信区间表示的数字可以被报告为超过其标称精度,尽管要小心,你现在不得不考虑用多少位数字来报告不确定性。一路都是乌龟。

更少的数字意味着更少的混乱和更好的科学。

避免报告超出统计意义的数字,除非你为它们提供明确的置信区间。这可以被认为是科学上的不当行为,尤其是在缺乏配对显著性检验的情况下,用来论证一个数字比另一个数字更好的时候。仅凭这一点,论文通常会被拒绝。总是怀疑用大量数字报告的数字的准确性是一个健康的习惯。请记住,在最坏的情况下,作为“气味测试”,统计显著性所需的样本数有 3000、300k 和 30M 的经验法则限制它将使你免于追逐统计幽灵。

(感谢为本文早期版本提供宝贵意见的许多同事。)

来自现代数据格式的数字污染

原文:https://towardsdatascience.com/digital-pollution-5a579f8c9bf?source=collection_archive---------53-----------------------

抛弃 JSON 如何减轻我们对环境的影响,并使应用程序更加灵敏和高效。

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

照片由艾拉·伊万内斯库

当听到数字污染时,你可能会想到一个位于农村的大型服务器农场,托管着废弃的脸书账户,其中有数百张照片,这些照片永远不会再被加载到浏览器中。或者你可能认为垃圾填埋场堆满了仍在工作,但几乎无用的 iPhone 4s。

作为开发者,为了地球和未来的人类,我们应该留下尽可能小的足迹。与废弃的脸书照片不同,我们的足迹可以成倍增长。让我解释一下…

让我们考虑一些看似简单的事情。这是为 Y-combinator 的黑客新闻实现的一个 API。

http://hn.algolia.com/api/v1/search?query=digitalpollution&标签=故事

下面是上面调用 API 的结果:(您不必阅读)

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

JSON 结果

酷毙了。按下按钮,拿香蕉。发出 URL 请求并获得您想要的故事,所有这些都可以在人类可读、机器可解析的 JSON 中获得。但是等等。

从什么时候开始我们的数据需要人类可读了?当然,在一个 API 的开发过程中拥有它可能是件好事,但是在最终产品中呢?看起来这是对文字和花括号的极大浪费。“[]} }]”是否向读者传达了很多意图或意义?但是当你把人类可读的格式和机器可解析的格式结合起来时,就会发生这种情况。有必要吗?这一切有什么意义?这样我就可以获取这个故事,并以一种漂亮的、人类可读的方式显示在我的应用程序中。我会向我的客户展示这个 JSON 吗?不要!那么,为什么我们要以人类可读的格式传递数据呢?

在我将其归咎于“货邪教编程”之前,也许我们应该进一步分析?人类出于什么原因想要阅读这些“数据”作为一名开发人员,拥有这个伟大的 API 不是很好吗?当然可以。这是一件好事。能够将我的请求结果打印到屏幕上,以确保我得到了“我需要的数据”,这真是太棒了但这不是我需要的数据。这是我需要的包装在文本中的数据,我不需要。这是我需要用文本表示的数据,我必须将它转换成我需要的数据。现在我有了 burn 资源和 CPU 解析和转换这些乱七八糟的东西,所以我终于可以得到我需要的数据了。

如果数据“人类可读”的目的是为了在开发过程中有所帮助,那么为什么不在对人类可读版本的请求中添加一个参数呢?类似于," &格式=可读。"然后,一个在我们知道我们正在读入正确的数据后,我可以删除那个参数,得到实际的数据。

这是为什么污染?

因为这是对 CPU、收音机和调制解调器的不必要的使用。这需要时间、金钱和精力。

不必要的 CPU 使用

为什么我们需要解析数据?如果我们只是收到了我们需要的数据,以约定的格式,我们可以把它放入我们需要的变量中。我们不需要一个 JSON 解码库,里面有处理器的成千上万条 if-then 指令。

无线电和调制解调器的不必要使用

尺寸很重要。与发送 200 字节的信息相比,发送 100 字节的信息会减少蜂窝无线电、家庭调制解调器或服务器调制解调器的能耗。

作为一个快速演示,让我们检查上面的一点 JSON。

"num_comments":0

这让我们知道上面检索到的文章标题没有评论。我可以在我的新闻阅读器应用程序中使用它,显示这篇文章没有评论。我们收到了多少 JSON 格式的数据?

JSON 通常以 UTF-8 格式传输。UTF 8 中的字符是可变长度的,但在这种情况下,它们都属于一个字节的范围。所以上面的*“num _ comments”:0*等于实际字符数。这里是 16 个字符,所以是 16 个字节。如果有 100 条注释,那么由于多了两个零,它应该是 18 个字节。"00."1000 条评论就是 19 个字节,依此类推。

如果我们不使用 JSON,只是将它作为序列化数据发送,我们可以将它作为无符号整数发送。这将只是 2 个字节,代表从 0 到 65,536 条评论。19 字节对 2 字节。我们节省了 17 个字节,节省了将近 90%。

JSON 版本:

00100010 01101110 01110101 01101101 01011111 01100011 01101111 01101101 01101101 01100101 01101110 01110100 01110011 00100010 00111010 00110000

数据版本:

00000000

传递同样的信息,这是一个非常显著的差异。
下面是一个 swift 示例,展示了类似这样的东西在 Swift 中的表现:

在操场上运行代码,打印结果将是:

**Article(id: 18798989, title: "JSON = fat", comments: 3, likes: 1000)****{length = 16, bytes = 0x0a004a534f4e203d206661740300e803}****Article(id: 18798989, title: "JSON = fat", comments: 3, likes: 1000)**

它用 ID、标题、评论数和赞数来序列化文章标题。结果是 16 个字节。

使用我们之前的 JSON 例子发送给我们的相同数量的数据仅仅是评论数,我们得到了两个更有意义的数字和文章的标题…哦,还有评论数。

这需要多少 JSON?

{ "id": 18798989, "title": "JSON = fat", "comments": 3, "likes": 1000 }

67 字节的 JSON 与 16 字节的紧密序列化数据。所以是的,我给 JSON fat 打了电话。

在这种情况下,我们使用不到 25%的数据来表示相同的信息。当然,一旦我们开始在一篇实际的文章中发送大量的内容,实际的节省将会下降。占用空间的实际文本。许多 API 甚至不包含长文文本。许多是以数字为中心的,这些节省是最显著的。

考虑来自同一黑客新闻 API 的以下请求,该 API 仅返回头版文章的元信息:

http://hn.algolia.com/api/v1/search?tags=front_page

在撰写本文时,这是它返回的 16137 个字节:

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

巨大的 JSON 回报

16 千字节,而如果我们使用紧密序列化数据,可能是 4 千字节。为了什么?只是为了让开发人员可以浏览一些文本,以验证我们在测试这段代码时是否得到了它,而不考虑这段代码可能会被使用成千上万次。想想如果 CNN 或福克斯新闻频道在他们的应用中使用这种类型的 API。他们可能是。想象一下如果 twitter 有呢?看起来是的。

数据就是金钱

他们可以在数据传输成本上节省多少钱?有人估计 twitter 每天使用12tb。在 AWS 上,这是 12,000 GB,每 GB 约 8 美分,每天约 960 美元或每年 350,400 美元。理论上,紧密的数据序列化可以将它们的传输成本降低到当前使用量的 25%。这可以为他们每年节省 262,800 美元。还不错。

他们也在存储这些数据,可能是序列化的… JSON,这是要花钱的。一年每天 12tb 的新推文,每年 4,380。让我们假设他们只保留了最近 5 年的推文。这相当于 21,000 万亿字节的存储推文数据。刚刚检查了 AWS 上的简单存储。这将花费每月 452,147 美元或每年 5,425,764 美元。紧密的电子监管似乎每年可以为他们节省 4,069,323 美元。也许他们正在压缩?JSON 通常会压缩到 50%左右。所以也许紧密的序列化每年只能节省几百万美元?但是压缩和解压缩会节省 CPU 周期。计算变得复杂,但证据相当简单。公司可以使用紧密的序列化来节省空间、时间和金钱。

这也是一个环境问题。成本和数据节约接近 1:1。环境影响减少更多。减少 75%的数据将比减少 75%的排放或能源使用量还要多。能量消耗在于储存、压缩、发送和接收。通常,发送和接收是通过多个服务器或节点进行的。来自 twitter 的一个字节可能会跳过五个或更多的服务器到达你的设备。考虑这个从随机用户服务器到 twitter 服务器的跟踪路由。

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

从您的电话,这将包括您和第一个服务器之间或您的电话和您的路由器之间的无线电跳。然后……五个左右收发(10x)之间。减少 75%的数据比减少 75%的能源成本要多得多。每次发送和接收都减少了 75%。在这种情况下,数据减少 4 倍相当于传输的能源成本减少 40 倍。

效率和延迟

较小的数据传输速度更快,到达速度也更快。这使得您的应用程序响应速度更快。紧密序列化的数据不必通过 JSON 解码器用数千条 if-then 语句来解析。这使得你的应用程序反应更快。为了省钱,数据不必在服务器上压缩,这使得你的应用在请求数据时响应更快。纯粹、紧密、序列化的数据让你的应用更快。这使得客户体验更好,您的应用程序更节能。

当我在我的应用程序中这样做时,我发现性能和响应能力都得到了提高。

结论

我喜欢 Maxim Zaks 在他题为停止在生产中使用 JSON 的文章中所说的。“模式的主要好处是它描述了有效负载。当你有一个模式时,你的负载携带的描述是多余的。”API 开发人员花费数天时间编写模式来描述他们的 JSON 格式,这种格式已经在他们的 JSON 格式中描述过了。我们应该停止在生产中使用 JSON。我们应该描述从我们的参数返回的数据格式。

我把这个问题的解决方案称为“紧密序列化”类似的解决方案还有平面映射或协议缓冲区。最终,它只是由提供者描述并被接收者理解的有序数据。它不需要是人类可读的。它可以节省时间、金钱和能源,并使您的应用程序响应更快。

降维方法

原文:https://towardsdatascience.com/dimensionality-reduction-approaches-8547c4c44334?source=collection_archive---------27-----------------------

获取主要变量的方法,以更好地表示数据,提高效率,节省时间。

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

2019 年 12 月 30 日,普雷纳·辛格,金斯敦。

大数据的全面爆发让我们相信还有更多的东西。当然,虽然大量的训练数据允许机器学习模型学习更多的规则并更好地概括新数据,但不加选择地引入低质量的数据和输入特征可能会引入太多的噪声,同时大大降低训练速度,这也是事实。此外,如果数据集包含大量数据列,那么最好查看这些数据要素中有多少对模型真正有用。

在机器学习中,我们倾向于在一开始添加尽可能多的特征,以抓住有用的指标,获得更准确的结果。然而,随着元素数量的增加,模型的输出将在某个级别后减少。这种现象通常被称为“维数灾难”。

维数灾难之所以存在,是因为随着维数的增加,样本的密度呈指数下降。如果我们继续增加特征而不增加训练样本的数量,特征空间的维度将会扩大,变得越来越稀疏。由于这种稀疏性,机器学习模型找到很可能导致过拟合的正确解决方案变得简单得多。当模型过于接近一组特定的数据并且不能很好地概括时,就会发生过度拟合。

然而,我们能否克服维数灾难,避免过度拟合,特别是当我们有很多特征而训练样本相对较少的时候?一种常见的方法是降低特征空间的维数。降维是通过获得主要特征的集合来考虑降维函数空间的方法。降维可以进一步分为特征的收集和特征的提取。

特征的选择试图挑选原始特征的子集用于机器学习模型。这样,我们可以删除冗余和过时的特征,而不会导致太多的信息损失。特征的提取也称为特征的投影。虽然特征的选择返回原始特征的子集,但是特征的提取通过将数据投影到高维空间中的较小维度的空间来创建新的特征。也可以从该方法中提取信息和非冗余功能。

我们可以一起使用特征的选择和特征的提取。除了减少过度拟合和冗余,维度的减少还导致更好的人类解释和模型简化的更低计算成本。

降维的优势

  1. 它减少了所需的时间和存储空间。
  2. 多重共线性的去除改善了机器学习模型的参数的解释。
  3. 当数据降低到非常低的维度时,如 2D 或 3D,将变得更容易可视化。
  4. 降低空间复杂度。
  5. 更容易理解,因为它消除了噪音,从而提供了一个更简单的解释。
  6. 以减轻“维数灾难”。

我们讨论了降维的好处,并概述了降维要求。我们现在将详细讨论降维的两个关键技术,即

  1. 主成分分析
  2. 线性判别分析

例如,将使用来自 UCI 机器学习知识库的参考文献、葡萄酒数据集。该数据集相当小,具有六个目标类别和十一个维度的特征集(即十一个不同的特征,如固定酸度、pH 值、酒精含量等,以预测葡萄酒的质量)。

可以通过下面的链接下载数据集。https://github . com/psi49/revising _ machine learning/blob/master/wine quality _ red . CSV

PCA 概念是如何工作的?

主成分分析(PCA)是一种无监督的学习算法,因为它忽略了使数据集中的方差最大化的类别标签(所谓的主成分),以找到方向。换句话说,PCA 基本上是数据的汇总。例如,为了获得葡萄酒的质量/类型,我们可以使用葡萄酒的不同特征,例如其 pH 值、酒精含量、葡萄酒的颜色、酸度含量等,然而,这些特征中的许多将是冗余的或虚拟的特征变量(可以从其他特征中导出),因此导致在不必要的特征上训练模型。简而言之,我们可以用更少的特征变量得到葡萄酒的类型,这实际上是 PCA 在盒子里做的。

请注意,PCA 不会选择一组特征并丢弃其他特征,而是推断出一些新的特征,这些新的特征从现有的特征中最好地描述了类别的类型(在我们的例子中是葡萄酒的类型)。

以前,在推导正式定义时,我们提出了一个短语—最大化数据集中的方差。现在问题来了——“方差”这个词和 PCA 有什么关系?记住,我们的主要任务是定义一个特征集来区分不同类型的酒。想象一下,你得到了一组不能区分酒的种类的特征,因此,这些特征是没有用的。这种类型的降维会降低模型的准确性,有时会导致数据拟合不足。因此,主成分分析寻找尽可能显示数据集差异的属性。

PCA 对协方差矩阵的特征向量和特征值起作用,这相当于将那些直的主成分线拟合到数据的方差。为什么?因为 PCA 确定数据集中被称为主成分的方差线,其中第一主成分具有最大方差,第二主成分具有第二最大方差,等等。

现在让我们以葡萄酒数据集为例,使用 sklearn 来实现 PCA,并理解数据是如何从高维度转换到低维度的。

让我们对葡萄酒数据集执行 PCA,并通过可视化表示进行分析:

import numpy as np
import pandas as pd
df=pd.read_csv(‘winequality_red.csv’)
def isQuality(quality):
if quality > 6:
     return 1
if (quality >= 5) and (quality <= 6):
     return 2
else:
   return 0

给定的数据有六种不同的质量类型。为了理解降维概念。葡萄酒的质量分为三个目标等级,如果你愿意,你也可以分为六个目标等级。

让我们用上面的函数转换成三个葡萄酒质量等级。

df[‘isQuality’] = df[‘quality’].apply(isQuality)
print(‘New classes are defined for the quality of wines:\n’,df[‘isQuality’].value_counts())

新的葡萄酒质量等级定义如下:

第二类: 1319

第一类: 217

第 0 类: 63

从数据集中删除 quality 列,因为我们已经创建了一个包含三个葡萄酒质量等级的新列。

df=df.drop(‘quality’, axis=1)

将数据分为要素和目标类。

feature=df.iloc[:,0:11]
target=df[‘isQuality’]
print(feature.shape)
print(target.shape)

特征和目标列的形状。

(1599, 11)

(1599,1)

使用 sklearn 的 train_test_split 函数将数据拆分为 train 和 test。

from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(feature, target, test_size = 0.2, random_state = 42)

缩放数据集

缩放数据集-可以使用最小-最大归一化来缩放具有平均值零和单位标准差的数据集。

该估计器单独缩放和转换每个特征,使得它在数据集上的给定范围内,例如在 0 和 1 之间。

from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()
X_train=scaler.fit(X_train).transform(X_train)
X_test=scaler.fit(X_test).transform(X_test)

在 sklearn 中应用内置 PCA 功能的 PCA:

from sklearn.decomposition import PCA
pca = PCA(n_components=2)
X_train = pca.fit(X_train).transform(X_train)
X_test= pca.fit(X_test).transform(X_test)

这里,特征是训练数据集,n_component 是我们想要从现有特征集中导出的 PCA 分量的数量。

因此,使用 sklearn,PCA 就像一个黑盒(如上所述),您给定一个缩放的特征集作为 sklearn PCA 的输入,并获得 PCA 分量作为输出,它可以用作数据训练算法的输入。对于 PCA 算法,在我们找到主成分之前,有必要执行数据缩放。

训练算法

在这里,我们将使用一个简单的逻辑回归工具来训练主成分,以解决这个分类问题。为此,请执行以下代码:

from sklearn.linear_model import LogisticRegression
clf = LogisticRegression(random_state = 0)
clf.fit(X_train, y_train)
y_pred = clf.predict(X_test)# Predicting the test set result using. Predict function under Random Forest Classifier
y_pred = clf.predict(X_test)

评估算法

对于分类问题,用于评估算法的度量是准确度、混淆矩阵、精确度、召回率和 F1 值。执行以下脚本来查找这些值:

from sklearn.metrics import classification_report, confusion_matrix, accuracy_score
print(confusion_matrix(y_test,y_pred))
print(classification_report(y_test,y_pred))
print(accuracy_score(y_test, y_pred))

输出将如下所示:

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

仅使用原始数据集中 11 个特征中的两个特征集,我们就获得了 84.06%的准确度。我不认为这太糟糕。使用逻辑回归模型的超参数优化或使用 sklearn 库中的一些其他模型,可以进一步提高模型精度。尝试多于 2 个且少于 6 个主成分的训练模型。使用 PCA 将是一个有趣的练习。

这里,我们将绘制两个图表,一个仅考虑 11 列中的两列,另一个绘制主成分,以了解 PCA 如何使高维数据的可视化变得容易。

import seaborn as sns
import matplotlib.pyplot as plt
sns.set(rc={‘figure.figsize’:(12,7)})
sns.scatterplot(x=”free sulfur dioxide”, y=”total sulfur dioxide”, hue=”isQuality”,data=df,palette=”Set1")
plt.show()

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

sns.scatterplot(pca_df[:,0],pca_df[:,1], hue=”isQuality”,data=df, palette=”Set1")
plt.show()

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

上图显示了使用两个特征绘制的数据点与使用主成分(基本上是我们数据集中所有特征的总结)即 PCA_1 和 PCA_ 绘制的数据点。这有助于我们识别 PCA 的另一种用途,即我们的数据集及其“质量”类别标签的适当和可分离的可视化。如果你看这个图表,你可以用两个特征变量而不是十三个特征变量来正确地显示整个数据集。虽然它们不能很好地区分葡萄酒质量等级(如二氧化硫和总二氧化硫之间的区别),但有助于以最小的信息损失减少特征集。

到目前为止,我们已经通过一些实际例子对 PCA 有了很好的理解。我们已经看到很少的组件足以训练模型,PCA 也是一个伟大的工具来减少数据维度,并给我们权力来适当地可视化数据。

让我们继续前进,深入研究另一个降维工具“线性判别分析”。我将使用相同的葡萄酒数据集来提供实践经验。

LDA 概念是如何工作的?

线性判别式是一种降维的统计方法,它在各种类别中提供最高可能的区分度,用于机器学习以找到特征的线性组合,这可以以最佳性能分离两个或更多类别的对象。该方法基于判别函数,这些判别函数是基于称为训练集的一组数据来估计的。这些判别函数相对于特征向量是线性的。

LDA 的目标是在假设每一类中的数据由具有相同协方差的高斯概率密度函数描述的情况下,通过线性判别函数来最大化类间方差和最小化类内方差。

理解 LDA 背后的数学是很好的,但我不想压倒任何人。我们将通过保持事情的简单来理解,这样对任何人来说都很容易遵循。

LDA 帮助你找到类簇的边界。这将您的数据点投影到一条直线上,以便尽可能地区分聚类,每个聚类与质心的距离相对较近。

因此,问题出现了——如何识别这些聚类,我们如何得到 LDA 的精简特征集?

基本上,LDA 考虑每个类的数据点的质心。例如,对于 11 个不同的要素,LDA 将使用 11 个不同的要素数据集来查找每个类的质心。基于这一点,它现在定义了一个新的维度,它只不过是一个满足两个要求的轴。

  1. 最大化每个类质心之间的距离。
  2. 最小化每组内的方差(LDA 称之为散点,用 s2 表示)。

因此,本质是(平均值 a —平均值 b)/(平均值 a —平均值 b)

(mean_a — mean_b) =理想的大(S_a — S_b) =理想的小

这里的意思无非是类质心。方差只不过是数据在平面上的分布。因此,如果数据差异很小,则类之间的重叠会更少,并且不同类之间的总体区别会得到保留。

因此,无论新轴的哪个坐标满足这两个条件,它们都会形成新的数据集维度。

现在让我们跳到在 wine 数据集上使用 sklearn 实现 LDA,看看数据是如何从高维度过渡到低维度的。

让我们对葡萄酒数据集执行 LDA 并进行图形分析:

所有必要的库都已经导入,让我们用 sklearn 中内置的 LDA 函数导入 LDA。

from sklearn.discriminant_analysis import LinearDiscriminantAnalysis as LDA
lda = LDA(n_components=2)
lda_df = lda.fit(feature, target).transform(feature)
sns.scatterplot(lda_df[:,0],lda_df[:,1], hue=”isQuality”,data=df, palette=”Set1")
plt.show()

注意:我想澄清的是,像(标准化)这样的特征缩放不会改变 LDA 的整体结果,因此是可选的。

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

在主成分分析图中,您可以可视化整个数据集,正确区分不同的类。而在 LDA 图中,由于类别的不均匀分布,类别不是明显可分的。这是 PCA 和 LDA 的主要区别。

总的来说,PCA 在每类样本较少的情况下表现更好。在这个葡萄酒数据集中,我们有高计数的类别 2 (1319),其次是类别 1 (217),最后是类别 0 (63)。

虽然 LDA 在处理大的多类数据集时效果更好,其中类的可分性是降维时的一个重要因素。

一般的 LDA 方法非常类似于主成分分析,但是除了找到使我们的数据的方差最大化的成分轴(PCA)之外,我们还对使多个类别之间的分离最大化的轴(LDA)感兴趣。

最后,我们来看看如何在 sklearn 内部选择降维方法中 n_components 的个数。简单的方法是使用 explained_variance_ratio_ 并绘制图表,以查看我们需要多少组件来保留新功能集的方差。让我们通过这样做来理解

scaler_df=scaler.fit(df).transform(df)pca = PCA().fit(scaler_df)
plt.figure()
plt.plot(np.cumsum(pca.explained_variance_ratio_))
plt.xlabel(‘Number of n_Components’)
plt.ylabel(‘Variance (%)’) #for each component present in the dataset
plt.title(‘Wine Dataset Explained Variance’)
plt.show()
plt.ylabel(‘Variance (%)’) #for each component present in the dataset
plt.title(‘Wine Dataset Explained Variance’)
plt.show()

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

这张图告诉我们,选择 8 个成分,我们可以保留葡萄酒数据总方差的 90 %以上。这是有意义的,我们不会使用 100%的方差,因为它表示所有的成分,我们只需要主要的成分。

现在,通过使用 n_components=8,我们可以执行相同的分析并训练任何模型。值得一玩。用于机器学习的高级 Python 库实际上使学习变得非常容易,不像早期我们必须从头开始硬编码。

祝你好运!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值