当你在Julia中开始使用监督学习算法时,你会很快认识到,一个一致且全面的框架是必需的。手动与各种算法专用包对接,每个包都有自己的API和数据要求,可能是一个繁琐且易出错的过程。MLJ.jl(Julia中的机器学习)正好在此发挥作用。MLJ.jl 作为一个核心,为Julia中的机器学习任务提供统一的接口和丰富的工具集。你可以把它想象成一位指挥家,协调众多不同的“乐器”(每个都是一个强大的算法),以创建和谐的机器学习流程。MLJ.jl 不仅仅是一个单一的包,而是一个生态系统的核心,旨在简化和规范机器学习模型的构建、评估和调优过程。它的设计理念围绕着几个重要原则:统一接口: MLJ.jl 为广泛的机器学习模型提供一致的API,无论它们是Julia原生实现(如GLM.jl或DecisionTree.jl中的模型)还是外部库的封装(如LIBSVM.jl)。这意味着你只学一种方式就能与模型交互,而不必管它们的底层实现。关注点分离: 模型的规范(其类型和超参数)与在数据上训练它的过程是分开的。这种分离有助于代码更清晰,工作流程更灵活。数据无关性与科学类型: MLJ.jl 使用 ScientificTypes.jl 来管理数据类型。你无需担心你的输入是 Float64 还是 Int32,而是指定科学类型,例如数值特征的 Continuous 或分类目标的 Multiclass。MLJ 随后确保数据被模型正确处理。模型组合: MLJ.jl 旨在组合复杂的工作流程。预处理步骤、模型,甚至后处理都可以链接成管道,然后被视为单一的复合模型。MLJ.jl 的核心组成部分要有效使用 MLJ.jl,理解其主要组成部分会很有帮助:模型: 在 MLJ.jl 中,“模型”指一个特定算法(例如,LinearRegressor、DecisionTreeClassifier)及其超参数。你首先指定要使用的模型类型,然后创建它的一个实例,并可自定义其超参数。MLJ 提供一个可用模型的注册表,方便查找和加载它们。例如,要使用决策树分类器,你可能需要使用 MLJ.load("DecisionTreeClassifier", pkg="DecisionTree") 来加载它。数据: MLJ.jl 期望数据以其科学类型可以确定的方式呈现。通常,特征 X 以表格(如 DataFrame)形式提供,目标 y 以向量形式提供。ScientificTypes.jl 帮助 MLJ 识别你的特征是连续的、计数的、分类的(多类或有序因子)等。这使得 MLJ 能够进行检查并确保数据和模型之间的兼容性。例如,回归模型期望 Continuous 目标,而分类模型可能期望 Multiclass 目标。机器 (Machines): machine 是 MLJ 中的一个核心对象。它将模型与数据绑定。你通过将模型实例与你的训练数据(X 和 y)配对来创建机器。例如:mach = machine(model, X, y)。机器随后成为你用于训练和预测的对象。它在训练后存储学习到的参数。操作: 有了机器,你就可以对其执行操作:fit!(mach):使用创建机器时提供的数据训练模型。学习到的参数存储在机器内部。predict(mach, X_new):使用训练好的模型对新的、未见过的数据 X_new 进行预测。transform(mach, X_new):如果模型是一个转换器(例如,像PCA这样的降维模型),则对 X_new 应用转换。fitted_params(mach):允许你检查模型的学习参数。生态系统结构MLJ.jl 自身提供了核心框架。实际的模型实现通常位于单独的、专门的包中。MLJModels.jl 充当注册表,并提供必要的样板代码,使这些外部包能够与 MLJ.jl API 对接。这种模块化设计使 MLJ.jl 保持精简,同时允许访问不断增长的算法集合。这里是这些组成部分如何交互的简化视图:digraph MLJ_Ecosystem { rankdir=TB; node [shape=box, style="filled,rounded", fontname="sans-serif", margin=0.2]; edge [fontname="sans-serif"]; USER [label="你(用户)", fillcolor="#a5d8ff"]; MLJ_CORE [label="MLJ.jl 核心\n(机器、操作、管道、调优)", fillcolor="#74c0fc"]; subgraph cluster_models { label="模型提供者"; style="filled"; color="#e9ecef"; node [fillcolor="#d0bfff"]; MLJMODELS [label="MLJModels.jl\n(注册表和适配器)"]; GLM [label="GLM.jl\n(线性模型)"]; DECISIONTREE [label="DecisionTree.jl\n(树、森林)"]; LIBSVM [label="LIBSVM.jl\n(支持向量机)"]; OTHER_PKGS [label="其他机器学习包..."]; } subgraph cluster_data { label="数据处理"; style="filled"; color="#e9ecef"; node [fillcolor="#96f2d7"]; DATAFRAMES [label="DataFrames.jl\n(表格数据)"]; SCITYPES [label="ScientificTypes.jl\n(数据语义)"]; } USER -> MLJ_CORE [label="交互"]; MLJ_CORE -> MLJMODELS [label="通过...加载模型"]; MLJMODELS -> GLM; MLJMODELS -> DECISIONTREE; MLJMODELS -> LIBSVM; MLJMODELS -> OTHER_PKGS; MLJ_CORE -> SCITYPES [label="用于类型自省"]; DATAFRAMES -> MLJ_CORE [label="提供数据给"]; SCITYPES -> DATAFRAMES [label="标注"]; }MLJ.jl 生态系统将用户连接到一个核心框架,该框架管理来自各种提供者包的模型,并通过专门的数据类型处理数据。这种结构使得 MLJ.jl 既灵活又可扩展。通过在 MLJModels.jl 中添加适当的接口,新模型可以轻松集成到生态系统中,而无需修改 MLJ.jl 核心。如果你有Python的scikit-learn使用经验,你会发现MLJ.jl的目标很熟悉:提供一个用于常见机器学习任务的统一工具包。然而,MLJ.jl 是从头开始设计的,旨在利用Julia的特定优势,例如多重分派、丰富的类型系统以及数值计算的高性能。这通常会带来更通用和可组合的模型实现。在本章的学习中,你将看到这些组成部分的实际运作。我们将从加载数据开始,从 MLJ 注册表中选择模型,将它们封装在机器中,然后训练和评估它们。理解 MLJ.jl 的这种整体结构将使你更容易理解具体的例子并在Julia中构建你自己的复杂机器学习解决方案。