#线性代数 #数据分析 #机器学习 #数据点 #统计分析 #统计学 #几何中值

rstats

统计学、信息度量、数据分析、线性代数、克利福德代数、机器学习、几何中值、矩阵分解、马氏距离、外壳、多线程

201 个版本 (112 个稳定版)

2.1.12 2024 年 7 月 20 日
2.1.10 2024 年 6 月 16 日
2.0.9 2024 年 3 月 6 日
2.0.7 2023 年 12 月 20 日
0.5.9 2020 年 10 月 6 日

#6机器学习 中排名

Download history 728/week @ 2024-05-03 629/week @ 2024-05-10 239/week @ 2024-05-17 111/week @ 2024-05-24 145/week @ 2024-05-31 318/week @ 2024-06-07 347/week @ 2024-06-14 296/week @ 2024-06-21 183/week @ 2024-06-28 109/week @ 2024-07-05 158/week @ 2024-07-12 434/week @ 2024-07-19 1091/week @ 2024-07-26 270/week @ 2024-08-02 257/week @ 2024-08-09 218/week @ 2024-08-16

1,901 每月下载量
用于 7 个 crate (3 个直接使用)

Apache-2.0

165KB
2.5K SLoC

Rstats crates.io crates.io GitHub last commit Actions Status

作者:Libor Spacek

使用方法

此 crate 使用 100% 安全的 Rust 编写。

根据需要,在源文件中使用以下结构体中的任何一种

use Rstats::{RE,RError,Params,TriangMat,MinMax};

以及以下 trait 中的任何一种

use Rstats::{Stats,Vecg,Vecu8,MutVecg,VecVec,VecVecg};

以及以下辅助函数中的任何一种

use Rstats::{
    fromop,sumn,tm_stat,unit_matrix,nodata_error,data_error,
    arith_error,other_error };

或者简单地使用一切

use Rstats::*;

最新(夜间)版本始终可在 GitHub 仓库 Rstats 中找到。有时它可能(仅在某些细节上)比 crates.io 发布版本提前一些。

强烈建议阅读并运行 tests.rs 以获取使用示例。要运行所有测试,请使用单个线程,以避免以令人困惑的混合顺序打印结果

cargo test --release -- --test-threads=1 --nocapture

但是,geometric_medians,它比较多线程性能,应在多个线程中单独运行,如下所示

cargo test -r geometric_medians -- --nocapture

或者,为了快速了解所提供的方法及其用法,请阅读由自动化测试运行产生的输出。对于github仓库的每次新推送都会生成测试日志。点击最新的(顶部)一个,然后是 RstatsRun cargo test ... 当所有测试都通过时,本文件顶部的徽章会亮起绿色,点击它也会带您进入这些日志。

由于 rstats 包引起的任何编译错误,很可能是某些依赖项已过时。执行 cargo update 命令通常会解决这个问题。

简介

Rstats 脚本体积小。只实现了最佳方法,主要考虑数据分析和机器学习。它们包括多维(nd 或 '超空间')分析,即表征 d 维空间中的 n 个点云。

将数学的几个分支:统计学、信息论、集合论和线性代数结合在这个一致的包中,基于这样一个抽象:它们都在同一数据对象上操作(这里是 Rust Vecs)。唯一的不同是,有时假设其组件的顺序(在线性代数、集合论中)和有时不假设顺序(在统计学、信息论、集合论中)。

Rstats 从基本统计量、信息量、向量代数和线性代数开始。这些为多维算法提供了自包含的工具,但它们本身也很有用。

首选非解析(非参数)统计学,其中将 '随机变量' 替换为真实数据向量。概率密度和其他参数优先从真实数据(极点量)中获得,而不是从某些假设的分布中获得。

Linear algebra 使用能够表示不规则矩阵的泛型数据结构 Vec<Vec<T>>

定义并使用 Struct TriangMat 对称、反对称和三角矩阵及其转置版本,以节省内存。

我们对多维点集的处理是从第一原理构建的。这里定义和实现了某些原创概念(参见下一节)。

通常首选零中位数向量而不是常用的零均值向量。

在 n 维中,许多作者通过使用 quasi medians(每个轴上的一维 1d 中位数)来 '作弊'。准中位数是多维数据稳定表征的一个糟糕起点。实际上,当维数超过琐碎的数字时,它们比我们的 gmgeometric median)计算得更慢。

具体来说,所有这些一维度量都对轴的选择敏感,因此会受到其旋转的影响。

相比之下,我们基于 gm 的方法与轴(旋转)无关。此外,它们更稳定,因为中位数有最大的可能故障点。

我们通过方法 gmedian 及其并行版本 par_gmedian 在特质 VecVec 中计算几何中位数,并在特质 VecVecg 中计算其加权的版本 wgmedianpar_wgmedian。正是这些高效算法使得以下描述的新概念变得实用。

附加文档

有关更详细的评论和一些示例,请参阅docs.rs中的rstats。您可能需要直接访问模块源代码。这些特性为实现现有的“此crate之外”的rust Vec类型而实现,遗憾的是rust文档并没有很好地展示“对外部类型的实现”。

新概念及其定义

  • zero median points(或向量)是通过将坐标系的原点移动到中位数(在1d中),或者在nd中的gm处获得的。它们是我们对通常使用的通过将原点移动到算术平均(在1d中)或算术质心(在nd中)获得的zero mean points的替代。

  • 两个相同长度的1d集合之间的median correlation
    我们将其定义与Pearson类似,即两个归一化样本之间的角度余弦值,解释为坐标向量。Pearson首先通过从所有成分中减去其平均值来归一化每个集合。而我们是减去中位数(参见图上方的零中位数点)。这种概念上的清晰性是解释长度为d的数据样本为d维空间中的单个向量的好处之一。

  • gmedian,par_gmedian,wgmedian和par_wgmedian
    我们快速的多维geometric mediangm)算法。

  • madgm(从gm到距离的中位数)
    madmedian of absolute differences from median)的推广,到n维。在nd中用gm代替了1d中的中位数。在1d中,mad是1d数据分散的稳健度量,而madgm成为nd数据分散的稳健度量。我们将其定义为:median(|pi-gm|i=1..n),其中p1..pn是一个包含n个数据点的样本,每个数据点现在是一个向量。

  • tm_stat
    我们定义单个标量观测值x的广义tm_stat为:(x-centre)/spread,建议尽可能用中位数代替均值,用mad代替std。与常见的t-stat相比,t-stat定义为(x-mean)/std,其中std是标准差。
    这些与已知的standard z-score类似,只是中心趋势和分散是从样本(枢纽量)而不是从任何假设的总体分布中获得的。

  • tm_statistic
    我们现在将tm_stat从标量域推广到任何数量维度的向量域,将tm_statistic定义为|p-gm|/madgm,其中pnd空间中的单个观测点。对于样本中心趋势现在服务的是geometric median gm向量,而分散是madgm标量(见上文)。观测点p与中位数之间的误差距离:|p-gm|,也是一个标量。因此,无论所讨论的向量空间的维数如何,tm_statistic的陪域都是一个简单的正标量。

  • 贡献
    机器学习中的一个关键问题是如何量化每个示例(通常表示为某个大型nd集合的成员)对该集合所表示的识别概念或结果类所做的贡献。为了回答这个问题,我们定义了点pcontribution为添加p到集合中所引起的gm位移的大小。通常,离群点对gm的贡献较大,但对centroid的贡献则小。贡献不仅取决于点p的半径,还取决于所有现有集合点的半径以及它们的数量。

  • comoediance
    类似于covariance。它是一个三角对称矩阵,通过将方法covar中的几何中位数而不是通常的质心提供。因此,在协方差计算中,zero mean vectors被替换为zero median vectors。结果在对待离群点方面更加稳定。

  • outer_hull是所有零中位数点p的子集,使得没有其他点位于通过p的正常平面之外。不满足这个条件的点称为internal点。

  • inner_hull是所有零中位数点p的子集,它们不位于任何其他点的正常平面之外。请注意,在高度维的空间中,所有点可能都属于内层和外层壳,例如,当它们都位于同一个超球面上时。

  • depth是零中位数点p属于数据云的可能性的度量。更具体地说,它是将所有位于通过p的正常平面之外的单位向量之和投影到单位p上。例如,所有外层壳点由于其定义,具有depth = 0,而内层壳点具有高深度值。这是对Mahalanobis距离的改进,它具有类似的目标,但没有说明点p被包含得多好。而tm_statistic只提供关于整个云的概率信息,而不是关于其近p的局部形状的信息。

  • sigvec(签名向量)
    所有零中位数向量云在所有半球轴上的比例投影。当需要对新零中位数点p进行分类时,我们可以快速估计其方向从gm的占满程度。也可以通过将所有点直接投影到p上来完成类似的工作,但这通常非常慢,因为通常有很多这样的点。然而,signature_vector只需要预计算一次,然后只需将一个向量投影到p上。

以前已知的概念和术语

  • centroid/centre/mean
    是使所有成员点到该点的距离平方和最小的点,通常不是成员。平方使得它容易受到离群点的影响。具体来说,它是d维算术平均值。有时也称为“质心”。质心有时也可以指集合中离中心最近的成员。在这里,我们遵循常见的使用方法:质心 = 中心 = 算术平均值。

  • quasi/marginal median
    是每个维度上分别最小化距离之和的点(其坐标是每个轴上的中位数)。这是一个错误的概念,我们不推荐使用。

  • Tukey 中位数
    是最大化 Tukey's Depth 的点,即在任意方向上在一个半球中找到的最小(异常)点数。这是一个可能有用的概念,但其相对于几何中位数的优势并不明显。

  • true 几何中位数 (gm)
    是到所有成员点距离之和最小的点(通常是非成员点)。这是我们想要的点。它比质心对异常值更不敏感。此外,与准中位数不同,gm 是旋转不变的。

  • 中心体
    是到所有其他成员的距离之和最小的集合成员。等价地,是离 gm 最近的成员(具有最小半径)。

  • 异常值
    是到所有其他成员的距离之和最大的集合成员。等价地,是离 gm 最远的点(具有最大半径)。

  • Mahalanobis 距离
    是一种缩放距离,其中缩放是从数据点云的协方差轴/ comediances 得到的。在点很少的方向上的距离增加,在显著的协方差/ comediances 方向上的距离减少。需要矩阵分解。Mahalanobis 距离定义为:m(d) = sqrt(d'inv(C)d) = sqrt(d'inv(LL')d) = sqrt(d'inv(LL')inv(LL)inv(L)inv(L)),其中 inv() 表示矩阵逆,永远不会显式计算,' 表示转置。
    x = inv(L)d(因此也有 x' = d'inv(L'))。
    将 x 代入上述定义:`m(d) = sqrt(x'x) = |x|。
    通过设置 Lx = d 并通过前向替换求解来获得 x。
    所有这些计算都在紧凑的三角形形式中进行。

  • Cholesky-Banachiewicz 矩阵分解
    将任何正定矩阵 S(通常是协方差矩阵或 comediance 矩阵)分解为下三角矩阵 L 和其转置 L' 的乘积:S = LL'。S 的行列式可以从 L 的对角线中获得。我们已在 TriangMat 上实现了分解,以提高效率。它主要被 mahalanobis 使用。

  • Householder's分解
    当Cholesky-Banachiewicz分解的先决条件(正定矩阵S)不满足时,Householder的(UR)分解通常被用作下一个最佳方法。这里在我们的高效struct TriangMat中实现了该方法。

  • 楔积,几何积
    Grassman代数和Clifford代数的乘积,分别。这里使用楔积将两个向量的叉积推广到任意维度,确定正确的符号(它们的公共平面的侧面)。

实现说明

Rstats的主要组成部分是其特性。不同的特性取决于要处理的对象类型。对象大多是任意长度/维度的向量(d)。主要特性是实现了适用于以下方法的

  • Stats:一个向量(数字向量),
  • Vecg:操作两个向量的方法,例如标量积,
  • Vecu8:针对端类型u8的一些专用方法,
  • MutVecg:上述方法中的一些,会修改自身,
  • VecVec:操作n个向量(数字行)的方法,
  • VecVecg:针对n个向量的方法,加上另一个泛型参数,通常是n个权重的向量,表示向量的相对重要性。

特性和它们的方法在它们所需的类别上操作。在经典统计学中,主要类别对应于“随机变量”的数量。

Vec<Vec<T>>类型用于矩形矩阵(也可能有不规则的行)。

struct TriangMat用于对称/反对称/转置/三角矩阵以及楔积和几何积。所有TriangMat实例都在单个扁平向量中存储只有n*(n+1)/2项,而不是n*n,因此几乎将内存需求减少了一半。它们的转置版本仅设置一个标志kind >=3,该标志由软件解释,而不是不必要地重写整个矩阵。因此节省了所有转置的处理(这是一个常见操作)。所有这些都很好地应用于我们实现的矩阵分解方法。

向量的端类型(实际数据的类型)大多是泛型的:通常是某种数字类型。这些泛型输入类型的Copy特性界限已被放宽到Clone,以允许以任何期望的方式克隆用户的端数据类型。对于原始类型没有区别。

计算结果的端类型通常是f64

错误

Rstats库生成自定义错误RError

pub enum RError<T> where T:Sized+Debug {
    /// Insufficient data
    NoDataError(T),
    /// Wrong kind/size of data
    DataError(T),
    /// Invalid result, such as prevented division by zero
    ArithError(T),
    /// Other error converted to RError
    OtherError(T)
}

它的每个枚举变体都携带一个泛型有效负载T。最常见的是这将是String消息,提供更有帮助的解释,例如。

if dif <= 0_f64 {
    return Err(RError::ArithError("cholesky needs a positive definite matrix".to_owned())));
};

format!(...) 可以用于将(调试)运行时值插入到负载字符串中。这些错误会被返回,然后可以自动转换为用户自己的错误(使用 ?)。在 errors.rs 文件的底部实现了此类错误转换,并在 tests.rs 中使用。

存在一个类型别名可以缩短返回声明,例如:Result<Vec<f64>,RE>,其中

pub type RE = RError<String>;

便利函数 nodata_error, data_error, arith_error, other_error 用于构建和返回这些错误。它们的消息参数可以是字面量 &str,也可以是 String(例如,由 format! 构建)。它们返回已经作为 ResultErr 变体封装的 ReError<String>。参看。

if dif <= 0_f64 {
    return arith_error("cholesky needs a positive definite matrix");
};

结构体

struct Params

包含 1d 数据的中心趋势,例如任何类型的平均值或中位数,以及任何分散度量,例如标准差或 'mad'。

struct TriangMat

包含所有类型的三角形矩阵,如上所述的实现部分。除了扩展到它们的完整矩阵形式之外,在 triangmat.rs 模块中直接实现了许多(最佳)线性代数方法,例如 TriangMat,包括

  • Cholesky-Banachiewicz 矩阵分解:S = LL'(其中 ' 表示转置)。这种分解被 mahalanobisdeterminant 等使用。

  • Mahalanobis 距离 用于机器学习识别任务。

  • TriangMat 的各种操作,包括 mult:在紧凑形式中两个三角形或对称或反对称矩阵的矩阵乘法,而不将它们扩展到完整矩阵。

此外,一些方法,特别是 VecVecVecVecg 中的协方差/协变计算,返回 TriangMat 矩阵。这些是正定矩阵,这使得最有效的 Cholesky-Banachiewicz 分解适用于它们。

类似地,更强的矩阵分解 Householder UR(M = QR),也返回 TriangMat

量化函数(依赖注入)

medians 中的大多数方法和 indxvec 插件中的一些方法,例如 find_anyfind_all,需要显式传递给它们的闭包,通常是为了告诉它们如何将任何类型 T 的输入数据量化为 f64。然后可以动态地使用各种不同的量化方法。

例如,在文本分析(&str 结束类型)中,它可以是单词长度,或者是其前几个字母的数值,或者是其辅音的数值等。然后我们可以根据这些不同的度量进行排序或找到它们的均值/中位数/离散度。我们不一定需要明确存储所有这些不同的值,因为输入数据可能非常庞大。通常最好是能够在需要时计算它们中的任何一个,使用这些闭包参数。

当数据已经是所需的结束类型时,使用“哑”闭包。

|&f| f

当 T 是可以转换为 f64 的原始类型,如 i64、u64、usize,可能会有一些精度损失时,使用

|&f| f as f64

fromop

当 T 可以通过现有的自定义 From 实现进行转换(并且 f64:From<T>, T:Clone 已被适当地添加到所有地方作为特征界限),然后只需传递 fromop,定义为

/// Convenience From quantification invocation
pub fn fromop<T: Clone + Into<f64>>(f: &T) -> f64 {
    f.clone().into()
}|

之前需要为(全局)From 特性对每种新类型和每种不同的量化方法编写新的手动实现,并添加其特征界限。即使如此,From 的不同实现之间也会相互冲突。现在我们可以在闭包内简单地实现所有自定义量化。这种通用性是以一个小不便为代价获得的:需要为原始类型提供上述闭包参数之一。

辅助函数

  • fromop:见上文。

  • sumn:序列 1..n = n*(n+1)/2 的和。它也是下三角矩阵或上三角矩阵的大小。

  • tm_stat:(x-中心)/分散度。一维广义 t 统计量。

  • unit_matrix:生成满方阵。

  • nodata_error, data_error, arith_error, other_error - 构建自定义 RE 错误(见上文错误部分)。

特质统计

为所有数值结束类型实现了单维统计量。

其方法在一个通用数据切片上操作,不接收任何参数。例如,s.amean()? 返回切片 s 中数据的算术平均值。这些方法会被检查并将报告 RError(s),例如空输入。这意味着您必须将 ? 应用到其结果上以传递错误,或显式匹配它们以采取恢复操作,具体取决于错误变体。

包含在这个特质中的有

  • 1d 中位数(经典、几何和调和)及其离散度
  • 1d 均值(算术、几何和调和)及其离散度
  • 线性加权均值(用于时间分析),
  • 概率密度函数(pdf)
  • 自相关,熵
  • 线性变换到 [0,1],
  • 其他度量以及基本向量代数运算符

请注意,截至版本 1.1.0,1d “经典”中位数的快速实现已在单独的 crate medians 中提供。

特质 Vecg

两个任意(公共)长度(维度)的切片之间的通用向量代数运算 &[T]&[U]。注意,可能需要使用 'turbofish' 语法 ::<type> 来指示提供的参数的类型 U,例如。

datavec.somemethod::<f64>(arg)

由该特性行实现的函数

  • 向量加法、减法和乘法(标量、克罗内克、外积),
  • 其他关系和差异度量,
  • 皮尔逊、斯皮尔曼和肯德尔相关系数,
  • 联合概率密度函数、联合熵、统计独立性(基于互信息)。
  • Contribution 衡量一个点对几何中位数的影响

注意,我们的 median correlation 在单独的包 medians 中实现。

此特性行的一些简单方法可能未经验证(为了速度),因此在处理数据时应谨慎。

特性行 MutVecg

在特性行下重新实现了 StatsVecg 的一些方法(例如,可变向量加法、减法和乘法),以便它们可以就地修改 self。在某些情况下,例如在向量迭代方法中,这更有效和方便。

然而,这些方法与函数式编程风格不兼容,因为它们没有明确返回任何内容(它们的调用是具有副作用的表达式,而不是表达式)。

特性行 Vecu8

一些向量代数,当最终类型恰好是 u8(字节)时可能更有效。这些方法在其名称中附加了 u8 以避免与 Vecg 方法混淆。这些特定算法与 Vecg 中的通用等效算法不同。

  • 根据值对字节进行频率计数(直方图、概率密度函数、联合概率密度函数)
  • 熵、联合熵、独立性。

特性行 VecVec

d 维度 n 个向量之间的关系。此(超)数据域在此表示为(nd)。此库的主要原始贡献在于 nd。通过快速稳定的迭代,使用改进的 Weiszfeld 算法 gmedian 找到真正的几何中位数(gm)。此算法解决了 Weiszfeld 在现有集合点邻域中的收敛性和稳定性问题。其变体 par_gmedian 使用多线程进行更快的执行,并给出相同的结果。

  • 质心、类中心、异常值、gm
  • 距离之和,点的半径(作为其与 gm 的距离)
  • 通过其点的半径的均值、标准差、中位数和 MAD 来表征多维点集。这些是集合的有用识别度量。
  • 转换为零几何中位数数据,
  • 两个 nd 点集之间的多元趋势(回归),
  • 协方差和共方差矩阵。
  • 内壳和外壳

特性行 VecVecg

接受额外泛型向量参数的函数,例如用于计算加权几何中位数(每个点都有其自己的显著性权重)的权重向量。矩阵乘法。

附录:最新版本

  • 版本 2.2.12 - 修复 Readme.md 的一些错误。

  • 版本 2.1.11 - 对代码进行了一些小的整理。

  • 版本 2.1.10 - 将 TriangMatproject 添加到由子空间索引给出的子空间。

  • 版本 2.1.9 - 为 TriangMat 添加了乘法和更多测试。

  • 版本 2.1.8 - 改进了 TriangMat::diagonal(),恢复了 TriangMat::determinant(),整理了 triangmat 测试。

  • 版本 2.1.7 - 移除了可疑的特征值/向量的计算。改进了 'householder' 测试。

  • 版本 2.1.5 - 将 projection 添加到 VecVecg 特性中,以便将所有自向量投影到新的基。这可以用于例如主成分分析数据降维,使用一些特征向量作为新的基。

  • 版本 2.1.4 - 整理了一些错误处理。

  • 版本 2.1.3 - 添加了 normalize 函数(归一化矩阵的列并将它们转置为行)。

  • 版本 2.1.2 - 添加了函数 project,将 TriangMat 投影到选定维度的低维空间。删除了与 dim 重复的 rows

  • 版本 2.1.0 - 将协方差方法中 mid 参数的类型从 U -> f64 改为,使正常的几何中位数类型明确。相应地,将 covarserial_covarVecVecg 特性移动到 VecVec。这可能会要求更改代码中的一些 use 声明。

  • 版本 2.0.12 - 添加了 depth_ratio

  • 版本 2.0.11 - 删除了不太有用的 variances。整理了 vecvecg.rs 中的错误处理。添加了 serial_covarserial_wcovar,以便在不需要重载所有核心时使用。

  • 版本 2.0.9 - 删除了一些很少使用的方法,简化了 gmpartsgmerror,更新了依赖项。

  • 版本 2.0.8 - 将迭代加权 GM 方法中的初始猜测改为加权平均值。这比简单平均值更精确,导致迭代次数更少。更新了一些依赖项。

  • 版本 2.0.7 - 更新到 ran 2.0

  • 版本 2.0.6 - 在 Stats 特性中添加了方便的方法 medmad,它将中位数和 mad 打包到 struct Params 中,类似于 ameanstd 和其他。因此,简化了某些测试中的打印输出。

  • 版本 2.0.5 - 纠正了 wsigvec,使其也返回归一化结果。更新了依赖项 Medians 到更快的版本 3.0.1。

  • 版本 2.0.4 - 对应地进行了更改:将 winsideness -> wdepth

  • 版本 2.0.3 - 改进了 insideness,使其成为单位向量和的投影,而不是简单的计数。将其重命名为 depth 以避免混淆。还修复了 hulls 的一些问题。

  • 版本 2.0.2 - 显著提高了 insideness 的速度,并在 VecVecg 特性中添加了加权版本 winsideness

  • 版本 2.0.1 - 添加了 TriangMat::dim() 并整理了一些注释。

  • 版本 2.0.0 - 将 MStats 重命名为 Params 以及其变体 dispersion 重命名为 spread。这可能会导致一些向后不兼容的问题,因此推出了新的主要版本。将 'centre' 作为参数添加到 dfdtdvdtwdvdt 中,以便无需重新计算。

依赖项

~1.5MB
~28K SLoC