4

Kotlin 数据科学:从数据分析视角看 Kotlin 语言的数据生态

 1 year ago
source link: https://www.phodal.com/blog/kotlin-data-science-with-archguard/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Kotlin 数据科学:从数据分析视角看 Kotlin 语言的数据生态

Posted by: Phodal Huang Feb. 18, 2023, 2:09 p.m.

自去年接手 ArchGuard 到现在,差不多是一年,也差不多是我真正(虽然也是业余时间)写 Kotlin 一年的时间。在不考虑 CLI 体制的体积下,Kotlin 确实是一个快乐的语言,特别是:你经常找不到北,但是非常好用的语法糖:extension functions。在那之前,我业余经常使用的是 Rust,有些语法糖虽然好用,但是吧,有时候编译器就不让你快乐。我觉得主要原因吧,应该是:Kotlin 是 Jetbrains 的亲儿子,而 Rust 不是。次要原因是:Rust 的静态分析真不是一件容易的事。

回到文章的正题,也是因为 ArchGuard Scanner 在语法分析完之后,需要进行一系列的数据处理和就地分析、交互式分析,也因此需要一系列的数据科学工具。

  • 交互式分析:创建一个类似于 Jupyter 或 IPython 的环境,以进一步探索和分析数据。
  • 数据处理与传输:从扫描器接收到的原始数据的解析和转换,以便进一步的分析和处理。
  • 就地数据分析:对解析的数据进行查询和二次计算,将计算交由 Client 分析,可以降低服务器的压力。
  • AI:还在探索适合的用途

当然,我们并不会详细展开每一方面。

REPL 与交互式分析:Kotlin Jupyter

在我们设计《ArchGuard 的架构工作台》时,旨在提供一个交互式的架构分析环境,以帮助人们设计架构、演进架构、观测架构。从结论上来说,我们要提供一个架构领域的 Jupyter,架构师就能像数据科学家一样进行分析。而软件架构师与数据科学家不同的是,严谨性的分析需要的是静态类型语言。

于是,去年我们引入了还在开发中的、不稳定的 Kotlin Jupyter 成为了我们的选择。Kotlin Jupyter 是一个交互式的 Kotlin 编程环境,它结合了 Kotlin 语言和 Jupyter Notebook 的优点,并提供了一个方便的方式来进行 Kotlin 语言的交互式编程和数据分析。对于开发一个交互式分析平台来说,我们做的工作如下:

  • 引入 jupyter-apijupyter-kernel 作为运行 Kotlin Script 的基础环境
  • 使用 Kotlin Jupyter 提供的 %use 构建了自己的架构即代码库,以提供底层的 API 封装
  • 使用 Kotlin TypeSafe builder 构建架构即代码DSL (领域特定语言)

最后,ArchGuard 的工作台 REPL 示例代码如下:

%use archguard

repos {
    repo(name = "Backend", language = "Kotlin", scmUrl = "https://github.com/archguard/archguard")
}

context.repos.create()

作为一个还在频繁变动的库,对于三方系统的接入,还是存在一些问题的:

  • 早期我们使用的是 0.11.0-89-1 版本,因为先前的接口无法直接使用,所以用的是 Jetbrains 的内部源,直到今年更新到 0.11.0-208 才算稳定。
  • 先前版本与 Jupyter 的耦合库过度,需要手动做一些剥离?
  • 接入时,没有 API 文档,只能看源码!!

不过,现在勉强算是可以跑起来,也是可喜可贺。现在想想,当时应该去提几个 issue 来着的。

就地数据分析:Kotlin DataFrame

Kotlin DataFrame 是我们最近正在计算引入就地数据分析时考虑的工具,它提供了与 Pandas 类似的数据结构,即 DataFrame,可以对数据进行索引、切片、过滤、分组和聚合等操作。与 Pandas 稍有不同的是,Kotlin DataFrame 采用了类型安全的设计,并在设计时考虑了 Kotlin 的语言特性,如空安全和函数式编程等。

Kotlin DataFrame 提供了各种数据读写工具,可以从 ArrowFeather、CSV、Excel、JSON、TSV 等格式中读取数据,并将数据保存到这些格式或数据库中。

val dataFrame = DataFrame.read("data/one_data.json").cast<CodeDataStruct>()

// or

val ds = listOf(
    CodeDataStruct(
        NodeName = "Main",
        Functions = listOf(CodeFunction(Name = "main")),
    )
).toDataFrame()

随后,我们就可以一些统计分析和机器学习相关的功能:

dataframe
    .filter { it[CodeDataStruct::Functions].isNotEmpty() }
    .filter { it[CodeDataStruct::Functions].any { function -> function.Name == "main" } }
    .print()

ArchGuard Scanner 在数据分析后,就会输出分析完的数据。那么下一个分析任务,就可以直接进行处理,诸如于 SQL Lint、API Lint 等。此时,我们就可以解耦几种不同类型的任务,唯一的问题就是过程中序列化产生的开销,这也就是下一小节要解决的问题。

