了解 HDBSCAN 和基于密度的聚类
自上而下全面介绍 HDBSCAN 聚类算法的内部工作原理以及基于密度的聚类的关键概念
HDBSCAN 是由 Campello、Moulavi 和 Sander [8]开发的一种聚类算法。它代表“带噪声的应用的基于层次密度的空间聚类”
在这篇博文中,我将尝试以自上而下的方式介绍一些关键概念,以帮助理解 HDBSCAN 的工作方式和原因。这是为了补充现有的文档,如 sklearn 的“【HDBSCAN 如何工作”[1],以及麦金尼斯和希利的其他作品和演示文稿[2],[3]。
除了一些噪音,没有(很少)假设
让我们从最上面开始。在我们描述我们的聚类算法之前,我们应该问,“我们要聚类什么类型的数据?”
我们希望对我们的数据有尽可能少的假设。也许我们唯一可以安全做出的假设是:
- 我们的数据中有噪音
- 在我们的数据中有我们希望发现的聚类
聚类数据集
为了激发我们的讨论,我们从[1]和[3]中使用的数据集开始。
只有二维,我们可以绘制数据,并在我们的数据集中识别 6 个“自然”集群。我们希望通过一些聚类算法来自动识别这些。
k 均值与 HDBSCAN
知道了预期的聚类数,我们运行经典的 K-means 算法,并将结果标签与使用 HDBSCAN 得到的标签进行比较。
即使提供了正确数量的聚类,K-means 也明显无法将数据分组到有用的聚类中。另一方面,HDBSCAN 为我们提供了预期的聚类。
K-means 为什么会失败?
简而言之, K-means 表现不佳,因为不满足对聚类形状的基本假设;这是一个参数算法,由 *K 个簇形心、*高斯球的中心来参数化。当聚类满足以下条件时,K-means 表现最佳:
- “圆形”或球形
- 大小相等
- 同等密集
- 球体中心密度最大
- 未被噪音/异常值污染
让我们从 ESLR [4]借用一个简单的例子来说明 K-means 如何对簇的形状敏感。下面是来自相同数据的两个聚类。在左边,数据在聚类前被标准化。没有标准化,我们会得到一个“错误的”聚类。
图 14.5 摘自《ESLR》第十四章[4]。标准化数据的聚类(左)与原始数据的聚类(右)。
我们的数据有什么特点?
我们回到我们的原始数据集,通过简单地描述它,很明显为什么 K-means 有困难。该数据集具有:
- 任意形状的簇
- 不同大小的集群
- 不同密度的集群
- 一些噪音和一些异常值
需要稳健的数据探索
虽然每个要点都可以从真实世界的数据集中合理地得到,但每个要点对于参数算法(如 K-means)来说都是有问题的。在信任算法的输出之前,我们可能需要检查算法的假设是否成立。但是,当对数据知之甚少时,检查这些假设可能是困难的。这是不幸的,因为聚类算法的主要用途之一是数据探索,我们仍在理解数据的过程中
因此,将用于数据探索的聚类算法需要尽可能少的假设,以便我们获得的初始洞察是“有用的”;更少的假设使其更加稳健,适用于更广泛的真实世界数据。
稠密区和多元模式
现在,我们知道了我们要处理的是什么类型的数据,让我们来探讨一下 HDBSCAN 的核心思想,以及它在数据具有以下特征时如何表现出色:
- 任意形状的簇
- 不同大小和密度的集群
- 噪音
HDBSCAN 使用基于密度的方法,该方法很少对聚类进行隐含假设。它是一种非参数方法,寻找由基础分布的多元模式形成的聚类层次。它不是寻找具有特定形状的簇,而是寻找比周围空间更密集的数据区域。你可以使用的心理图像是试图将岛屿从海洋中分离出来,或者将山脉从山谷中分离出来。
什么是集群?
我们如何定义“集群”?我们直觉认为的集群的特征可能很难定义,并且通常是特定于上下文的。(概述见克里斯蒂安·亨宁的演讲[5])
如果我们回到原始数据集,我们识别簇的原因是我们看到被稀疏和嘈杂空间包围的 6 个密集区域。
被包围的区域密度很高
一种通常与我们对集群的直观概念一致的定义集群的方式是:由稀疏区域分隔的高密度区域。
请看一维模拟数据的曲线图。我们可以看到 3 个集群。
看看下面的分布
X 是来自混合正态分布的模拟数据,我们可以画出 X 的精确概率分布
峰值=密集区域。波谷=稀疏区域
波峰对应于最密集的区域,波谷对应于稀疏的区域。这给了我们另一种解决问题的方法,假设我们知道潜在的分布,簇是被不可能的区域分开的高度可能的区域。想象更高维的概率分布形成了山脉和山谷的景观,其中山脉是你的集群。
给三座山峰/山脉/集群着色
对于不太熟悉的人来说,这两种说法实际上是一样的:
- 由稀疏区域分隔的高密度区域
- 被不太可能的区域分开的高度可能的区域
一种是通过概率分布来描述数据,另一种是通过分布中的随机样本。
PDF 图和上面的带状图是等效的。PDF,*概率密度函数,*解释为位于某点周围小区域内的概率,从 X 看样本时,也可以解释为该点周围的期望密度。
给定基础分布,我们预计在随机样本中,更有可能的区域往往会有更多的点(更密集)。同样,给定一个随机样本,你可以根据经验密度推断出一个区域的概率。
随机样本中更密集的区域对应于基础分布中更可能的区域。
事实上,如果我们观察 X 的随机样本的直方图,我们会发现它看起来与 X 的真实分布完全一样。直方图有时被称为*经验概率分布,*有了足够的数据,我们希望直方图收敛到真实的基本分布。
还是那句话,密度=概率。密度越大=可能性越大。
但是……什么是集群?
可悲的是,即使有了我们对集群的定义,也很难知道某个东西是否是一个单独的集群。看看下面的例子,我们把 X 的一个模式向右移动了。虽然我们还有 3 个峰值,但是我们有 3 个集群吗?在某些情况下,我们可以考虑 3 个集群。“直觉上”我们说只有两个集群。我们如何决定?
通过观察*X’,*的带状图,我们可以更加确定只有两个星团。
X 有 3 个簇,*X’*有 2 个簇。集群的数量在什么时候会发生变化?
定义它的一种方法是为底层分布的 PDF 设置一些全局阈值。所得水平集的连通分量就是你的聚类[3]。这就是 DBSCAN 算法所做的,在多个层次上做将导致 DeBaCl [7]。
基于两个不同水平集的两个不同聚类
这可能因为它的简单而吸引人,但是不要被愚弄了!我们最终得到一个额外的超参数,阈值𝜆,,我们可能需要对其进行微调。此外,这对于具有不同密度的集群来说不太适用。
为了帮助我们选择,我们给我们的聚类选择涂上颜色,如下图所示。我们应该只考虑蓝色和黄色、或绿色吗?
左侧有 3 个集群,右侧有 2 个集群
要选择,我们看哪一个更“坚持”。我们看到他们在一起多还是分开多?我们可以用彩色区域的面积来量化。
在左侧,我们看到蓝色区域和黄色区域和黄色区域的面积之和大于绿色区域和绿色区域的面积之和。这意味着两个峰值更加突出,因此我们决定它们是两个独立的集群。
在右边,我们看到绿色的面积要大得多。这意味着它们只是“凸起”而不是峰值。所以我们说它们只是一个集群。
在文献[2]中,这些区域的面积是持续时间、的度量,这种方法称为eom
或质量过剩。更正式的说法是*,我们在所选聚类不重叠的约束下,最大化聚类的持久性总和。*
构建层次结构
通过在 𝜆 的不同值处得到多个水平集,我们得到一个层次结构。对于多维设置,想象星团是海洋中间的岛屿。随着你降低海平面,岛屿将开始“生长”,最终岛屿将开始彼此连接。
为了能够捕捉和表示集群(岛)之间的这些关系,我们将其表示为一个层次树。这种表示推广到更高的维度,是一种自然的抽象,更容易表示为我们可以遍历和操作的数据结构。
将集群层次结构可视化为树
按照惯例,树是自上而下绘制的,其中根(所有东西都是一个集群的节点)在顶部,树向下生长。
自上而下可视化树
如果您正在使用 HDBSCAN 库,您可能会使用clusterer.condensed_tree_.plot()
API。下面显示的结果与上面显示的结果相同。圈出的节点对应于所选择的簇,分别是黄色、蓝色和红色区域。
来自 HDBSCAN 的压缩树图
使用 HDBSCAN 时,这个特定的图可能有助于评估集群的质量,并有助于微调超参数,我们将在*“参数选择”*部分讨论。
局部近似密度
在上一节中,我们访问了底层发行版的真实 PDF。然而,对于真实世界的数据,基本分布几乎总是未知的。
因此,我们必须使用经验密度来估计 PDF。我们已经讨论了一种方法,使用直方图。然而,这只对一维数据有用,并且随着维数的增加,计算变得困难。
我们需要其他方法来得到经验概率密度函数。这里有两种方法:
- 计算𝜀-radius 内特定点的邻居数量
- 寻找到第 K 个最近邻居的距离(这是 HDBSCAN 使用的)
计算𝜀-radius 境内的邻居
对于每个点,我们围绕该点画一个𝜀-radius 超球,并计算其中的点数。这是我们对空间中该点密度的局部近似。
使用邻居计数估计概率密度函数
我们对每个点都这样做,并将估计的 PDF 与 PDF 的真实值进行比较(我们现在才这样做,因为我们模拟了数据,它的分布是我们定义的)。
对于我们的一维模拟数据,邻居计数与 PDF 的真实值高度相关。邻居的数量越多,估计的 PDF 就越高。
使用邻居计数 eps = 0.1 估计 X 的 PDF
我们看到,这种方法可以很好地估计模拟数据 x 的 PDF。请注意,这可能对数据规模和样本大小很敏感。您可能需要迭代𝜀的几个值才能获得好的结果。
到第 K 个最近邻居的距离
在这个例子中,我们得到了前面方法的补充。我们不是设置𝜀然后计算邻居,而是确定我们想要的邻居数量,并找到包含这 k 个邻居的𝜀的最小值。
K = 7 时的核心距离
结果就是我们在 HDBSCAN 中所说的核心距离。核心距离较小的点位于密度较大的区域,因此 PDF 的估计值较高。具有更大核心距离的点位于更稀疏的区域,因为我们必须行进更大的距离来包含足够多的邻居。
使用核心距离估算 X 的 PDF,其中 K = 100
我们尝试在模拟数据 x 上估计 PDF。在上面的图中,我们使用1/core_distance
作为 PDF 的估计值。正如所料,估计值与真实的 PDF 高度相关。
虽然以前的方法对数据的规模和数据集的大小都很敏感,但这种方法主要对数据集的大小敏感。如果您均等地缩放每个维度,那么所有核心距离将成比例地增加。
这里的关键要点是:
- 核心距离=密度估计值
- (回想一下)密度=概率
- 核心距离 PDF 的一些估计值
所以当我们提到一个点的核心距离时,你可以想到隐含地提到 *PDF。*基于核距离过滤点类似于从底层分布获得水平集。
每当我们有core_distance ≤ 𝜀
,就有一个隐含的pdf(x) ≥ 𝜆
在发生。𝜀和𝜆之间总是有一个映射,为了简单起见,我们将只使用符号𝜆来表示核心距离和 PDF。
找到水平集并给区域着色
回想一下,在前面的例子中,我们从 PDF 中得到一个水平集,得到的区域就是我们的聚类。这很容易,因为一个区域被表示为某种形状。但是当我们处理点的时候,我们怎么知道不同的区域是什么呢?
左边是一个小数据集,右边是相应的 PDF。
PDF 不“准确”
第一步是找到某个𝜆的水平集。我们用core_distance ≤ 𝜆
过滤区域pdf(x) ≥ 𝜆
或者过滤点。
现在我们需要找到不同的区域。这是通过将“附近”的点相互连接来实现的。“附近”是由𝜆定义的当前密度水平决定的,如果两个点的欧几里德距离小于𝜆.,我们说这两个点足够近
我们围绕每个点画一个半径为𝜆的球体。
我们将该点连接到其𝜆-球内的所有点。如果两个点相连,则它们属于同一区域,并且应该具有相同的颜色。
对每个点都这样做,我们剩下的是几个相连的部分。这些是我们的集群。
这是你在某个水平集上得到的聚类。我们继续“降低海平面”,并跟踪新的星团出现,一些星团增长,最终一些合并在一起。
降低海平面
这里有四个可视化,我们在 4 个不同的水平集显示 4 个集群。我们跟踪不同的集群,以便能够构建我们之前讨论过的层次树。
定义新的距离度量
我想强调的是,点可以在𝜆-球内,但它们仍然不会连接。它们必须首先包含在水平集内,因此对于要考虑的点来说, 𝜆 应该大于其核心距离。
两点最终连接的 𝜆 的值可以解释为某个新的距离。对于要连接的两点,它们必须是:
- 在足够密集的区域
- 彼此足够接近
对于 a 和 b ,我们根据 𝜆 得到如下不等式:
- 核心 _ 距离(a) ≤ 𝜆
- 核心 _ 距离(b) ≤ 𝜆
- 距离(a,b) ≤ 𝜆
(1)和(2)是针对*“在足够密集的区域”。③是为【彼此足够接近】*
结合这些不等式,能够直接连接 a 和 b 所需的𝜆的最小值为
mutual_reachability_distance(a, b) *=* max(
core_distance(a),
core_distance(b),
distance(a, b)
)
这在 HDBSCAN 文献中称为相互可达性距离。
投影到 𝜆-space
注意:这个“λ空间”是一个在文献中找不到的术语。这只是为了这个博客。
我们现在可以使用相互可达性距离作为新的度量,而不是使用欧几里德距离作为我们的度量。使用它作为度量相当于将点嵌入一些新的度量空间,我们将简单地称之为 𝜆-space.*
排斥效应。圆圈代表每个点的核心距离。
这具有在稀疏区域中分散接近点的效果。
由于随机样本的随机性,两个点可以在非常稀疏的区域中彼此接近。然而,我们期望稀疏区域中的点彼此相距很远。通过使用相互可达性距离,稀疏区域中的点如果过于靠近就会“排斥其他点”,而非常密集区域中的点则不受影响。
下面是使用多维缩放在𝜆-space 投影的点的图,以更具体地显示其效果。
我们可以在左边和上面看到这种排斥效应。左边的四个点是最分散的,因为它们在一个非常稀疏的空间中。
使用𝜆-space 构建层次结构树
回想一下,为了构建层次结构树,我们有以下步骤:
- 将 𝜆 设置为核心距离的最小值
- 过滤水平集中的点
- 连接最多相距 𝜆 单位的点
- 创建新集群、扩展新集群和合并集群
- 将 𝜆 设置为核心距离的下一个最小值,并转到步骤(2)
注意,在执行步骤(3)时,连接已经属于同一个连通分量的两个点是没有用的。真正重要的是集群之间的联系。将连接两个聚类的连接对应于来自两个不同聚类的具有最小相互可达性距离的点对。如果我们忽略这些“无用”的连接,只注意相关的连接,我们剩下的是一个有序的边列表,这些边总是合并两个簇(连接的组件)。
丢弃“无用”边的连接…这是最小生成树的形成吗?
这听起来可能很复杂,但如果我们将相互可达性距离视为我们的新指标 : ,这就可以简化
- 将点嵌入𝜆-space,并将每个点视为一个独立的聚类
- 找出两个不同聚类中两点之间的最短距离
- 合并两个集群
- 回到步骤(2 ),直到只有一个集群
如果这听起来很熟悉,这就是经典的凝聚聚类。这只是𝜆-space 的单一连锁集群!
在欧几里得空间中进行单链聚类可能对噪声敏感,因为噪声点可能会形成跨越岛的伪桥。通过在𝜆-space 中嵌入点,“排斥效应”使得聚类对噪声更加鲁棒。
单一链接集群相当于构建一棵最小生成树!因此,我们可以利用图论中所有有效的方法来构造 MST。
HDBSCAN 的最小生成树
参数选择和其他注意事项
现在,我们来了解一下关于 HDBSCAN、min_samples
和min_cluster_size
以及 HDBSCAN 的主要参数的说明。
最小样本数
回想一下我们的模拟数据 X,在这里我们试图估计真实的 PDF。
我们尝试使用核心距离来估计这一点,核心距离是到第 K 个最近邻居的距离。超参数 K 在 HDBSCAN API 中被称为min_samples
。
这些只是来自模拟数据的经验观察。我们将上面的图与基于不同min_samples
值的估计 PDF 进行比较。
基于 10000 样本量的估计 PDF
正如你所看到的,设置min_samples
太低会导致 PDF 非常嘈杂的估计,因为核心距离变得对密度的局部变化敏感。这可能导致虚假集群,或者一些大集群可能最终分裂成许多小集群。
设置min_samples
过高会使 PDF 过于平滑。PDF 的更精细的细节丢失了,但是至少你能够捕捉到更大更全局的底层分布结构。在上面的例子中,两个小集群被“模糊”成一个集群。
确定min_samples
的最佳值可能很困难,并且最终取决于数据。不要被我们这里使用的min_samples
的高值所误导。我们使用 1-d 模拟数据,该数据在整个域和仅 3 个集群中具有平滑的密度变化。典型的真实世界数据是完全不同的特性,较小的min_samples
值就足够了。
关于平滑效果的见解肯定适用于其他数据集。增加min_samples
的值可以平滑估计的分布,从而使小峰变平,我们可以只关注更密集的区域。
对于
min_samples
所做的事情,最简单的直觉是提供一个你希望你的聚类有多保守的度量。您提供的min_samples
值越大,聚类就越保守——更多的点将被声明为噪声,聚类将被限制在越来越密集的区域。[7]
请小心,这样做的一个可能的副作用是,它可能需要更长的运行时间,因为您必须为每个点找到更多的“最近邻居”,并且可能需要更多的内存。
最小聚类大小
请注意,我们试图估计的潜在 PDF 非常平滑,但因为我们试图用样本进行估计,所以我们预计估计值会有一些变化。
这导致一个“颠簸”的估计 PDF。让我们关注 PDF 的一小部分来说明这一点。
这种凹凸在层次树中有什么影响?这影响了集群的持久性度量。
因为小突起被解释为迷你聚类,所以真实聚类的持久性度量被划分为小段。如果不移除凸起,通过质量过剩方法可能看不到主星团。它看到的不是一座光滑的大山,而是无数迷你山峰的集合。
为了解决这个问题,我们把这些小突起弄平。这是通过“修剪”层次树中不够大的集群来实现的。这样做的效果是质量过剩方法不再被小突起分散注意力,现在可以看到主星团。
min_cluster_size
规定了在被认为是峰之前“凸起”的最大尺寸。通过增加min_cluster_size
的值,你在某种程度上平滑了估计的 PDF,使得分布的真正峰值变得突出。
因为我们可以访问 X 的真实 PDF,我们知道一个好的min_samples
值,它将产生一个平滑的估计 PDF。如果估计不错,那么min_cluster_size
就不那么重要了。
理想凝聚树
假设我们对min_samples
使用了一个较小的值,并将其设置为 100。如果你看 PDF 图,它有 PDF 的一般形状,但有明显的差异。
尽管我们知道应该只有 3 个峰值,但我们看到了许多小峰。
如果你看到一个更极端的版本,也许你甚至看不到条形的颜色了,那么这意味着层次结构树是复杂的。也许是因为估计的方差,也许这就是数据的结构。解决这个问题的一个方法是增加min_cluster_size
,这有助于 hdb 简化树,专注于更大更全局的结构。
数据转换
尽管我们已经确定 HDBSCAN 可以找到任意形状的簇,但这并不意味着不需要任何数据转换。这真的取决于你的用例。
缩放某些特征可以增加或减少该特征的影响。此外,一些变换如对数和平方根变换可以完全改变底层分布的形状。
评估集群质量
另一个需要注意的观点是,在使用 HDSCAN 时,评估和总结集群的传统方法可能没有意义。当聚类为圆形时,一些度量标准(如轮廓得分)工作得最好。
对于 sklearn 中的“月亮”数据集,K-means 比 HDBSCAN 的结果具有更好的轮廓得分,即使我们看到 HDBSCAN 中的聚类更好。
这也适用于通过获取聚类所有点的平均值来汇总聚类。这对于 K-means 非常有用,是一个很好的集群原型。但是对于 HDBSCAN 来说,可能会有问题,因为星团不是圆的。
空心圆是星团的“质心”。
均值点可以远离实际集群!这可能会非常误导人,并导致错误的见解。您可能想要使用类似于 medoid 的东西,它是最接近所有其他点的集群的一部分。但是要小心,试图用空间中的一个点来概括一个复杂的形状可能会丢失太多的信息。
这完全取决于您喜欢哪种类型的集群以及您正在处理的底层数据。请参见 Henning’s talk [5] 了解集群评估的概述。
HDBSCAN 摘要
我们完了!我们已经讨论了 HDBSCAN 的核心思想!我们将简要介绍一些具体的实现细节。
HDBSCAN 的实施大致如下:
- 计算每个点的核心距离
- 使用
mutual_reachability(a, b)
作为每个 a、b 的距离度量 - 构建一棵最小生成树
- 修剪这棵树
- 使用过剩质量选择集群
计算每个点的核心距离
这基本上是我们“估计潜在 pdf”的方式
使用相互可达性距离的最小生成树
相互可达距离是在什么层次的 𝜆 两个在一起的点将连接的总结。这就是我们使用的新度量标准。
构建最小生成树相当于𝜆-space 中的单链接聚类,这相当于遍历每个可能的水平集并跟踪聚类。
修剪生成的树
简而言之,因为我们得到的只是一个估计的 PDF,我们期望有一些差异。因此,即使底层分布非常平滑,估计的 PDF 也可能非常不平坦,因此导致非常复杂的层次树。
我们使用参数min_cluster_size
来平滑估计分布的曲线,因此,将树简化为condensed_tree_
用“质量过剩”来选择星团
使用浓缩树,我们可以估计每个集群的持久性,然后计算出最佳集群,如前一节所述。
参考
[1]https://hdb scan . readthedocs . io/en/latest/how _ hdb scan _ works . html
[2]麦金尼斯,利兰和约翰希利。加速分层密度聚类。 arXiv 预印本 arXiv:1705.07321 (2017)。
[3]约翰·希利。 HDBSCAN,基于快速密度的聚类,方法和原因。 PyData 纽约。2018
[4]哈斯蒂、特雷弗、罗伯特·蒂布拉尼和杰罗姆·弗里德曼。统计学习的要素:数据挖掘、推理和预测。斯普林格科学&商业媒体,2009 年。
[5]克里斯蒂安·亨宁。评估聚类质量。PyData 纽约。2018.
[6]亚历山德罗·里纳尔多。 DeBaCl:一种基于密度的聚类算法及其性质。
[7]https://hdb scan . readthedocs . io/en/latest/parameter _ selection . html
[8]坎佩洛、里卡多·JGB、达武德·穆拉维和约尔格·桑德。"基于层次密度估计的密度聚类."亚太知识发现和数据挖掘会议。施普林格,柏林,海德堡,2013。
照片由【Dan Otis】【on】【不连续】 , 【泰 51】【凯西荷纳】 【对 【非致命】 , 】
了解 Oracle 中的层次结构
这篇文章讲述了在 Oracle 数据库中处理分层数据。它通过示例给出了详细的描述,从概念上解释了层次查询,并构建了层次查询以满足业务需求。
由Edvard Alexander lvaag在 Unsplash 上拍摄的照片
树形结构
在现实生活中,有很多情况下,一组特定的数据依赖于另一组数据,而另一组数据又依赖于另一组数据,如此等等。因此,这种数据的逻辑结构形成了树形结构。关系数据库不以分层的方式存储数据。因此,通常很难在关系数据库中浏览这些数据。Oracle 提供了许多分层查询特性,使我们能够处理这样的数据。
从连接方式开始
Oracle 的“START WITH CONNECT BY”子句允许非常有效地遍历分层数据。为了理解它的工作原理,我们来看一个示例表,其中包含如下示例数据:
CREATE TABLE ENTITIES(PARENT_ENTITY VARCHAR2(20 BYTE),CHILD_ENTITY VARCHAR2(20 BYTE),VAL Number);
现在在其中插入一些示例值。
Insert into ENTITIES (PARENT_ENTITY, CHILD_ENTITY,VAL) Values (NULL,’a’,100);Insert into ENTITIES (PARENT_ENTITY, CHILD_ENTITY,VAL) Values (‘a’, ‘af’,50);Insert into ENTITIES (PARENT_ENTITY, CHILD_ENTITY,VAL) Values (‘a’, ‘ab’,50);Insert into ENTITIES (PARENT_ENTITY, CHILD_ENTITY,VAL) Values (‘a’, ‘ax’,50);Insert into ENTITIES (PARENT_ENTITY, CHILD_ENTITY,VAL) Values (‘ab’, ‘abc’,10);Insert into ENTITIES (PARENT_ENTITY, CHILD_ENTITY,VAL) Values (‘ab’, ‘abd’,10);Insert into ENTITIES (PARENT_ENTITY, CHILD_ENTITY,VAL) Values (‘ab’, ‘abe’,10);Insert into ENTITIES (PARENT_ENTITY, CHILD_ENTITY,VAL) Values (‘abe’, ‘abes’,1); Insert into ENTITIES (PARENT_ENTITY, CHILD_ENTITY,VAL) Values (‘abe’, ‘abet’,1); Insert into ENTITIES (PARENT_ENTITY, CHILD_ENTITY,VAL) Values (NULL,’b’,100);Insert into ENTITIES (PARENT_ENTITY, CHILD_ENTITY,VAL) Values (‘b’, ‘bg’,50);Insert into ENTITIES (PARENT_ENTITY, CHILD_ENTITY,VAL) Values (‘b’, ‘bh’,50);Insert into ENTITIES (PARENT_ENTITY, CHILD_ENTITY,VAL) Values (‘b’, ‘bi’,50);Insert into ENTITIES (PARENT_ENTITY, CHILD_ENTITY,VAL) Values (‘bi’, ‘biq’,10);Insert into ENTITIES (PARENT_ENTITY, CHILD_ENTITY,VAL) Values (‘bi’, ‘biv’,10);COMMIT;
数据层次结构如下所示:
要遍历此类数据,Oracle 中的 SQL 查询可以写成:
SELECT parent_entity,child_entity
FROM entities
START WITH parent_entity is NULL CONNECT BY PRIOR child_entity= parent_entity
现在,让我们分析一下这个查询。
**开始于:**指定层次的根行,即从哪里开始“行走”。
CONNECT BY: 指定层次结构中父行和子行之间的关系。
**先验:**一元运算符,用于实现递归条件,即实际行走。
上述查询的结果如下:
执行过程如下:
a.>开始条件决定了开始点。在我们的例子中,我们将开始条件指定为 parent_entity 为 NULL。因此,它将标记 parent_entity 为 NULL 的那些行。
b.>条件 CONNECT BY PRIOR child _ entity = parent _ entity 将导致子实体值成为父实体,直到遍历整个分支。因此,在我们的例子中,值“a”将成为父值,它将搜索其子值。返回的第一行将是:
a 的孩子是 ab,af,ax。它现在将 ab 作为父节点并搜索其子节点。因此,到目前为止的结果集将是:
’ ab '的孩子是 abc 和 abd 和 abe。它现在将搜索 abc 的子节点。因为
“abc”没有任何子级,它将在结果集中返回它,并将搜索 abd 的子级。它也没有任何子元素,所以它也将在结果集中返回这个。到目前为止的结果集是:
它现在会寻找“亚伯”的孩子。它有两个孩子:abes 和 abet。它现在将搜索 abes 的子节点,然后搜索 abet。abes 和 abet 都没有孩子。因此,结果集将如下所示:
它现在将搜索 af 的孩子。它没有任何子元素,因此将在结果集中返回。同样,ax 将在结果集中返回。
这就完成了对步骤 a 中返回的第一行的遍历。现在将对步骤 1 中返回的第二行重复相同的过程。最终结果集将如下所示:
遍历方向
层次结构可以双向遍历:自顶向下或自底向上。CONNECT BY 子句中的条件和运算符“PRIOR”的位置决定了遍历的方向。
下面的查询以自上而下的方向遍历行。
**SELECT parent_entity,child_entity
FROM entities
START WITH parent_entity is NULL
CONNECT BY PRIOR child_entity= parent_entity**
如果我们将 PRIOR 放在条件的右侧,它将自下而上遍历行:
SELECT parent_entity,child_entity
FROM entities
START WITH parent_entity is NULL
CONNECT BY child_entity= PRIOR parent_entity
该查询的输出将是:
这将尝试在 START WITH 条件中找出返回行的父行。由于上述行没有父记录,因此这是返回的结果集。如果您将上述查询更改如下:
**SELECT parent_entity,child_entity
FROM entities
START WITH child_entity =’abet’
CONNECT BY child_entity= PRIOR parent_entity**
结果集将是
因此,它从 child_entity='abet '处开始自下而上地遍历数据
通过改变列 child_entity 和 parent_entity 的位置,同时保持在左侧之前,可以获得相同的结果。因此,以下查询也将产生上述结果集:
**SELECT parent_entity,child_entity
FROM entities
START WITH child_entity =’abet’
CONNECT BY PRIOR parent_entity = child_entity**
水平
LEVEL 是一个 Oracle 伪列,显示层次结构树中特定行的级别或等级。只有当查询中存在 CONNECT BY 子句时,才能使用它。如果我们执行下面的查询:
SELECT level, parent_entity,child_entity
FROM entities
START WITH parent_entity is NULL
CONNECT BY PRIOR child_entity= parent_entity
结果将如下所示:
使用函数 LPAD 和级别,我们可以在结果集中返回一个树状结构,如下所示:
SELECT LPAD(child_entity,Length(child_entity) + LEVEL * 10–10,’-’) tree
FROM entities
START WITH parent_entity is NULL
CONNECT BY PRIOR child_entity= parent_entity
修剪树枝
可能存在部分检索分层树和修剪分支的业务需求。比方说,在我们的数据中,我们不需要以’ ab '开头的分支和以下分支。
为此,我们将把查询修改为:
**SELECT parent_entity,child_entity
FROM entities
START WITH parent_entity is NULL
CONNECT BY PRIOR child_entity = parent_entity and child_entity !=’ab’**
结果将如下所示:
NOCYCLE 和 CONNECT_BY_ISCYCLE
如果分层数据包含循环,即如果当前行有一个也是其祖先的子行,则可能会出现这种情况。例如,在实体表上执行下面的 Insert 语句:
**insert into entities values(‘abet’,’a’);**
它添加了一行,其中“abet”是“a”的父级。但是,‘a’也是‘abet’的祖先。这将导致一个循环。如果您执行以下查询:
它添加了一行,其中“abet”是“a”的父级。但是,‘a’也是‘abet’的祖先。这将导致一个循环。如果您执行以下查询:
**SELECT parent_entity,child_entity
FROM entities
START WITH parent_entity is NULL
CONNECT BY PRIOR child_entity = parent_entity**
然后,会弹出以下错误:
若要在数据中存在 CONNECT BY 循环的情况下从查询中返回行,请按如下方式使用 NOCYCLE 参数:
**SELECT parent_entity,child_entity
FROM entities
START WITH parent_entity is NULL
CONNECT BY NOCYCLE PRIOR child_entity = parent_entity**
这不会返回错误。如果我们需要知道循环存在于哪一行,我们可以使用伪列 CONNECT_BY_ISCYCLE 。如果当前行有一个也是其祖先的子行,则返回 1。否则,它返回 0。因此,如果您运行以下查询:
**SELECT parent_entity,child_entity,CONNECT_BY_ISCYCLE isloop
FROM entities
START WITH parent_entity is NULL
CONNECT BY NOCYCLE PRIOR child_entity = parent_entity**
输出将是:
系统连接路径
如果要查看从根节点到当前节点的完整路径,可以按如下方式使用 SYS_CONNECT_BY_PATH:
**SELECT parent_entity,child_entity,SYS_CONNECT_BY_PATH(child_entity,’\’) PATH
FROM entities
START WITH parent_entity is NULL
CONNECT BY PRIOR child_entity = parent_entity**
输出将是:
对于每一行,它显示了从顶层节点到当前节点的完整路径。
在从数据库中获取信息时,遍历层次结构通常会带来挑战。使用 Oracle 的内置功能可以解决这个问题。希望这篇文章对如何做到这一点有所启发。快乐阅读!
用典型相关分析理解学校如何工作
Python 典型相关分析简介
彼得·巴克斯在 Unsplash 上的照片
美国数据科学家把大部分时间花在分析数据中的关系和模式上。然而,我们的大多数探索工具都集中在一对一的关系上。但是,如果我们想有一个更概括的观点,并找到某些变量组之间的共性和模式呢?
这篇文章包括:
- 典型相关分析的介绍,让我们一次确定变量组之间的关联。
- 一个关于学校环境如何影响学生表现的 Python CCA 教程。
那么什么是 CCA 呢?
假设我们想知道学校的氛围如何影响学生的学业成就。一方面,在他们的学习环境中,我们有关于支持、信任和协作水平的变量。另一方面,我们有学生的学习成绩和考试成绩。
CCA 让我们从整体上探索这两组变量之间的关联,而不是在单个基础上考虑它们。粗略地说,我们为这些变量集合中的每一个集合提出了一个集合表示(一个潜在变量,称为规范变量),以最大化这些变量之间的相关性。
首先,为什么 CCA 有用?
在深入研究一堆方程之前,让我们看看为什么它值得努力。
借助 CCA,我们可以:
- 找出两组变量是否独立,或者,如果有一组变量,测量它们之间的关系。
- 通过评估每个变量对规范变量(即组件)的贡献来解释它们之间关系的本质,并找出两个集合之间的共同维度。
- 将关系总结成较少的统计数据。
- 进行降维,将某些变量组的存在考虑在内。
构造标准变量
给定两组变量:
我们将第一对规范变量构建为每组变量的线性组合:
其中权重(a1,… ap),(b1,…,bq)以两个变量之间的相关性最大化的方式选择。
计算第一标准变量。
我们有一对协变量:
典型相关系数是典型变量 CVX 和 CVY 之间的相关性。
为了计算第二对协变量,我们通过添加另一个约束来执行相同的过程:每个新变量都应该与前一个变量正交且不相关。
计算第二对变量。
我们以类似的方式计算 min(p,q)对,并最终得到准备探索的 min(p,q)分量。(注意,每组中变量的数量不必相同。)
就像在 PCA 中一样,我们将数据投射到最小(p,q)潜在维度上。然而,并不是所有的都是信息丰富和重要的。让我们看看下面例子中规范变量的构成和解释。
纽约市学校数据
我们将使用来自纽约学校数据集的两个变量组:
第 1 组:环境指标
- 严格指导%
- 协作教师%
- 支持性环境%
- 有效的学校领导%
- 家庭-社区关系%
- 信任百分比
第 2 组:绩效指标
- 平均 ELA 熟练程度
- 平均数学水平
至于工具,我们将使用 pyrcca 实现。
我们从在单个数据帧中分离每个变量组开始:
import pandas as pd
import numpy as np
df = pd.read_csv('2016 School Explorer.csv')# choose relevant features
df = df[['Rigorous Instruction %',
'Collaborative Teachers %',
'Supportive Environment %',
'Effective School Leadership %',
'Strong Family-Community Ties %',
'Trust %','Average ELA Proficiency',
'Average Math Proficiency']]# drop missing values
df = df.dropna()# separate X and Y groupsX = df[['Rigorous Instruction %',
'Collaborative Teachers %',
'Supportive Environment %',
'Effective School Leadership %',
'Strong Family-Community Ties %',
'Trust %'
]]Y = df[['Average ELA Proficiency',
'Average Math Proficiency']]
X 组
Y 组
将 X 组转换成数字变量,并将数据标准化:
for col in X.columns:
X[col] = X[col].str.strip('%')
X[col] = X[col].astype('int')# Standardise the datafrom sklearn.preprocessing import StandardScaler
sc = StandardScaler(with_mean=True, with_std=True)
X_sc = sc.fit_transform(X)
Y_sc = sc.fit_transform(Y)
在相关的预处理之后,我们准备应用 CCA。请注意,我们将正则化参数设置为 0,因为正则化 CCA 超出了本文的范围(不过我们将在未来的文章中回到这个问题)。
import pyrcca
nComponents = 2 # min(p,q) components
cca = pyrcca.CCA(kernelcca = False, reg = 0., numCC = nComponents,)
# train on data
cca.train([X_sc, Y_sc])
print('Canonical Correlation Per Component Pair:',cca.cancorrs)
print('% Shared Variance:',cca.cancorrs**2)
数字背后的含义
临床相关性
>> Canonical Correlation Per Component Pair: [0.46059902 0.18447786]
>> % Shared Variance: [0.21215146 0.03403208]
对于我们的两对正则变量,我们的正则相关分别为 0.46 和 0.18。因此,学校氛围和学生表现的潜在表征确实具有 0.46 的正相关,并且共享 21%的方差。
平方典型相关通过变量集的潜在表示来表示共享方差,而不是从变量集本身推断的方差。
规范权重
为了获取分配给标准化变量(a1,…,ap)和(b1,…,bq)的权重,我们使用cca.ws
:
cca.ws>> [array([[-0.00375779, 0.0078263 ],
[ 0.00061439, -0.00357358],
[-0.02054012, -0.0083491 ],
[-0.01252477, 0.02976148],
[ 0.00046503, -0.00905069],
[ 0.01415084, -0.01264106]]),
array([[ 0.00632283, 0.05721601],
[-0.02606459, -0.05132531]])]
例如,给定这些权重,集合 Y 的标准变量用以下公式计算:
分配给标准化变量的权重。
其中权重可以被解释为线性回归模型中的系数。我们应该考虑到,在解释单个变量对协变量的贡献时,不建议过分依赖权重。
原因如下:
- 不同样品的重量存在差异。
- 多重共线性对权重的影响很大(对于相同上下文的变量组来说,多重共线性很常见)。
更常见的做法是依赖规范加载。
规范载荷
规范载荷只不过是原始变量和那个集合的规范变量之间的相关性。例如,为了评估信任在学校环境表征中的贡献,我们计算变量集合 x 的变量信任和结果变量之间的相关性。
计算第一个变量中 Y 组的载荷:
print('Loading for Math Score:',np.corrcoef(cca.comps[0][:,0],Y_sc[:,0])[0,1])
print('Loading for ELA Score:',np.corrcoef(cca.comps[0][:,0],Y_sc[:,1])[0,1])>> Loading for Math Score: -0.4106778140971078
>> Loading for ELA Score: -0.4578120954218724
规范协变量
最后,我们可能希望直接访问协变量值,无论是为了可视化还是任何其他目的。
为此,我们需要:
# CVX
cca.comps[0]
# First CV for X
cca.comps[0][:,0]
# Second CV for X
cca.comps[0][:,1]
# CVY
cca.comps[1]
# First CV for Y
cca.comps[1][:,0]
# Second CV for Y
cca.comps[1][:,1]
差不多就是这样!
希望您发现这很有帮助,并在您的 EDA 例程中更多地使用 CCA。
-继续探索
参考:
[1]比连科·n·加兰。,2016,pyr CCA:Python 中的正则化核典型相关分析及其在神经成像中的应用,神经信息数学前沿
[2] Dattalo,P.V .,2014 年,使用正交旋转进行典型相关分析的演示,以便于解释
理解假设检验
从抽样分布到中心极限定理再到假设检验
来源: Julius_silver ,via pixabay (cc0)
在这篇博客中,我试图通过一系列的思考过程来理解假设检验。我先问一个问题:
单个样本的平均值如何揭示总体的真实平均值? ”
这些思考过程包括:
1.任意指定一个值作为样本平均值的 采样分布的平均值,****
2.用总体的标准偏差表示抽样分布的标准误差,
3.使用从单个样本计算的标准偏差来近似总体的标准偏差。
我将向您介绍上面使用的所有术语和概念,并用一个示例来说明它们。最后,我将简单讨论一下我在假设检验的背景下学到了什么。尝试写这篇博客对我帮助很大,我希望它也能帮助你。
假设我们的第一个目标是计算出总体中某个参数的平均值。比如韦斯特伍德高中所有学生的平均身高。我们可能不想测量每个学生的身高,而是想随机选择一个样本,例如 30 个学生(样本大小为 30),然后测量他们的身高并计算平均值。为了彻底起见,如果可能的话,我们可能想要重复随机抽样,比如说,20 次以上。请注意,这里允许再次随机选择一名学生。然后,我们可以绘制出我们计算的每个样本平均值的分布图,该图可能有点像图 1 所示。我们称这个图为“ 抽样,样本的分布是指 ”。
图 1:样本均值的抽样分布
在大多数情况下,我们会很偶然地得到一个样本,它的平均高度接近这个抽样分布在中心(= x)的平均值。在少数情况下,我们可能在这条曲线的尾部得到一个平均值(= x)。
L et 提个问题:“如果我们从只取 30 个学生的一个样本开始,计算平均身高(假设是 x),这个平均身高位于图 1 所示尾部位置的概率是多少? 。此时,由于我们没有进行任何其他抽样,我们不知道图 1 中抽样分布(= x)的平均值。我们也不知道分布的 标准差 (说是σx),它代表分布有多宽(可以定义为从曲线中心到频率下降到某个固定值的位置的距离)。似乎我们知道的很少。但如果我们换一种方式问问题呢:“ 如果我们任意给 x 赋一个确定的值,那么 x 位于图 1 所示尾部位置的概率是多少? ”。
让我们看看如何解决这个问题。通常我们用一个参数(说是 z)来描述 x 离 x 有多远,用σx 的单位数来表示,
其中 x 是我们收集的样本(样本大小为 30)的平均值(其值我们已经计算过了),x 是我们任意赋值 的抽样分布 的平均值,σx 是我们希望能够以某种方式估计的分布的标准误差。
有一个强大的等式(源于所谓的“ 中心极限定理 ”)将原始总体 的 标准差(= σ)与样本均值 的抽样分布的 标准差(σx)联系起来当我们一次只对原始总体的一小部分进行抽样(例如一次选取 30 名学生)并多次重复抽样(这样 a
其中σ是我们原始总体(例如,Westwood 高中的全体学生)的标准差,n 是样本量(这里是 30),σx 是我们要搞清楚的样本均值的抽样分布的标准差。
让我们更深入地看看这个等式。在一个极端的情况下,假设我们在抽样中只挑选了 1 名学生(样本量 n = 1),那么平均身高将只是这名学生的身高,抽样分布将只是原始人口的一个试探性复制,因此在这种情况下,σx 将等于σ。在另一个极端的情况下,假设我们对学生群体中的所有学生进行抽样,并计算平均值,那么每次我们都会得到相同的平均值,这就是总体的真实平均值。在这种情况下,分布变为单线,表明σx 接近零。
好的,但是我们仍然不知道σ的值是多少(而且 很可能我们永远也不会确切知道 ),那么我们如何使用等式 2 来估计σx 呢?现在我们需要做一个信念的飞跃。我们仅有的数据是我们从人群中“随机”选择的 30 名学生的身高。现在我们假设我们使用随机过程收集的 30 个数据点最终会得到一个标准差(姑且称之为 S,仅使用这 30 个数据点计算得到),即 近似于 整个总体的标准差(σ)。换句话说,由于这组 30 名学生的选择过程是随机的,这些学生身高的标准偏差将作为整个群体标准偏差的可接受估计。现在我们可以将上面的等式 1 改写为:
其中,我们将等式右侧的所有值(无论是我们从收集的样本中计算的值,如 x、S 和 n,还是 x 的 任意分配的 值)用于计算 z。
现在让我们来看一个真实的例子。我们在样本量 n = 30 的样本中收集的学生身高(以英尺为单位)列于下表 1 中,它们也绘制在图 2 的直方图中(我们稍后将讨论直方图中 5.2 英尺处的橙色线)。样本平均值(x)和标准偏差(S)可以分别计算为 5.56 英尺和 0.63 英尺。
表 1:样本大小为 30 的学生身高样本(英尺)
图 2:样本大小为 30 的学生身高样本的直方图
让我们回到我们提出的最后一个问题,稍微重新措辞一下,“如果我们将某个值指定为图 1 中采样分布的平均值(= x),那么我们得到位于尾部位置(或更远离中心的位置,如图 1 所示)的 x 的概率是多少?”。让我们再换一种说法,如果 x 的值为 5.2 英尺(我们任意指定的值),那么我们获得的样本看起来像我们收集的平均值为 5.56 英尺的样本(或者像任何其他具有更大平均值的潜在样本)的概率(机会)是多少? 。
使用上面的等式 3,我们可以计算出 z 值为(5.56–5.2)/(0.63/sqrt(30))(= 3.15),这意味着 5.56 英尺(= x)的样本平均值位于分布曲线的 0.114 英尺(= 0.63/sqrt(30))的的 3.15 倍处远离该采样分布(x = 5.2 英尺)的平均值。**
关于可能性部分呢?图 1 所示样本均值的抽样分布的本质是什么? 对于 30(或以上)的样本量,分布可以用正态(高斯)分布来表示。神奇的是,不管原始人口分布的形状如何,这都是真的。 正态分布的特征是众所周知的。例如,所有数据位于距中心正负 1 个标准偏差内的概率约为 68%,位于正负 2 和 3 个标准偏差内的概率分别约为 95%和 99.7%。概率的详细值可以在所谓的“Z 表”中找到,如表 2 所示。
表 2: Z 工作台(来自http://www.z-table.com/
在我们的例子中,我们知道我们的 Z 值是 3.15,从 Z 表中我们可以找到相应的概率值 0.9992 (99.92%的几率),这意味着有 99.92%的几率 Z 值小于 3.15 。换句话说,z 值为 3.15 或更大的 几率仅为 0.08% 。另一种说法是,假设 x 值为 5.2,那么我们的“p 值”为 0.0008。
让我们再看一下图 2。上面的陈述表明, 如果我们确实有一个 5.2 英尺的抽样分布平均值(我们假设它非常接近总体的真实平均值),那么我们收集这个平均值为 5.56 英尺的样本(样本大小为 30)的机会加上我们收集任何其他平均值大于 5.56 英尺的样本的机会只有 0.08% ,这是非常小的。也就是说,如果我们执行 1 万次采样,我们只会看到 8 次 5.56 英尺(或更大)的样本均值。所以,我们不太可能以我们收集的样本结束。换句话说,我们有 99.92%的信心不会以我们收集的样本结束。那么,我们任意选择的这个 5.2 英尺(= x)的抽样分布的平均值会不会有点偏差呢?大概如此。
我们注意到,我们任意选择的这个 5.2 英尺(= x)的采样分布的平均值可能是偏离的,并且,如果这个选择的 5.2 英尺的值是真实的,我们有 99.92%的信心,我们不会以我们收集的采样结束。是否拒绝这个 x 值取决于我们想要拥有的 置信度 ,这由我们想要接受的所谓的 置信度 来定义。一个高标准是,如果数据提供了至少 99.87% (z > = 3)的概率,我们可以拒绝我们选择的 x。 如果我们接受 z = 3 的这个值(即 99.87%的置信水平),我们可以拒绝 5.2 的 x,因为我们 99.92%的概率大于 99.87%的置信水平 。然而,如果我们决定选择一个更高的置信水平(比如 99.99%),那么 x 的这个值(= 5.2)是不能被拒绝的,这意味着在 x 的任何假设被拒绝之前,我们希望非常、非常、非常有信心。现在让我们把这个放到所谓的 假设检验 的语境中。
S omebody 这样声明,“ 西林高中学生群体平均身高不超过 5.2 英尺 ”。我们选择勉强不满足上述语句要求的最小可能值,即= 5.2 英尺,并创建一个所谓的“”为“H0: = 5.2 英尺”。如果我们的数据支持拒绝 H0,这表明任何低于 5.2 英尺也被拒绝。为了对抗零假设,我们创建另一个所谓的“ 替代假设 ”作为“ 西林高中学生群体的平均身高大于 5.2 英尺。”(《H1:>5.2 尺》)。在我们拒绝零假设之前,我们希望有 99.87% (z > = 3)的置信度。为了进行调查,我们收集了 30 名学生的样本并测量了他们的身高,结果如表 1 和图 2 所示。从前面几段的讨论中,我们可以得出这样的结论, 仅基于这个样本 ,我们就可以有把握地拒绝零假设,也就是说,我们至少有 99.87%的把握,西林高中学生群体(人口)的真实平均身高大于 5.2 英尺。
如果我们的样本量少于 30 个呢?我们可以按照与上面相同的步骤来计算 z 值,但这里我们只是将值称为“T 值”,并使用另一个名为 T 表(表 3)的表来找出概率。概率列在表的顶行,其对应的 t 值从第二列开始列出。第一列表示一个新参数,称为“自由度”(df),等于样本大小减 1。例如,如果样本大小为 15,则 df 为 14。在这种情况下,样本均值的采样分布的形状作为自由度的函数而变化。从表 3 中可以看出,在这个所谓的“t 分布”中,自由度越小,尾部越重。
表 3: T 表(来自https://www . sjsu . edu/faculty/gerst man/stat primer/T-table . pdf)
L et 再来重温一下本博客开头的第一个问题,
单个样本的平均值如何揭示总体的真实平均值?
似乎单个样本的均值和标准差可以为我们提供一定程度的信心,来判断我们是否可以安全地拒绝假设检验中总体真实均值的假设。
我希望你已经学到了一些有用的东西,或者找到了一些加强你自己信念的想法。请随意评论。
理解基于真实犯罪率的假设检验
统计推断使你能够从数据中得出有意义的结论。统计推断的过程包括首先观察一个模式,然后确定它出现的概率。概率告诉你什么是可能的,什么是不可能的,在此基础上你可以做出合理的判断。
一个非常有用的统计推断工具是 假设检验 。统计学中假设检验的概念是受司法系统中的法律程序的启发。唯一的区别是统计学使用数据进行定量评估;而在法庭上,证据被用来进行定性评估。假设检验的基本思想保持不变。统计中使用的工具经常会妨碍对全局的理解。在司法系统的背景下理解假设检验要容易得多,也有趣得多。这里的目的是使用一个真实的犯罪事件的例子来提供对假设检验的初级理解。
刑事案件
2012 年 11 月 29 日,一群男子闯入住在硅谷的百万富翁科技投资者马赫什·马图尔(Mahesh Mathur)的家。他们把他绑起来,蒙上他的眼睛,用印有小胡子的胶带堵住他的嘴。他们在房子里搜刮现金和珠宝。受害者被发现已经死亡,验尸官后来断定他是被小胡子胶带窒息而死的。三个半星期后,警方逮捕了卢卡斯·安东尼奥(和其他人一起)并指控他谋杀。
定义假设
刑事系统与 无罪推定 一起工作。除非被证明有罪,否则被告永远是无辜的。检察官的工作是通过提供证据来证明被告“有罪”。这有助于我们定义我们的假设,如下。
零假设(H0)
被告在谋杀指控中是无辜的。
替代假设(H1)
被告被指控犯有谋杀罪。
在进行定量统计评估时,研究人员扮演检察官的角色。这似乎违反直觉,但研究人员经常创建零假设,希望能够拒绝它。
显著性水平
下一步是想出一个阈值,在这个阈值我们会拒绝我们的无效假设。这个阈值也称为显著性水平。显著性水平到底是什么意思?
假设检验的最终结果是,我们要么拒绝零假设,要么拒绝失败。(注意,我们从来没有声称 H1 是正确的,但更多的是在以后)。拒绝零假设的决定是基于证据的强度,当然有一定程度的不确定性。我们承认,总是有可能观察到和我们所拥有的证据一样强的证据,只是纯粹出于偶然。这里我们需要问的问题是,在做这个决定时,我们准备承担多大的风险?
显著性水平是我们错误拒绝零假设的风险上限。
研究人员使用的最常见的显著性水平是 0.1、0.05 或 0.01(或分别为 10%、5%和 1%)。在我们的案例中,让我们假设法官将显著性水平固定为 0.05。这意味着法官准备承担 5%的风险对被告作出判决,而实际上他是无辜的。如果你听说过“排除合理怀疑有罪”这句话,当法官做出不利于被告的判决时,他愿意有至少 95%的信心。
注意:我用任意的数字来解释如何用统计假设检验进行定量评估。在现实中,不可能为法庭诉讼的信任程度指定一个固定的数字。
p 值
让我们检查一下检察官提出的证据。
- 在受害者的指甲里发现了被告的 DNA,尽管他们以前从未见过面
- 被告的犯罪历史——几起轻罪
- 一起严重的入室盗窃案
- 无家可归者、精神健康障碍者和酗酒者
我没有法学学位,但对我来说,提出的证据似乎不足以证明被告有罪。甚至被告的 DNA 出现在受害者的身体上也可以有一个合乎逻辑的替代解释(如果这让你感到不安,请继续阅读这个)。如果我们不得不分配一个数字,让我们说所有这些纯粹出于偶然的证据的组合概率是 0.12。这就是所谓的 p 值,即如果零假设为真,得到极端结果的特定概率。
p 值是在零假设为真的情况下,得到我们所拥有的极端结果的特定概率。
在我们的例子中,p 值大大高于预先确定的 0.05 的显著性水平,因此,我们无法拒绝零假设。作为一个语义问题,我们还没有证明零假设为真。我们并没有声称被告是无辜的,但是根据所提供的证据,我们并不认为被告是无辜的。
错误
在之前决定显著性水平时,我们承认存在误差。概括地说,人们需要意识到假设检验可能出现的两种主要错误。
- 第一类错误:拒绝不应该拒绝的无效假设
- 第二类错误:当你应该拒绝一个零假设时,却没有拒绝
在我看来,这两个错误非常容易理解,但很难记住,可能是因为他们懒惰的术语。记住的一个方法是这样想——把一个无辜的人送进监狱可能是最坏的情况,这是第一类错误。
第一类错误是把无辜的人送进监狱。
假设检验通常被设计用来减少 I 型错误。相比之下,第二类错误是释放罪犯。如你所见,这两个错误和*“哪个错误更糟糕”的答案之间存在权衡*通常根据具体情况而变化。选择适当的显著性水平应基于对 I 型和 II 型误差之间权衡的理解。
至此,我为你搭建了一个舞台,探索使用统计假设检验的定量评估。你可能要了解 中心极限定理 、 正态分布 和 学生的 t-分布 才能充分把握其潜力,但你肯定对假设检验有很强的直觉。祝你好运,阅读愉快!
姓名已被更改,以尊重受影响者的隐私。
参考
- 被自己的 DNA 诬陷谋杀。
- 查尔斯·惠兰的《裸体统计》
了解投资风险
由 Unsplash 上的 Shashank Sahay 拍摄的照片
关于我们如何对投资风险建模以及这是否有意义的哲学探索
在金融中,风险和回报被认为是一枚硬币的两面——你不能缺一不可。回报相当简单。我们买一只股票,等一年,然后查看我们的经纪账户。它增值了,给了我们 10%的可观回报。不错!所以投资的回报,也就是我们赚的 10%,是我们可以直接观察到的。
风险呢?那就不那么明显了。对大多数人来说,投资的风险就是赔钱的可能性。但是事前,那真的很难估计。我们只能看到实际发生的事情。你的投资表现不佳(或表现更佳)的其他替代现实无法直接观察到。我们只看到导致我们获得 10%投资回报的一系列事件。相反,这意味着我们永远也不会知道为了赚取那 10%的利润,我们承担了多大的风险。
风险的驱动因素
投资风险有两个主要驱动因素:
- 特定股票或债券的内在质量或缺乏质量。对一家公司的投资(这适用于股票和债券)是对该公司未来现金流的要求权。这篇文章让我们集中讨论股票。如果我们投资一家公司的股票,那么我们就是在赌这家公司会持续地赚越来越多的钱,让我们在这家公司的股份(购买一家公司的一些股份会让我们拥有这家公司很小一部分的所有权)变得越来越有价值。要做到这一点,该公司既需要继续经营,也需要扩大业务。像谷歌这样拥有强大品牌、资产负债表和商业模式的公司比像 WeWork 这样商业模式薄弱、管理糟糕的公司更有可能做到这一点。因此,如果基础业务的质量下降,那么在其他条件相同的情况下,这将增加投资的风险。
- 我们分析的不确定性,也就是出错的风险。当我们分析一家公司时,我们永远不能确定我们已经发现了一切,或者我们已经正确地分析和理解了一切。如果我们错误地将一个实际上脆弱的商业模式归类为强大,那么我们的投资业绩将受到影响。
对一项投资进行评估既困难又耗时,更不用说数百甚至数千项投资的投资组合了。因此,在定量金融中,投资回报的标准差(通常被称为其波动性)通常被用作其风险的近似值。
计算详情: 为了估计一项投资的风险(即波动性),我们会收集几年的周收益数据(每次观察都是投资在指定周内的收益)并取其标准差。如果我们想按年计算,那么我们将把计算值乘以 52 的平方根。
标准差作为风险的近似值
让我们首先思考为什么标准差可能被用作风险的近似值。在统计学中,我们对某事物估计的标准差越高,我们就越不确定它的真实价值。
看看下面的两条钟形曲线。它们有不同的标准差,在图上显示为不同的分布宽度。当分布很窄时,这意味着真实值位于一个很小的范围内——或者换句话说,我们非常确定值是多少。当分布很宽时,我们很不确定值是多少,必须考虑它可能等于任意数量的值的可能性。
钟形曲线比较
所以在统计学中,大的标准差等同于高的不确定性。但这真的有风险吗?让我们用一个例子来更深入地考察这一点。假设我们认为股票投资组合的预期年回报率为 7%,标准差为 14%。
这意味着,虽然我们预计股票回报通常为正,但也有很大的可能最终为负(根据我们的统计假设,有 30%的可能性是准确的)。因此,在其他条件不变的情况下,一项投资的标准差越高,其回报最终可能为负的可能性就越大。但是波动是对称的——虽然有 30%的机会经历负回报,但也有 30%的机会获得 14%或更高的回报:
波动对称地起作用
此外,不要忘记任何正态分布的随机变量都有两个关键属性——均值和标准差(关于正态分布的复习,请查看我之前的博客)。在这种情况下,平均值是我们投资的预期回报率(7%)。在金融领域,我们在计算投资风险时通常会忽略均值,而只关注标准差。如果我们退一步想想,这似乎违背了直觉。看看下面两个描述两种不同投资的风险和回报的直方图?哪个看起来风险更大?
投资 A 与 B
金融理论会告诉我们,投资 B 的风险更大,因为它的分布更广(标准差更高)。但它也有更高的回报,所以每年经历负回报的机会低于投资 A。所以就尽量不亏损而言,投资 B 其实是更安全(风险更小)的选择。关键是,如果投资的预期回报足够高,即使是非常高的标准差(相对于其他投资)也不是什么大不了的事情——尽管你最好再三检查你是如何估计预期回报的。因此,如果我们将风险视为赔钱的概率,那么相对于其标准差而言预期回报较低(且产生负回报的概率较高)的投资才是真正有风险的投资。因此,看起来一项投资的预期回报从根本上与该项投资的风险息息相关。
也就是说,在计算风险时,我们需要同时考虑均值和标准差。
那么,金融业是如何忽略一项投资的预期回报,只使用其标准差来估计风险的呢?
有效市场
这是因为模型假设市场通常是有效的。这意味着金融市场作为一个整体(所有投资者的总和)被认为在资产定价方面做得很好。
在其他条件相同的情况下,你为一项投资付出的价格决定了它的回报。如果你花 200 万美元买一家麦当劳餐厅,你可能会获得可观的回报(在很长一段时间内)。如果你能以 100 万美元买下同一家餐厅,你将获得更高的回报。如果你被骗了 400 万美元,你可能永远也赚不回你的初始投资。
因此,如果市场在吸收信息和评估风险方面做得很好,那么可以得出结论,它们在投资定价方面也做得很好。如果他们正确地为投资定价,那就意味着资本市场也正确地评估了预期回报。
现在让我们想想这意味着什么。在一个市场正确分配价格(和回报)的理想世界中,这些价格将如何设定?价格会根据投资者最关心的因素而变化。金融理论假设所有重要因素都是风险——投资风险越大,价格越低(相对于其产生的现金流而言),预期回报越高。也就是说,假设风险和收益之间存在大致线性的关系:
随着风险的增加,投资者被认为会要求更高的预期回报作为补偿
如果你仔细想想,这是一个非常简化的捷径。通过假设市场是有效的,我们不再需要担心如何计算预期回报——相反,我们依赖于一个基本信念,即投资的风险决定其价格,从而决定其回报。或者换句话说,预期收益被认为是波动率的一个明确定义的函数,而不是别的。如果我们假设波动性决定回报,那么在分析投资风险时,我们现在可以安全地忽略预期回报部分。
所以有效市场会告诉我们投资 B 是不可能的。要么我们计算的回报率太高,要么标准差太低。与投资 A(以及世界上的其他投资)相比,投资 B 的风险和收益特征“与现实脱节”(违背了功能),因此是不可能的。毕竟,正如市场效率的信奉者喜欢说的那样,“没有免费的午餐”。
但是有意义吗?
有效市场的前提是强大的。相信市场效率基本上是相信群众的智慧。数以百万计的专业人士已经花了无数个小时研究这些数据——所以你认为你对一只股票可能有的任何洞察力实际上都不是洞察力,而是已经被纳入股票价格的信息。此外,只要存在意见的多样性,市场的单个成分所犯的错误就会多样化(类似于随机森林),整体将产生平均正确的输出。
从高层次来看,这听起来确实有道理,但这里有一些反驳意见,或许可以解释为什么市场可能不总是最好的价格制定者:
- 人群的疯狂也适用。当意见多样化时,错误也会多样化。但是,如果没有多样性,每个人或多或少都相信同样的事情,错误就会扩大。比特币这样的投资泡沫就是这样产生的。
- 不是所有的投资都存在于一个有足够多的买家和卖家(或数据)来有效定价的市场中。比如,我会把初创公司股权市场描述为极度缺乏流动性、不透明和低效的(任何不幸在 2018 年或 2019 年获得 WeWork 股票报酬的人可能都不认为他们的执行价格是有效的)。就观点和意见而言,它也是一个极度缺乏多样性的国家。
- 在繁荣时期,市场往往会逐渐上涨(伴随着波动性的逐渐下降)。因此,随着对上次崩盘的记忆逐渐消失,经济扩张成为我们样本中相对较大的一部分,我们的模型将开始低估风险。虽然你可能会说我们更关心相对风险(一项投资的波动性与另一项投资或整体市场的波动性相比如何),但金融业确实使用绝对波动性和从绝对波动性得出的指标来进行风险预算(即计算出多少钱用于风险较高的投资,多少钱作为无风险现金)。因此,随着波动性下降(通过向股票等风险更高的投资增加资金)和下一次衰退的逼近,投资经理承担越来越多的风险是有危险的。
- 市场崩盘发生得非常快,通常以周计,如果不是几天的话。崩盘的巨大负回报通常会导致波动性飙升,触发各地的风险警报。突然之间,各地的投资经理都认为他们的投资组合风险极大(因为投资的波动性和投资之间的相关性增加了如此之多),并疯狂地尽快抛售高风险投资。
- 相关性上升对投资组合总风险的影响可能是巨大的。那些在繁荣时期被证明分散投资于你的美国股票的泰国股票,在市场崩盘时,几乎肯定会和你所有的其他股票投资一起下跌。在危机中,相关性达到 1。
注意到我在第 3 和第 4 条中描述的行为有些奇怪吗?这是典型的高买低卖。回想起来,那不是非常理性或有利可图的行为。但这是恐惧和波动等于风险的信念的副产品。发生这种情况的另一个原因是,随着经理们争先恐后地向上修正他们的风险估计,他们保持他们的预期回报估计不变。这使得一般的风险投资看起来不那么有吸引力,因为它突然有了更高的波动性,但仍然有相同的预期回报。
实际上,有一种更明智的方式来处理事情,不需要我们打破波动性和风险之间的联系(并抛弃所有简化的好处)。波动性是一个动态值,随着投资价格的波动而不断变化。
我们应该像看待保险报价一样看待波动性,而不是将波动性视为对资产风险的公正而准确的估计。比如说,飓风保险的价格主要取决于两个因素——对灾难风险的感知(这影响到希望购买保险的人数,也就是需求)和愿意承保的公司数量(供应)。同样,在任何时间点,投资的波动性是两个因素的函数——投资的感知风险和愿意承担风险的人数。
飓风过后,每个人都意识到风暴的破坏力有多大,因此对保险的需求非常高。与此同时,在阳光明媚的时期以过低的保费签订了过多合同的保险公司正在遭受打击,因此保险供应非常低。如果你能够在这个时候介入提供保险,你可能会获得巨大的财务回报,因为你可以赚取极高的保费。
在金融领域也是如此。当一项投资的波动性发生变化时,这是因为投资的感知风险随着愿意承担该风险的投资者数量的变化而变化。在繁荣时期,强劲的增长和利润降低了股票等投资的风险,强劲的回报让越来越多的投资者愿意持有股票。所有这些的净效应是,只要好日子还在,波动性就会持续下降。但就像保险一样,如果没有人关心股票的风险,每个人都愿意持有股票,那就意味着股票价格异常高,而他们在中短期内的预期回报将异常低。当市场崩溃、公司利润锐减时,情况就会相反。现在,股票将被视为风险极高,同时有意愿持有股票的人急剧减少(由于恐惧、失业等原因)。)—使得预期股票收益畸高。
如果我们真的相信风险和回报之间存在联系,那么随着波动性下降,我们应该同时降低对预期回报的估计。这种预期回报的降低将抵消波动性的降低,并抵消购买更多股票的冲动(它甚至可能使我们想要减少我们的股票持有量)。当波动性飙升时,我们应该向上修正我们对预期回报的估计,这将消除我们低价卖出的冲动,甚至可能促使我们低价买入。
结论
投资风险是一个极其复杂的话题,也是一个经常争论的话题。在这篇文章中,我尽我所能给你一个 10,000 英尺的视角来看事物是如何工作的。我不同意投资风险理论的某些部分,但总的来说,它是一个非常有用的工具,涉及现代金融的许多方面。但是就像我们决定开始使用的任何其他工具一样,我们应该首先了解它的局限性。我希望这有所帮助。干杯!
了解 K-Means、K-Means++和 K-Medoids 聚类算法
K-means、K-means++和 K-Medoids 聚类算法及其关系概述。本文还包括它的从头开始的实现和使用 sklearn 库。
卢卡斯·布拉塞克在 Unsplash 上的照片
聚类是一种无监督的机器学习技术,它将群体或数据点分成几个组或聚类,使得相同组中的数据点与相同组中的其他数据点更相似,而与其他组中的数据点不相似。
- 同一簇中的点彼此更接近。
- 不同簇中的点相距很远。
来源,样本数据点,(图 1)
在上面的二维数据集样本中,可以看到数据集形成了 3 个相距很远的聚类,并且同一聚类中的点彼此靠近。
聚类的衡量标准是什么?
如果聚类具有最大的簇间距离和最小的簇内距离,则被认为是最佳的。
***Notes to avoid any confusion:*****Intracluster distance:** Distance between two point in the same cluster.
**Intercluster distance:** Distance between two points in the different clusters.
(图片由作者提供)、簇内和簇间距离(图片 2)
上图(图 2)描述了什么是簇间和簇内距离。
可以使用各种评估度量来测量形成的集群的有效性。
邓恩指数:
上述函数的分子测量属于两个不同聚类的每两个点(x_i,x_j)之间的最大距离。这代表星团内距离。
上述函数的分母测量属于同一聚类的每两个点(y_i,y_j)之间的最大距离。这代表集群间距离。
具有邓恩指数最大值的聚类被认为是最好的。
剪影分析:
这用于确定聚类之间的分离程度。对于每个样本。 a_i 表示同一个聚类中所有数据点的平均距离。 b_i 代表离最近聚类中所有数据点的平均距离。
SA 的系数可以取区间[-1,1]内的值。
- SA = 0:样本非常接近相邻的聚类。
- SA = 1:样本远离相邻聚类。
- SA = -1:样本被分配到错误的聚类。
因此,我们希望系数尽可能大,并且接近 1。
有不同类型的聚类技术,我们将讨论其中的一种。
k 均值聚类:
K-Means 算法是一种基于质心的聚类技术。该技术将数据集聚类成 k 个具有几乎相等数量的点的不同聚类。每个聚类是用一个质心点来表示的 k-means 聚类算法。
什么是质心点?
形心点是代表其群集的点。形心点是集合中所有点的平均值,将在每一步中发生变化,计算方法如下:
For the above equation,
C_i: i'th Centroid
S_i: All points belonging to set_i with centroid as C_i
x_j: j'th point from the set
||S_i||: number of points in set_i
K-Means 算法的思想是找到 K 个质心点,并且数据集中的每个点将属于具有最小欧几里德距离的 K 个集合中的任一个。
图 3
根据上图(图 3),点 x_i 到所有三个质心的距离为 d1、d2、d3,点 x_i 距离质心 _3 最近,距离为 d3,因此点 x_i 将属于质心 _3 的聚类,并且该过程将对数据集中的所有点继续进行。
K 均值的成本函数:
K-Means 算法的思想是找到 K 个质心点(C1,C1,.。。C_k)通过最小化每个聚类上该点与其质心之间距离的平方和。
这个代价是 NP 难的,并且具有指数级的时间复杂度。所以我们使用劳埃德算法的近似思想。
劳埃德算法:
劳埃德算法是一种用于聚类点的近似迭代算法。该算法的步骤如下:
- 初始化
- 分配
- 更新质心
- 重复步骤 2 和 3,直到收敛。
K 均值算法的迭代实现:
步骤#1:初始化:
初始 k 形心是从数据集中随机选取的(第 27-28 行)。
步骤#2:分配:
对于数据集中的每个点,找出该点和所有质心之间的欧几里德距离(第 33 行)。该点将被分配给质心最近的聚类。
步骤#3:质心的更新:
用新的平均值更新质心的值(第 39–40 行)。
步骤#4:重复:
除非达到收敛,否则重复步骤 2 和 3。如果实现了收敛,则中断循环(第 43 行)。收敛是指质心的先前值等于更新值的情况。
结果:
初始数据集的绘图(图 4)
数据集的图(图 4)
k=2 的聚类结果图(图 5)
k=2 时的聚类图(图 5)
k=3 的聚类结果图(图 6)
k=3 时的聚类图(图 6)
K-Means++聚类:
在使用劳埃德 K 均值聚类算法寻找初始质心的情况下,我们使用了随机化。初始的 k 形心是从数据点中随机选取的。
这种选取 k-质心点的随机化导致了初始化敏感性的问题。这个问题倾向于影响最终形成的簇。最终形成的聚类取决于初始质心是如何选取的。
以下是一些聚类的结果,其中质心的初始化是不同的:
通过不同的初始化形成不同的最终聚类(图 7)
在上图(图 7)中,最终形成的簇是不同的,因为最终形成的簇依赖于质心的初始化。在上面图像的第一部分,可以观察到质心(黑色*)和星团没有正确形成。在上面图像的第二部分,可以观察到质心(黑色*)和星团的形成。
有两种方法可以避免初始化敏感性的问题:
- 重复 K-means: 多次重复算法和质心初始化,选择簇内距离小、簇间距离大的聚类方法。
- K-Means++: K-Means++是一种智能质心初始化技术。
以上两种方法可以用来避免初始化敏感性的问题,但在这两种方法中,K-Means++是最好的方法。
K-Means ++是如何工作的?
K-Means++是一种智能质心初始化技术,算法的其余部分与 K-Means 相同。质心初始化的步骤如下:
- 随机选取第一个质心点(C1)。
- 计算数据集中所有点与所选质心的距离。x_i 点到最远质心的距离可以通过下式计算
d_i: Distance of x_i point from the farthest centroid
m: number of centroids already picked
- 将点 x_i 作为新的质心,它具有与 d_i 成比例的最大概率。
- 重复上述两个步骤,直到你找到 k 形心。
使用 sklearn 实现 K-means++:
上面我们已经从头开始讨论了 K-Means 的迭代方法,为了实现 K-Means++算法,我们将使用 sklearn 库。
实施和结果演练:
- 加载或创建数据集(第 8 行)
- 为数据集实现 k-means++算法(第 9 行)
- 绘制原始数据集以观察数据集(第 25–26 行)。
数据点图(图 8)
- 找到 k 形心点
- 绘制聚类结果(圆形)和 k 形心(红色*)(第 29-32 行)。
聚类结果图(图 9)
K-Medoids 聚类:
K-Means 和 K-Means++聚类的一个问题是最终的质心是不可解释的,或者换句话说,质心不是实际的点,而是该聚类中存在的点的平均值。这是不像数据集中真实点的 3-质心坐标。
K-Medoids 聚类的思想是将最终的质心作为实际的数据点。这个结果使形心可以解释。
K-Medoids 聚类的算法被称为 Medoids 周围划分(PAM ),它与 Lloyd’s 算法几乎相同,只是在更新步骤上略有变化。
PAM 算法要遵循的步骤:
- **初始化:**与 K-Means++相同
- **赋值:**同 K 均值赋值
- **更新质心:**在 K 均值的情况下,我们正在计算聚类中所有点的均值。但是对于 PAM 算法,质心的更新是不同的。如果在一个群集中有 m 个点,则用该群集中的所有其他(m-1)个点交换先前的质心,并将该点最终确定为具有最小损失的新质心。最小损失通过以下成本函数计算:
- **重复:**与 K 均值相同
如何挑选 K 的最佳值?
K 的最佳值可以使用弯头法计算。K-Means、K-Means 和 K-Medoids 技术的成本函数是最小化簇间距离和最大化簇内距离。这可以通过最小化上面文章中讨论的损失函数来实现:
为了确定正确的“K ”,在损失和 K 之间画一个图。
损耗与 K 的关系图(图 10)
对于上述曲线,可以观察到随着“k”值的增加,损耗减少。为了找到绘制 k-聚类的最佳 k 值,我们可以选择 k=3。
感谢您的阅读!
了解 K-最近邻
kNN 的分解及其工作原理!
图片作者:特里斯特·约瑟夫
机器学习(ML)算法通常分为监督的或非监督的,这广义上指的是正在使用的数据集是否被标记。监督 ML 算法通过使用带标签的例子来预测未来的结果,将过去学到的知识应用到新数据中。本质上,对于这些类型的问题,正确的答案是已知的,并且基于预测的输出是否正确来判断估计模型的性能。
相比之下,无监督 ML 算法指的是当用于训练模型的信息既没有被分类也没有被标记时开发的算法。这些算法试图通过提取样本中的特征和模式来理解数据。
当给定的任务是分类或回归问题时,监督学习是有用的。分类问题指的是根据模型开发的特定标准将观察结果或输入数据分组到离散的“类”中。一个典型的例子是预测一张给定的图片是否显示一只猫。该模型将在包含猫图片和非猫图片的数据集上开发和训练,其中每个观察都被适当地标记。
图片作者:特里斯特·约瑟夫
虽然监督学习对于分类和回归问题都是合适的方法,但是这两者是非常不同的。回归问题是指接受一组输入数据并确定一个连续量作为输出的过程。也就是说,回归问题的目标是在给定一个输入向量的情况下预测一个特定的数字。而另一方面,分类问题预测与输入向量相关联的离散值(或标签)。
通常,分类算法基于相似性将观察结果分组在一起。例如,假设我们想将爬行动物和非爬行动物进行分组。人们可能会发现,有鳞、产卵、有毒的动物更可能是爬行动物,而不是非爬行动物。因此,如果将具有这些特征的新观察结果添加到数据集,相似性分析将发现该观察结果与爬行动物的关系比与非爬行动物的关系更密切,并且该观察结果将被归类为爬行动物。
图片作者:特里斯特·约瑟夫
要进行的一种常见的相似性分析是距离矩阵的分析。这表明,就它们的共同点而言,观测结果彼此之间相距有多远。观测值之间的距离越小,它们之间的相似性就越大,被组合在一起的可能性就越大。确定距离有多种方法,但一种相对简单的方法是 Jaccard 指数。
该指数也称为 Jaccard 相似系数,它比较两个组的成员,以查看哪些成员是相同的,哪些是不同的。相似性的度量范围从 0%到 100%,百分比越高表示相似性越大。回到爬行动物与非爬行动物的例子,假设相关特征是鳞片、有毒、产卵、有胡须和有血。如果我们把一条蝰蛇和一个人相比,他们可能只有 1/5 的共同点,相似度为 20%。因此,不应将它们归为一类。
图片作者:特里斯特·约瑟夫
这个例子是最简单的分类方法之一,它被称为最近邻。该算法的“学习部分”相当简单,因为该算法所要做的就是记住训练数据。然后,当一个新的观察值需要分类时,算法就会转到训练数据,看这个新的观察值与之前的哪个观察值最相似,然后预测它为那个组。
从表面上看,这种最近邻方法似乎很壮观,因为很可能彼此最相似的观测值应该被分组在一起。从上面的例子中我们看到,蝰蛇和人类没有太多的共同点,所以它们被归为爬行动物的可能性很小。但是回想一下,我们的任务是预测爬行动物和非爬行动物。鱼应该归入非爬行动物类,但也有有毒的鱼,有鳞,会产卵。基于相似性分析(以及前面给出的变量),鱼将被归类为回复。
因此,最近邻方法的问题是它对噪声数据非常敏感,可能导致不正确的分类。
图片作者:特里斯特·约瑟夫
通常解决这一问题的办法是修改最近邻法; k 最近邻(kNN) 。这里的想法是,我们不只是取最近的邻居,而是取一些最近的邻居(通常是奇数),并让他们“投票”预测分类应该是什么。
那么现在问题来了,我们如何选择合适的 k 呢?嗯,有三件主要的事情需要考虑。第一,随着 k 变大,算法运行的时间越长,因为它必须进行更多的比较。当训练集包含更多观察值时,情况也是如此。第二,如果 k 太小,那么邻居可能没有办法“投票”选出一个获胜者。因此,k 必须足够大。最后一点是,如果 k 太大,就会有被班级规模所左右的风险。也就是说,假设在我们的集合中有许多种类的爬行动物,并且爬行动物的数量超过了非爬行动物。鉴于 k 非常大,一个新的观察结果可能会被归类为爬行动物。
因此,选择适当 k 的最可靠方法是交叉验证。这是一种用于评估模型拟合度的技术,通过在样本数据集的不同子集上训练几个模型,然后在训练集的互补子集上评估它们。
图片作者:特里斯特·约瑟夫
kNN 的优点是学习速度非常快,它不涉及太多的数学,并且非常容易解释过程或算法得出的结果。然而,缺点是它非常占用内存,并且由于进行了大量的比较,产生预测需要很长时间(随着数据集变大)。
参考资料和其他有用的材料:
OCW . MIT . edu/courses/electrical-engineering-and-computer-science/6-034-artificial-intelligence-fall-2010/tutorials/MIT 6 _ 034 F10 _ tutor 03 . pdf
jmlr.org/papers/volume10/weinberger09a/weinberger09a.pdf
geeks forgeeks . org/find-the-JAC card-index-and-JAC card-distance-between-the-two-given-sets/
towards data science . com/machine-learning-basics-with-k-nearest-neighbors-algorithm-6a6e 71d 01761
analyticsvidhya . com/blog/2018/03/简介-k-邻居-算法-聚类/
sci kit-learn . org/stable/modules/generated/sk learn . neighbors . kneighborsclassifier . html
理解卡夫卡,就像是你设计的一样——第一部分
由内向外理解阿帕奇·卡夫卡
阿帕奇卡夫卡已经成为 IT 驱动的企业的支柱。从实时消息传递到长期存储,它在处理大数据的所有“3v”环境中几乎无处不在,即容量、多样性和速度。
作者图片
尽管它的 API 很容易理解和使用,但是它的内部结构并不简单。和往常一样,你不需要了解引擎就能成为一名优秀的飞行员,然而,更深入的研究可以区分优秀和优秀。
这是解释卡夫卡背后的构建模块的两部分系列的第一部分。这一部分将关注其主要动机,以及每个代理如何在内部存储和管理数据。第二部分将关注可伸缩性和持久性的元素。
我们将从两个非常好且雄心勃勃的朋友的角度来进行我们的探索。
创业驱动
你的一个好朋友开始在市气象部门工作。和任何新加入者一样,他充满热情和动力去完成事情。
他有一个新的实时天气预报方法的想法,但意识到遍布城市的温度计数量远远不够。他去和他的上司谈了谈,他的上司告诉他——尽管他对这个问题并不了解——并不是缺少设备,而是不可能实时处理这么多数据。但他了解你,对你来说,技术上的不可能性只不过是一个机会。
要求很简单:每两秒钟从温度计接收一次数据,然后 1)存储这些数据以供进一步研究,然后 2)将它们发送到他伟大的新模型。
你的需求草图
第一次尝试
一切都很清楚。您只需要一个单一的过程来接收测量值,存储它们,然后发送给模型。然而,由于您非常熟悉单一责任和接口分离等概念,您决定将系统解耦为两个部分: 1) 一个从温度计接收测量值、附加时间戳并存储它们的过程,以及 2) 一个每两秒钟查询一次数据库的过程,将消耗的最后一个时间戳作为偏移量传递,并将结果发送到您朋友的模型。你的问题太简单了,最难的是选择使用哪种开源 RDBMS。
在选择了您喜欢的 RDBMS 之后,您通过创建两个类开始了这个项目,一个接收测量值并存储它们,另一个读取存储的测量值并将它们发送到模型。尽管两者都将从某个地方读取和写入,但是您决定从存储解决方案的角度来命名它们,因此接收度量值并将它们写入 RDBMS 的类被命名为 Writer ,而读取度量值并将它们发送到模型的类被命名为 Reader 。
您还创建了一个名为 Measurement 的类来保存您正在处理的数据。然而,由于您喜欢习惯性的,您决定遵循通常与 RDBMS 条目相关的命名,即记录。这样你也可以让你的设计更加通用。
没费多大力气,您的第一个解决方案就准备好了:一个将记录写入您的存储解决方案的写入器和一个从那里进行消费的读取器。
你的第一次尝试
庆典和天亮后
一个星期后,你带着完全可操作的解决方案回来找你的朋友。你按下回车键,他的模型开始每两秒钟左右记录一次。他请你喝啤酒,他请客。在庆祝期间,他承认他的模型做得比预期的好,也许它能够每 1 秒钟处理一次传入的记录(他也认为记录是个好名字)。
这并没有让你感到惊讶,因为你已经习惯了需求的变化。但这次已经解决了。你所要做的就是将配置从 2 秒钟改为 1 秒钟,这样就完成了。
第二天早上,你只需将计时器从 2 秒钟改为 1 秒钟,它就能持续工作,他的模型也是如此。他花了一天时间对它进行更多的调整,到一天结束时,它变得疯狂,能够以流的方式每秒处理数百万条记录,即记录不再需要每隔 X 秒发送一次,而是从温度计接收到记录后立即发送。
为了满足这个新的请求,您考虑过用合并写进程和读进程,这样写进程就可以存储记录并在之后发送消息。但是您考虑到了在失败或过载的情况下应用重试和反压会有多麻烦。然后,您考虑在两个进程之间创建某种并行通信,这样写者可以存储记录并通过单独的队列将其发送给读者,这样读者就不需要为了获得基于时间戳的记录而查询 RDBMS。但这意味着您的解决方案会更加复杂。所以你只是从阅读器进程中移除了计时器。通过这种方式,它查询 RDBMS,获得最新插入的记录,并将它们作为一个批处理发送出去。由于您选择的存储解决方案的吞吐量相当不错,因此它是可行的。
碰壁
几天后,你的朋友打电话给你。这个解决方案——以及他的名声——迅速走红,让人们如此感兴趣,以至于他们现在正在订购一种新型温度计,这种温度计能够采集更多的数据。你非常高兴你的解决方案为你朋友的梦想提供了动力,以至于你没有立即注意到这个问题。相反,你得到了一个新温度计的样品,并让它发送一些测试数据,只是为了看看你的解决方案,第一次,失败了。
经过一些调试后,您找到了问题的根源: 新温度计使用的模式与 不同。你感到一阵颤抖。如果每个温度计都有不同的模式会怎样?如果是这样的话,从可维护性的角度来看,您的解决方案将注定失败。你应该为每一种新的温度计添加一个新的表格吗?你打电话给你的朋友,他证实了这一点。他还问是不是主要问题,你否认了。这不是问题,只是一个机会。
问题:每个新传感器都需要新的模式
更深的潜水
你发现自己处于以下情况:
1.您有两个进程,写进程和读进程,它们从给定的存储解决方案中存储和检索数据
2.您的存储解决方案需要预先知道模式,以便在编写时应用该模式
3.您不需要任何特殊的处理来写入记录,只需要按原样存储它们
4.您不需要任何特殊的查询或过滤功能,只需要能够按照记录到达的顺序检索每条记录
5.您只需要在检索记录时,即在读取记录时,知道模式
在对当前事态进行了大量思考之后,您记得曾经考虑过实现某种队列,以便将记录从作者直接传递给读者。如果该队列以某种方式通过一个字段(时间戳)持久化并可搜索,您将接近满意的解决方案,因为您可以 1) 保留您已经拥有的流程, 2) 将记录存储为二进制对象,这样它们的模式在写入时就无关紧要了, 3) 检索在给定时间戳之后存储的所有记录, 4) 在分派之前应用模式
这听起来很有希望,但从某种意义上来说,你是在提出一种新的存储解决方案,这也应该带来可伸缩性、弹性、容错等方面的需求。那将是很大的工作量,你的朋友也会同意。
政治家
第二天早上,你邀请你的朋友去喝啤酒(这次你请客)。在信息中,你提到一个革命性的想法打动了你,你必须分享它。
目前的情况
“你知道,在数据库领域,关于如何将模式应用于记录有两种想法:在写入期间和在读取期间。我称它们为 写模式 和 读模式 。前者使执行查询更快,因为您可以利用格式和数据类型,但它也有点束缚了您。每次你需要改变它的时候,整个系统都会遭到破坏。另一方面,后者让您可以根据自己的意愿灵活地更改数据,这对于我们正在进行的创新至关重要。查询变得有点困难,但是我们不需要任何特殊的过滤,只需要时间戳。你知道,我们可以继续像现在这样做,但我们在这里不是为了小壮举,是吗?所以,想想这个。现在,我们接收记录并将其发送到 RDBMS,RDBMS 将其写入事务日志,然后写入最终存储。只有在那之后,我们才能访问数据。如果我们需要对记录进行一些额外的过滤,那是没问题的,但是我们不需要。我们唯一需要的是在记录被保存到日志后立即获取它们,就像跟踪它一样。我们绝对可以应用一个名为 的花哨想法,更改数据捕获 并直接从那个日志中检索数据,但如果我们实现自己的日志,我们可以根据自己的需要优化它,我们可以同时在您的模型和我的解决方案上取得两个突破”。
你的朋友被迷住了,不仅被这个想法迷住了,还被他不知道的术语迷住了。他喝了一小口,问了一个重要的问题:我们需要什么?。你的回答很及时:就像生活中所有美好的事物一样,时间和金钱。你的自信迫使你的朋友承认,由于你们的共同努力,他得到了提升,现在他也有了研究预算。头奖!
棘手的问题
随着你朋友的一声“开始”,现在是时候把事情做完了。
您将开发一个类似日志的存储,它接收记录、附加时间戳并保存它们。在阅读器端,最常见的用例是跟踪日志,这可以通过利用页面缓存和避免磁盘寻道来有效地完成。因此,在某种意义上,您需要一个键值存储,其中时间戳将是写入和读取的关键。
你有什么想法
乍一看,这很简单,但是更新和删除呢?酸担保?时间戳的粒度应该是多少,秒、毫秒、纳秒?如果您需要检索一个特定的记录或从该记录重新开始呢?由于它的复杂性,开始感觉有点令人生畏,但是你知道方法:分而治之。
首先要做的事情
经过一番思考,您意识到即使记录与时间戳相关联,这也不是用作键的最佳数据类型。出于您的目的,时间戳代表到达的顺序,但是如果您只是在记录到达时为每个记录分配一个单调递增的标识符,那么您会获得完全相同的效果。
因为您正在向日志中添加记录,所以该标识符可以是一个长值,包含从日志开始的偏移量,其偏移量为0。长值比时间戳更容易引用。现在,您的编写器和读取器将只保留对最近处理的偏移量的引用。写入方将增加 1,并将其分配给每个新记录,读取方也将增加 1,以检索下一个记录。
更好的方法
考虑到这个更好的可访问性设计,是时候决定如何实际存储记录了。无论如何,它们都必须存储在磁盘上。如果您能保证每当需要重新处理时,整个记录集都会重新处理,那么您可以将所有记录存储在同一个文件中。但是如果需要从一个特定的偏移量开始呢?如果所有的消息都存储在同一个文件中,您就必须从头开始扫描,直到达到那个偏移量,这种效率很低,与突破性进展不太相容。
分得更多
你知道随机存取文件以及它们支持从特定偏移量读取和写入的能力。既然您已经在使用偏移量的概念来标识您的记录,那么您想到了一个聪明的主意:如果您创建两个文件,一个用于您的记录,,另一个用于偏移量,会怎么样?
如果你这样做,那么你的偏移文件将只包含关于记录偏移的信息以及它们在记录文件中的开始和结束位置。这个偏移文件可能保存在内存中,或者如果没有,可以很快加载。现在,您的编写器只需追加到这两个文件中,如果有人需要从特定的偏移量检索记录,您的阅读器可以读取偏移量文件(如果在页面缓存中还没有找到记录),在记录文件中找到开始和结束位置,然后砰!
你也认为偏移文件已经是一个足够有特色的名字,但是记录文件听起来没有那么好。经过一番思考,您意识到您的记录文件实际上是您试图实现的日志。清清楚楚!
Writer: 1)写入日志,2)索引偏移量;阅读器: 1)查找偏移量,2)读取记录
当激励的气息袭来时,你决定走得更远,也允许时间的恢复。您所要做的就是遵循与 offsets 文件相同的推理,也就是说,如果您添加另一个包含记录到达时间的时间戳和 offsets 文件中与该记录相关联的偏移量的文件,您也可以以非常高效的方式从特定时间戳检索记录。这个文件将作为记录到达时间的索引,所以您认为 timeindex 是一个好名字。
您现在有了一个解决方案,可以将偏移量附加到记录上,并在记录到达时将它们保存到一个名为logfile 的持久存储中,并在几乎相同的时间使用它们。您也可以从偏移文件中以非常有效的方式获得任意偏移的记录。最后,您甚至可以通过使用 timeindex 文件获得基于到达时间的记录。
解决了插入和查询
但是更新和删除呢?
艰难的决定
这次你似乎碰到了一堵墙。如果您想提供更新功能,您还需要以下内容:
1.一种改变记录文件的有效机制
2.偏移文件的更新
从最后一个开始,改变偏移文件并不是什么大不了的事情。更改记录文件也是可行的,但是,您最终会遇到两个问题之一:更新所有其他记录的开始和结束位置,或者浪费空间。这两种方式都与你所追求的突破不相容。
然后你意识到一些事情,一些人后来会称之为一些有趣的流表二元性理论的一部分。你正在开发的发明不需要更新,因为对一个事件的*更新只是另一个事件 。从这个角度来看,更新只是在日志尾部添加一个新事件,这是你的发明已经支持的。答对了。现在您可以说您有一个只附加日志,记录按到达日期排序。你已经能感觉到炒作了!*
最后一次除法
兴奋占据了主导,但是删除怎么办?
有一个只附加的系统是好的,因为更新只是新的事件,但是删除是必须的,否则磁盘会和你的梦想一起死去。
如果你通过允许修改日志来支持删除,你在更新中发现的同样的问题将会出现,而且你将不能再称它为仅追加*,缺少一个吸引人的词来进一步宣传。*
你回家后无法入睡,只是想着这个难题。最终你的大脑会关闭一段时间,这段时间足够你梦到大毒蛇了。你兴奋地醒来。就像蛇一点一点地吃掉自己一样,你的发明应该一点一点地吃掉自己的木头。只缺两样东西:棋子和午餐时间。
征服
在感谢伟大的修普诺斯,睡眠之神之后,你回到你的电脑前。你需要你的日志碎片,这意味着它应该成为许多。你需要决定这些部分可以有多大,什么时候它们必须消失。关于后两者,到最后,你意识到它更多的取决于系统被使用的上下文,而不是你的意愿,所以你决定把控制权交还给用户。
您的新方法将创建多个日志文件,而不是一个,每个日志文件都包含自己的索引文件。用户将指定每个日志文件应该有多大,以及每个记录必须保留多长时间。
但是如何给这些文件添加名字呢?或许有些随机性?不,不太适合突破。但是由于 1) 名字需要唯一, 2) 每个偏移量都是唯一的,并且 3) 每个文件都将负责一个偏移量范围,那么用两部分来命名这些文件怎么样,其中第一个偏移量的编号以及它所扮演的角色?
例如,假设用户希望每个文件有三个偏移量,而你有五个记录,你会有 0.index 、 0.log 和 0.timeindex 从偏移量 0* 开始并包含前三个记录,以及 3.index 、 3.log 和 3.timeindex 从偏移量 3 开始在第六条记录到达之前,从 3 开始的序列将处于活动状态,因为它还可以保存一条记录。但是当这个新记录到达时,将开始一个新的序列, 6.index 、 6.log 和 6.timeindex ,从偏移量 6 开始并准备好接收接下来的三个记录。*
在停下来思考这一切有多棒之后,你也会意识到将这些文件命名为序列并不是最好的选择,因为术语序列与整个事物(整个大毒蛇)联系更紧密。相反,这些文件是序列的段。漂亮!
美丽简单(作者图片)
现在你有了这些碎片,是时候决定何时和如何吃掉它们了。当很容易。您已经从用户那里收到了每条记录的预期持续时间,并且知道它是何时插入的。时间索引来救援)。只要计算一下,找出每次应该删除哪些记录。
另一方面,删除实际上不是删除,而是分配给每个记录的一种标签。当读者要求数据时,您只需保留这些标签并跳过与之相关的偏移量。下面是大毒蛇的真正贡献:从时间角度来看,属于同一片段的记录很可能是在彼此更接近的情况下生成的。因此,一旦属于一个段的最后一条记录被标记为删除,整个段就可以被删除,这导致了极其高效的删除和零空间浪费!
大毒蛇,自古埃及以来推动创新。
收获荣誉的时候到了
你已经取得了巨大的成就。您部署了您的新解决方案,它像魔法一样有效。你要打电话给你的朋友,但他先打给你。你甚至没有给他说话的时间,就马上开始拍摄:
伙计,这就是我们所拥有的
1。 我们可以接收包含任何格式的记录并无缝存储它们
2。 我们可以几乎实时地按到达顺序消费这些记录
3。 我们可以非常有效地找到任何特定偏移或时间的记录
4。 我们可以以一种最佳的方式删除记录
是的,我们可以!
你朋友的反应在意料之中。他向您表示祝贺,并说他已经注意到了进展,因为他的模型正在接受测量的狂轰滥炸,没有停止。他还说他打电话给你是想告诉你一些更好的消息。他的模型和你的解决方案做得非常好,现在整个州的气象部门都感兴趣了,其他州的一些城市也开始联系。他们热衷于投资任何需要的基础设施。
虽然你对自己的解决方案很兴奋,但还是让你大吃一惊。从设计的角度来看,您的解决方案很棒,但是它的可扩展性足以支持需求的巨大增长吗?如果您为每个新城市都准备了基础设施,那么如何支持多个城市呢?如何支持多个读者和作者?您如何保证耐用性,也就是说,如果磁盘出现故障怎么办?如何在编写器和读取器全速运行时执行备份?
你和你的朋友分享这些担忧,但是在这一点上没有回头路。他信任你,你的绰号是挑战。但是你累了,在回到那些疯狂的时间之前,你需要一个短暂的休假。这将帮助您考虑如何解决这些可伸缩性问题。你的朋友同意了。
你买了一张去阿尔卑斯山的票,因为当你从高处俯瞰时,你可以更好地思考。你承诺自己会带着改变世界的解决方案回来。
进一步阅读
卡夫卡文献:https://kafka.apache.org/documentation/#uses
卡夫卡 vs 其他 db:https://dzone . com/articles/is-Apache-Kafka-a-database-the-2020-update
页面缓存:https://en.wikipedia.org/wiki/Page_cache
此外,如果你喜欢这种解释,并且对 Spark 感兴趣,你可能会喜欢查看https://towardsdatascience . com/understand-Spark-as-if-you-has-designed-it-c 9c 13 db 6 AC 4b
了解卡普兰-迈耶估计量(生存分析)
里面的艾
一种生存分析技术的介绍。
什么是生存分析?
它是一组用于数据分析的统计操作,感兴趣的结果变量是事件发生前的 时间 。这些事件可能是死亡、疾病发病率、客户流失、恢复等。
它被用来估计特定人群的寿命。
它也被称为 【到事件的时间】 分析,因为目标是估计个人或一组个人经历感兴趣的事件的时间。当时间是一个重要因素时,生存分析用于比较组。其他测试,如简单的线性回归,可以比较组,但这些方法没有时间因素。它集中在两个重要的信息部分,第一个 , 参与者在研究期间是否遭受利益事件;第二个、每个被随访者的随访时间。
生存分析由以下部分组成:
- 生存数据
- 生存功能
- 分析方法
卡普兰-迈耶估计量到底是什么?
Kaplan-Meier 分析测量从某个日期到死亡、失败或其他重大事件的存活时间。也称为乘积限估计量,是一种非参数统计量,用于从寿命数据中估计生存函数。
例如,它可用于计算:
- 失业后人们会失业多久?
- 接受生育治疗的夫妇需要多久才能怀孕?
- 机器零件的无故障时间。
- 治疗后存活时间。(在医学实践中)
Kaplan Meier 估计值的图表是一系列递减的水平步长,在给定足够大的样本量的情况下,它接近该总体的真实生存函数。卡普兰-迈耶估计经常被使用,因为它的假设易于使用。
通过示例了解
例如,我们将调查世界各地政治领袖的一生。在这种情况下,政治领袖是由控制统治政权的个人在任时间来定义的。出生事件是个人任期的开始,死亡事件是个人的退休。
审查可能发生,如果他们是,
- 在汇编数据集时仍在办公室(2008 年)
- 在位时死亡(包括暗杀)。
考虑以下数据(前 20 个观察值,来自 1808 个观察值),
为了估计生存函数,我们首先将使用卡普兰-迈耶估计,定义为:
其中‘d’是时间‘t’时死亡事件的数量,而‘n’是时间‘t’之前处于死亡风险中的受试者的数量。
生存函数
上图显示了政治领导人使用 Kaplar-Meier 估计值的生存函数。y 轴代表领导者在“t”年后仍然存在的概率,其中“t”年在 x 轴上。我们看到很少有领导人在位超过 20 年。
此外,我们还可以将数据分为不同的政权,如下图所示。
全球制度
令人难以置信的是,这些非民主政权还能存在多久!我们也可以通过下面的国与国的比较来理解,
重要!
在进行卡普兰-迈耶分析时,为了避免常见错误,可以记住以下几点:
- 为了对这些生存概率做出推断,我们需要对数秩检验。
- 将变量分成两类,以便将值分类为低或高。中值分界点通常用于区分高低分组,以避免像对数秩检验只比较组间存活率这样的问题。
- 卡普兰迈耶是一个单变量的方法。这意味着 Kaplan Meier 的结果很容易有偏差,夸大了预后的重要性,或者完全错过了信号。
- 人们应该研究新的预后因素的附加值,量化新的标志物改善预测的程度。
结论
Kaplan-Meier 估计因其简单和易于使用而被广泛使用。但是在实施时应该小心,因为它可能会导致错误的结果,错误的假设。
参考
- https://lifelines.readthedocs.io/en/latest/Quickstart.html
- https://www.ncbi.nlm.nih.gov/pmc/articles/PMC3932959/
- 【https://www.ncbi.nlm.nih.gov/pmc/articles/PMC3059453/
- 完整的 Python 分析,
机器学习和深度学习项目。为 pr2tik1/ml-models 开发贡献一份力量
github.com](https://github.com/pr2tik1/ml-models/blob/master/survival-analysis/kaplan-meier.ipynb)
其他职位:
根据调查数据分析开发人员和编程趋势。
pr2tik1.medium.com](https://pr2tik1.medium.com/what-happens-to-programmers-in-2020-d04a6bd7452f) [## 探索神经网络(第一部分)
理解深度学习的概念以及使用 Python 和它的神经网络的实现…
medium.com](https://medium.com/towards-artificial-intelligence/neural-networks-from-scratch-a-brief-introduction-for-beginners-d3776599aaac) [## 如何创建令人敬畏的 Github 个人资料-自述文件!
探索展示你作为开发者或开源贡献者的“GitHub 简历”的新方法。每一个开源…
towardsdatascience.com](/explore-new-github-readme-feature-7d5cc21bf02f)
理解机器学习中的潜在空间
学习深度学习的一个基本的,但经常是“隐藏的”概念
来源:Hackernoon,https://hacker noon . com/latent-space-visualization-deep-learning-bits-2-bd09a 46920 df
什么是潜在空间?
如果我必须用一句话来描述潜在空间,它仅仅意味着压缩数据的表示。
想象一个大型的手写数字(0–9)数据集,如上图所示。与其他不同数字的图像(即 3 对 7)相比,相同数字的手写图像(即 3 的图像)彼此最相似。但是我们能训练一个算法来识别这些相似之处吗?如何?
如果你训练一个模型对数字进行分类,那么也训练这个模型学习图像之间的“结构相似性”。事实上,这就是模型首先能够对数字进行分类的方式——通过学习每个数字的特征。
如果看起来这个过程对你是“隐藏的”,那是因为它确实是。潜伏,顾名思义,就是“隐藏”的意思
“潜在空间”的概念是重要的,因为它的效用是“深度学习”的核心——学习数据的特征并简化数据表示,以找到模式。
好奇吗?让我们一点一点地打破潜在空间:
我们为什么要用 ML 压缩数据?
数据压缩定义为使用比原始表示更少的比特对信息进行编码的过程。这就像取一个 19D 的数据点(需要 19 个值来定义唯一的点)并将所有信息压缩到一个 9D 的数据点中。
压缩的图解。来源:浮士德 2013
通常情况下,数据在机器学习中被压缩,以学习关于数据点的重要信息。我举个例子解释一下。
假设我们想要训练一个模型来使用完全卷积神经网络(FCN)对图像进行分类。(即输出给定图像的数字位数)。当模型“学习”时,它只是学习每一层(边缘、角度等)的特征。)并将特征的组合归因于特定的输出。
但是每次模型通过数据点学习时,图像的维度在最终增加之前首先减少。(参见下面的编码器和瓶颈)。当维数减少时,我们认为这是一种有损压缩。
卷积神经网络的描述。来源:来源:Hackernoon 潜在空间可视化。
因为要求模型然后重建压缩数据(见解码器),它必须学会存储所有相关信息并忽略噪声。这就是压缩的价值——它允许我们去掉任何无关的信息,只关注最重要的特征。
这种“压缩状态”是我们数据的潜在空间表示。
我说的空间是什么意思?
你可能想知道为什么我们称它为潜在空间。毕竟,乍一看,压缩数据可能不会引起任何形式的“空间”
但这里有个相似之处。
在这个相当简单的例子中,假设我们的原始数据集是尺寸为 5 x 5 x 1 的图像。我们将我们的潜在空间维度设置为 3×1,这意味着我们的压缩数据点是一个三维向量。
示例 5x5x1 数据
“潜在空间”中的压缩 3x1 数据示例
现在,每个压缩数据点仅由 3 个数字唯一定义。这意味着我们可以在 3D 平面上绘制这些数据(一个数字是 x,另一个是 y,另一个是 z)。
在 3D 空间中绘制的点(0.4,0.3,0.8)
这就是我们所说的“空间”。
每当我们在潜在空间中绘制点或思考点时,我们可以将它们想象为空间中的坐标,在该坐标中,*【相似】*的点在图上靠得更近。
一个自然出现的问题是,我们如何想象 4D 点或 n 维点的空间,或者甚至是非向量的空间(因为潜在空间表示不需要是 2 维或 3 维向量,并且经常不是,因为太多的信息将丢失)。
不满意的答案是,我们不能。我们是三维生物,无法理解 n 维空间(比如 n > 3)。然而,有一些工具,比如 t-SNE,可以将我们更高维度的潜在空间表征转化为我们能够可视化的表征(2D 或 3D)。(参见下面的可视化潜在空间部分。)
但是你可能想知道,什么是*“相似”图像,为什么减少我们数据的维度会使相似的图像在空间上“更接近”?*
我说的相似是什么意思?
如果我们看三张图片,两张椅子和一张桌子,我们会很容易地说这两张椅子图片最相似,而桌子与这两张椅子图片最不同。
两把椅子和一张桌子。
但是是什么让这两张椅子的图像“更相似呢?”椅子具有可区分的特征*(即靠背、无抽屉、腿间连接)。我们的模型可以通过学习边缘、角度等模式来“理解”这些。*
如前所述,这些特征被打包在数据的潜在空间表示中。
因此,随着维度的减少,对每个图像(即椅子颜色)不同的“无关”信息从我们的潜在空间表示中“移除”,因为只有每个图像的最重要的特征存储在潜在空间表示中。**
结果,当我们降低维度时,两把椅子的表现变得不那么明显,而更相似。如果我们在太空中想象它们,它们会离得更近。
*请注意,我在整篇文章中提到的“接近度”是一个模糊的术语,不是一个确定的欧几里德距离,因为空间距离有多种定义。
为什么潜在空间很重要?
潜在空间的概念绝对是耐人寻味。但是怎么用呢?我们什么时候使用它?而且最重要的是,为什么是?
我们会发现,潜在空间“隐藏”在许多我们最喜欢的图像处理网络、生成模型等中。
虽然潜在空间对大多数人来说是隐藏的,但是在某些任务中,了解潜在空间不仅是有益的,而且是必要的。
表征学习
数据的潜在空间表示包含了表示原始数据点所需的所有重要信息。
该表示法必须表示原始数据的特征。
换句话说,模型学习数据特征并简化其表示,使其更容易分析。
这是一个名为**表示学习的概念的核心,**定义为一套技术,允许系统从原始数据中发现特征检测或分类所需的表示。**
在这个用例中,我们的潜在空间表示用于将更复杂形式的原始数据(即图像、视频)转换为“更便于处理”和分析的更简单表示。
下面列出的是表征学习的具体例子。
多支管
潜在空间是表征学习的子领域流形学习中的一个基本概念。
数据科学中的流形可以理解为在某些方面“相似”的数据组或子集。
这些相似性,通常在高维空间中不易察觉或模糊不清,一旦我们的数据在潜在空间中被表示出来,就可以被发现。
以下面的“瑞士卷”为例。
***
瑞士卷的 3D 表示与相同数据的 2D 表示。来自https://datascience.stackexchange.com/a/5698的例子*
在 3D 中,我们知道存在组类似的数据点,但是用更高维度的数据来描绘这样的组要困难得多。**
通过将我们的数据维度减少到 2D,在这种情况下可以认为是一种“潜在空间”表示,我们能够更容易地区分我们数据集中的流形(相似数据的组)。
要了解更多关于流形和流形学习的知识,我推荐以下文章:
流形是在更高维度中表示数据的基本工具。但是什么是流形,它们是如何…
towardsdatascience.com](/manifolds-in-data-science-a-brief-overview-2e9dde9437e5) [## 2.2.流形学习-sci kit-学习 0.22.1 文档
寻找最基本的必需品简单的最基本的必需品忘记你的忧虑和冲突我是说最基本的…
scikit-learn.org](https://scikit-learn.org/stable/modules/manifold.html)
自动编码器和生成模型
一种常见类型的深度学习模型操纵潜在空间中数据的“接近度”,这种模型是自动编码器— 一种充当身份函数的神经网络。换句话说,自动编码器学习输出任何输入的内容。
自动编码器的一般结构
现在,如果你是这个领域的新手,你可能会想,为什么我们需要这样的模型?如果它输出的都是它自己,那似乎就没什么用了…
虽然这个推理是有效的,但是我们并不太关心模型输出什么。我们更关心模型在这个过程中学到了什么。
当我们强迫一个模型成为一个身份函数时,我们是在强迫它将所有数据的相关特征存储在一个压缩的表示中,这样在那个压缩的形式中就有足够的信息,使得模型能够“准确地”重建它。听起来熟悉吗?应该是,因为这个压缩的表象是我们的潜在空间表象(上图中的红色块)。
我们已经看到了如何在潜在空间中更容易地发现模式,因为相似的数据点往往会聚集在一起,但是我们还没有看到如何从这个潜在空间的中对点进行采样,以似乎生成“新”数据。
通过潜在空间插值生成图像。来源:*随机噪声向量的潜在空间上的双线性插值。*图 20
在上面的例子中,我们可以通过对潜在空间进行插值来生成不同的面部结构,并使用我们的模型解码器将潜在空间表示重建为与我们的原始输入具有相同维度的 2D 图像。
我说的在潜空间上插值是什么意思?
假设我已经将前一部分的椅子图像压缩成以下 2D 向量,[0.4,0.5]和[0.45,0.45]。假设桌子被压缩到[0.6,0.75]。如果我要对潜在空间进行插值,我将在潜在空间中的“椅子”聚类和“桌子”聚类之间的采样点。
我们可以将这些采样的 2D 向量输入模型的解码器,瞧!我们得到的“新”图像看起来像是介于椅子和桌子之间的变体。*new 在引号中,因为这些生成的图像在技术上并不独立于原始数据样本。
下面是潜在空间中两种椅子之间的线性插值示例。
潜在空间插值。来源:Hackernoon 潜在空间可视化。
图像生成仍然是一个活跃的研究领域,潜在空间是一个必须理解的基本概念。有关生成模型的更多用例,以及使用 GAN(生成对抗网络,另一种使用潜在空间表示的生成模型)的潜在空间插值的实践示例,请参见以下文章。
[## 生成性对抗网络(GANs)的 18 个令人印象深刻的应用
生成式对抗网络(GAN)是一种用于生成式建模的神经网络架构。生成…
machinelearningmastery.com](https://machinelearningmastery.com/impressive-applications-of-generative-adversarial-networks/) [## 生成人脸时如何挖掘 GAN 潜在空间
如何利用插值和矢量运算探索 GAN 潜在空间?生成性对抗网络,或…
machinelearningmastery.com](https://machinelearningmastery.com/how-to-interpolate-and-perform-vector-arithmetic-with-faces-using-a-generative-adversarial-network/)
可视化潜在空间
关于潜在空间可视化的更多内容,我推荐 Hackernoon 的文章,它提供了一个使用 t-SNE 算法可视化 2D 空间中数字图像之间相似性的实践示例。
特色:插值,t-SNE 投影(有 gif 和例子!)
hackernoon.com](https://hackernoon.com/latent-space-visualization-deep-learning-bits-2-bd09a46920df)
关键要点
- 潜在空间是压缩数据的简单表示,其中相似的数据点在空间上更加靠近。
- 潜在空间对于学习数据特征和寻找用于分析的更简单的数据表示是有用的。
- 我们可以通过分析潜在空间中的数据来了解数据点之间的模式或结构相似性,无论是通过流形、聚类等。
- 我们可以在潜在空间中插入数据,并使用我们模型的解码器来“生成”数据样本。
- 我们可以使用 t-SNE 和 LLE 等算法来可视化潜在空间,这些算法将我们的潜在空间表示转化为 2D 或 3D。
在学习“潜在空间”的时候,我被这个“隐藏”却又重要的概念迷住了。我希望这篇文章揭开了潜在空间表示的神秘面纱,并提供了我作为新手所渴望的对深度学习的“更深入的理解”。*
了解线性回归
数据科学的主力
尽管近年来流行更复杂和更奇特的模型,但线性回归仍然难以击败,因为它具有通用性、稳健性和可解释性。
这是一个简单但功能强大的模型,只需完成工作。如果你想进入定量领域,你需要了解它是如何工作的。
线路拟合
线性回归基本就是直线拟合。它会问问题— **“最符合我的数据的直线方程是什么?”**好看又简单。
一条线的方程式是:
Y = b0 + b1*X
目标变量 y 是我们试图建模的东西。我们想了解(也就是解释)它的变化。在统计学中,方差是不确定性的度量。这是一种价值在它的平均值附近波动的趋势。
波动性的可视化(图形由作者创建)
左图说明了这一点。绿色变量具有很高的方差,因此在其平均值(圆锥的中心)周围有很大的不确定性圆锥。红色变量具有较低的方差。在对变量一无所知的情况下,当猜测红色变量的值时,我们会对自己不会太离谱的能力更有信心。
但是在数据科学和统计学中,我们通常不担心方差,我们只担心无法解释的方差。也就是说,如果我们能找到一些其他的变量(特征变量,X ),来解释 Y 的大部分变化,那么我们是好的。
有了这样一个特征变量,如果有人问我对 Y 的预测,我只需要查找 X 等于什么,我就可以合理地确定 Y 会是什么。Y 的大部分变化已经通过引入 x 得到了解释。
相关特征有助于解释差异
那么为什么直线拟合能帮助我们解释方差呢?想想这条线的方程代表什么。它定义了 X 和 Y 之间的关系。通过将 X 乘以 b1 并与 b0 (b0 + b1*X)求和,我们可以根据给定的 X 值来预测 Y。
正相关的事物往往会一起移动(作者创建的图形)
**当然,这只适用于 X 和 Y 相关的情况(正相关或负相关)。**相关性衡量两个事物一起运动的趋势(或者在负相关的情况下彼此相反)。比如人的身高和体重是正相关的。你越高,体重越重。
所以直线拟合允许我们从已知的 X 值来推断未知的 Y 值,这要归功于 X 和 Y 之间的相关性。
我们用线性回归方程中的 X 变量来解释 Y 的方差。通过以这种方式解释方差,我们实际上减少了方差——解释方差是我们不再需要担心的方差。
关键的假设是 X 变量是容易测量的,容易理解的,并且它们本身不是一个谜。 一个常见的建模错误是使用本身无法实时观察到的变量来预测某事。用未来的数据预测未来的模型是不好的。
让我们看看这个过程是如何进行的。当我们从一个 Y 变量开始时,我们所知道的只是它的分布。在下图中,所有的方差(绿色圆锥)都是无法解释的,我们对 Y 的未来值的最佳猜测是它的平均值。
仅 Y 变量(由作者创建的图形)
现在,假设我们发现了一个与 y 正相关的特征变量 X。下图显示了 X 如何帮助解释方差。我们可以根据 Y 的 X 值将 Y 的观测值分成两部分。对于较低的 X 值,Y 的期望值为平均值 1,方差近似为左边的红色圆锥。对于较高的 X 值,Y 的期望值为平均值 2,方差近似为右边的红色圆锥。
特征 X 有助于解释 Y 的一些变化(图形由作者创建)
注意通过这种方式分割,方差(红色圆锥)相对于原始绿色圆锥有所减少。我们对 Y 的新预测,或者是均值 1,或者是均值 2,这取决于 X 是什么,比我们以前的天真预测(Y 的均值)要精确得多。
但是为什么要在两个分段上停下来呢?如果我们画更多的蓝色垂直虚线,将数据分成更多的桶,我们可以解释更多的差异,并产生更精确的预测。
这就是线性回归的作用。实际上,它绘制了大量的垂直线,将数据分成许多微小的片段。这最大化了解释的方差和我们预测的精确度。
线条拟合(作者创建的图形)
普通最小二乘法(OLS)
让我们快速了解一下线性回归如何找到最佳拟合线。虽然有一个解析解,但你可以把它看作一个优化问题。线性回归算法想要:
Find the values for **b0** and **b1**that **minimizes the sum of squared errors.**
误差是数据(黑点)和蓝线之间的距离——在下图中,红色箭头表示误差。我们平方误差,因为它可以是正的,也可以是负的。
OLS 可视化(图形由作者创建)
既然我们知道误差是实际观察值(Y,黑点)和我们的预测值(蓝线)之间的差异,我们可以更详细地写出我们的优化问题:
Find the values for **b0** and **b1**that **minimizes the sum of squared errors.**Where squared error for observation i
= **(Yi - (b0 + b1*Xi))^2**And the sum of squared error is just the sum of
(Yi - (b0 + b1*Xi))^2 for all observations.
为了计算误差平方和,我们取一个黑点和蓝线之间的每一个垂直距离,对它们求平方,然后求和。找到使误差平方和最小的 b0 和 b1 值,就能得到最佳拟合线。
回归参数
参数(b0,b1 等。)、被称为贝塔,这种回归是很重要的。在我们之前的例子中,我们只有一个特征变量。但是假设我们有三个特征变量:
Y = b0 + b1*X1 + b2*X2 + b3*X3
- b0 是 Y 轴和蓝线之间的截距,告诉我们当所有特征变量都为 0 时 Y 的期望值。
- b1 告诉我们,当保持 X2 和 X3 不变时,改变 X1 如何影响 y
- b2 告诉我们,当保持 X1 和 X3 不变时,改变 X2 如何影响 y
- b3 告诉我们,当保持 X1 和 X2 不变时,改变 X3 如何影响 y
**解释贝塔系数的一个关键假设是,你可以保持其他特征变量不变。**在某些情况下,很难在不改变一个特性的情况下改变另一个特性。在这种情况下,我们希望包括这些交互效应(另一篇文章的主题)。
r——量化解释的差异量
最后,我们想弄清楚我们能够解释多少原始方差(因为目标是解释,因此减少方差)。
我们可以通过计算 R:
R^2 = 1 - (residual sum of squares / total sum of squares)
残差(也称为误差)平方和与我们预测误差的方差(黑点和蓝线之间的垂直距离)成比例。预测误差是实际观测值和我们的模型预测值之间的差异。这是一种无法解释的方差的度量。
总平方和与我们试图解释的(Y 的)总方差成正比——它实际上是 Y 方差公式的分子。
残差平方和与总平方和的比率衡量运行线性回归后未解释的方差的比例。换句话说,它是不确定性的比例,我们不能用线性回归使其消失。
因为 R 是 1 减去该比率,所以它可以被认为是解释的方差的比例:
**R^2**
= 1 - (residual sum of squares / total sum of squares)
= 1 - proportion of variance unexplained
= **proportion of variance explained**Since:
prop. of variance unexplained + prop of variance explained = 1
因此,如果在运行我们的回归后,我们看到 R 为 0.90,这意味着我们在模型中包括的 X 变量有助于解释 y 中观察到的 90%的方差。换句话说,我们成功地解释了我们感兴趣的变量周围的许多不确定性。
在以后的文章中,我们会做一些例子,看看当一些支持线性回归的假设被违反时会发生什么。在那之前,干杯!
如果你总体上喜欢这篇文章和我的写作,请考虑通过我在这里的推荐链接注册 Medium 来支持我的写作。谢谢!
延伸阅读:
当我们试图预测未来时,到底发生了什么
towardsdatascience.com](/the-art-of-forecasting-d2a8806b7aa0) [## 用一个简单的例子理解逻辑回归
逻辑回归是进行分类的基本工具之一。作为未来的数据科学家,我…
towardsdatascience.com](/understanding-logistic-regression-using-a-simple-example-163de52ea900) [## 理解最大似然估计
这是什么?它是用来做什么的?
towardsdatascience.com](/understanding-maximum-likelihood-estimation-mle-7e184d3444bd)
了解线性回归
线性回归背后的数学详细解释
作者图片
假设你想从网上商店买一台新电脑(你最感兴趣的是它有多少内存),你在首页上看到一些 4GB 的电脑售价 100 美元,还有一些 16 GB 的售价 1000 美元。你的预算是 500 美元。因此,你在脑子里估计,根据你目前看到的价格,一台 8 GB 内存的电脑应该在 400 美元左右。这将符合您的预算,并决定购买一台 8 GB 内存的电脑。
这种估计几乎可以在你的大脑中自动发生,而不知道它被称为线性回归,也不需要在你的大脑中明确计算回归方程(在我们的例子中:y = 75x - 200)。
那么,线性回归是什么*?*
我将尝试简单地回答这个问题:
线性回归就是根据一些已知的量来估计一个未知量的过程(这是回归部分),条件是未知量可以通过只使用标量乘法和加法(这是线性部分)这两种运算从已知量中获得。我们将每个已知量乘以某个数,然后将所有这些项相加,得到未知量的估计值。
当它以正式的数学方式或代码描述时,它可能看起来有点复杂,但事实上,如上所述的简单估计过程,你可能在听到机器学习之前就已经知道了。只是你不知道这叫线性回归。
现在,让我们深入线性回归背后的数学。
在线性回归中,我们获得未知变量的估计值(用 y 表示;我们的模型的输出)通过计算我们的已知变量(用 xᵢ表示;输入),我们向其添加了偏置项。
其中 n 是我们拥有的数据点的数量。
添加偏差与想象我们有一个始终为 1 的额外输入变量并且只使用权重是一样的。我们将考虑这种情况,使数学符号变得简单一点。
其中 x₀ 永远是 1, w₀ 是我们之前的 b
为了使记法简单一点,我们将从上面的和记法过渡到矩阵记法。上述等式中的加权和相当于所有输入变量的行向量与所有权重的列向量的乘积。那就是:
上面的等式只针对一个数据点。如果我们想一次计算更多数据点的输出,我们可以将输入行连接成一个矩阵,用 X 表示。对于所有这些不同的输入行,权重向量将保持不变,我们将用 w 表示。现在 y 将用于表示具有所有输出的列向量,而不仅仅是单个值。这个新方程的矩阵形式如下:
给定一个输入矩阵 X 和一个权重向量 w ,我们可以使用上面的公式很容易地得到 y 的值。假设输入值是已知的,或者至少是容易获得的。
但问题是:我们如何获得权重向量?
我们将从例子中学习它们。为了学习权重,我们需要一个数据集,其中我们知道 x 和 y 值,基于这些我们将找到权重向量。
如果我们的数据点是定义我们的回归线所需的最小值(比输入数多 1),那么我们可以简单地求解方程(1)得到 w :
我们称这个东西为回归线,但实际上,它是一条只针对 1 个输入的线。对于 2 个输入,它将是一个平面,对于 3 个输入,它将是某种“3D 平面”,等等。
大多数情况下,上述解决方案的要求并不成立。大多数时候,我们的数据点不会完全符合一条直线。我们的回归线周围会有一些随机噪声,我们将无法获得 w 的精确解。然而,我们将尝试为 w 获得的最佳可能解,以使误差最小。
如果等式(1)无解,这意味着 y 不属于 X 的列空间。因此,我们将使用 y 在 X 的列空间上的投影,而不是 y 。这是离 y 最近的向量,也属于 X 的列空间。如果我们将等式两边相乘。(1)通过 X 的转置,我们将得到一个考虑了这个投影的方程。你可以在麻省理工学院的吉尔伯特·斯特朗的讲座中找到更多关于解决这个问题的线性代数方法。
虽然这个解决方案对 X 的限制比我们之前的方案要少,但是在某些情况下还是不行;我们将在下面看到更多关于这个问题的内容。
另一种获得 w 的方法是使用微积分。主要思想是定义一个误差函数,然后用微积分找到最小化这个误差函数的权重。
我们将定义一个函数 f ,它将一个权重向量作为输入,并给出这些权重将在我们的线性回归问题上产生的平方误差。该函数只是查看数据集的每个真实 y 值与回归模型的估计 y 值之间的差异。然后将所有这些差值平方并相加。在矩阵符号中,这个函数可以写成:
如果这个函数有最小值,它应该在临界点之一(梯度 ∇f 为 0 的点)。所以,我们来找临界点。如果你不熟悉矩阵微分,可以看看这篇维基百科的文章。
我们从计算梯度开始:
然后我们将其设为 0,并求解 w :
我们有一个关键点。现在我们应该弄清楚它是最小值还是最大值。为此,我们将计算 Hessian 矩阵并建立函数 f 的凸凹性。
现在,我们可以观察到关于 H 的什么?如果我们取任意实值向量 z 并将其乘以 H 的两边,我们将得到:
因为 f 是一个凸函数,这意味着我们上面找到的 w 的解是一个极小点,这正是我们要找的。
正如你可能注意到的,我们通过使用前面的线性代数方法和这种寻找权重的微积分方法得到了相同的解决方案。我们可以认为它要么是我们用 y 到 X 的列空间上的投影代替 y 时矩阵方程的解,要么是使误差平方和最小的点。
这种解决方案总是有效吗?号码
比平凡解限制少: w = X ⁻ y 其中我们需要 X 为方阵非奇异矩阵,但还是需要一些条件才能成立。我们需要 Xᵀ X 是可逆的,为此 X 需要有完整的列秩;也就是说,它的所有列都是线性独立的。如果我们的行数比列数多,通常就满足了这个条件。但是如果我们的数据例子比输入变量少,这个条件就不可能成立。
这个 X 具有满列秩的要求与 f 的凸性密切相关。如果你看上面那个关于 f 是凸的小证明,你会注意到,如果 X 具有满列秩,那么 X z 不可能是零向量(假设 z ≠ 0 ),这意味着 H 是正定的,因此 f 是严格凸的。如果 f 是严格凸的,那么它只能有一个最小点,这就解释了为什么在这种情况下我们可以有一个封闭形式的解。
另一方面,如果 X 没有满列秩,那么会有一些 z ≠ 0 ,对于这些 X z = 0 ,因此 f 是非严格凸的。这意味着 f 可能没有单一的最小点,但是有一个同样好的最小点的山谷,我们的封闭形式的解决方案不能捕获所有的最小点。视觉上,未满列秩的情况在 3D 中看起来像这样:
来源: GeoGebra
一种即使在这种情况下也能给我们解决方案的方法是随机梯度下降 (SGD)。这是一种迭代方法,从误差函数 f 表面上的随机点开始,然后在每次迭代中,沿着梯度 ∇f 的负方向向谷底前进。
这个方法总会给我们一个结果(即使有时候需要大量迭代才能水落石出);在 X 上不需要任何条件。
此外,为了提高计算效率,它不会一次使用所有数据。我们的数据矩阵 X 被垂直分割成批。在每次迭代中,仅基于一个这样的批次进行更新。
在列秩 X 不全的情况下,解不会唯一;在“最小谷”中的所有点中,SGD 将只给出一个依赖于随机初始化和批次随机化的点。
SGD 是一种更通用的方法,它不仅仅局限于线性回归;它还用于更复杂的机器学习算法,如神经网络。但在最小二乘线性回归的情况下,我们的优势在于,由于误差函数的凸性,SGD 不会陷入局部最小值,而这在神经网络中是常见的情况。当这种方法将达到最小值时,它将是一种全球性的方法。下面是该算法的简要概述:
其中 α 是一个常数,称为学习率。
现在,如果我们插入本文中上面计算的梯度,我们会得到下面专门针对最小二乘线性回归的结果:
暂时就这样了。在接下来的两篇文章中,我还将展示如何使用一些数值库(如 NumPy、TensorFlow 和 PyTorch)实现线性回归。
更好地理解线性回归并提高您的数字技能
towardsdatascience.com](/how-to-implement-linear-regression-with-numpy-172790d2f1bc) [## 如何用 TensorFlow 实现线性回归
通过实施线性回归学习张量流基础知识
medium.com](https://medium.com/towards-artificial-intelligence/how-to-implement-linear-regression-with-tensorflow-406b2cff1ffa) [## 如何用 PyTorch 实现线性回归
通过实现线性回归学习 PyTorch 基础知识
towardsdatascience.com](/how-to-implement-linear-regression-with-pytorch-5737339296a6)
我希望这些信息对你有用,感谢你的阅读!
这篇文章也贴在我自己的网站这里。随便看看吧!
使用奇异值分解理解线性回归
介绍奇异值分解以及如何用它来解决线性回归问题
作者图片
介绍
解释线性回归的博客文章和教育材料非常常见。在大多数情况下,可能是因为大数据和深度学习偏见,这些教育资源中的大多数都采用梯度下降方法来拟合线、平面或超平面以适应高维数据。在本帖中,我们也将讨论如何解决线性回归问题,但是是通过不同的视角。更具体地说,我们将讨论线性代数最基本的应用之一,以及我们如何用它来解决回归问题。是的,我说的是奇异值分解。这种计算工具被用作解决无数问题的基础,包括使用 PCA 进行维度缩减,以及使用线性回归进行统计学习。
线性模型和线性方程组
通过线性代数的视角,回归问题简化为求解形式为 Ax = b 的线性方程组。这里, A 和 b 是已知的, x 是未知的。我们可以把 x 当做我们的模型。换句话说,我们想要为 x 求解系统,因此, x 是将 A 中的观察值与 b 中的测量值相关联的变量。
在这里, A 是一个数据矩阵。我们可以认为和的行代表同一现象的不同实例。它们可以代表提交给医院的单个患者的记录、正在出售的不同房屋的记录或不同人的脸部照片。作为补充,我们可以将矩阵 A 的列视为记录了 A 的行中每个实例的不同特征。在患者医院的例子中,这样的特征可以包括他/她到达医院时的血压,或者患者是否进行过外科手术。
另外,注意矩阵和可能有不同的形状。首先, A 可以是一个方阵。是的,这是非常不可能的(对于我们通常在数据科学中遇到的情况),但在其他方面是可能的。
矩阵和可以具有不同的形状。可以平方。它可以又宽又矮,也可以又高又瘦——图片由作者提供
第二, A 的列数可以多于行数。在这个场景中, A 会有一个又短又宽的形状。最后,(这是数据科学中最常见的情况),矩阵 A 呈现出又高又瘦的矩阵形式,行数比列数多得多。
但是我为什么要关心矩阵 A 的形状呢?
有趣的是, A 的形状将决定线性方程组是否有解,是否有无穷多个解,或者根本没有解。
先说无聊的案子。如果矩阵是平方的(行数等于列数)并且是可逆的,这意味着矩阵 A 具有满秩(所有列线性无关),这就很好地解决了问题。
如果矩阵 A 是平方且可逆的,则方程组有解——作者图片
然而,如果矩阵的列数比行数多,我们可能会遇到有无穷多个解的情况。为了形象化这个奇怪的场景,想象一个 3 × 6 的矩阵,即 3 行 6 列。我们可以认为它有一个 3D 空间和 6 个不同的向量,我们可以用它们来跨越 3D 空间。然而,要跨越一个 3D 空间,我们只需要 3 个线性无关的向量,但我们有 6 个!这留下了 3 个相关向量,可用于制定无限多的解决方案。
最后,通过类比,如果我们有一个行数比列数多的矩阵 A ,我们可以将它视为试图用比我们需要的更少的向量来跨越一个非常高维的空间。例如,想象一个 6 行 2 列的矩阵。这里,我们有一个 6D 空间,但是我们只有两个向量来跨越它。不管我们怎么努力,在最好的情况下,我们只能在 6D 上跨越一个平面。这是至关重要的,因为如果向量 b 在 A 的列空间中,我们只有 Ax = b 的解。但是在这里, A 的列空间跨越了一个更大的 6D 空间上的 2D 子空间(一个平面)。这使得向量 b 在由 A 的列所跨越的子空间中的概率变得不可能。
为了形象化这种可能性有多大,想象一个 3D 空间和一个由两个向量构成的子空间(一个 3D 平面)。现在,想象你随机选择 3 个值。这将给你一个三维空间的点。现在,问问你自己:我随机选择的点在平面上的概率是多少?
尽管如此,在我们没有一个线性方程组 Ax = b 的解的情况下(或者我们有无穷多个解),我们仍然想尽力而为。为此,我们需要找到最佳近似解。这就是奇异值分解发挥作用的地方。
SVD 的简短介绍
奇异值分解或 SVD 的主要思想是,我们可以将任意形状的矩阵 A 分解成 3 个其他矩阵的乘积。
给定任意形状的矩阵,奇异值分解将 A 分解成 3 个矩阵的乘积: U,σ, Vᵀ — 作者图片
这里, U 是一个 m × m 的方阵,σ是一个形状为 m × n 的矩形矩阵, Vᵀ 是一个形状为 n × n 的方阵。
完整的奇异值分解矩阵——作者图片
矩阵 U 和 Vᵀ 有一个非常特殊的性质。它们是 酉矩阵 。拥有像 U 和 Vᵀ 这样的酉矩阵的一个主要好处是,如果我们将这些矩阵中的一个乘以它的转置(或者反过来),结果等于单位矩阵。
另一方面,矩阵σ是对角的,它存储按相关性排序的非负奇异值。
酉矩阵的性质——作者图片
注意,由于σ矩阵是对角的,只有第一 n 行对角值值得保留。事实上,σ的最后 n 行都是用 0 填充的。为此,通常只保留σ的第一个 r × r 非负对角线值,以及相应的 r 列和 U 和 Vᵀ 行。注意 r = min(m,n) 。这通常被称为经济(或紧凑)SVD,从这一点开始,我们将假设矩阵 U 、σ和 Vᵀ 来自经济过程。
经济奇异值分解数据矩阵—作者图片
值得注意的是,经济 SVD 产生矩阵 U 和σ的形状变化(如果σ的对角线值之一为零, Vᵀ 也会发生形状变化)。如果σ的对角线值都是正的,因此 r = n ,我们丢弃 U 矩阵的右半部分( U 的正交补),这给出了 U 一个矩形 m × r 的形状。更关键的是, U ,可能还有 Vᵀ ,现在都是半酉矩阵,也就是说只有 UᵀU = VᵀV = I 。
奇异值分解提供了一个基础,允许我们根据低秩矩阵近似来重构输入信号。让我说得更清楚些。如果我们将 U 的每一列与 Vᵀ 的相应行组合,并通过相应的 σ 值缩放所得矩阵,我们将得到 A 的最佳秩 1 近似,以最小二乘法表示。
输入矩阵的秩 n 近似(一个图像)一个对于不同的秩-图像由作者提供
并且当我们继续将 U 的列与 Vᵀ 的行组合时,通过相应的 σ 进行缩放,我们得到数据矩阵 A 的下一个最佳秩 I 近似。事实上,这是奇异值分解的另一个优秀应用——数据压缩。但那是另一篇文章的主题。
使用奇异值分解的 U 、**σ、**和 Vᵀ 矩阵进行图像重建。使用前 256 个奇异值,我们得到原始输入图像的最佳秩-256 近似(它可以在视觉上完美地重建原始图像)-作者图像
正如我们之前说过的,使用非方阵 A 的问题是我们不能求逆。这就是为什么我们不能像解方阵 A 那样解方程组的主要原因。然而,如果我们不能将矩阵 A 求逆,我邀请你问自己以下问题。
什么是最佳矩阵 A⁺ ,当乘以 A 时,会尽可能接近单位矩阵 I ?
这个问题的答案解决了当方程组有无穷多解或无解时,寻找最佳可能解的问题。幸运的是,答案也在 SVD 中。
如果我们知道 SVD 总是存在(对于任何形状的矩阵),并且通过组合 U 的列、 Vᵀ 的行和奇异值 σ ,我们可以几乎完美地重构原始输入矩阵,如果我们试图对 SVD 求逆会发生什么呢?
我就不多说了吧。原来近似解决问题a⁺a≈I 的最佳矩阵 A⁺ 是 SVD 的逆。换句话说,A⁻的最佳近似值是 SVD⁻的最佳近似值。让我们跟着数学走。
通过奇异值分解求 A 的伪逆。伪逆的 A⁺ 是我们能得到的最接近作者不存在的 A⁻ — 的图像
首先,我们计算 A 的奇异值分解,得到矩阵 USVᵀ 。为了求解 x 的方程组,我需要将方程的两边乘以 SVD 矩阵的逆矩阵。幸运的是,现在很容易对 3 个 SVD 矩阵中的每一个求逆。为了求 3 个矩阵 USVᵀ 的乘积的逆,我取逆矩阵的乘积!
在对 USVᵀ 矩阵求逆后,如果我们仔细观察左边,我们可以看到大多数矩阵会疯狂地抵消,给我们留下最佳近似解 x̂ 。注意,由于矩阵 U 是半酉矩阵,只有 UᵀU = I 成立。此外,如果(并且我们假设)所有奇异值都是非负的,那么 V ᵀ 连续成为酉矩阵。因此,为了反转 U 和 Vᵀ ,我们只需将每一个乘以它们的转置,即 UᵀU = I 和 VVᵀ = I 。
找到作者的 b — 图像的投影
如果我们更进一步,将我们的最佳解 x̂ 代入 Ax̂ ,我们将看到大多数矩阵也相互抵消,直到我们到达 UUᵀ 。我们之前说过, U 是半酉矩阵, UUᵀ 不是单位矩阵。相反, UUᵀ 是 b 在 U 的列(因此是 A 的列)所生成的子空间上的投影,这是最小二乘意义上的最佳近似解,即我们找到了最小二乘解 x̂ = 最小值(ax-b‖₂).
注意,如果 A 的列数多于行数,并且有无穷多个解,那么奇异值分解会选择具有最小 2 范数的解,即 x̂ = 最小值(x̂‖₂).
SDV 线性回归
一旦我们建立了所需的 SVD 术语,我们就可以用它来寻找现实世界问题的近似解决方案。在这个例子中,我将使用波士顿房价数据集。房价数据矩阵 A 包含 506 行(代表单个房屋)和 13 列(每一列描述房屋的不同特征)。这 13 项功能包括:
- 按城镇分列的人均犯罪率
- 每个住宅的平均房间数
- 到五个波士顿就业中心的加权距离
你可以在这里看到的完整描述。
我们希望预测中值房价为 $1000。这些测量值是从 5 到 50 的真实值,它们代表我们的方程组 Ax = b 中的 b 向量。
通常,矩阵的行数比列数多得多。这意味着我们不能将 A 求反来找到 Ax = b 的解。此外,它大大降低了找到解决方案的可能性。事实上,只有当 b 是 A 的列的线性组合时,这样的解决方案才是可能的。然而,使用 SVD,我们将能够导出伪逆 A⁺ ,以找到最小二乘法的最佳近似解— ,这是向量 b 到由 a 的列所跨越的子空间上的投影。
代码非常简单,结果非常好。事实上,它们是线性模型的最佳选择。
简单说明一下,请看上面 python 代码的第 9 行。在这一行,我在数据矩阵 A 中添加了一列全 1。该列将允许线性模型学习偏置向量,该偏置向量将向超平面添加偏移,使得它不穿过原点。
看看下面的训练和测试结果。
基于奇异值分解的线性模型的训练预测—图片由作者提供
基于奇异值分解的线性模型的测试预测—图片由作者提供
目标/预测图允许我们直观地评估目标值和模型预测之间的相关性。非常准确的预测使点非常接近虚线-图片由作者提供
感谢阅读!
原载于 2020 年 10 月 12 日https://sthalles . github . io。