同样的,我们所经历了和 Kotlin Jupyter 相似的痛苦 —— 文档缺失,最后还是去看源码里的测试用例了。

数据传输与处理

ArchGuard 1.x 里,不存在数据传输的场景,Scanner 直接生成 SQL 然后导入数据库。在 ArchGuard 2.0 里,我们使用 JSON 来传输代码的元数据,在数据量大场景下,服务端的 OutOfMemory 成为了日常的 issue —— 虽然系统在设计之初不是给单体系统设计的,微服务架构下这么大的代码量本身就不合理。在这时,有更好的方案是引入流式系统机制,其对于现有系统的改动太大,需要有专人来负责;另外一种比较简单的方案,就是服务器不需要一个反序列化的数据格式,就成了一种更简单的选择。

Apache Arrow 与 FlatBuffers 是我们考虑的选择,而 DataFrame 支持了 Aapche Arrow 格式的转换,这就让处理工作变得相当简单:

val dataFrame = DataFrame.read("data/onedata.arrow").cast<CodeDataStruct>()

dataFrame
    .print(10)

不过,在我们引入 ArchGuard 的过程中,发现它并不支持类型嵌套 —— 原因是开发人员在设计的时候漏了:issues 271,我尝试去修复这个 issue,但是发现我需要一系列的先验知识,就暂时性放弃了。希望官方有空早日修复这个 issue,这样我就可以进行后续的发电工作。接下来,在有了数据之后,我们就可以用 Lets-Plot 来绘图:

var p = letsPlot(data)
p += geomDensity(color="dark_green", alpha=.3) {x="rating"; fill="cond"}
p + ggsize(700, 350)

在 Jetbrains IDE 支持下,结合 Kotlin 的特性,它变得很强大。诸如于,我们可以使用 DataSpell + Jupyter 来实现实时数据分析。

其它 Kotlin 数据科学:AI 等

其它的一些点诸如于:

  • 深度学习模型开发:Kotlin 不仅仅是一种通用编程语言,还可以用于开发深度学习模型。官方维护的 KotlinDL 是一个基于 Kotlin 编写的高级深度学习 API,受到 Keras 的启发。KotlinDL 使用 TensorFlow Java API 和 ONNX Runtime API for Java,提供简单易用的 API 用于训练深度学习模型、导入 Keras 和 ONNX 模型进行推断,以及利用迁移学习调整预训练模型以适应任务。
  • 数学表达式处理:如果你需要处理数学表达式,Kmath 是一个非常有用的高级数学库。它实现了组合的代数结构的数学操作,定义了线性结构、表达式、直方图、流操作的 API,并提供了对现有 Java 和 Kotlin 库的可互换包装,包括 ND4J、Commons Math、Multik 等。我们计划在 ArchGuard 2023 中探索自定义架构适应度函数,因此像 Kmath 这种库也成为了我们未来的试验范围。
  • 可视化:可视化是数据科学中重要的一环。如果你需要绘制图表,可以考虑使用 Lets-Plot 提供的绘图功能。同时,JLaTeXMath 可以显示使用 LaTeX 编写的数学公式,虽然它更多是针对理论研究的需求。

当然,除了 Kotlin 相关的库,Java 生态中也有一系列库可以满足你的需求。不过 Kotlin 的语法更加舒服,如果你想了解更多关于 Kotlin 在数据科学中的应用,可以查阅 Kotlin 官方文档:https://kotlinlang.org/docs/data-science-overview.html。

其它:除了上述提到的库,Kotlin 社区还有一个名为 Koma 的科学计算框架,可以在 Kotlin 中进行数学运算和矩阵计算。不过,由于该库目前较为不活跃,我们未展开详细研究。

小结:Kotlin 数据科学?

在现有的生态体系里,主流的数据分析语言包含(主要是我就熟悉这几个):

  • Python 依旧是今天最好的数据科学工具,它有广泛的库和工具,如 NumPy, Pandas, Matplotlib 和 Scikit-learn,这些库提供了大量的数据处理、分析和可视化功能。
  • Java 也是一种在数据科学领域使用广泛的编程语言,尤其在大数据分析方面,Apache 生态系统提供了很多强大的工具和库,如 Hadoop, Spark, Flink 和 Kafka 等。这些工具可以帮助处理大规模数据集,并提供高度可扩展的数据处理和分析能力。
  • Scala 作为一种静态类型语言,具有 Java 的可靠性和稳定性,同时又具备 Python 和 R 语言的数据科学特性。其优势在于处理大规模数据集、函数式编程范式、丰富的工具库、REPL 环境(交互式编程环境)。
  • 其它语言:R 语言、Julia 我都不太熟悉。

在诸多方面,Kotlin 与 Scala 相似,在上手的学习曲线上,Kotlin 更为简单。虽然,我也在公司项目里用过 Scala,但是要重写现有的 ArchGuard 是不可能的,除非 Copilot 哪天能帮我自动重写。所以,探索使用 Kotlin 进行数据科学更为了一种更好的选择。除此,Kotlin 也更适合于那些希望快速学习和使用 Java 风格编程语言的数据科学开发者。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK