模块 basalt.ml¶
102 个公开类型 · 14 个包内可见类型
经典机器学习:线性模型、近邻、SVM、树、梯度提升、聚类、降维、朴素贝叶斯、指标与切分。
类型概览
| 类型 | 种类 | 说明 |
|---|---|---|
AgglomerativeClustering | class | 自底向上合并的层次聚类,支持四种链接准则。 |
BoostingAlgorithm | enum | 直方图树的生长策略:深度优先或叶优先 |
BoostingObjective | enum | 直方图提升支持的目标:平方误差与二分类逻辑 |
DBSCAN | class | 按 eps 邻域与 minPoints 判定核心点的密度聚类。 |
DataSplit | class | 基于行下标的确定性 holdout、k 折与分层 k 折划分。 |
DecisionTree | class | 预分箱特征上的 CART 树,分裂搜索走直方图 |
DistanceMetric | enum | KNN 使用的距离函数枚举。 |
EigenSolver | enum | PCA 可选的对称特征分解求解器。 |
Estimator | interface | 经典估计器的统一契约。 |
Estimators | class | 按枚举选择算法的一行式门面。 |
FeatureImportance | class | 统一的特征重要性入口:树杂质、线性权重绝对值与置换重要性。 |
GaussianMixture | class | EM 估计的高斯混合模型,协方差可选 FULL / TIED / DIAG。 |
GaussianNaiveBayes | class | 按类估计均值、方差与先验的高斯朴素贝叶斯分类器。 |
GridSearchCV | class | 网格穷举加交叉验证的调参器,选优后全量重训。 |
HistogramGradientBoosting | class | 二阶直方图梯度提升,支持深度优先与叶优先生长 |
ImpurityCriterion | enum | 决策树用于最大化信息增益的节点不纯度 |
IsolationForest | class | 随机轴对齐切分的无监督孤立森林异常检测器。 |
KBinsDiscretizer | class | 按分位数、等宽或一维 K-Means 把连续特征离散为箱。 |
KFold | class | K 折交叉验证划分器,默认打乱且种子为 42。 |
KMeans | class | K-Means++ 播种的 Lloyd 迭代聚类,支持多次重启。 |
KNearestNeighbors | class | 统一权重的 KNN 分类器。 |
KNeighborsRegressor | class | 统一权重的 KNN 回归器。 |
Kernel | class | 四种半正定核函数:LINEAR、RBF、POLY 与 SIGMOID。 |
KernelDensity | class | 高斯与 TOPHAT 核的核密度估计,输出对数密度。 |
KernelPCA | class | 核主成分分析:在核空间中心化后做特征分解的降维估计器。 |
KernelRidge | class | 核岭回归:在核空间解 (K + alpha·I)α = y 的回归估计器。 |
LabelEncoder | class | 把类别标签双向映射为 0..k-1 整数码的编码器。 |
Lasso | class | 坐标下降求解的 L1 正则最小二乘。 |
LimeExplainer | class | 用局部加权线性代理模型解释单个预测的 LIME 解释器。 |
LinearRegression | class | 全批量梯度下降的普通最小二乘。 |
LinearSVM | class | PEGASOS 次梯度法训练的二分类线性 SVM。 |
LogisticRegression | class | 全批量梯度下降的二分类逻辑回归。 |
Metrics | class | 分类与回归指标,纯 Java 实现。 |
MinMaxScaler | class | 按列线性映射到指定区间的缩放器。 |
OneHotEncoder | class | 把类别列展开为稠密 0/1 指示特征的编码器。 |
PCA | class | 中心化主成分分析,含协方差与 Gram 两条精确路径。 |
Pipeline | class | 顺序串联预处理步骤与最终估计器的管道 |
PolynomialFeatures | class | 生成最高到 degree 的多项式与交互特征 |
RFE | class | 按重要性递归剔除特征直到保留指定数量 |
RandomForest | class | 自助聚合的直方图森林,节点级特征子采样 |
RandomizedSearchCV | class | 按参数分布随机采样并交叉验证选优 |
Ridge | class | Cholesky 求解的 L2 正则最小二乘。 |
SVC | class | SMO 求解的核支持向量分类器,支持 OvR 多分类与 Platt 概率校准。 |
SelectKBest | class | 按单变量统计量保留得分最高的 k 个特征 |
ShapExplainer | class | 计算可加的 SHAP 归因值,满足 Σφ = f(x) − E[f] |
SimpleImputer | class | 用列统计量填补 NaN 缺失值 |
StandardScaler | class | 按列去均值并缩放到单位方差 |
StratifiedKFold | class | 保持类别比例的分层 K 折划分器 |
Transformer | interface | 有状态特征预处理与特征工程步骤的统一契约 |
TreeTask | enum | 单棵决策树的监督目标:分类或回归 |
AgglomerativeClustering.Builder | class | AgglomerativeClustering 的构建器。 |
AgglomerativeClustering.Linkage | enum | 层次聚类的簇间连接准则 |
DBSCAN.Builder | class | DBSCAN 的构建器,设置邻域半径、密度阈值与距离度量。 |
DataSplit.Fold | record | 一折的训练与测试四元组。 |
DataSplit.Holdout | record | 一次 holdout 划分的四元组。 |
DecisionTree.Builder | class | DecisionTree 的流式构造器 |
Estimators.Algorithm | enum | 门面可选算法及其任务类型。 |
Estimators.Metric | enum | 交叉验证可选的评估指标。 |
Estimators.Task | enum | 算法的任务类型分类。 |
FeatureImportance.PermutationResult | record | 置换重要性的计算结果,含逐次重复的原始分数。 |
GaussianMixture.Builder | class | GaussianMixture 的构建器。 |
GaussianMixture.CovarianceType | enum | GMM 的协方差参数化方式。 |
GaussianNaiveBayes.Builder | class | GaussianNaiveBayes 的构建器。 |
GridSearchCV.Builder | class | GridSearchCV 的构建器,登记参数网格与交叉验证策略。 |
GridSearchCV.CandidateResult | record | 网格搜索中单个参数组合的交叉验证结果快照。 |
HistogramGradientBoosting.Builder | class | HistogramGradientBoosting 的流式构造器 |
IsolationForest.Builder | class | IsolationForest 的流式构建器。 |
KBinsDiscretizer.Builder | class | KBinsDiscretizer 的流式构建器。 |
KBinsDiscretizer.Encode | enum | 离散化结果的编码方式。 |
KBinsDiscretizer.Strategy | enum | 分箱边界的计算策略。 |
KMeans.Builder | class | KMeans 的构建器,设置簇数、迭代上限、收敛阈值与随机种子。 |
KNearestNeighbors.Builder | class | KNearestNeighbors 的流式构建器。 |
KNeighborsRegressor.Builder | class | KNeighborsRegressor 的流式构建器。 |
Kernel.Type | enum | Kernel 支持的四种半正定核函数类型。 |
KernelDensity.Builder | class | KernelDensity 的流式构建器。 |
KernelDensity.KernelType | enum | 核密度估计可用的核函数类型。 |
KernelPCA.Builder | class | KernelPCA 的流式构建器。 |
KernelRidge.Builder | class | KernelRidge 的流式构建器。 |
Lasso.Builder | class | Lasso 的流式构建器。 |
LimeExplainer.LocalExplanation | record | LIME 对单个样本的局部解释结果。 |
LinearRegression.Builder | class | LinearRegression 的流式构建器。 |
LinearSVM.Builder | class | LinearSVM 的流式构建器。 |
LogisticRegression.Builder | class | LogisticRegression 的流式构建器。 |
MinMaxScaler.Builder | class | MinMaxScaler 的流式构建器。 |
OneHotEncoder.Builder | class | OneHotEncoder 的流式构建器。 |
OneHotEncoder.HandleUnknown | enum | transform 遇到未见类别时的处理策略。 |
PCA.Builder | class | PCA 的构建器,设置分量数、求解器、扫描上限与白化开关。 |
Pipeline.Builder | class | Pipeline 的构造器,按序追加步骤并挂接末端估计器。 |
Pipeline.Step | record | 流水线中的具名步骤:名称与变换器的不可变组合。 |
PolynomialFeatures.Builder | class | PolynomialFeatures 的构造器,设置阶数与偏置项。 |
RFE.Builder | class | RFE 的构造器,设置保留特征数与淘汰步长。 |
RandomForest.Builder | class | RandomForest 的流式构造器 |
RandomizedSearchCV.Builder | class | 随机搜索的构造器,登记参数分布与分折策略。 |
RandomizedSearchCV.ParameterSampler | interface | 参数分布的抽样接口,单方法返回一个参数值。 |
Ridge.Builder | class | Ridge 的流式构建器。 |
SVC.Builder | class | SVC 的构造器,设置核函数、惩罚系数与 SMO 参数。 |
SelectKBest.Builder | class | SelectKBest 的构造器,设置保留数与评分函数。 |
SelectKBest.ScoreFunc | enum | 特征打分的统计检验:分类 F、回归 F、卡方 |
ShapExplainer.Explanation | record | 一次解释的结果:基准值、SHAP 矩阵、预测与平均绝对值 |
SimpleImputer.Builder | class | 构造 SimpleImputer,设置缺失值策略与常数填充值 |
SimpleImputer.Strategy | enum | 缺失值填充策略:均值、中位数、众数、常数 |
StandardScaler.Builder | class | 构造 StandardScaler,设置是否中心化与是否缩放 |
- final class AgglomerativeClustering implements Estimator¶
自底向上合并的层次聚类,支持四种链接准则。
拟合从每个样本各自成簇开始,反复合并代价最小的一对活跃簇,直到剩余簇数等于 clusters。初始距离矩阵保存全部样本对的欧氏距离,占用 n×n 个 double,构造耗时为 O(n²p);此后每轮合并都要扫描所有活跃簇对,共 n−clusters 轮,整体时间达到 O(n³)。因此该实现适合中小规模数据,样本数上万时距离矩阵本身就难以承受。
四种准则的差别在选择合并对时的代价:SINGLE 取两簇间最近样本的距离,倾向于串起长链,能发现非凸形状但易受噪声牵连;COMPLETE 取最远样本距离,产生紧致且直径相近的簇;AVERAGE 取簇间全部样本对距离的均值,介于两者之间,对噪声更稳健;WARD 用 (ni·nj/(ni+nj))·‖μi−μj‖² 衡量合并带来的方差增量,倾向等方差的球形簇。
合并后距离矩阵就地更新:SINGLE 取 min、COMPLETE 取 max、AVERAGE 与 WARD 都取按簇大小加权的平均 (sizeA·dAK + sizeB·dBK)/(sizeA+sizeB)。簇编号在合并结束后按活跃簇的下标升序重编为 0 起,与合并先后无关。
示例Matrix features = Matrix.fromRows(new double[][] { {0.0, 0.0}, {0.2, 0.1}, {0.1, 0.3}, {5.0, 5.0}, {5.2, 4.9}, {4.8, 5.1} }); AgglomerativeClustering model = AgglomerativeClustering.builder() .clusters(2) .linkage(AgglomerativeClustering.Linkage.WARD) .build() .fit(features); int[] labels = model.labels(); double[] assigned = model.predict(features);注意
WARD 的选择代价与距离矩阵的更新公式并不相同:前者是方差增量,后者是加权平均距离
注意
只有 fit 而没有 fitPredict,训练标签通过 labels() 读取
注意
predict 在输入与拟合数据逐元素相同时直接返回训练标签,否则按到最终簇均值的平方欧氏距离归属,属于质心近似而非层次归属
注意
clusters 必须为正且不超过样本数,后者在 fit 时校验
参见:basalt.ml.Estimator, basalt.ml.KMeans, basalt.ml.DBSCAN
方法
- builder() → Builderstatic¶
创建 AgglomerativeClustering 构建器。
- 返回
clusters 为 2、linkage 为 WARD 的新 Builder 实例
- fit(Matrix features) → AgglomerativeClustering¶
以无监督方式执行层次聚类。
等价于 fit(features, null),目标数组不参与任何计算。
- 参数
features (Matrix) – 样本矩阵,行是样本、列是特征;元素必须有限
- 返回
this,便于链式调用
- 抛出
NullPointerException – features 为 null
IllegalArgumentException – features 含非有限值,或 clusters 大于样本数
- fit(Matrix features, double[] ignoredTargets) → AgglomerativeClustering¶
在给定特征上执行自底向上的合并聚类。
先复制输入特征,建立 n×n 的欧氏距离矩阵,再循环挑选代价最小的活跃簇对并合并:合并后的均值按两簇样本数加权,被合并行的距离按链接准则更新,另一簇标为非活跃。簇数降到 clusters 时停止。
注意
重复调用 fit 会重建距离矩阵与标签,上一次结果被覆盖
注意
样本数等于 clusters 时不发生任何合并,每个样本自成一簇
- 参数
features (Matrix) – 样本矩阵,行是样本、列是特征;元素必须有限
ignoredTargets (double[]) – 占位参数;聚类为无监督任务,源码不读取,传 null 或任意数组均可
- 返回
this,便于链式调用
- 抛出
NullPointerException – features 为 null
IllegalArgumentException – features 含非有限值,或 clusters 大于样本数
- predict(Matrix features) → double[]¶
把样本归入最近的最终簇均值。
输入与拟合数据行数相同且底层数组逐元素相等时,直接返回训练标签的副本;否则逐行计算到 clusters 个簇均值的平方欧氏距离并取最小者。距离比较用严格小于,平局时返回编号较小的簇。
- 参数
features (Matrix) – 样本矩阵,列数须等于拟合时的特征数;元素必须有限
- 返回
长度为样本数的簇编号数组,取值 0 到 clusters−1
- 抛出
NullPointerException – features 为 null
IllegalStateException – 尚未拟合
IllegalArgumentException – 特征列数与拟合时不一致,或含非有限值
- labels() → int[]¶
返回训练样本的簇标签副本。
簇编号从 0 开始,按合并结束后活跃簇的下标升序编号,因此同一份输入的编号与 linkage 无关。返回 clone,修改它不影响模型状态。
- 返回
长度等于训练样本数的标签数组
- 抛出
IllegalStateException – 尚未拟合
- linkage() → Linkage¶
返回构造时指定的链接准则。
- 返回
Linkage 常量(WARD、COMPLETE、AVERAGE 或 SINGLE);未拟合时同样返回配置值
- enum BoostingAlgorithm¶
直方图树的生长策略:深度优先或叶优先
XGBOOST 按层递归生长:节点在深度小于 maxDepth 且增益为正时分裂,左右子树继续递归,树的叶数由深度与数据决定。LIGHTGBM 维护一个按增益降序排列的候选叶队列,每轮分裂全局增益最大的叶,直到叶数达到 maxLeaves。
示例HistogramGradientBoosting depthWise = HistogramGradientBoosting.builder() .algorithm(BoostingAlgorithm.XGBOOST) .maxDepth(4) .build(); HistogramGradientBoosting leafWise = HistogramGradientBoosting.builder() .algorithm(BoostingAlgorithm.LIGHTGBM) .maxLeaves(15) .build();注意
XGBOOST 策略不读取 maxLeaves
注意
LIGHTGBM 策略同时受 maxDepth 约束,每分裂一次叶数加一
参见:basalt.ml.HistogramGradientBoosting
枚举成员
- XGBOOST()¶
深度优先(level-wise)逐层分裂节点
- LIGHTGBM()¶
叶子优先(leaf-wise)按最大增益继续分裂
- enum BoostingObjective¶
直方图提升支持的目标:平方误差与二分类逻辑
SQUARED_ERROR 取残差 raw - target 为梯度、hessian 恒为 1,叶权重等于负梯度除以 hessian 加 lambda。LOGISTIC 取概率减标签为梯度、p(1-p) 为 hessian(下限 1e-12),baseScore 为训练集正类均值的对数几率。
示例HistogramGradientBoosting classifier = HistogramGradientBoosting.builder() .objective(BoostingObjective.LOGISTIC) .iterations(200) .build();注意
LOGISTIC 的 fit 会逐行校验标签,出现 0 与 1 之外的值即抛 IllegalArgumentException
注意
predictProbability 只在 LOGISTIC 下可用,其他目标调用会抛 IllegalStateException
参见:basalt.ml.HistogramGradientBoosting
枚举成员
- SQUARED_ERROR()¶
平方误差,用于回归
- LOGISTIC()¶
二分类逻辑损失
- final class DBSCAN implements Estimator¶
按 eps 邻域与 minPoints 判定核心点的密度聚类。
以 eps 为半径的邻域内样本数不少于 minPoints 的点为核心点,簇从核心点出发按广度优先扩展。边界点归入首个到达它的簇,无法从任何核心点到达的点保留噪声标签 -1。
邻域查询逐点线性扫描全部样本,整体需要 O(n²) 次距离计算,适用于中小规模数据。拟合时复制输入特征,后续 predict 与标签查询都基于这份副本。
示例Matrix features = Matrix.fromRows(new double[][] { {0.0, 0.0}, {0.3, 0.1}, {0.1, 0.4}, {5.0, 5.0}, {5.2, 4.8}, {4.9, 5.3}, {9.0, 0.5} }); DBSCAN dbscan = DBSCAN.builder() .eps(0.6) .minPoints(3) .metric(DistanceMetric.EUCLIDEAN) .build() .fit(features, null); int[] labels = dbscan.labels(); int clusters = dbscan.clusterCount(); int noise = dbscan.noiseCount();注意
minPoints 统计包含点自身,因为点与自身的距离为 0 且不大于 eps
注意
predict 在全部核心点中取 eps 内的最近邻并返回其标签,未命中时返回 -1;这是近似归属,不是密度可达判定
注意
DBSCAN 只实现 Estimator,没有 fit(Matrix) 单参数重载,也没有 write/read
参见:basalt.ml.DistanceMetric, basalt.ml.Estimator
方法
- builder() → Builderstatic¶
创建 DBSCAN 构建器。
- 返回
参数取默认值的新 Builder 实例
- fit(Matrix features, double[] ignoredTargets) → DBSCAN¶
在给定特征上执行密度聚类并返回自身。
先复制特征矩阵,再把全部标签初始化为 -1,然后按样本顺序扫描:邻域样本数达到 minPoints 的点成为新簇的种子,队列向外扩展直到没有新的核心点可达。
注意
重复调用 fit 会丢弃上一次的标签与核心点标记
- 参数
features (Matrix) – 样本矩阵,行是样本、列是特征;元素必须有限
ignoredTargets (double[]) – 占位参数;聚类为无监督任务,传 null 或任意数组都被忽略
- 返回
this,便于链式调用
- 抛出
IllegalArgumentException – features 为 null 或包含非有限值
- predict(Matrix features) → double[]¶
按最近核心点的标签预测样本所属簇。
对每个待预测样本,在全部核心点中寻找 eps 邻域内距离最近的一个,返回该核心点的簇标签;邻域内不存在核心点时返回 -1。边界点不参与查询,因此结果可能比训练标签更保守。
- 参数
features (Matrix) – 样本矩阵,列数须与拟合时一致
- 返回
长度为样本数的标签数组,噪声或未命中为 -1
- 抛出
IllegalStateException – 尚未拟合
IllegalArgumentException – 特征列数与拟合时不一致
- labels() → int[]¶
返回训练样本的簇标签副本。
簇编号从 0 开始,按种子点的发现顺序递增;噪声点保持 -1。返回的是副本,修改它不影响模型状态;未拟合时返回 null。
- 返回
长度等于训练样本数的标签数组;未拟合时为 null
- clusterCount() → int¶
返回拟合得到的簇数量。
- 返回
簇数,不含噪声;未拟合时为 0
- noiseCount() → int¶
统计标签为负的样本数量。
注意
直接遍历内部标签数组,未拟合时该数组为 null,调用会抛 NullPointerException
- 返回
标签小于 0 的样本个数
- final class DataSplit¶
基于行下标的确定性 holdout、k 折与分层 k 折划分。
holdout 与两个 trainTestSplit 重载都先用 seed 构造 Random,对行下标数组做 Fisher-Yates 洗牌,再按洗牌后的顺序切片;两个 kFold 重载复用同一套下标洗牌,把洗牌顺序切成 folds 段连续区间。相同 seed 与相同输入必然产生相同切分,与标签分布无关。
返回的特征与标签都是新建副本,调用方修改切分结果不会影响原始数据。holdout 的测试行数取 round(rows·testFraction) 后夹到 [1, rows−1];kFold 的每折测试块大小相差不超过 1。
stratifiedKFold 与 trainTestSplit 的 stratify 分支改为按目标值分组:每类内部独立洗牌,再用跨类连续的轮转把行分发到各折或切出测试行,使每侧都保留全部类别。某个类别的样本数少于折数时 stratifiedKFold 直接拒绝,因为无法保证每折都有该类样本。
示例Matrix x = Matrix.fromRows(new double[][]{{0, 0}, {0, 1}, {1, 0}, {1, 1}, {2, 2}, {2, 1}}); double[] y = {0, 0, 1, 1, 1, 1}; DataSplit.Holdout split = DataSplit.holdout(x, y, 0.25, 42L); LinearRegression model = LinearRegression.builder().build() .fit(split.trainFeatures(), split.trainTargets()); double[] predicted = model.predict(split.testFeatures());注意
holdout 与 kFold 不做分层,类别偏斜时小测试块可能缺少某一类;需要类别均衡时改用 stratifiedKFold 或 stratify 分支
注意
洗牌只重排行,不改变列顺序与数值
注意
所有入口都会先做非空、行数一致与非有限值校验
注意
testFraction 取开区间 (0, 1);分层分支的实际测试比例是各类比例的汇总,可能与入参略有偏差
参见:basalt.ml.DataSplit.Holdout, basalt.ml.DataSplit.Fold, basalt.ml.Estimators
方法
- holdout(Matrix features, double[] targets, double testFraction, long seed) → Holdoutstatic¶
按比例切出一份测试集,其余作为训练集。
洗牌后取前 testSize 行为测试集,其余行为训练集,因此测试集在原始数据中并不连续。
注意
实际测试行数被夹到 [1, rows-1],样本极少时也不会产生空的一侧
- 参数
features (Matrix) – 样本矩阵,行数即样本数
targets (double[]) – 目标数组,长度必须等于 features.rows()
testFraction (double) – 测试集比例,必须落在开区间 (0, 1)
seed (long) – 洗牌随机源种子,决定具体划分
- 返回
持有 trainFeatures、trainTargets、testFeatures、testTargets 四个副本的 Holdout
- 抛出
NullPointerException – features 或 targets 为 null
IllegalArgumentException – targets 长度与行数不符、数据含 NaN/无穷,或 testFraction 不在 (0, 1)
- trainTestSplit(Matrix features, double[] targets, double testFraction, long seed) → Holdoutstatic¶
按比例切分训练集与测试集,默认洗牌且不分层。
等价于 trainTestSplit(features, targets, testFraction, true, false, seed),也是 holdout 的实现。
- 参数
features (Matrix) – 样本矩阵,行数即样本数
targets (double[]) – 目标数组,长度必须等于 features 的行数
testFraction (double) – 测试集比例,必须落在开区间 (0, 1)
seed (long) – 洗牌随机源种子,决定具体划分
- 返回
持有 trainFeatures、trainTargets、testFeatures、testTargets 四个副本的 Holdout
- 抛出
NullPointerException – features 或 targets 为 null
IllegalArgumentException – targets 长度与行数不符、数据含非有限值、testFraction 不在 (0, 1),或样本数小于 2
- trainTestSplit(Matrix features, double[] targets, double testFraction, boolean shuffle, boolean stratify, long seed) → Holdoutstatic¶
可控洗牌与分层的 holdout 切分。
不分层时先按 shuffle 决定是否对行下标做 Fisher-Yates 重排,取重排后的前 round(rows·testFraction) 行(夹到 [1, rows−1])作测试集,其余作训练集。
stratify 为真时改为按目标值分组:每组内部单独洗牌,按自身比例切出测试行且至少保留 1 行训练、1 行测试;只有单个样本的类整类留在训练集。因此实际测试比例是各类比例的汇总,可能与 testFraction 略有偏差。
注意
行数校验在分层判断之前,分层分支同样要求样本数不小于 2
注意
分层模式不重新混排类别,训练集与测试集内部按类别首次出现的顺序分块
注意
shuffle 为假时保持原始行序,此时测试集就是原始数据的头部若干行
- 参数
features (Matrix) – 样本矩阵,行数即样本数
targets (double[]) – 目标数组,长度必须等于 features 的行数;stratify 为真时按其中的取值分组
testFraction (double) – 测试集比例,必须落在开区间 (0, 1)
shuffle (boolean) – 为真时对行下标(分层时为每个类内的行号)做 Fisher-Yates 重排
stratify (boolean) – 为真时按目标值分组抽样,使训练集与测试集都保留全部类别
seed (long) – 洗牌随机源种子;不分层与分层两条分支各自新建 Random,含义相同
- 返回
四个字段均为新建副本的 Holdout
- 抛出
NullPointerException – features 或 targets 为 null
IllegalArgumentException – targets 长度与行数不符、数据含非有限值、testFraction 不在 (0, 1),或样本数小于 2
- kFold(Matrix features, double[] targets, int folds, long seed) → List<Fold>static¶
按折数切分为互不重叠的测试块。
第 i 折的测试区间为 [i*rows/folds, (i+1)*rows/folds),训练集由其余折按洗牌顺序拼接而成,因此各折训练集大小同样只相差至多 1。
注意
列表顺序即折编号顺序,可直接顺序遍历做交叉验证
- 参数
features (Matrix) – 样本矩阵
targets (double[]) – 目标数组,长度必须等于 features.rows()
folds (int) – 折数,必须满足 2 <= folds <= features.rows()
seed (long) – 洗牌随机源种子
- 返回
长度为 folds 的 Fold 列表,测试块并集覆盖全部行
- 抛出
NullPointerException – features 或 targets 为 null
IllegalArgumentException – folds 越界,或 targets 长度不符、数据含非有限值
- kFold(Matrix features, double[] targets, int folds, boolean shuffle, long seed) → List<Fold>static¶
按折数切分,可选是否先洗牌。
shuffle 为假时直接按原始行顺序切片,各折测试块是连续的原始区间;为真时先对行下标做 Fisher-Yates 重排,再在重排顺序上切段。
注意
训练集由测试块之前与之后两段拼接而成,行序与原始顺序不同
- 参数
features (Matrix) – 样本矩阵
targets (double[]) – 目标数组,长度必须等于 features 的行数
folds (int) – 折数,必须满足 2 <= folds <= 行数
shuffle (boolean) – 为真时先重排行下标,为假时保持原始顺序
seed (long) – 洗牌随机源种子;shuffle 为假时不起作用
- 返回
长度为 folds 的 Fold 列表,测试块并集覆盖全部行
- 抛出
NullPointerException – features 或 targets 为 null
IllegalArgumentException – folds 越界,或 targets 长度不符、数据含非有限值
- stratifiedKFold(Matrix features, double[] targets, int folds, boolean shuffle, long seed) → List<Fold>static¶
按类别分层切分的 k 折。
先按目标值把行分组,每组内部可选洗牌,再用一个跨组连续累加的轮转计数器把样本依次放进 folds 个桶,因此同一类在各折的数量相差不超过 1。第 f 折以桶 f 为测试集,其余桶按桶序号拼接为训练集,每折都含有全部类别。
注意
轮转计数器跨类别连续累加,因此各类别的起始折不同
注意
只保证类内均衡,不保证各折总样本数完全相等
- 参数
features (Matrix) – 样本矩阵
targets (double[]) – 目标数组,长度必须等于 features 的行数;每个不同取值视为一个类别
folds (int) – 折数,必须满足 2 <= folds <= 行数,且每个类别的样本数不少于 folds
shuffle (boolean) – 为真时在每个类别内部做 Fisher-Yates 重排
seed (long) – 洗牌随机源种子;shuffle 为假时不起作用
- 返回
长度为 folds 的 Fold 列表,各折测试桶互不重叠且并集覆盖全部行
- 抛出
NullPointerException – features 或 targets 为 null
IllegalArgumentException – folds 越界、某个类别的样本数少于 folds,或 targets 长度不符、数据含非有限值
- final class DecisionTree implements Estimator, Persistable¶
预分箱特征上的 CART 树,分裂搜索走直方图
分裂搜索基于直方图:一次遍历节点样本即可填满每个特征的类别计数(分类)或和与平方和(回归),随后每个桶边界以 O(classes) 或 O(1) 评估增益。分类准则为 GINI 或 ENTROPY,回归固定使用 MSE 的和与平方和等价形式。
叶子值:分类取多数类标签(票数相同时取下标最小者),回归取样本均值。特征重要性按「分裂增益乘以节点样本数」逐特征累加,再归一化到总和 1。
拟合结果展平为 TreeModel,推理只在原始数组上迭代行走。RandomForest 复用一份全局 BinnedFeatures 并调用 fitBinned 传入自助采样行号,省去每棵树的重复分箱与矩阵复制。
示例Matrix x = Matrix.fromRows(new double[][]{ {0.0, 1.0}, {1.0, 1.0}, {1.0, 0.0}, {2.0, 0.0}}); double[] y = {0.0, 0.0, 1.0, 1.0}; DecisionTree tree = DecisionTree.builder() .task(TreeTask.CLASSIFICATION) .criterion(ImpurityCriterion.GINI) .maxDepth(3) .minSamplesLeaf(1) .bins(32) .seed(7L) .build() .fit(x, y); double[] predicted = tree.predict(x); double[] importance = tree.featureImportances();注意
分裂要求两侧样本数均不小于 minSamplesLeaf,父节点样本数不小于 minSamplesSplit 与 2*minSamplesLeaf
注意
最优增益不超过 1e-12*max(1, 父不纯度) 时停止分裂,节点转为叶
注意
maxDepth 为 0 时根节点直接成为叶
注意
fit 就地更新估计器状态并返回 this
参见:basalt.ml.RandomForest, basalt.ml.TreeModel, basalt.ml.ImpurityCriterion
方法
- builder() → Builderstatic¶
创建构造器,参数全部取默认值
- 返回
新的 Builder 实例
- fit(Matrix features, double[] targets) → DecisionTree¶
在原始特征矩阵上分箱并训练单棵树
先校验训练数据,再以 maxBins 构建 BinnedFeatures,最后用全部行号调用 fitBinned。分类标签按升序去重后编码为 0 起的整数,回归直接使用原始目标值。
注意
每次调用都会重建分箱与树,重复拟合覆盖上一次结果
- 参数
features (Matrix) – 训练特征矩阵,行数为样本数,列数成为特征数
targets (double[]) – 目标数组,长度必须等于行数;分类为类别标签,回归为连续值
- 返回
this,已完成拟合
- 抛出
IllegalArgumentException – 目标数量与行数不一致、特征或目标含非有限值,或样本数小于 minSamplesLeaf
NullPointerException – features 或 targets 为 null
- predict(Matrix features) → double[]¶
输出每行的叶值,分类为类别标签
内部调用 TreeModel.addInto 一次遍历完成,不做逐行对象分配。分类返回叶节点保存的类别标签,回归返回叶节点均值。
- 参数
features (Matrix) – 特征矩阵,列数须等于拟合时的特征数
- 返回
长度为行数的预测数组
- 抛出
IllegalStateException – 估计器尚未拟合
IllegalArgumentException – 列数与拟合时不一致,或含非有限值
- featureImportances() → double[]¶
归一化的特征重要性,总和为 1
口径为「分裂增益乘以该节点样本数」,在整棵树范围内按特征累加;总和大于 0 时整体除以总和,否则保持全零。只有真正参与分裂的特征会累积到非零值。
注意
返回 clone,修改不影响估计器内部状态
- 返回
长度为特征数的副本;树未产生分裂时全为 0
- 抛出
IllegalStateException – 估计器尚未拟合
- task() → TreeTask¶
构造时指定的任务类型
- 返回
CLASSIFICATION 或 REGRESSION
- classes() → double[]¶
分类任务的类别标签,按升序排列
注意
标签顺序来自 TreeMap 的自然序,与 predictProbability 的列顺序无关
- 返回
类别标签副本;回归任务返回 null
- featureCount() → int¶
拟合时使用的特征数
- 返回
特征数;未拟合为 0
- nodeCount() → int¶
树的节点总数
- 返回
节点数,含叶节点;未拟合为 0
- depth() → int¶
根到叶的最大边数
- 返回
树深;未拟合或单叶树为 0
- kind() → ModelKind¶
返回模型类型标识。
- 返回
ModelKind.DECISION_TREE
- write(ModelWriter writer)¶
序列化入口,等价于 writeState。
Persistable 的实现方法,直接委托 writeState,落盘格式与直接调用 writeState 完全一致。
注意
读取端用静态 read 或 readState 均可,两者等价
- 参数
writer (ModelWriter) – 目标写入器,由调用方负责容器头与关闭
- 抛出
IllegalStateException – 估计器尚未拟合
- read(ModelReader reader) → DecisionTreestatic¶
反序列化入口,等价于 readState。
静态工厂,直接委托 readState;读回后超参数取 Builder 默认值,只有任务、类别标签与树拓扑被还原。
注意
静态方法,调用形式为 DecisionTree.read(reader)
- 参数
reader (ModelReader) – 已定位到本对象载荷起点的读取器
- 返回
新的 DecisionTree 实例,已具备预测能力
- 抛出
ModelFormatException – 任务序号越界,或分类树缺少类别标签
- writeState(ModelWriter writer)¶
写出特征数、任务、类别标签与树拓扑
写入顺序为特征数、任务序号、类别数(回归写 0)与类别标签,最后是树的节点数组。超参数不落盘,读取方需要自行重建配置;分类树缺少标签会导致读取失败。
注意
与 readState 成对使用,格式由 ModelCodec 的容器包裹
- 参数
writer (ModelWriter) – 目标二进制写入器
- 抛出
IllegalStateException – 估计器尚未拟合
- readState(ModelReader reader) → DecisionTreestatic¶
从二进制流重建树
注意
重建后的超参数取 Builder 默认值,仅任务与准则被还原
注意
重建后的特征重要性全为 0,不参与持久化
- 参数
reader (ModelReader) – 已定位到本对象载荷起点的读取器
- 返回
新的 DecisionTree 实例,已具备预测能力
- 抛出
ModelFormatException – 任务序号越界,或分类树缺少类别标签
- enum DistanceMetric¶
KNN 使用的距离函数枚举。
EUCLIDEAN 返回平方欧氏距离开方,MANHATTAN 返回逐元素绝对差之和;两者都调用 VectorMath 的 SIMD 内核,按扁平数组上的偏移窗口计算。
distance 直接接收两个 double[] 与起始偏移,因此可以在 Matrix.data() 上按行取窗口,不必为每一行构造临时数组。
示例double[] a = {1.0, 2.0, 3.0}; double[] b = {1.0, 4.0, 3.0}; double euclidean = DistanceMetric.EUCLIDEAN.distance(a, 0, b, 0, 3); double manhattan = DistanceMetric.MANHATTAN.distance(a, 0, b, 0, 3);注意
偏移以元素为单位,不是字节
注意
不做越界检查,调用方需保证 offset + length 不超出数组长度
注意
两个常量都在枚举体内覆写 distance,没有默认实现
参见:basalt.ml.KNearestNeighbors, basalt.ml.KNeighborsRegressor
方法
- distance(double[] a, int aOffset, double[] b, int bOffset, int length) → doubleabstract¶
计算两段等长向量在该度量下的距离。
注意
越界与 length 为负都不检查,由调用方保证
- 参数
a (double[]) – 第一个向量的扁平存储
aOffset (int) – a 中参与计算的起始元素下标
b (double[]) – 第二个向量的扁平存储
bOffset (int) – b 中参与计算的起始元素下标
length (int) – 参与计算的元素个数,即特征维数
- 返回
按枚举常量定义的距离,非负;相同位置返回 0.0
- enum EigenSolver¶
PCA 可选的对称特征分解求解器。
AUTO 依据数据形状挑选实现:特征数大于样本数时走 GRAM,否则走 JACOBI。JACOBI 直接分解 p × p 协方差矩阵,GRAM 分解 n × n Gram 矩阵再还原主方向。
显式指定的求解器不会因形状被改写;但 GRAM 需要为 n × n 矩阵分配内存,样本数超过 20000 时 fit 拒绝执行。
注意
AUTO 仅在特征数大于样本数且样本数不超过 20000 时选择 GRAM
注意
两条路径输出在符号与数值误差范围内一致,符号由最大绝对值分量为正的约定固定
参见:basalt.ml.PCA, basalt.ml.PCA.Builder
枚举成员
- AUTO()¶
特征数多于样本数时选 GRAM,否则选 JACOBI
- JACOBI()¶
对 p×p 协方差做 Jacobi 对角化,O(n·p²)
- GRAM()¶
对 n×n Gram 矩阵做对角化,适合宽表,O(n²·p)
- interface Estimator¶
经典估计器的统一契约。
fit 消费特征矩阵与目标数组,就地更新估计器状态并返回 this,便于链式调用;predict 返回与输入行数等长的预测数组,顺序与输入行一一对应。
接口不规定重复 fit 的语义、也不声明线程安全:实现类在 fit 期间可变,predict 只读,因此同一实例的并发 predict 依赖实现是否持有可变临时状态。无监督实现可忽略 targets。
示例Matrix x = Matrix.fromRows(new double[][]{{0, 0}, {0, 1}, {1, 0}, {1, 1}}); double[] y = {0, 1, 1, 0}; Estimator model = KNearestNeighbors.builder().k(3).build().fit(x, y); double[] prediction = model.predict(x);注意
predict 前必须先 fit,实现类通过内部标记抛出 IllegalStateException
注意
不同实现的 predict 返回语义不同:分类器返回原始类别标签,回归器返回连续值
- final class Estimators¶
按枚举选择算法的一行式门面。
fit 按 Algorithm 分支构造对应估计器并立即训练,超参数一律取各 Builder 的默认值;需要调参时改用具体类的 builder()。有监督算法传入 null targets 会被拒绝,无监督算法则忽略 targets 并以 null 调用。
crossValidate 用 DataSplit.kFold 做种子固定为 42 的 k 折划分,逐折训练、预测、计分,返回各折算术平均。RMSE 在累加前取负号,使所有 Metric 都满足越大越好。
示例Matrix x = Matrix.fromRows(new double[][]{{0, 0}, {0, 1}, {1, 0}, {1, 1}, {2, 2}, {2, 1}}); double[] y = {0.5, 1.0, 1.5, 2.0, 2.5, 2.2}; Estimator model = Basalt.fit(Basalt.Algorithm.RIDGE, x, y); double[] prediction = Basalt.predict(model, x); double score = Basalt.crossValidate(Basalt.Algorithm.RIDGE, x, y, 3, Estimators.Metric.R2);注意
门面不缓存模型也不管理生命周期,返回的 Estimator 由调用方持有
注意
交叉验证的划分种子固定为 42,相同输入的结果可复现
注意
folds 的合法范围沿用 DataSplit.kFold 的约束(2 到样本数)
注意
门面本身无状态,全部方法为 static
参见:basalt.ml.Estimators.Algorithm, basalt.ml.Estimators.Metric, basalt.ml.Estimator, basalt.ml.DataSplit
方法
- fit(Algorithm algorithm, Matrix features, double[] targets) → Estimatorstatic¶
按算法枚举训练一个默认配置的估计器。
分支覆盖 16 个算法常量,其中 RANDOM_FOREST_REGRESSOR 复用 RandomForest 并切换 task,两个梯度提升常量分别绑定 LOGISTIC 与 SQUARED_ERROR 目标。
注意
KNN 与 KNN_REGRESSOR 固定 k=5、欧氏距离
注意
KMEANS、PCA 调用只接收特征的 fit 重载;DBSCAN 以 null targets 调用 fit
- 参数
algorithm (Algorithm) – 算法枚举,同时决定实现类与默认超参数
features (Matrix) – 训练特征矩阵
targets (double[]) – 训练目标;有监督算法不可为 null
- 返回
已拟合的估计器实例,静态类型为 Estimator
- 抛出
NullPointerException – algorithm 为 null
IllegalArgumentException – 有监督算法传入 null targets,或训练数据未通过估计器自身的校验
- predict(Estimator model, Matrix features) → double[]static¶
委托给估计器自身的 predict。
注意
门面不追加任何校验,全部检查由估计器完成
- 参数
model (Estimator) – 已拟合的估计器
features (Matrix) – 待预测特征矩阵
- 返回
估计器返回的预测数组,不做转换
- 抛出
NullPointerException – model 为 null
IllegalStateException – model 尚未 fit
- crossValidate(Algorithm algorithm, Matrix features, double[] targets, int folds, Metric metric) → doublestatic¶
k 折交叉验证并返回各折指标均值。
每折独立调用 fit 重新训练,模型之间不共享状态;指标在折内测试集上计算后累加,最后除以折数。
注意
划分种子固定为 42,重复调用结果一致
注意
ACCURACY 与 MACRO_F1 要求预测是类别码,R2 与 RMSE 要求连续值,错配不报错
- 参数
algorithm (Algorithm) – 待评估算法,必须是有监督算法
features (Matrix) – 全部样本特征
targets (double[]) – 全部样本目标,长度等于特征行数
folds (int) – 折数,2 <= folds <= 样本数
metric (Metric) – 评估指标枚举
- 返回
各折指标的算术平均;RMSE 以负值参与平均,故越大越好
- 抛出
IllegalArgumentException – 算法属于 UNSUPERVISED,或 folds 越界、数据校验失败
- final class FeatureImportance¶
统一的特征重要性入口:树杂质、线性权重绝对值与置换重要性。
三种口径按模型分派。树的杂质重要性直接复用 DecisionTree、RandomForest、HistogramGradientBoosting 的 featureImportances,量纲是「分裂增益乘以节点样本数」,本身已归一化到总和 1;线性模型取权重绝对值后归一化,反映的是系数幅度,方向信息因此丢失,也不代表对预测的因果贡献。
置换重要性不依赖模型内部结构:以真实目标与未打乱预测算出的分数为基线,逐列打乱该特征后重新预测,用分数下降量衡量重要性。它对任意 Estimator 与 Pipeline 都成立,也能反映特征间的交互,代价是每列 nRepeats 次完整预测。
of 遇到 Pipeline 会递归到 p.estimator(),返回的是末端估计器所见特征空间的重要性,列数可能不等于原始输入列数。
示例Matrix x = Matrix.fromRows(new double[][]{ {0.0, 1.0}, {1.0, 1.0}, {1.0, 0.0}, {2.0, 0.0}}); double[] y = {0.0, 0.0, 1.0, 1.0}; DecisionTree tree = DecisionTree.builder() .task(TreeTask.CLASSIFICATION) .maxDepth(3) .build() .fit(x, y); double[] impurity = FeatureImportance.of(tree); FeatureImportance.PermutationResult permuted = FeatureImportance.permutationImportance( tree, x, y, Estimators.Metric.ACCURACY, 5, 42L); double[] mean = permuted.importancesMean(); int[] order = permuted.rankedFeaturesDescending();注意
of 只支持 DecisionTree、RandomForest、HistogramGradientBoosting、Ridge、Lasso、LinearRegression、LogisticRegression、LinearSVM,其余类型抛 IllegalArgumentException
注意
线性归一化把绝对值之和缩放到 1;系数全为零时保持全零而不做除法
注意
置换重要性返回分数下降量,正值表示该特征有用,负值表示打乱后反而更好(常见于噪声列)
注意
metric 已统一为越大越好(RMSE 在内部取负),因此误差指标下「置换后变差」同样得到正的重要性
注意
置换在特征矩阵副本上进行,不会修改调用方传入的矩阵
参见:basalt.ml.DecisionTree, basalt.ml.RandomForest, basalt.ml.HistogramGradientBoosting
方法
- of(Estimator model) → double[]static¶
返回归一化到总和 1 的固有特征重要性。
按类型分派取原始值:树模型用其 featureImportances,线性模型用权重绝对值;随后整体除以总和,使结果之和为 1。Pipeline 会先递归到底层估计器。
注意
返回的数组可安全修改,树实现内部返回 clone
注意
对 Pipeline 只取末端估计器,忽略前置变换对列的影响
- 参数
model (Estimator) – 已拟合的估计器;未拟合的树在取重要性时抛 IllegalStateException
- 返回
长度等于该估计器特征数的数组,非负且总和为 1;原始值全零时保持全零
- 抛出
NullPointerException – model 为 null
IllegalArgumentException – 该估计器类型不暴露固有重要性
- permutationImportance(Estimator model, Matrix features, double[] targets, Estimators.Metric metric, int nRepeats, long seed) → PermutationResultstatic¶
逐列打乱特征,用评分下降量衡量重要性。
先对未打乱的预测算基线分数;再对每一列重复 nRepeats 次:用同一个 Random 做 Fisher-Yates 重排行下标,按重排结果把该列的值搬到新位置,复制成新矩阵后重新预测,单次下降量 = 基线 − 打乱后分数。最后按列求均值,并以总体标准差(除以 nRepeats)作为波动量。
注意
rawImportances 形状为 特征数 × nRepeats,第 c 行是第 c 列的各次下降量
注意
行下标数组在所有列与所有重复之间复用,洗牌状态不重置
注意
结果用 PermutationResult.rankedFeaturesDescending 可直接取降序特征下标
- 参数
model (Estimator) – 已拟合的估计器;predict 会被调用 列数×nRepeats+1 次
features (Matrix) – 评估用样本矩阵,行数为样本数、列数为特征数;元素必须有限
targets (double[]) – 真实目标,长度必须等于 features 的行数
metric (Estimators.Metric) – 评分口径,取 Estimators.Metric 的 ACCURACY、MACRO_F1、R2 或 RMSE;RMSE 在内部取负,使所有指标都越大越好
nRepeats (int) – 每列重复打乱的次数,必须为正
seed (long) – 洗牌随机源种子,决定重排序列
- 返回
持有 importancesMean、importancesStd 与 rawImportances 的 PermutationResult
- 抛出
NullPointerException – model、features、targets 或 metric 为 null
IllegalArgumentException – 目标数与行数不符、数据含非有限值,或 nRepeats 不为正
IllegalStateException – model 尚未拟合
- final class GaussianMixture implements Estimator, Persistable¶
EM 估计的高斯混合模型,协方差可选 FULL / TIED / DIAG。
协方差由
covarianceType决定:FULL 为每个分量存一个 p×p 矩阵,TIED 让全部分量共享一个矩阵,DIAG 只存 p 个方差。FULL 与 TIED 在每轮 E 步前先做 Cholesky 分解,用前代把马氏距离换成 ‖L⁻¹(x−μ)‖²,对数行列式取 2·Σlog L_ii;分解失败时按 regCovar·10ⁿ 追加 jitter 重试,6 次仍非正定则抛 IllegalStateException。拟合先用 KMeans 初始化:簇数等于 components、maxIterations 固定 30、使用同一 seed。均值取质心,权重取簇占比,协方差取簇内样本协方差(TIED 取全局共享)。随后每轮 E 步计算「log 权重 + 对数密度」并按行做 log-sum-exp 得到责任度,M 步更新权重、均值与协方差,相邻两轮平均对数似然差不超过 tolerance 即收敛。
AIC/BIC 的自由参数个数随协方差类型变化:DIAG 为 K·2p+K−1,FULL 为 K·(p+p(p+1)/2)+K−1,TIED 为 K·p+p(p+1)/2+K−1。相关特征上 FULL 的对数似然明显更高,但参数更多,需用 AIC/BIC 权衡。
注意
默认 covarianceType 为 FULL;改回 DIAG 可获得 O(K·p) 的存储与求值,代价是无法表达分量内的特征相关
注意
E 步对权重取 max(1e-15, w) 后再取对数,某个分量被压到 0 时不会出现负无穷
注意
lowerBound 是平均每样本对数似然而非总似然,量纲与 sklearn 的 lower_bound_ 一致
注意
write 落盘协方差类型与完整 p×p 矩阵;read 之后 maxIterations、tolerance、regCovar、seed 回落到 Builder 默认值
注意
DIAG 的非对角项恒为 0,但 covariance(k) 仍返回 p×p 稠密矩阵,便于统一处理
方法
- builder() → Builderstatic¶
创建 GaussianMixture 构建器。
- 返回
components 为 2、maxIterations 为 100、tolerance 为 1e-4、regCovar 为 1e-6、seed 为 42 的新 Builder 实例
- fit(Matrix features) → GaussianMixture¶
以无监督方式拟合混合模型。
等价于 fit(features, null),目标数组不参与计算。
- 参数
features (Matrix) – 样本矩阵,行是样本、列是特征;元素必须有限
- 返回
this,便于链式调用
- 抛出
NullPointerException – features 为 null
IllegalArgumentException – features 含非有限值,或 components 大于样本数
- fit(Matrix features, double[] ignoredTargets) → GaussianMixture¶
用 EM 估计混合权重、均值与方差。
初始化阶段调用 KMeans 得到质心与初始簇划分,据此估算各分量的初始方差与权重;之后交替执行 E 步(算责任度、算 lowerBound)与 M 步(用责任度加权重估权重、均值、方差,并把 regCovar 加回方差)。
注意
每轮 E 步都覆盖 lowerBound,未收敛时它对应最后一次 E 步
注意
M 步用 max(nk, 1e-10) 作分母,空分量的权重被压到接近 0 而不会除零
- 参数
features (Matrix) – 样本矩阵,行数为样本数,列数成为特征数;元素必须有限
ignoredTargets (double[]) – 占位参数;混合模型为无监督任务,源码不读取,传 null 或任意数组均可
- 返回
this,已完成拟合
- 抛出
NullPointerException – features 为 null
IllegalArgumentException – features 含非有限值,或 components 大于样本数
- scoreSamples(Matrix features) → double[]¶
返回每个样本的对数概率密度 log p(x)。
逐样本对 K 项的「log 权重 + 对角高斯对数密度」做 log-sum-exp:先减最大值,再取指数累加取对数,最后加回最大值,避免下溢。
- 参数
features (Matrix) – 样本矩阵,列数须等于拟合时的特征数;元素必须有限
- 返回
长度为样本数的对数密度数组,元素通常为负
- 抛出
NullPointerException – features 为 null
IllegalStateException – 尚未拟合
IllegalArgumentException – 特征列数与拟合时不一致,或含非有限值
- predictProbability(Matrix features) → Matrix¶
返回样本属于各分量的后验概率。
对每行做减最大值的 softmax,得到 K 个非负且和为 1 的责任度,等价于 E 步的输出。
- 参数
features (Matrix) – 样本矩阵,列数须等于拟合时的特征数;元素必须有限
- 返回
样本数 × components 的矩阵,第 k 列对应第 k 个分量
- 抛出
NullPointerException – features 为 null
IllegalStateException – 尚未拟合
IllegalArgumentException – 特征列数与拟合时不一致,或含非有限值
- predict(Matrix features) → double[]¶
返回后验概率最大的分量编号。
先算后验概率矩阵,再逐行取最大列。比较用严格大于,概率并列时返回编号较小的分量。
- 参数
features (Matrix) – 样本矩阵,列数须等于拟合时的特征数;元素必须有限
- 返回
长度为样本数的分量编号数组,取值 0 到 components−1
- 抛出
NullPointerException – features 为 null
IllegalStateException – 尚未拟合
IllegalArgumentException – 特征列数与拟合时不一致,或含非有限值
- parameterCount() → int¶
按协方差类型计算的自由参数个数
- 返回
DIAG 为 K·2p+K−1,FULL 为 K·(p+p(p+1)/2)+K−1,TIED 为 K·p+p(p+1)/2+K−1
- aic(Matrix features) → double¶
赤池信息量,用于在分量数之间取舍。
logLik 取 scoreSamples 之和,nParams = components·2·特征数 + (components−1),返回 2·nParams − 2·logLik。参数越多惩罚越大,似然越高值越小。
注意
参数计数按对角协方差给出,每个分量计 p 个均值与 p 个方差
注意
样本数不影响 AIC,只影响 logLik 的累加项数
- 参数
features (Matrix) – 用于评估的样本矩阵,列数须与拟合时一致,可与训练集不同
- 返回
AIC 值,无下界
- 抛出
NullPointerException – features 为 null
IllegalStateException – 尚未拟合
IllegalArgumentException – 特征列数与拟合时不一致,或含非有限值
- bic(Matrix features) → double¶
贝叶斯信息量,对参数的惩罚随样本数增长。
返回 nParams·ln(rows) − 2·logLik,nParams 与 aic 相同,rows 为传入矩阵的行数。样本数超过 e² 时 ln(rows) 大于 2,同一模型的 BIC 惩罚重于 AIC,因此 BIC 更倾向少分量。
注意
样本数取自传入矩阵而非训练集,用测试集评估时惩罚项随之变化
- 参数
features (Matrix) – 用于评估的样本矩阵,列数须与拟合时一致,可与训练集不同
- 返回
BIC 值,无下界
- 抛出
NullPointerException – features 为 null
IllegalStateException – 尚未拟合
IllegalArgumentException – 特征列数与拟合时不一致,或含非有限值
- weights() → double[]¶
返回各分量的混合权重。
权重由 M 步的 nk/rows 得到,总和为 1;未经过 M 步时是初始化阶段的类频率。
- 返回
长度等于 components 的副本;未拟合时返回 null 而不抛异常
- covarianceType() → CovarianceType¶
拟合时使用的协方差参数化
- 返回
FULL、TIED 或 DIAG
- means() → Matrix¶
返回各分量的均值向量。
- 返回
components × 特征数 的矩阵,第 k 行是第 k 个分量的均值
- 抛出
IllegalStateException – 尚未拟合
- variances() → Matrix¶
返回各分量的对角方差。
矩阵元素已包含 regCovar,因此均不小于 regCovar,可直接用于高斯密度求值。
注意
只保存对角元素,非对角协方差不在模型中
- 返回
components × 特征数 的矩阵,第 k 行是第 k 个分量在各特征上的方差
- 抛出
IllegalStateException – 尚未拟合
- covariance(int component) → Matrix¶
返回某个分量的 p×p 协方差矩阵
- 参数
component (int) – 分量下标,需满足 0 ≤ component < components
- 返回
形状 [featureCount, featureCount] 的稠密对称矩阵;DIAG 时非对角为 0
- 抛出
IllegalArgumentException – component 越界
IllegalStateException – 模型尚未拟合
- converged() → boolean¶
报告 EM 是否在迭代上限内达到收敛判据。
- 返回
收敛为 true;未拟合或跑满 maxIterations 仍不满足为 false
- iterations() → int¶
返回实际执行的 EM 轮数。
注意
收敛的那一轮也计入,即使该轮跳过了 M 步
- 返回
轮数,从 1 开始计;未拟合为 0,未收敛时等于 maxIterations
- lowerBound() → double¶
返回最近一轮的平均每样本对数似然。
每轮 E 步把它更新为 totalLogProb/rows,因此它是收敛判据的比较对象,也是逐轮单调不减的见证量。
注意
收敛时对应最后一次 E 步,而非最后一次 M 步的参数
- 返回
lowerBound 值;未拟合时为 0.0
- kind() → ModelKind¶
返回模型类型标识。
- 返回
ModelKind.GAUSSIAN_MIXTURE
- write(ModelWriter writer)¶
把超参数与全部统计量写入序列化流。
写入顺序为 components、特征数、收敛标志、迭代轮数、lowerBound、权重、均值、方差。maxIterations、tolerance、regCovar、seed 不落盘。
注意
与静态 read 成对使用,读取端必须按同一顺序消费
- 参数
writer (ModelWriter) – 目标写入器,由调用方负责容器头与关闭
- 抛出
IllegalStateException – 尚未拟合
- read(ModelReader reader) → GaussianMixturestatic¶
从序列化流重建 GaussianMixture。
注意
静态方法,调用形式为 GaussianMixture.read(reader)
注意
读回的 converged、iterations、lowerBound 来自流,不重新计算
- 参数
reader (ModelReader) – 已完成容器头解析的读取器
- 返回
恢复统计量的新实例,超参数取 Builder 默认值
- 抛出
ModelFormatException – components 或特征数不为正
- final class GaussianNaiveBayes implements Estimator, Persistable¶
按类估计均值、方差与先验的高斯朴素贝叶斯分类器。
拟合时按目标值升序枚举类别,逐类计算各特征均值与总体方差(除以该类样本数),先验取类频率的对数。预测在对数域累加先验与各特征的独立高斯对数似然,避免概率连乘下溢。
方差平滑沿用 scikit-learn 的尺度无关约定:epsilon 等于 varianceSmoothing 乘以全体方差最大值,再加到每个方差上;该乘积不为正时直接使用 varianceSmoothing。
示例Matrix features = Matrix.fromRows(new double[][] { {1.0, 2.0}, {1.2, 1.8}, {0.9, 2.1}, {5.0, 8.0}, {5.4, 7.6}, {4.8, 8.2} }); double[] targets = {0.0, 0.0, 0.0, 1.0, 1.0, 1.0}; GaussianNaiveBayes model = GaussianNaiveBayes.builder() .varianceSmoothing(1e-9) .build() .fit(features, targets); double[] predicted = model.predict(features); Matrix logPosterior = model.predictLogProbability(features); Matrix posterior = model.predictProbability(features);注意
类别取值按升序排列,概率并列时 predict 返回序号最小、即取值最小的类
注意
拟合样本数不少于 512 且原生内核可用时由原生实现计算均值、方差与先验
注意
varianceSmoothing 不写入序列化流,read 后取 Builder 默认值;已平滑的方差本身被保存,预测不受影响
参见:basalt.ml.Estimator, basalt.core.Persistable
方法
- builder() → Builderstatic¶
创建 GaussianNaiveBayes 构建器。
- 返回
参数取默认值的新 Builder 实例
- fit(Matrix features, double[] targets) → GaussianNaiveBayes¶
估计各类的均值、方差与先验。
类别集合来自目标数组的去重升序结果,随后两遍扫描:第一遍累计类内和与类计数得到均值、先验,第二遍累计离差平方得到总体方差,最后统一加上平滑项 epsilon。
- 参数
features (Matrix) – 训练样本矩阵,行是样本、列是特征;元素必须有限
targets (double[]) – 每行对应的类别标签,长度必须等于样本数;元素必须有限
- 返回
this,便于链式调用
- 抛出
NullPointerException – features 或 targets 为 null
IllegalArgumentException – targets 长度与样本数不一致,或存在非有限值
- predictLogProbability(Matrix features) → Matrix¶
返回各类的对数联合概率矩阵。
每个元素等于 log(先验) 加上各特征对数高斯密度之和,形如 -0.5 · (log(2πσ²) + (x - μ)² / σ²) 的累加。数值上比直接乘概率稳定。
- 参数
features (Matrix) – 样本矩阵,列数须与拟合时一致
- 返回
样本数 × 类别数 的矩阵,列顺序与 classes() 一致
- 抛出
IllegalStateException – 尚未拟合
IllegalArgumentException – 特征列数与拟合时不一致
- predictProbability(Matrix features) → Matrix¶
把对数联合概率归一化为后验概率。
逐行减去最大值后取指数并归一,等价于对对数概率做 softmax,可避免上溢。若整行对数概率都不是有限值,则退化为按先验归一;先验之和也不为正时返回均匀分布。
- 参数
features (Matrix) – 样本矩阵,列数须与拟合时一致
- 返回
样本数 × 类别数 的矩阵,每行元素和为 1
- 抛出
IllegalStateException – 尚未拟合
IllegalArgumentException – 特征列数与拟合时不一致
- predict(Matrix features) → double[]¶
返回后验概率最大的类别标签。
先计算后验概率矩阵,再逐行取最大列,映射回原始类别取值。比较使用严格大于,因此概率并列时返回序号最小、即取值最小的类。
- 参数
features (Matrix) – 样本矩阵,列数须与拟合时一致
- 返回
长度为样本数的类别标签数组
- 抛出
IllegalStateException – 尚未拟合
IllegalArgumentException – 特征列数与拟合时不一致
- classes() → double[]¶
返回按升序排列的类别取值。
- 返回
类别数组的副本;未拟合时为 null
- means() → Matrix¶
返回各类别各特征的均值矩阵。
- 返回
类别数 × 特征数 的矩阵,第 i 行对应 classes()[i]
- 抛出
IllegalStateException – 尚未拟合
- variances() → Matrix¶
返回各类别各特征的方差矩阵。
数值为总体方差(分母是类内样本数)加平滑项 epsilon 之后的结果,因此全部为正,不会出现零方差导致除零。
- 返回
类别数 × 特征数 的矩阵,第 i 行对应 classes()[i]
- 抛出
IllegalStateException – 尚未拟合
- logPriors() → double[]¶
返回各类别先验概率的自然对数。
注意
取对数而非概率,便于与对数似然直接相加
- 返回
长度等于类别数的数组副本;未拟合时为 null
- kind() → ModelKind¶
返回模型类型标识。
- 返回
ModelKind.GAUSSIAN_NAIVE_BAYES
- write(ModelWriter writer)¶
把特征数、类别、均值、方差与对数先验写入序列化流。
注意
写入顺序为特征数、类别数、类别、均值、方差、对数先验,读取端必须按同一顺序消费
- 参数
writer (ModelWriter) – 目标写入器,由调用方负责容器头与关闭
- 抛出
IllegalStateException – 尚未拟合
- read(ModelReader reader) → GaussianNaiveBayesstatic¶
从序列化流重建 GaussianNaiveBayes 模型。
- 参数
reader (ModelReader) – 已完成容器头解析的读取器
- 返回
只恢复统计量的模型实例,varianceSmoothing 取 Builder 默认值
- 抛出
ModelFormatException – 特征数或类别数不为正
- final class GridSearchCV implements Estimator¶
网格穷举加交叉验证的调参器,选优后全量重训。
交叉验证来源是 DataSplit:stratified 为 false 时调用 DataSplit.kFold,为 true 时调用 DataSplit.stratifiedKFold,两者都以 shuffle=true 与构造时的 seed 打乱,折数为 cvFolds。
param 声明的每个键对应一组候选值,所有键做笛卡尔积并按声明顺序遍历。每个组合在每折上调用一次 estimatorFactory 新建估计器,在训练折拟合、测试折预测,再用 scoring 折算为标量:ACCURACY、MACRO_F1、R2 取原值,RMSE 取负值,因此分数一律越大越好。
组合之间用各折均值比较,严格大于才替换当前最优,并列时保留先出现的组合;均值标准差按总体公式 sqrt(Σ(s-mean)²/k) 计算。选优后以同一工厂再构造一个估计器并在全部数据上拟合,作为 bestEstimator。
示例Matrix x = Matrix.fromRows(new double[][] { {0.0, 0.0}, {0.2, 0.1}, {0.1, 0.3}, {0.3, 0.2}, {1.0, 1.0}, {1.2, 0.9}, {0.9, 1.1}, {1.1, 1.2} }); double[] y = {0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0}; GridSearchCV search = GridSearchCV.builder( params -> KNearestNeighbors.builder() .k((Integer) params.get("k")) .build()) .param("k", 1, 3) .scoring(Estimators.Metric.ACCURACY) .cv(2) .stratified(true) .seed(42L) .build() .fit(x, y); Estimator best = search.bestEstimator(); Map<String, Object> bestParams = search.bestParams(); double bestScore = search.bestScore(); double[] label = search.predict(x);注意
默认 scoring=ACCURACY、cvFolds=5、stratified=false、seed=42;构建时 paramGrid 为空会抛 IllegalArgumentException
注意
RMSE 评分下 bestScore 与 cvResults 中的分数均为负值,比较时仍取最大者
注意
分层划分要求每个类别的样本数不少于折数,否则 DataSplit 抛 IllegalArgumentException
注意
工厂每折调用一次,估计器实例不跨折复用,工厂内部应无共享可变状态
注意
每次 fit 会清空 cvResults 并重置最优结果
参见:basalt.ml.KFold, basalt.ml.DataSplit, basalt.ml.Estimators, basalt.ml.Estimator
方法
- builder(Function<Map<String, Object>, Estimator> estimatorFactory) → Builderstatic¶
以估计器工厂创建构造器。
- 参数
estimatorFactory (Function<Map<String, Object>, Estimator>) – 参数组合到未拟合估计器的映射,每折调用一次且应返回新实例
- 返回
新的 Builder 实例,scoring=ACCURACY、cvFolds=5、stratified=false、seed=42
- 抛出
NullPointerException – estimatorFactory 为 null
- fit(Matrix features, double[] targets) → GridSearchCV¶
按折评分遍历网格并重训最优模型。
先按 stratified 选择划分方式,以 cvFolds 与 seed 生成折;再对 param 网格取笛卡尔积,逐个组合在每折上新建估计器、拟合训练折、预测测试折并折算分数,得到均值与总体标准差。
比较用严格大于,并列时保留先出现的组合;结束后用最优参数在全部数据上重新拟合一次作为 bestEstimator。
注意
折数大于样本数时同样由 DataSplit 抛 IllegalArgumentException
注意
同一组合的各折互不影响,分数按折序存入 foldScores
- 参数
features (Matrix) – 训练特征矩阵,行数为样本数
targets (double[]) – 目标数组,长度须等于行数
- 返回
this,已完成拟合并持有最优估计器
- 抛出
NullPointerException – features 或 targets 为 null
IllegalArgumentException – 目标数量与行数不一致、数据含非有限值,或分层划分时某类样本数少于折数
- predict(Matrix features) → double[]¶
用最优估计器预测。
注意
列数校验由最优估计器自身的 predict 完成
- 参数
features (Matrix) – 待预测特征矩阵,列数须与训练数据一致
- 返回
最优估计器的预测数组,标签或回归值取决于被调优的估计器
- 抛出
IllegalStateException – 尚未拟合
- bestEstimator() → Estimator¶
返回在全部数据上重训的估计器。
- 返回
已完成拟合的 Estimator 实例
- 抛出
IllegalStateException – 尚未拟合
- bestParams() → Map<String, Object>¶
返回最优参数组合。
- 返回
不可变的参数映射,键与 param 声明一致
- 抛出
IllegalStateException – 尚未拟合
- bestScore() → double¶
返回最优组合的交叉验证均分。
- 返回
各折分数的算术平均;scoring 为 RMSE 时为负值
- 抛出
IllegalStateException – 尚未拟合
- cvResults() → List<CandidateResult>¶
返回每个候选组合的逐折成绩。
注意
未拟合时返回空列表,不抛异常
注意
stdScore 为总体标准差,分母取折数而非折数减一
注意
fit 会清空并重建该列表
- 返回
不可变列表,元素为 CandidateResult(params、meanScore、stdScore、foldScores),顺序与网格遍历顺序一致
- final class HistogramGradientBoosting implements Estimator, Persistable¶
二阶直方图梯度提升,支持深度优先与叶优先生长
分裂增益按正则化目标计算:0.5*(G_L^2/(H_L+lambda) + G_R^2/(H_R+lambda) - G^2/(H+lambda)) - gamma,叶权重为 -G/(H+lambda)。直方图用相减技巧:每次只累加较小子节点,较大子节点由 parent 减 small 得到,平衡树因此只做约一半遍历。
XGBOOST 策略按层递归,由 maxDepth 控制深度;LIGHTGBM 策略用优先队列每轮分裂全局增益最大的叶,由 maxLeaves 控制叶数。两种策略都受 minSamplesLeaf、minChildWeight 与 maxDepth 约束。
累计量较大时通过 JNI 交给 Rust AVX2 内核,原生调用失败则回退到分块并行的 Java 路径。featureFraction 按轮次抽取特征子集,validationFraction 切出验证集,配合 earlyStoppingRounds 把树列表回退到最优轮次。
示例Matrix x = Matrix.fromRows(new double[][]{ {0.0, 1.0}, {1.0, 1.0}, {1.0, 0.0}, {2.0, 0.0}, {2.0, 1.0}, {3.0, 0.0}, {3.0, 1.0}, {4.0, 0.0}}); double[] y = {0.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0, 0.0}; HistogramGradientBoosting model = HistogramGradientBoosting.builder() .algorithm(BoostingAlgorithm.LIGHTGBM) .objective(BoostingObjective.LOGISTIC) .iterations(200) .learningRate(0.1) .maxLeaves(15) .featureFraction(0.8) .validationFraction(0.25) .earlyStoppingRounds(20) .build() .fit(x, y); double[] probability = model.predictProbability(x); double[] label = model.predict(x); double[] history = model.lossHistory();注意
LOGISTIC 目标要求标签恰为 0 或 1,其余取值在 fit 入口被拒绝
注意
早停触发后树列表截断到 bestIteration+1,lossHistory 同步截断
注意
write 只保存算法、目标、学习率、baseScore 与树;读回时其余超参数取 Builder 默认值
参见:basalt.ml.BoostingAlgorithm, basalt.ml.BoostingObjective, basalt.ml.DecisionTree
方法
- builder() → Builderstatic¶
创建构造器,参数全部取默认值
- 返回
新的 Builder 实例
- fit(Matrix features, double[] targets) → HistogramGradientBoosting¶
分箱、切分验证集并逐轮提升
先按 validationFraction 用 seed 打乱行号,前若干行作验证集,其余作训练集;baseScore 取训练集标签均值,LOGISTIC 下取该均值的对数几率。每轮计算梯度与 hessian、生长一棵树、以 learningRate 累加到原始得分,并记录训练与验证损失。
注意
验证集大小取 round(rows*validationFraction),下限 1,上限 rows-2
注意
featureFraction 小于 1 时,第 i 轮用 seed + i*7919 抽取 ceil(fraction*featureCount) 个特征
- 参数
features (Matrix) – 训练特征矩阵,行数为样本数
targets (double[]) – 目标数组,长度须等于行数;LOGISTIC 时取值须为 0 或 1
- 返回
this,已完成拟合
- 抛出
IllegalArgumentException – 目标数量与行数不一致、含非有限值,或 LOGISTIC 标签不是 0 或 1
- predictRaw(Matrix features) → double[]¶
输出原始得分,未过 sigmoid
结果以 baseScore 为初值,逐棵树以 learningRate 加权累加叶值。行数乘树数不小于 2000 万时转交原生集成预测内核,否则在 Java 侧逐树累加。
- 参数
features (Matrix) – 特征矩阵,列数须等于拟合时的特征数
- 返回
长度为行数的原始得分数组
- 抛出
IllegalStateException – 尚未拟合(树列表为空)
IllegalArgumentException – 列数不匹配或含非有限值
- predictProbability(Matrix features) → double[]¶
输出正类概率,等于 sigmoid(原始得分)
注意
sigmoid 按符号分支实现,负值不经过 exp 溢出
- 参数
features (Matrix) – 特征矩阵,列数须等于拟合时的特征数
- 返回
长度为行数的概率数组,取值 (0, 1)
- 抛出
IllegalStateException – 目标不是 LOGISTIC(该校验先于拟合状态校验)
- predict(Matrix features) → double[]¶
输出预测值,LOGISTIC 下为 0/1 标签
回归直接返回原始得分;LOGISTIC 把 sigmoid(原始得分) 与 0.5 比较,大于等于 0.5 取 1.0,否则取 0.0。
- 参数
features (Matrix) – 特征矩阵,列数须等于拟合时的特征数
- 返回
长度为行数的预测数组
- 抛出
IllegalStateException – 尚未拟合
IllegalArgumentException – 列数不匹配或含非有限值
- lossHistory() → double[]¶
每轮训练集平均损失
平方误差目标记录 0.5*残差^2 的均值;LOGISTIC 记录 softplus(raw) - target*raw 的均值,数值上等价于二元交叉熵。
注意
早停后长度等于保留下来的树数
- 返回
长度为实际训练轮数的副本;未拟合为空数组
- validationHistory() → double[]¶
每轮验证集平均损失
- 返回
长度为实际训练轮数的副本;未设置 validationFraction 或未拟合时为空数组
- featureImportances() → double[]¶
归一化的特征重要性,总和为 1
口径与 DecisionTree 一致:每次分裂的增益乘以该节点样本数,按特征累加后整体归一化到总和 1。分裂发生在特征子集上时,未参与该轮的特征不增加。
注意
读回的模型不携带重要性,返回全 0
- 返回
长度为特征数的副本;未拟合为空数组
- treeCount() → int¶
已训练的树数
- 返回
树数;未拟合为 0,早停后小于 iterations
- bestIteration() → int¶
验证损失最优的轮次下标
- 返回
最优轮次;无验证集时为最后一轮,未拟合为 iterations-1
- kind() → ModelKind¶
持久化类型标识
- 返回
ModelKind.HISTOGRAM_BOOSTING
- write(ModelWriter writer)¶
按 Persistable 契约写出提升模型
写入算法序号、目标序号、learningRate、baseScore、特征数、树数与各棵树的节点数组。maxDepth、maxLeaves、lambda 等超参数不参与序列化。
- 参数
writer (ModelWriter) – 目标二进制写入器
- read(ModelReader reader) → HistogramGradientBoostingstatic¶
从二进制流重建提升模型
注意
读回后 lossHistory 与 validationHistory 为空数组,featureImportances 全为 0
注意
bestIteration 置为树数减 1,训练相关字段不恢复
- 参数
reader (ModelReader) – 已定位到本对象载荷起点的读取器
- 返回
新的 HistogramGradientBoosting 实例,可直接预测
- 抛出
ModelFormatException – 算法或目标序号越界,或特征数不大于 0、树数不在 [1, 100000]
- enum ImpurityCriterion¶
决策树用于最大化信息增益的节点不纯度
GINI 计算 1 - Σp^2,ENTROPY 计算 -Σ p*log2(p),两者绑定 TreeTask.CLASSIFICATION。MSE 绑定 TreeTask.REGRESSION,其 impurity 方法直接抛出 IllegalStateException,因为回归分裂改用和与平方和的代数等价形式,不经过类别计数。
每个常量在构造时绑定任务,task() 暴露该绑定。DecisionTree.Builder 在 build() 时校验 criterion.task() 与 task 一致,准则与任务不会在运行期错配。
示例ImpurityCriterion criterion = ImpurityCriterion.ENTROPY; DecisionTree tree = DecisionTree.builder() .criterion(criterion) .task(criterion.task()) .maxDepth(4) .build();注意
骨架中的 ENTROPY 与 MSE 条目是枚举常量,签名里出现的参数即构造时传入的任务标记
注意
MSE 只作任务标识,逐节点计算不经过 impurity
参见:basalt.ml.DecisionTree, basalt.ml.TreeTask
方法
- task() → TreeTask¶
该准则绑定的任务类型
注意
Builder 用它校验准则与任务是否匹配
- 返回
构造时传入的 TreeTask
- final class IsolationForest implements Estimator, Persistable¶
随机轴对齐切分的无监督孤立森林异常检测器。
每棵树在 min(行数, maxSamples) 个无放回抽样的样本上递归切分:随机挑一个取值不全相同的特征,在该列最小值与最大值之间均匀取切点,小于等于切点的样本进左子树;样本数不超过 1、深度达到 max(1, ceil(log2(effectiveMaxSamples)))、或所选特征无区分度时成为叶节点,叶节点保存 depth + c(n)。
路径长度归一化 s(x, n) = 2^(-E(h(x))/c(n)),E(h) 为样本在各棵树上路径长度的平均值,c(n) 为二叉搜索树平均路径修正项:n <= 1 取 0,n == 2 取 1,否则取 2*(ln(n-1) + EulerGamma) - 2*(n-1)/n。分数落在 (0, 1],越接近 1 越异常,约 0.5 为平均路径长度。
contamination 只影响判决阈值:拟合末尾对训练集的 0.5 - s 升序排序,取下标 max(0, min(rows-1, floor(rows * contamination))) 处的值作为 threshold。decisionFunction 返回 0.5 - s - threshold,predict 对非负者给 +1.0、负者给 -1.0。
示例Matrix features = Matrix.fromRows(new double[][] { {0.0, 0.1}, {0.2, 0.0}, {0.1, 0.2}, {0.15, 0.1}, {9.0, 9.2}, {9.4, 8.8}, {10.0, 9.0}, {0.3, 0.25} }); IsolationForest forest = IsolationForest.builder() .trees(100) .maxSamples(256) .contamination(0.25) .seed(42L) .build() .fit(features); double[] score = forest.anomalyScore(features); double[] decision = forest.decisionFunction(features); double[] label = forest.predict(features);注意
默认 trees=100、maxSamples=256、contamination=0.1、seed=42;trees 须为正,maxSamples 须 >= 2,contamination 须在 (0, 0.5) 开区间内
注意
随机性全部来自 seed:主随机源为每棵树派生一个子种子,同 seed 同数据得到相同的树与阈值
注意
write 保存全部超参数、featureCount、effectiveMaxSamples、threshold 与树结构,read 直接沿用读入的阈值,不重新打分
注意
样本数少于 maxSamples 时 effectiveMaxSamples 退化为行数,c(n) 与树高上限随之按行数计算
参见:basalt.ml.Estimator, basalt.core.Persistable, basalt.ml.Estimators
方法
- builder() → Builderstatic¶
创建构造器,超参数取默认值。
- 返回
新的 Builder 实例,trees=100、maxSamples=256、contamination=0.1、seed=42
- fit(Matrix features) → IsolationForest¶
仅凭特征拟合,等价于 fit(features, null)。
- 参数
features (Matrix) – 训练特征矩阵,行数为样本数,列数为特征数
- 返回
this,已完成拟合并可打分
- 抛出
NullPointerException – features 为 null
IllegalArgumentException – 特征含非有限值
- fit(Matrix features, double[] ignoredTargets) → IsolationForest¶
建树并对训练集打分确定阈值。
effectiveMaxSamples 取行数与 maxSamples 的较小值,树高上限为 max(1, ceil(log2(effectiveMaxSamples)))。每棵树用主随机源派生的子种子做无放回抽样,再随机选一个取值不全相同的特征、在列最小与最大之间均匀取切点递归下分。
全部树建成后对训练集计算 0.5 - s,升序排序并取 contamination 对应的分位值作为 threshold,供 decisionFunction 与 predict 使用。
注意
effectiveMaxSamples 极小时树高上限至少为 1
注意
每棵树的抽样与切点都由各自的子种子决定,treeCount 棵树互相独立
- 参数
features (Matrix) – 训练特征矩阵,行数为样本数
ignoredTargets (double[]) – 占位参数,内容被完全忽略,可为 null
- 返回
this,已完成拟合
- 抛出
NullPointerException – features 为 null
IllegalArgumentException – 特征含非有限值
- anomalyScore(Matrix features) → double[]¶
计算归一化异常分数 2^(-E(h)/c(n))。
注意
E(h) 为样本在各棵树上的平均路径长度,归一化分母 c(n) 用 effectiveMaxSamples 计算
注意
c(n) 下限截到 1e-12,避免退化数据导致除零
- 参数
features (Matrix) – 待打分特征矩阵,列数须等于拟合时的特征数
- 返回
长度等于行数的分数数组,取值 (0, 1],越接近 1 越异常
- 抛出
IllegalStateException – 尚未拟合(树列表为空)
IllegalArgumentException – 列数不符或特征含非有限值
- decisionFunction(Matrix features) → double[]¶
返回以阈值为零点的偏移分数。
注意
阈值由拟合时训练集的 contamination 分位确定,未拟合时无法得到有意义的零点
- 参数
features (Matrix) – 待打分特征矩阵,列数须等于拟合时的特征数
- 返回
0.5 - s - threshold,正值表示正常点,负值表示异常点
- 抛出
IllegalStateException – 尚未拟合
IllegalArgumentException – 列数不符或特征含非有限值
- predict(Matrix features) → double[]¶
输出 +1.0 正常、-1.0 异常。
注意
判定规则为 decisionFunction 结果不小于 0 时取 +1.0,否则取 -1.0
- 参数
features (Matrix) – 待预测特征矩阵,列数须等于拟合时的特征数
- 返回
长度等于行数的标签数组,正常为 +1.0,异常为 -1.0
- 抛出
IllegalStateException – 尚未拟合
IllegalArgumentException – 列数不符或特征含非有限值
- kind() → ModelKind¶
返回模型类型标识。
- 返回
ModelKind.ISOLATION_FOREST
- write(ModelWriter writer)¶
写入超参数、阈值与全部树结构。
注意
依次写入 trees、maxSamples、contamination、seed、featureCount、effectiveMaxSamples、threshold 与树数
注意
阈值随模型一并保存,读回后不再重新计算
- 参数
writer (ModelWriter) – 目标写入器,由调用方负责容器头与提交
- 抛出
IllegalStateException – 尚未拟合(树列表为空)
- read(ModelReader reader) → IsolationForeststatic¶
重建孤立森林模型。
- 参数
reader (ModelReader) – 已完成容器头解析的读取器
- 返回
含已训练树与阈值的模型实例,可直接用于 predict
- 抛出
ModelFormatException – 树数、特征数或实际读到的树数不为正
- final class KBinsDiscretizer implements Transformer, Estimator¶
按分位数、等宽或一维 K-Means 把连续特征离散为箱。
拟合逐列计算 nBins+1 个边界:edges[0] 取该列最小值、edges[nBins] 取最大值,中间边界按策略生成。UNIFORM 取 min + b*(max-min)/nBins;QUANTILE 先排序该列,再在位置 (rows-1)*b/nBins 处对相邻样本做线性插值;KMEANS 在该列上运行一维 KMeans(clusters=nBins、maxIterations=50、seed=42),取排序后相邻质心的中点作为边界。列内取值全相同时,中间边界全部等于该常量。
变换用边界比较定位:从 b=1 起找第一个满足 value < edges[b] 的 b,返回 b-1;没有任何边界满足时落入最后一箱,因此区间是左闭右开,恰好等于边界值的样本归入右侧箱。ORDINAL 输出与输入同宽、元素为箱序号 0..nBins-1;ONEHOT_DENSE 输出宽度为 特征数 * nBins,每个原始特征占一段连续列,命中位置置 1。
逆变换用箱中点 0.5*(edges[b] + edges[b+1]) 还原:ORDINAL 先把箱序号四舍五入并夹到 [0, nBins-1];ONEHOT_DENSE 对每段取最大值所在的列,并列时取靠前的箱。
示例Matrix x = Matrix.fromRows(new double[][] { {0.0, 10.0}, {0.5, 12.0}, {1.0, 14.0}, {2.0, 16.0}, {4.0, 18.0}, {8.0, 20.0} }); KBinsDiscretizer discretizer = KBinsDiscretizer.builder() .nBins(3) .strategy(KBinsDiscretizer.Strategy.QUANTILE) .encode(KBinsDiscretizer.Encode.ORDINAL) .build() .fit(x); Matrix binned = discretizer.transform(x); Matrix restored = discretizer.inverseTransform(binned); double[][] edges = discretizer.binEdges();注意
默认 nBins=5、strategy=QUANTILE、encode=ORDINAL;nBins 须 >= 2
注意
变换前必须 fit,否则抛 IllegalStateException;输入列数须等于拟合时的特征数
注意
列内取值全相同的特征恒落在最后一箱,因为没有任何边界能严格大于该值
注意
KMEANS 策略的随机性固定为 seed=42,同一列多次拟合得到相同边界
注意
write 保存 nBins、策略、编码与逐列边界,read 后无需重新拟合即可 transform
参见:basalt.ml.Transformer, basalt.ml.KMeans, basalt.ml.OneHotEncoder
方法
- builder() → Builderstatic¶
创建构造器,nBins=5、QUANTILE、ORDINAL。
- 返回
新的 Builder 实例
- fit(Matrix features) → KBinsDiscretizer¶
仅凭特征拟合,等价于 fit(features, null)。
- 参数
features (Matrix) – 训练特征矩阵,列数决定边界组数
- 返回
this,已算出逐列边界
- 抛出
NullPointerException – features 为 null
IllegalArgumentException – 特征含非有限值
- fit(Matrix features, double[] ignoredTargets) → KBinsDiscretizer¶
逐列计算 nBins+1 个箱边界。
每列取最小与最大值作为首尾边界,中间边界按策略生成;列内取值全相同时中间边界退化为该常量。
注意
QUANTILE 的插值位置为 (rows-1)*b/nBins,等价于 numpy 默认的 linear 分位
注意
KMEANS 每列单独跑一次一维 KMeans,迭代上限 50、种子 42
- 参数
features (Matrix) – 训练特征矩阵,列数决定边界组数
ignoredTargets (double[]) – 占位参数,内容被完全忽略,可为 null
- 返回
this,已完成拟合
- 抛出
NullPointerException – features 为 null
IllegalArgumentException – 特征含非有限值
- transform(Matrix features) → Matrix¶
把特征映射为箱序号或 One-Hot。
注意
判定为 value < edges[b],等于边界值的样本进入右侧箱
注意
ONEHOT_DENSE 的列顺序为特征优先,每个特征的 nBins 列连续排列
- 参数
features (Matrix) – 待转换矩阵,列数须等于拟合时的特征数
- 返回
ORDINAL 为 行数 × 特征数 的箱序号矩阵;ONEHOT_DENSE 为 行数 × (特征数 * nBins) 的 0/1 矩阵
- 抛出
IllegalStateException – 尚未拟合
IllegalArgumentException – 列数不符或特征含非有限值
- inverseTransform(Matrix transformed) → Matrix¶
用箱中点还原近似原特征。
注意
ORDINAL 先把箱序号四舍五入再夹到 [0, nBins-1],越界值被截断
注意
ONEHOT_DENSE 取每段最大值位置,并列时取靠前的箱;全零段落到第 0 箱
注意
还原值只保证落在对应箱内,不等于原始输入
- 参数
transformed (Matrix) – 形状与 transform 输出一致的矩阵
- 返回
行数 × 特征数 的近似原特征矩阵,元素为对应箱的中点
- 抛出
IllegalStateException – 尚未拟合
IllegalArgumentException – 列数不符(ORDINAL 需特征数列,ONEHOT_DENSE 需特征数 * nBins 列)或含非有限值
- predict(Matrix features) → double[]¶
返回展平后的离散结果。
注意
元素仍是箱序号或 0/1,便于把转换结果当作估计器输出消费
- 参数
features (Matrix) – 待转换矩阵,列数须等于拟合时的特征数
- 返回
transform 结果按行优先展平的一维数组,长度为 行数 × 输出列数
- 抛出
IllegalStateException – 尚未拟合
IllegalArgumentException – 列数不符或特征含非有限值
- binEdges() → double[][]¶
返回逐列的箱边界副本。
注意
返回深拷贝,修改不影响模型内部边界
- 返回
二维数组 [特征数][nBins+1],首尾为列最小值与最大值
- 抛出
IllegalStateException – 尚未拟合
- kind() → ModelKind¶
返回模型类型标识。
- 返回
ModelKind.KBINS_DISCRETIZER
- write(ModelWriter writer)¶
写入箱数、策略、编码与逐列边界。
注意
策略与编码以枚举 ordinal 落盘
注意
按特征顺序写入每组 nBins+1 个边界
- 参数
writer (ModelWriter) – 目标写入器,由调用方负责容器头与提交
- 抛出
IllegalStateException – 尚未拟合
- read(ModelReader reader) → KBinsDiscretizerstatic¶
读回箱数、策略、编码与逐列边界。
- 参数
reader (ModelReader) – 已完成容器头解析的读取器
- 返回
已可直接 transform 的实例
- 抛出
ModelFormatException – 箱数小于 2、特征数不为正,或策略、编码序号越界
- final class KFold¶
K 折交叉验证划分器,默认打乱且种子为 42。
划分是位置切分:先按 shuffle 与 seed 得到行序(不打乱时即 0..rows-1),第 f 折的测试区间为 [f*rows/folds, (f+1)*rows/folds),其余行按行序首尾拼接成训练集。行数不能被折数整除时,多出的样本落在靠后的折上。
是否打乱由 shuffle 决定,构造器默认 true,与 sklearn 的默认 false 不同;seed 只在 shuffle 为 true 时起作用,相同 seed 与相同数据得到完全一致的划分。
每折以 DataSplit.Fold 返回四个字段:trainFeatures、trainTargets、testFeatures、testTargets,均为按索引复制出的新数组,可安全修改。
示例Matrix x = Matrix.fromRows(new double[][] { {0.0, 1.0}, {1.0, 0.0}, {1.0, 1.0}, {2.0, 2.0}, {2.0, 3.0}, {3.0, 2.0}, {3.0, 3.0}, {4.0, 4.0} }); double[] y = {0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 1.0, 0.0}; KFold kfold = new KFold(4); List<DataSplit.Fold> folds = kfold.split(x, y); DataSplit.Fold first = folds.get(0); Matrix trainX = first.trainFeatures(); Matrix testX = first.testFeatures(); int count = kfold.folds(); boolean shuffled = kfold.shuffle();注意
构造器只校验 folds >= 2,folds 超过样本数的检查延到 split 阶段
注意
类本身不持有数据,同一实例可对不同矩阵反复 split
注意
目标数组只随行搬运,划分过程不看标签取值,不做分层
参见:basalt.ml.DataSplit, basalt.ml.GridSearchCV, basalt.ml.StratifiedKFold
构造器
- KFold(int folds)¶
按折数构造,默认打乱且种子为 42。
注意
等价于 KFold(folds, true, 42L)
- 参数
folds (int) – 折数,须 >= 2
- 抛出
IllegalArgumentException – folds 小于 2
- KFold(int folds, boolean shuffle, long seed)¶
指定折数、是否打乱与随机种子。
- 参数
folds (int) – 折数,须 >= 2
shuffle (boolean) – 是否在划分前打乱行序;false 时按原始行号顺序切分
seed (long) – 打乱所用随机源种子,shuffle 为 false 时无效
- 抛出
IllegalArgumentException – folds 小于 2
方法
- folds() → int¶
返回折数。
- 返回
构造时给定的折数
- shuffle() → boolean¶
返回是否打乱。
- 返回
true 表示划分前按 seed 打乱行序
- split(Matrix features, double[] targets) → List<DataSplit.Fold>¶
生成各折的训练与测试划分。
第 f 折测试区间取 [f*rows/folds, (f+1)*rows/folds),训练集为其余区间的拼接,因此每折训练集大小等于 rows 减去该折测试集大小。
注意
返回的矩阵与数组都是新分配的副本,与原数据不共享存储
- 参数
features (Matrix) – 特征矩阵,行数为样本数
targets (double[]) – 目标数组,长度须等于行数,仅随行搬运
- 返回
长度为 folds 的列表,每项为 DataSplit.Fold,含 trainFeatures、trainTargets、testFeatures、testTargets
- 抛出
NullPointerException – features 或 targets 为 null
IllegalArgumentException – 折数大于样本数、目标数量与行数不一致,或数据含非有限值
- final class KMeans implements Estimator, Persistable¶
K-Means++ 播种的 Lloyd 迭代聚类,支持多次重启。
分配步逐样本计算到 k 个质心的平方欧氏距离,按行区间并行执行;质心累加与求均值为串行循环,且复用预分配缓冲区。多次重启各自独立初始化,保留惯性最小的一次结果。
第 r 次重启使用 seed + 7919r 作为随机源种子。空簇修复从当前分配中挑选距离所属质心最远、且所属簇样本数大于 1 的样本,把它捐给空簇并以该样本位置作为新质心;找不到合格捐赠者时退化为全局最远样本。
示例Matrix features = Matrix.fromRows(new double[][] { {0.0, 0.0}, {0.4, 0.2}, {0.1, 0.5}, {9.6, 9.8}, {10.0, 10.2}, {9.4, 9.9} }); KMeans kmeans = KMeans.builder() .clusters(2) .restarts(4) .maxIterations(200) .seed(7L) .build() .fit(features); double[] assignment = kmeans.predict(features); double[] distance = kmeans.transform(features); Matrix centers = kmeans.centroids(); double inertia = kmeans.inertia();注意
tolerance 作用于质心位移:全部质心各分量位移的平方和不超过 tolerance² 时停止迭代
注意
inertia 在迭代结束后按最终质心重新计算,等于各样本到最近质心平方距离之和,可能与最后一轮分配时的值略有差异
注意
样本数不少于 1024、特征数不少于 8 且原生内核可用时,整个拟合交给原生实现
注意
特征数不少于 128 时,单轮分配步也可能切换到原生内核
参见:basalt.ml.Estimator, basalt.core.Persistable
方法
- builder() → Builderstatic¶
创建 KMeans 构建器。
- 返回
参数取默认值的新 Builder 实例
- fit(Matrix features) → KMeans¶
只用特征拟合,目标数组缺省为 null。
- 参数
features (Matrix) – 训练样本矩阵,行是样本、列是特征
- 返回
this,便于链式调用
- fit(Matrix features, double[] ignoredTargets) → KMeans¶
执行 K-Means++ 初始化与 Lloyd 迭代。
首个质心从样本中均匀随机抽取,后续质心按到最近已有质心的平方距离加权抽取;若全部距离之和为 0,则改用簇序号对样本数取模。每次重启跑满收敛条件或 maxIterations,取惯性最小者。
注意
每次重启都新建 Random,因此同一 seed 与 restarts 组合可复现结果
- 参数
features (Matrix) – 训练样本矩阵,行是样本、列是特征;元素必须有限
ignoredTargets (double[]) – 占位参数;聚类忽略监督目标,可为 null
- 返回
this,便于链式调用
- 抛出
IllegalArgumentException – features 为 null 或含非有限值,或簇数大于样本数
- predict(Matrix features) → double[]¶
把每个样本分配给最近的质心。
- 参数
features (Matrix) – 样本矩阵,列数须与拟合时一致
- 返回
长度为样本数的簇索引,以 double 表示
- 抛出
IllegalStateException – 尚未拟合
IllegalArgumentException – 特征列数与拟合时不一致
- transform(Matrix features) → double[]¶
返回各样本到其所属质心的平方距离。
先按最近质心确定归属,再取该质心与样本的平方欧氏距离。返回一维数组,每个样本一个标量,而不是距离矩阵;需要欧氏距离时自行开方。
- 参数
features (Matrix) – 样本矩阵,列数须与拟合时一致
- 返回
长度为样本数的平方距离数组
- 抛出
IllegalStateException – 尚未拟合
IllegalArgumentException – 特征列数与拟合时不一致
- centroids() → Matrix¶
返回最终质心矩阵。
- 返回
簇数 × 特征数 的矩阵,每行一个质心
- 抛出
IllegalStateException – 尚未拟合
- inertia() → double¶
返回最优重启的惯性值。
- 返回
样本到最近质心平方距离之和;未拟合时为 0
- iterations() → int¶
返回最优重启实际执行的迭代轮数。
- 返回
1 到 maxIterations 之间的轮数;未拟合时为 0
- restarts() → int¶
返回已完成的随机重启次数。
- 返回
拟合后等于配置的 restarts;未拟合或由 read 重建的模型为 0
- kind() → ModelKind¶
返回模型类型标识。
- 返回
ModelKind.KMEANS
- write(ModelWriter writer)¶
写入簇数、特征数、惯性、迭代轮数与质心。
注意
tolerance、seed、restarts 与 threads 不写入流,read 后回到 Builder 默认值
- 参数
writer (ModelWriter) – 目标写入器,由调用方负责容器头与关闭
- 抛出
IllegalStateException – 尚未拟合
- read(ModelReader reader) → KMeansstatic¶
从序列化流重建 KMeans 模型。
- 参数
reader (ModelReader) – 已完成容器头解析的读取器
- 返回
只恢复质心与统计量的模型实例,可直接用于 predict
- 抛出
ModelFormatException – 簇数或特征数不为正
- final class KNearestNeighbors implements Estimator¶
统一权重的 KNN 分类器。
fit 只保存训练集的副本(特征 copy、标签 clone),不做归一化或索引结构;predict 对每个查询样本线性扫描全部训练行,用距离度量维护容量为 k 的最大堆,堆中即 k 个最近邻,再按标签多数投票。
投票是统一权重,距离不参与加权;票数相同时选择数值更小的标签,因此结果与 HashMap 迭代顺序无关,完全可复现。单次查询的时间为 O(n·d),额外内存为 O(k) 加上训练集副本。
示例Matrix x = Matrix.fromRows(new double[][]{{0, 0}, {0, 1}, {1, 0}, {1, 1}}); double[] y = {0, 1, 1, 0}; KNearestNeighbors knn = KNearestNeighbors.builder() .k(3) .metric(DistanceMetric.MANHATTAN) .build() .fit(x, y); double[] labels = knn.predict(x);注意
k 在 build() 时校验为正,fit 时再校验不超过训练样本数
注意
特征未标准化,量纲差异会主导欧氏距离
注意
训练集在 fit 时复制,之后修改原 Matrix 不影响模型
参见:basalt.ml.KNeighborsRegressor, basalt.ml.DistanceMetric, basalt.ml.KNearestNeighbors.Builder
方法
- builder() → Builderstatic¶
创建构建器,默认 k=5、欧氏距离。
注意
每次调用都返回独立实例,可安全地分别配置
- 返回
新的 Builder,字段取默认值
- fit(Matrix features, double[] targets) → KNearestNeighbors¶
保存训练集副本,不做任何预计算。
注意
重复 fit 会用新数据覆盖旧训练集
- 参数
features (Matrix) – 训练特征矩阵,列数即特征维数
targets (double[]) – 训练标签数组,取值可以是任意 double
- 返回
this
- 抛出
NullPointerException – features 或 targets 为 null
IllegalArgumentException – k 大于训练样本数,或行数与标签长度不符、数据含非有限值
- predict(Matrix features) → double[]¶
对每个样本取 k 近邻多数投票。
注意
平票时返回数值更小的标签,保证确定性
- 参数
features (Matrix) – 待预测特征矩阵,列数须等于训练特征数
- 返回
每行一个训练集中出现过的标签值
- 抛出
IllegalStateException – 尚未 fit
IllegalArgumentException – 列数不匹配或含非有限值
- final class KNeighborsRegressor implements Estimator¶
统一权重的 KNN 回归器。
与分类版共享同一套流程:fit 只复制训练集,predict 逐样本线性扫描并用容量为 k 的最大堆保留最近邻。区别在聚合方式——对 k 个邻居的目标值取算术平均,不做距离加权。
单次查询的时间为 O(n·d),额外内存为 O(k) 加上训练集副本。目标值未做任何变换,因此预测结果始终落在训练目标的最小值与最大值之间,不会外推。
示例Matrix x = Matrix.fromRows(new double[][]{{0, 0}, {0, 1}, {1, 0}, {1, 1}}); double[] y = {0.0, 1.0, 1.0, 2.0}; KNeighborsRegressor regressor = KNeighborsRegressor.builder().k(2).build().fit(x, y); double[] predictions = regressor.predict(x);注意
k 在 fit 时校验不超过训练样本数
注意
距离加权、叶节点裁剪等加速结构均未实现
参见:basalt.ml.KNearestNeighbors, basalt.ml.DistanceMetric
方法
- builder() → Builderstatic¶
创建构建器,默认 k=5、欧氏距离。
- 返回
新的 Builder,字段取默认值
- fit(Matrix features, double[] targets) → KNeighborsRegressor¶
保存训练集副本,不做预计算。
- 参数
features (Matrix) – 训练特征矩阵
targets (double[]) – 训练目标数组,长度等于行数
- 返回
this
- 抛出
NullPointerException – features 或 targets 为 null
IllegalArgumentException – k 大于训练样本数,或形状不符、数据含非有限值
- predict(Matrix features) → double[]¶
对 k 个最近邻的目标值取平均。
- 参数
features (Matrix) – 待预测特征矩阵,列数须等于训练特征数
- 返回
每行一个连续预测值,为 k 个邻居目标的算术平均
- 抛出
IllegalStateException – 尚未 fit
IllegalArgumentException – 列数不匹配或含非有限值
- final class Kernel¶
四种半正定核函数:LINEAR、RBF、POLY 与 SIGMOID。
四种核的定义为 LINEAR K(x, y) = x · y;RBF K(x, y) = exp(-gamma * ||x - y||^2);POLY K(x, y) = (gamma * (x · y) + coef0)^degree;SIGMOID K(x, y) = tanh(gamma * (x · y) + coef0)。SIGMOID 不保证半正定,仅在参数合适时可用作核。
gamma 控制内积或距离的缩放:RBF 中越大核越窄、单个样本影响半径越小;POLY 与 SIGMOID 中缩放内积后再叠加 coef0。degree 只对 POLY 生效,coef0 对 POLY 与 SIGMOID 生效,LINEAR 不使用这三个参数。
评估有两条路径:evaluate 直接在原数组上按偏移与长度计算单点核值,避免为每个样本对分配临时向量;gram 逐行逐列调用 evaluate 组装批量的 Gram 矩阵。
示例Matrix a = Matrix.fromRows(new double[][] {{1.0, 2.0}, {2.0, 1.0}}); Matrix b = Matrix.fromRows(new double[][] {{0.0, 1.0}, {3.0, 3.0}}); Kernel kernel = Kernel.rbf(0.5); double value = kernel.evaluate(a.data(), 0, b.data(), 0, 2); Matrix gram = kernel.gram(a, b); Kernel poly = Kernel.poly(3, 0.25, 1.0); double degree = poly.degree(); double coef0 = poly.coef0();注意
构造器允许 gamma 取 0,此时 evaluate 内部改用 1/max(1, length) 作为缩放,等价于按维数缩放;rbf/poly/sigmoid 工厂则要求 gamma 严格为正
注意
linear() 固定 gamma=1.0、degree=3、coef0=0.0;sigmoid 工厂固定 degree=3,只有 poly 工厂会改写 degree
注意
gram 不做分块与原生加速,时间复杂度为 rows(a) * rows(b) * 特征数
注意
write 按类型序号、gamma、degree、coef0 的顺序落盘,read 依赖 Type 枚举的声明顺序
参见:basalt.ml.SVC, basalt.ml.KernelRidge, basalt.ml.KernelPCA
构造器
- Kernel(Type type, double gamma, int degree, double coef0)¶
按显式类型与参数构造核函数。
注意
构造器不按类型裁剪参数,未参与计算的字段照原样保存
- 参数
type (Type) – 核类型,取 Type 枚举值,不接受 null
gamma (double) – 缩放系数,须有限且非负;取 0 时评估按 1/max(1, length) 替代
degree (int) – POLY 的多项式次数,须 >= 1
coef0 (double) – POLY 与 SIGMOID 的常数项,须有限
- 返回
持有给定参数的核函数实例
- 抛出
NullPointerException – type 为 null
IllegalArgumentException – gamma 非有限或为负、degree 小于 1、coef0 非有限
方法
- linear() → Kernelstatic¶
构造线性核 K(x, y) = x · y。
注意
三个参数都不参与 LINEAR 的计算,仅随实例保存并参与序列化
- 返回
gamma=1.0、degree=3、coef0=0.0 的 LINEAR 核
- rbf(double gamma) → Kernelstatic¶
构造高斯核 exp(-gamma * ||x - y||²)。
- 参数
gamma (double) – 尺度系数,须为正且有限;越大核越窄、影响半径越小
- 返回
degree=3、coef0=0.0 的 RBF 核
- 抛出
IllegalArgumentException – gamma 小于等于 0 或非有限
- poly(int degree, double gamma, double coef0) → Kernelstatic¶
构造多项式核 (gamma * x·y + coef0)^degree。
- 参数
degree (int) – 多项式次数,须 >= 1
gamma (double) – 内积缩放系数,须为正且有限
coef0 (double) – 加在内积上的常数项,须有限
- 返回
POLY 核实例
- 抛出
IllegalArgumentException – gamma 非正或非有限,或 degree 小于 1、coef0 非有限
- sigmoid(double gamma, double coef0) → Kernelstatic¶
构造 sigmoid 核 tanh(gamma * x·y + coef0)。
- 参数
gamma (double) – 内积缩放系数,须为正且有限
coef0 (double) – 双曲正切内的偏移量,须有限
- 返回
degree=3 的 SIGMOID 核实例
- 抛出
IllegalArgumentException – gamma 非正或非有限,或 coef0 非有限
- type() → Type¶
返回核类型。
- 返回
Type 枚举值 LINEAR、RBF、POLY 或 SIGMOID
- gamma() → double¶
返回 gamma 系数。
- 返回
RBF、POLY、SIGMOID 的尺度系数;LINEAR 固定为 1.0
- degree() → int¶
返回多项式次数。
- 返回
POLY 的次数;其余类型固定为 3
- coef0() → double¶
返回常数项 coef0。
- 返回
POLY 与 SIGMOID 的常数项;LINEAR 与 RBF 为 0.0
- evaluate(double[] x, int xOffset, double[] y, int yOffset, int length) → double¶
按偏移与长度计算两点核值。
注意
gamma 为 0 时内部改用 1/max(1, length),即按维数缩放
注意
不检查偏移与长度的越界,由调用方保证区间合法
- 参数
x (double[]) – 左向量所在的数组
xOffset (int) – 左向量在 x 中的起始下标
y (double[]) – 右向量所在的数组
yOffset (int) – 右向量在 y 中的起始下标
length (int) – 参与计算的维数
- 返回
核函数值:LINEAR 为内积,RBF 落在 (0, 1],POLY 与 SIGMOID 可为任意实数
- gram(Matrix a, Matrix b) → Matrix¶
计算两批样本之间的 Gram 矩阵。
注意
逐元素调用 evaluate,串行双重循环,无分块或原生加速
- 参数
a (Matrix) – 左样本矩阵,行数为样本数,列数为特征数
b (Matrix) – 右样本矩阵,列数须与 a 相同
- 返回
rows(a) × rows(b) 的矩阵,第 i 行第 j 列为 K(a 的第 i 行, b 的第 j 行)
- 抛出
IllegalArgumentException – 两个矩阵的列数不同
- write(ModelWriter writer)¶
写入类型序号、gamma、degree 与 coef0。
注意
依次写入一个 int 序号、一个 double、一个 int 与一个 double,共四个字段
注意
类型以 Type.ordinal() 落盘,read 依赖同一枚举顺序
- 参数
writer (ModelWriter) – 目标写入器,由调用方负责容器头与提交
- read(ModelReader reader) → Kernelstatic¶
从序列化流重建核函数。
- 参数
reader (ModelReader) – 已完成容器头解析的读取器
- 返回
参数与写入时一致的 Kernel 实例
- 抛出
ModelFormatException – 类型序号不在 Type 枚举范围内
- final class KernelDensity implements Estimator, Persistable¶
高斯与 TOPHAT 核的核密度估计,输出对数密度。
拟合不做任何参数估计,只把训练样本复制一份作为核中心集合,因此打分代价为查询点数、训练样本数与特征数三者之积。
GAUSSIAN 核下 log p(x) = -log(n) - d*log(bandwidth) - 0.5*d*log(2π) + log Σ exp(-||x - x_i||² / (2 * bandwidth²)),求和用减去最大项的方式做 log-sum-exp 以避免下溢;TOPHAT 核下以带宽为半径的球内命中数 hits 决定密度,log p(x) = log(hits / n) - [0.5*d*log(π) - logΓ(d/2 + 1) + d*log(bandwidth)],无命中时返回负无穷。
bandwidth 是唯一平滑参数:越大分布越平滑、峰值越低,方差约等于 bandwidth² 加上训练样本自身方差。sample 从训练行中均匀抽取一个中心再叠加噪声,GAUSSIAN 加各向同性正态噪声,TOPHAT 加逐维均匀噪声。
示例Matrix train = Matrix.fromRows(new double[][] { {0.0}, {0.4}, {1.0}, {1.2}, {2.0}, {3.5} }); Matrix query = Matrix.fromRows(new double[][] {{0.5}, {1.5}, {3.0}}); KernelDensity kde = KernelDensity.builder() .bandwidth(0.5) .kernel(KernelDensity.KernelType.GAUSSIAN) .build() .fit(train); double[] logDensity = kde.scoreSamples(query); Matrix drawn = kde.sample(100, 7L); double bandwidth = kde.bandwidth();注意
默认 bandwidth=1.0、kernel=GAUSSIAN;bandwidth 须为正且有限
注意
scoreSamples 与 predict 返回对数密度而非概率密度,需要密度时自行取 exp
注意
write 只保存 bandwidth、核类型、特征数与训练样本,模型无其他可训练状态
注意
TOPHAT 在稀疏数据上常出现查询点邻域内无训练样本的情况,此时整行为负无穷
参见:basalt.ml.Estimator, basalt.core.Persistable, basalt.ml.Kernel
方法
- builder() → Builderstatic¶
创建构造器,bandwidth=1.0、核为 GAUSSIAN。
- 返回
新的 Builder 实例
- fit(Matrix features) → KernelDensity¶
仅凭样本拟合,等价于 fit(features, null)。
- 参数
features (Matrix) – 训练样本矩阵,行数为样本数,列数为特征数
- 返回
this,已保存训练样本
- 抛出
NullPointerException – features 为 null
IllegalArgumentException – 特征含非有限值
- fit(Matrix features, double[] ignoredTargets) → KernelDensity¶
保存训练样本副本与特征数。
KDE 无需估计参数,拟合只把特征矩阵复制一份作为核中心集合,所有距离在打分时按需计算。
注意
保存的是副本,拟合后再修改原矩阵不影响模型
- 参数
features (Matrix) – 训练样本矩阵,行数为样本数
ignoredTargets (double[]) – 占位参数,内容被完全忽略,可为 null
- 返回
this,已完成拟合
- 抛出
NullPointerException – features 为 null
IllegalArgumentException – 特征含非有限值
- scoreSamples(Matrix features) → double[]¶
输出每个查询点的对数密度 log p(x)。
GAUSSIAN 下对每个查询点累加 -||x - x_i||²/(2*bandwidth²),再以 log-sum-exp 汇总并加上归一化常数;TOPHAT 下统计平方距离不超过 bandwidth² 的训练样本数,按球体积归一化。
注意
复杂度为查询行数 × 训练行数 × 特征数,无树结构或原生加速
注意
GAUSSIAN 的归一化常数包含 -log(n) 与 -d*log(bandwidth)
- 参数
features (Matrix) – 查询点矩阵,列数须等于拟合时的特征数
- 返回
长度等于行数的对数密度数组;TOPHAT 下无命中时为负无穷
- 抛出
IllegalStateException – 尚未拟合
IllegalArgumentException – 列数不符或特征含非有限值
- sample(int nSamples, long seed) → Matrix¶
从拟合的密度中抽取随机样本。
注意
每个样本先均匀抽取一个训练行作为中心,再叠加噪声
注意
GAUSSIAN 的噪声为标准差等于 bandwidth 的各向同性正态噪声;TOPHAT 为每维 [-bandwidth, bandwidth] 上的均匀噪声
- 参数
nSamples (int) – 抽样个数,须为正
seed (long) – 随机源种子,仅影响本次抽样的结果
- 返回
nSamples × 特征数 的矩阵
- 抛出
IllegalStateException – 尚未拟合
IllegalArgumentException – nSamples 小于等于 0
- predict(Matrix features) → double[]¶
与 scoreSamples 等价,返回对数密度。
注意
沿用 scoreSamples 的实现,输出是打分而非分类标签
- 参数
features (Matrix) – 查询点矩阵,列数须等于拟合时的特征数
- 返回
长度等于行数的对数密度数组
- 抛出
IllegalStateException – 尚未拟合
IllegalArgumentException – 列数不符或特征含非有限值
- bandwidth() → double¶
返回带宽。
- 返回
构造时给定的 bandwidth,正有限值
- kind() → ModelKind¶
返回模型类型标识。
- 返回
ModelKind.KERNEL_DENSITY
- write(ModelWriter writer)¶
写入带宽、核类型与训练样本。
注意
核类型以 KernelType.ordinal() 落盘
注意
训练样本按行优先展平后整体写入,读回时按特征数还原形状
- 参数
writer (ModelWriter) – 目标写入器,由调用方负责容器头与提交
- 抛出
IllegalStateException – 尚未拟合
- read(ModelReader reader) → KernelDensitystatic¶
读回带宽、核类型与训练样本。
- 参数
reader (ModelReader) – 已完成容器头解析的读取器
- 返回
已可打分的模型实例
- 抛出
ModelFormatException – 核类型序号越界、特征数或样本数不为正
- final class KernelPCA implements Estimator, Transformer, Persistable¶
核主成分分析:在核空间中心化后做特征分解的降维估计器。
fit 先用核函数在训练集上求 n × n Gram 矩阵,按行均值、列均值与全均值做双重中心化 K - 1K/n - K1/n + 1K1/n²,再用循环 Jacobi 对称特征分解求特征值与特征向量;特征值截断为非负、按降序取前 components 个,特征向量按 1/sqrt(λ) 缩放后存为 alphas,λ 不超过 1e-12 的分量缩放因子取 0。
transform 对新样本计算它与全部训练样本的核值,用拟合阶段缓存的 kFitRows 与 kFitAll 做同样的中心化,再与 alphas 逐分量做内积得到投影坐标。predict 只是把投影矩阵按行优先展开成扁平数组。
示例Matrix features = Matrix.fromRows(new double[][] { {1.0, 2.0}, {2.0, 1.0}, {3.0, 4.0}, {4.0, 3.0}, {5.0, 6.0} }); KernelPCA kpca = KernelPCA.builder() .components(2) .rbf(0.5) .build() .fit(features); Matrix projected = kpca.transform(features); double[] eigenvalues = kpca.eigenvalues();注意
核函数默认 rbf(gamma=1.0),可用 kernel(Kernel)、rbf(gamma) 或 poly(degree, gamma, coef0) 替换
注意
components 不能超过样本数,否则 fit 抛 IllegalArgumentException
注意
Jacobi 迭代上限 60 轮、收敛阈值 1e-12,Builder 未暴露这两个参数的设值方法
注意
主方向符号按特征向量绝对值最大的分量为正固定,同一输入重复拟合可复现
注意
训练集与核行均值随模型一起序列化,预测时的内存占用与训练集规模成正比
参见:basalt.ml.Kernel, basalt.ml.PCA, basalt.ml.KernelPCA.Builder
方法
- builder() → Builderstatic¶
创建构建器,默认 2 个分量、rbf(1.0) 核。
- 返回
新的 Builder,字段取默认值
- fit(Matrix features) → KernelPCA¶
只用特征拟合,目标数组缺省为 null。
注意
等价于 fit(features, null),目标参数被忽略
- 参数
features (Matrix) – 训练样本矩阵,行是样本、列是特征;元素必须有限
- 返回
this,便于链式调用
- 抛出
NullPointerException – features 为 null
IllegalArgumentException – features 含非有限值,或 components 大于样本数
- fit(Matrix features, double[] ignoredTargets) → KernelPCA¶
计算中心化核矩阵并提取前若干核主成分。
核矩阵在训练集自身上求值后做双重中心化;Jacobi 分解得到的特征值截断为非负、降序排序,前 components 个特征向量按 1/sqrt(λ) 缩放为 alphas。
注意
时间与内存都是 O(n²),n 为训练样本数
注意
特征值不大于 1e-12 的分量缩放因子取 0,该分量投影恒为 0
- 参数
features (Matrix) – 训练样本矩阵,行是样本、列是特征;元素必须有限
ignoredTargets (double[]) – 占位参数;核 PCA 忽略监督目标,可为 null
- 返回
this,便于链式调用
- 抛出
NullPointerException – features 为 null
IllegalArgumentException – features 含非有限值,或 components 大于样本数
- transform(Matrix features) → Matrix¶
把样本投影到核主成分坐标。
注意
每个样本都要与全部训练样本求核值,代价为 O(m·n) 次核求值
- 参数
features (Matrix) – 样本矩阵,列数须等于训练特征数
- 返回
样本数 × components 的投影矩阵
- 抛出
NullPointerException – features 为 null
IllegalStateException – 尚未 fit
IllegalArgumentException – 列数不匹配或含非有限值
- predict(Matrix features) → double[]¶
返回投影结果的扁平数组。
等价于 transform(features).toArray(),按行优先展开,便于接入只需要 double[] 的下游流程。
- 参数
features (Matrix) – 样本矩阵,列数须等于训练特征数
- 返回
长度为 样本数 × components 的数组
- 抛出
NullPointerException – features 为 null
IllegalStateException – 尚未 fit
IllegalArgumentException – 列数不匹配或含非有限值
- eigenvalues() → double[]¶
返回各核主成分的特征值。
注意
数值是中心化核矩阵的特征值,量纲与原始特征方差不同
- 返回
长度等于 components 的数组副本,非负且按降序排列
- 抛出
IllegalStateException – 尚未 fit
- kind() → ModelKind¶
返回模型类型标识。
- 返回
ModelKind.KERNEL_PCA
- write(ModelWriter writer)¶
写入核函数、分量数、训练集与中心化统计量。
注意
写入顺序为核函数、分量数、特征数、训练样本数、全均值、训练数据、核行均值、特征值、alphas
注意
maxIterations 与 tolerance 不写入流,read 后回到 Builder 默认值
- 参数
writer (ModelWriter) – 目标写入器,由调用方负责容器头与关闭
- 抛出
IllegalStateException – 尚未 fit
- read(ModelReader reader) → KernelPCAstatic¶
从序列化流重建 KernelPCA 模型。
注意
核函数按流中记录的类型与参数还原,不会退回默认的 rbf(1.0)
- 参数
reader (ModelReader) – 已完成容器头解析的读取器
- 返回
可直接用于 transform 与 predict 的模型实例
- 抛出
ModelFormatException – 分量数、特征数或训练样本数不为正
- final class KernelRidge implements Estimator, Persistable¶
核岭回归:在核空间解 (K + alpha·I)α = y 的回归估计器。
fit 用核函数在训练集上求 n × n Gram 矩阵,对角线加 alpha 后用 Cholesky 分解解线性方程组,得到对偶系数 α;预测值是目标样本与全部训练样本核值的加权和,模型没有独立截距项。
Cholesky 分解对对角元取 max(sum, 1e-12) 作为抖动,半正定退化时不产生 NaN。alpha 越大解越平滑,对偶系数的绝对值整体变小。
示例Matrix x = Matrix.fromRows(new double[][]{{0, 0}, {1, 0}, {0, 1}, {1, 1}}); double[] y = {0.0, 1.0, 1.0, 2.0}; KernelRidge model = KernelRidge.builder() .rbf(1.0) .alpha(0.1) .build() .fit(x, y); double[] predictions = model.predict(x); double[] dual = model.dualCoef();注意
核函数默认 rbf(gamma=1.0),可用 kernel(Kernel)、rbf(gamma) 或 poly(degree, gamma, coef0) 替换
注意
alpha 必须严格为正且有限,在 build() 时校验
注意
训练集与对偶系数一起序列化,预测代价与训练样本数成正比
注意
没有截距项:目标未中心化时预测会带系统性偏移
参见:basalt.ml.Kernel, basalt.ml.Ridge, basalt.ml.KernelRidge.Builder
方法
- builder() → Builderstatic¶
创建构建器,默认 rbf(1.0) 核、alpha=1.0。
- 返回
新的 Builder,字段取默认值
- fit(Matrix features, double[] targets) → KernelRidge¶
组装正则化核矩阵并用 Cholesky 求解对偶系数。
注意
Gram 矩阵为 n × n,时间 O(n²·d)、内存 O(n²)
注意
alpha 只加在 Gram 对角线上,等价于对偶问题的 L2 惩罚
- 参数
features (Matrix) – 训练特征矩阵,n 行 d 列
targets (double[]) – 训练目标数组,长度等于 n
- 返回
this,便于链式调用
- 抛出
NullPointerException – features 或 targets 为 null
IllegalArgumentException – 行数与目标长度不符,或数据含 NaN/无穷
- predict(Matrix features) → double[]¶
用对偶系数与核值加权求和。
注意
每行需要 n 次核求值,n 为训练样本数
- 参数
features (Matrix) – 待预测特征矩阵,列数须等于训练特征数
- 返回
每行一个连续预测值
- 抛出
NullPointerException – features 为 null
IllegalStateException – 尚未 fit
IllegalArgumentException – 列数不匹配或含非有限值
- dualCoef() → double[]¶
返回对偶系数副本。
注意
系数与训练样本一一对应,顺序即 fit 时特征矩阵的行序
- 返回
长度为训练样本数的对偶系数数组副本
- 抛出
IllegalStateException – 尚未 fit
- kernel() → Kernel¶
返回配置的核函数。
注意
核函数在构造时确定,fit 不会替换它
- 返回
拟合所用的 Kernel 实例;未 fit 时也可读取
- kind() → ModelKind¶
返回模型类型标识。
- 返回
ModelKind.KERNEL_RIDGE
- write(ModelWriter writer)¶
写入核函数、alpha、训练集与对偶系数。
注意
写入顺序为核函数、alpha、特征数、训练样本数、训练数据、对偶系数
- 参数
writer (ModelWriter) – 目标写入器,由调用方负责容器头与关闭
- 抛出
IllegalStateException – 尚未 fit
- read(ModelReader reader) → KernelRidgestatic¶
从序列化流重建 KernelRidge 模型。
注意
alpha 从流中还原并重新经过 Builder 校验
- 参数
reader (ModelReader) – 已完成容器头解析的读取器
- 返回
可直接用于 predict 的模型实例
- 抛出
ModelFormatException – 特征数或训练样本数不为正
- final class LabelEncoder implements Transformer¶
把类别标签双向映射为 0..k-1 整数码的编码器。
fit(double[]) 用 TreeSet 收集升序唯一值作为类别表;fit(String[]) 按字符串自然序收集,同时建立标签到下标的哈希表,并把 classes 置为 0..k-1,使数值接口与字符串接口共享同一套下标语义。
transform 对未见过的标签不做兜底:数值路径用二分查找,字符串路径查表,命中失败一律抛 IllegalArgumentException;inverseTransform 把整数码还原为类别值,浮点输入要求与最近整数相差不超过 1e-9。
示例LabelEncoder encoder = new LabelEncoder(); double[] codes = encoder.fitTransform(new double[]{3.0, 1.0, 3.0, 2.0}); double[] original = encoder.inverseTransform(codes); double[] classes = encoder.classes(); LabelEncoder names = new LabelEncoder(); int[] ids = names.fitTransform(new String[]{"cat", "dog", "cat"}); String[] restored = names.inverseTransformStrings(ids);注意
fit(double[]) 与 fit(String[]) 互斥,后一次 fit 会清空另一种模式的类别表
注意
在字符串上拟合后 classes() 返回 0..k-1 的整数码,反查字符串需用 stringClasses() 或 inverseTransformStrings
注意
空输入与 null 元素在 fit 阶段即被拒绝,未知标签只在 transform 阶段报错
注意
write 把字符串按 UTF-8 逐条写入,长度前缀为字节数而非字符数
参见:basalt.ml.OneHotEncoder, basalt.ml.Transformer
构造器
- LabelEncoder()¶
创建尚未拟合的空编码器。
注意
fit 之前调用任何 transform 或 inverseTransform 都抛 IllegalStateException
方法
- fit(double[] targets) → LabelEncoder¶
收集升序唯一值作为类别表。
注意
类别表按数值升序排列,编码值即该顺序中的下标
注意
会清空此前 fit(String[]) 建立的字符串表
- 参数
targets (double[]) – 标签数组,不能为空,元素必须有限
- 返回
this,便于链式调用
- 抛出
NullPointerException – targets 为 null
IllegalArgumentException – targets 为空或含 NaN/无穷
- fit(String[] labels) → LabelEncoder¶
按字符串自然序建立类别表。
注意
排序使用 String 的自然序,区分大小写,不做归一化
注意
同时把 classes 置为 0..k-1,因此数值接口在字符串拟合后仍可用
- 参数
labels (String[]) – 标签数组,不能为空,元素不能为 null
- 返回
this,便于链式调用
- 抛出
NullPointerException – labels 为 null,或其中某个元素为 null
IllegalArgumentException – labels 为空
- transformToInt(double[] targets) → int[]¶
把标签转成整数下标。
注意
内部用 Arrays.binarySearch,依赖类别表升序
- 参数
targets (double[]) – 待编码标签
- 返回
与输入等长的整数码数组,取值 0..k-1
- 抛出
NullPointerException – targets 为 null
IllegalStateException – 尚未 fit
IllegalArgumentException – 出现训练时未见过的标签
- transform(double[] targets) → double[]¶
把标签转成 double 形式的整数码。
注意
等价于 transformToInt 的逐元素 double 化
- 参数
targets (double[]) – 待编码标签
- 返回
与输入等长的编码数组,元素为整数值的 double
- 抛出
NullPointerException – targets 为 null
IllegalStateException – 尚未 fit
IllegalArgumentException – 出现训练时未见过的标签
- fitTransform(double[] targets) → double[]¶
先 fit 再 transform。
注意
同一数组既作训练又作输入,因此不会出现未知标签
- 参数
targets (double[]) – 既用于拟合又用于编码的标签数组
- 返回
与输入等长的编码数组
- 抛出
NullPointerException – targets 为 null
IllegalArgumentException – targets 为空或含 NaN/无穷
- inverseTransform(double[] encoded) → double[]¶
把浮点编码还原为类别值。
注意
先用 Math.round 取整再校验,容差 1e-9
- 参数
encoded (double[]) – 编码数组,元素须接近 [0, k-1] 内的整数
- 返回
与输入等长的类别值数组
- 抛出
NullPointerException – encoded 为 null
IllegalStateException – 尚未 fit
IllegalArgumentException – 下标越界,或元素与最近整数相差超过 1e-9
- inverseTransform(int[] encoded) → double[]¶
把整数编码还原为类别值。
- 参数
encoded (int[]) – 整数码数组,元素须在 [0, k-1] 内
- 返回
与输入等长的类别值数组
- 抛出
NullPointerException – encoded 为 null
IllegalStateException – 尚未 fit
IllegalArgumentException – 下标越界
- transform(String[] labels) → int[]¶
把字符串标签转成整数下标。
注意
只查表,不做大小写或空白归一化
- 参数
labels (String[]) – 待编码字符串标签
- 返回
与输入等长的整数码数组
- 抛出
NullPointerException – labels 为 null
IllegalStateException – 未在字符串标签上 fit
IllegalArgumentException – 出现未见过的字符串标签
- fitTransform(String[] labels) → int[]¶
先 fit 再编码字符串标签。
- 参数
labels (String[]) – 既用于拟合又用于编码的字符串标签
- 返回
与输入等长的整数码数组
- 抛出
NullPointerException – labels 为 null,或其中某个元素为 null
IllegalArgumentException – labels 为空
- inverseTransformStrings(int[] encoded) → String[]¶
把整数编码还原为字符串标签。
- 参数
encoded (int[]) – 整数码数组,元素须在 [0, k-1] 内
- 返回
与输入等长的字符串数组
- 抛出
NullPointerException – encoded 为 null
IllegalStateException – 未在字符串标签上 fit
IllegalArgumentException – 下标越界
- fit(Matrix features, double[] ignoredTargets) → LabelEncoder¶
以单列矩阵为输入的适配方法。
注意
把矩阵数据按行展开后交给 fit(double[]),因此只接受单列输入
- 参数
features (Matrix) – 单列矩阵,每行一个标签
ignoredTargets (double[]) – 占位参数,被忽略,可为 null
- 返回
this,便于链式调用
- 抛出
NullPointerException – features 为 null
IllegalArgumentException – features 的列数不等于 1,或数据含非有限值
- transform(Matrix features) → Matrix¶
编码单列矩阵。
注意
内部走 transform(double[]),编码值以 double 写出
- 参数
features (Matrix) – 单列矩阵,每行一个标签
- 返回
行数不变、单列的编码矩阵
- 抛出
NullPointerException – features 为 null
IllegalStateException – 尚未 fit
IllegalArgumentException – 列数不等于 1,或出现未见过的标签
- inverseTransform(Matrix transformed) → Matrix¶
解码单列矩阵。
注意
内部走 inverseTransform(double[]),同样要求编码接近整数
- 参数
transformed (Matrix) – 单列的编码矩阵
- 返回
行数不变、单列的类别值矩阵
- 抛出
NullPointerException – transformed 为 null
IllegalStateException – 尚未 fit
IllegalArgumentException – 列数不等于 1,或编码值越界
- classes() → double[]¶
返回数值类别表副本。
- 返回
升序类别值副本;在字符串上拟合时为 0..k-1
- 抛出
IllegalStateException – 尚未 fit
- stringClasses() → String[]¶
返回字符串类别表副本。
注意
不抛异常,未拟合或数值模式下一律返回 null
- 返回
按自然序排列的字符串类别副本;未在字符串上 fit 时为 null
- kind() → ModelKind¶
返回模型类型标识。
- 返回
ModelKind.LABEL_ENCODER
- write(ModelWriter writer)¶
写入数值类别表与可选的字符串表。
注意
先写类别数与类别值,再写字符串条数(0 表示无字符串表)
注意
每条字符串先写 UTF-8 字节数再写字节,读取端按同一格式消费
- 参数
writer (ModelWriter) – 目标写入器,由调用方负责容器头与关闭
- 抛出
IllegalStateException – 尚未 fit
- read(ModelReader reader) → LabelEncoderstatic¶
从序列化流重建 LabelEncoder。
注意
字符串条数大于 0 时同时重建标签到下标的哈希表
- 参数
reader (ModelReader) – 已完成容器头解析的读取器
- 返回
可直接用于 transform 与 inverseTransform 的编码器
- 抛出
ModelFormatException – 类别数不为正
- final class Lasso implements Estimator, Persistable¶
坐标下降求解的 L1 正则最小二乘。
fit 先令截距等于目标均值、残差为零均值化后的目标,再循环坐标下降:对每个特征计算 rho = Σ x_i·(r_i + w_j·x_i),用软阈值把 rho 向零收缩 alpha,再除以该特征的平方和得到新系数,并把变化量即时回写到残差。
每轮扫描结束后把残差均值并入截距,使残差保持零均值。alpha 作用在按行求和的尺度上(rho 与 norms 都未除以样本数),与按均方误差定义的 alpha 相差 n 倍,取值需相应放大。
示例Matrix x = Matrix.fromRows(new double[][]{{1, 0}, {0, 1}, {1, 1}, {2, 2}}); double[] y = {1.0, 2.0, 3.0, 5.0}; Lasso lasso = Lasso.builder() .alpha(0.1) .maxIterations(500) .build() .fit(x, y); double[] coefficients = lasso.weights(); double bias = lasso.intercept();注意
alpha 允许为 0,此时退化为无正则的坐标下降最小二乘
注意
收敛判据是本轮坐标更新的最大绝对变化小于 tolerance;达到 maxIterations 时静默停止,不抛异常
注意
各特征的平方和只在 fit 开始时计算一次
注意
特征未中心化或标准化,列尺度直接决定收缩强度
参见:basalt.ml.Ridge, basalt.ml.LinearRegression, basalt.ml.Lasso.Builder
方法
- builder() → Builderstatic¶
创建构建器,默认 alpha=0.1、1000 轮、1e-8。
- 返回
新的 Builder,字段取默认值
- fit(Matrix features, double[] targets) → Lasso¶
用循环坐标下降拟合 L1 正则模型。
注意
系数初值全为零,相同输入的迭代轨迹完全确定
注意
平方和为零的常数列会被跳过,系数保持 0
- 参数
features (Matrix) – 训练特征矩阵,n 行 d 列
targets (double[]) – 训练目标数组,长度等于 n
- 返回
this
- 抛出
NullPointerException – features 或 targets 为 null
IllegalArgumentException – 行数与目标长度不符,或数据含 NaN/无穷
- predict(Matrix features) → double[]¶
计算截距与系数的线性组合。
- 参数
features (Matrix) – 待预测特征矩阵,列数须等于训练特征数
- 返回
每行一个连续预测值
- 抛出
IllegalStateException – 尚未 fit
IllegalArgumentException – 列数不匹配或含非有限值
- weights() → double[]¶
返回回归系数副本。
- 返回
长度为特征数的系数数组副本,稀疏结果中不重要的特征为 0.0
- 抛出
NullPointerException – 尚未 fit,内部数组为 null
- intercept() → double¶
返回截距项。
注意
截距不受 L1 惩罚,每轮扫描后按残差均值修正
- 返回
标量截距;未 fit 时为 0.0
- kind() → ModelKind¶
返回模型类型标识。
- 返回
ModelKind.LASSO
- write(ModelWriter writer)¶
写入 alpha、迭代参数、截距与系数。
注意
写入顺序为 alpha、maxIterations、tolerance、特征数、截距、系数
- 参数
writer (ModelWriter) – 目标写入器,由调用方负责容器头与关闭
- 抛出
IllegalStateException – 尚未 fit
- read(ModelReader reader) → Lassostatic¶
从序列化流重建 Lasso 模型。
注意
alpha、maxIterations、tolerance 从流中还原并重新经过 Builder 校验
- 参数
reader (ModelReader) – 已完成容器头解析的读取器
- 返回
可直接用于 predict 的模型实例
- 抛出
ModelFormatException – 特征数不为正
- final class LimeExplainer¶
用局部加权线性代理模型解释单个预测的 LIME 解释器。
构造时统计训练数据每列的标准差(分母取样本数,标准差不超过 1e-12 的列按 1.0 处理),作为扰动的尺度。explainInstance 以目标样本为中心按 0.5 倍标准差做高斯采样:第 0 条样本固定为目标本身、权重为 1,其余样本按 w = exp(-d²/kernelWidth²) 加权,其中 d² 是采样偏移按列标准差归一化后再乘 0.5 的平方和。
代理模型是对增广设计矩阵 [1, x] 的加权岭回归,用 Cholesky 求解,特征对角加 1e-4、截距加 1e-9 的抖动。拟合优度用加权 R² 表示,即 1 减去加权残差平方和与加权总平方和之比;总平方和不超过 1e-15 时直接记为 1.0,结果下限截断为 0。
示例Matrix train = Matrix.fromRows(new double[][]{{0, 0}, {1, 0}, {0, 1}, {1, 1}}); double[] y = {0, 0, 1, 1}; LogisticRegression model = LogisticRegression.builder().build().fit(train, y); LimeExplainer lime = new LimeExplainer(model, train, 200, 0.75, 7L); LimeExplainer.LocalExplanation explanation = lime.explainInstance(new double[]{1.0, 0.2}); double[] weights = explanation.featureWeights(); double fidelity = explanation.r2Fidelity(); int[] ranked = explanation.topFeatures();注意
kernelWidth 不大于 0 时自动取 0.75·sqrt(特征数),单参数构造器即走该路径
注意
numSamples 必须不小于 20,默认 500
注意
每次调用都用 seed 重新初始化随机源,同一实例的多次解释结果完全一致
注意
topFeatures 按 |系数 × 该列标准差| 降序给出全部特征的下标,不做截断
注意
模型统一经 ShapExplainer 的求值入口调用:逻辑回归与随机森林取正类概率,直方图梯度提升取原始分数
参见:basalt.ml.ShapExplainer, basalt.ml.Estimator, basalt.ml.Pipeline
构造器
- LimeExplainer(Estimator model, Matrix trainingData)¶
用默认采样数 500、自动核宽、种子 42 构造。
注意
等价于 new LimeExplainer(model, trainingData, 500, 0.0, 42L)
- 参数
model (Estimator) – 被解释的估计器或 Pipeline,不能为 null
trainingData (Matrix) – 训练数据,用于估计每列标准差
- 抛出
NullPointerException – model 或 trainingData 为 null
IllegalArgumentException – trainingData 含 NaN 或无穷
- LimeExplainer(Estimator model, Matrix trainingData, int numSamples, double kernelWidth, long seed)¶
指定采样数、核宽与随机种子构造。
注意
标准差按总体口径计算,分母为样本数而非样本数减一
注意
标准差不超过 1e-12 的列按 1.0 处理,避免扰动退化为常数
- 参数
model (Estimator) – 被解释的估计器或 Pipeline,不能为 null
trainingData (Matrix) – 训练数据,用于估计每列标准差
numSamples (int) – 局部采样数,必须不小于 20
kernelWidth (double) – 距离核的宽度;不大于 0 时取 0.75·sqrt(特征数)
seed (long) – 随机种子,决定扰动样本的生成
- 抛出
NullPointerException – model 或 trainingData 为 null
IllegalArgumentException – trainingData 含 NaN 或无穷,或 numSamples 小于 20
方法
- explainInstance(double[] instance) → LocalExplanation¶
为目标样本生成局部解释。
注意
localPrediction 由代理模型在目标样本上求值,与 modelPrediction 的差异反映代理拟合质量
注意
全部扰动样本的预测通过一次批量调用完成,不逐行调用
- 参数
instance (double[]) – 目标样本,长度须等于训练特征数
- 返回
含截距、各特征权重、局部与真实预测、加权 R² 与特征排序的 LocalExplanation
- 抛出
NullPointerException – instance 为 null
IllegalArgumentException – instance 长度与训练特征数不符
- final class LinearRegression implements Estimator, Persistable¶
全批量梯度下降的普通最小二乘。
fit 从全零权重与零截距出发,每个 epoch 用全部样本累加 MSE 梯度(缩放因子 2/n),加上 2·l2·w 后按 learningRate 做一次整批更新;fitIntercept 为 true 时截距同步更新,且不受 l2 惩罚。
lossHistory 记录每个 epoch 更新前算出的均方误差,可用于判断是否收敛。算法对特征尺度敏感:未标准化时应降低 learningRate,否则梯度下降可能震荡或发散。
示例Matrix x = Matrix.fromRows(new double[][]{{0, 1}, {1, 1}, {2, 1}, {3, 1}}); double[] y = {1.0, 3.0, 5.0, 7.0}; LinearRegression model = LinearRegression.builder() .learningRate(0.05) .epochs(2000) .fitIntercept(true) .build() .fit(x, y); double[] predictions = model.predict(x); double one = model.predictOne(new double[]{4.0, 1.0}, 0);注意
权重初值恒为零,同一输入的拟合结果完全确定
注意
l2 以 2·l2·w 加入梯度,只作用于权重
注意
不对特征做中心化或标准化,也不做特征筛选
参见:basalt.ml.Ridge, basalt.ml.LogisticRegression, basalt.ml.LinearRegression.Builder
方法
- builder() → Builderstatic¶
创建构建器,默认 lr=0.05、2000 轮、无正则。
- 返回
新的 Builder,字段取默认值
- fit(Matrix features, double[] targets) → LinearRegression¶
用全批量梯度下降最小化均方误差。
注意
epochs 轮内不做提前停止,lossHistory 长度恒为 epochs
- 参数
features (Matrix) – 训练特征矩阵,n 行 d 列
targets (double[]) – 训练目标数组,长度等于 n
- 返回
this
- 抛出
NullPointerException – features 或 targets 为 null
IllegalArgumentException – 行数与目标长度不符,或数据含 NaN/无穷
- predict(Matrix features) → double[]¶
批量计算线性预测值。
- 参数
features (Matrix) – 待预测特征矩阵,列数须等于训练特征数
- 返回
长度等于行数的连续预测值
- 抛出
IllegalStateException – 尚未 fit
IllegalArgumentException – 列数不匹配或含非有限值
- predictOne(double[] features, int offset) → double¶
对扁平数组中的单个样本预测。
适合在已经展开的批量缓冲区上按偏移逐行调用,避免为单行构造 Matrix。
注意
只检查长度,不检查取值是否有限
- 参数
features (double[]) – 扁平特征数组
offset (int) – 该样本第一个特征在数组中的下标
- 返回
单样本的预测值
- 抛出
IllegalStateException – 尚未 fit
IndexOutOfBoundsException – offset 为负,或 offset 加特征数超过数组长度
- weights() → double[]¶
返回权重副本。
注意
返回副本,修改它不影响模型
- 返回
长度为特征数的权重副本;未 fit 时返回空数组
- intercept() → double¶
返回截距项。
注意
fitIntercept 为 false 时该值恒为 0.0
- 返回
标量截距;未 fit 时为 0.0
- lossHistory() → double[]¶
返回每个 epoch 的均方误差。
注意
返回副本;未 fit 时为空数组
注意
曲线单调下降说明学习率合适,震荡说明步长偏大
- 返回
长度为 epochs 的数组,元素是当轮更新前的 MSE
- kind() → ModelKind¶
返回模型类型标识。
- 返回
ModelKind.LINEAR_REGRESSION
- write(ModelWriter writer)¶
写入超参数、截距与权重。
注意
写入顺序为 learningRate、epochs、l2、fitIntercept 字节、特征数、截距、权重
注意
lossHistory 不写入流,read 后为空数组
- 参数
writer (ModelWriter) – 目标写入器,由调用方负责容器头与关闭
- 抛出
IllegalStateException – 尚未 fit
- read(ModelReader reader) → LinearRegressionstatic¶
从序列化流重建 LinearRegression 模型。
注意
超参数从流中还原并重新经过 Builder 校验
注意
lossHistory 为空数组,训练曲线不可恢复
- 参数
reader (ModelReader) – 已完成容器头解析的读取器
- 返回
已标记为拟合状态、可直接 predict 的实例
- 抛出
ModelFormatException – 特征数不为正
- final class LinearSVM implements Estimator, Persistable¶
PEGASOS 次梯度法训练的二分类线性 SVM。
fit 要求标签恰好取两个不同值,按升序映射为负类与正类(较大者记 +1)。每个 epoch 先洗牌样本顺序,再逐样本判断 margin:小于 1 时做 hinge 更新 w ← (1-ηλ)w + η·y·x、b ← b + η·y,否则只做收缩 w ← (1-ηλ)w。
步长 η = 1/(λ·t),t 是跨 epoch 累计的样本计数,因此收缩因子 1-ηλ 等于 1-1/t。偏置只累加 η·y,不受 L2 正则。predict 取 w·x + b 的符号,返回原始标签值而非 ±1。
示例Matrix x = Matrix.fromRows(new double[][]{{0, 0}, {0, 1}, {1, 0}, {1, 1}}); double[] y = {0, 0, 1, 1}; LinearSVM svm = LinearSVM.builder() .lambda(0.01) .epochs(20) .seed(42L) .build() .fit(x, y); double[] labels = svm.predict(x); double[] w = svm.weights(); double b = svm.bias();注意
lambda 越小正则越弱、早期有效步长越大
注意
洗牌由 seed 驱动的 Random 完成,默认 42,结果可复现
注意
单类别或三分类以上的数据会在 fit 时被拒绝
注意
目标值只用于确定两个类别,不做 0/1 之外的假设
参见:basalt.ml.LogisticRegression, basalt.ml.LinearSVM.Builder
方法
- builder() → Builderstatic¶
创建构建器,默认 lambda=0.01、20 轮、种子 42。
- 返回
新的 Builder,字段取默认值
- fit(Matrix features, double[] targets) → LinearSVM¶
用 PEGASOS 迭代训练二分类线性模型。
注意
类别按升序决定符号:较大值为正类
注意
每轮重新洗牌,累计步数 t 不随 epoch 重置
- 参数
features (Matrix) – 训练特征矩阵,n 行 d 列
targets (double[]) – 训练标签,必须恰好包含两个不同取值
- 返回
this
- 抛出
NullPointerException – features 或 targets 为 null
IllegalArgumentException – 类别数不等于 2,或形状不符、数据含非有限值
- predict(Matrix features) → double[]¶
按判别值的符号输出原始标签。
注意
判别值恰为 0 时判为正类
- 参数
features (Matrix) – 待预测特征矩阵,列数须等于训练特征数
- 返回
每行一个训练集中出现过的标签值
- 抛出
IllegalStateException – 尚未 fit
IllegalArgumentException – 列数不匹配或含非有限值
- weights() → double[]¶
返回权重向量副本。
- 返回
长度为特征数的权重副本
- 抛出
NullPointerException – 尚未 fit,内部数组为 null
- bias() → double¶
返回偏置项。
注意
偏置不参与正则化,只按 η·y 累加
- 返回
标量偏置 b;未 fit 时为 0.0
- classes() → double[]¶
返回两个类别值。
注意
下标 0 为负类、1 为正类,判别值非负时输出下标 1
注意
不抛异常,未拟合时返回 null
- 返回
升序排列的两个类别副本;未 fit 时为 null
- kind() → ModelKind¶
返回模型类型标识。
- 返回
ModelKind.LINEAR_SVM
- write(ModelWriter writer)¶
写入超参数、偏置、类别与权重。
注意
写入顺序为 lambda、epochs、seed、特征数、bias、classes、weights
- 参数
writer (ModelWriter) – 目标写入器,由调用方负责容器头与关闭
- 抛出
IllegalStateException – 尚未 fit
- read(ModelReader reader) → LinearSVMstatic¶
从序列化流重建 LinearSVM 模型。
注意
类别数组固定按 2 个元素读取
注意
lambda、epochs、seed 从流中还原并重新经过 Builder 校验
- 参数
reader (ModelReader) – 已完成容器头解析的读取器
- 返回
可直接用于 predict 的模型实例
- 抛出
ModelFormatException – 特征数不为正
- final class LogisticRegression implements Estimator, Persistable¶
全批量梯度下降的二分类逻辑回归。
fit 要求标签严格等于 0.0 或 1.0,其他取值直接拒绝。每个 epoch 用全部样本计算交叉熵梯度;损失按 max(z,0) - z·y + log1p(exp(-|z|)) 计算,在 logit 绝对值很大时也不会溢出。
l2 以 2·l2·w 加入权重梯度,截距不受惩罚。predictProbability 用分段 sigmoid 输出概率,predict 再以固定阈值 0.5 转成 0/1 硬标签。
示例Matrix x = Matrix.fromRows(new double[][]{{0, 0}, {0, 1}, {1, 0}, {1, 1}}); double[] y = {0, 0, 1, 1}; LogisticRegression model = LogisticRegression.builder() .learningRate(0.1) .epochs(2000) .build() .fit(x, y); double[] probability = model.predictProbability(x); double[] labels = model.predict(x);注意
概率阈值硬编码为 0.5,不可配置
注意
特征未标准化时需按尺度调整 learningRate
注意
类别必须是 0 与 1,不做任意标签的自动映射
参见:basalt.ml.LinearSVM, basalt.ml.Metrics, basalt.ml.LogisticRegression.Builder
方法
- builder() → Builderstatic¶
创建构建器,默认 lr=0.1、2000 轮、无正则。
- 返回
新的 Builder,字段取默认值
- fit(Matrix features, double[] targets) → LogisticRegression¶
用全批量梯度下降最小化交叉熵。
注意
标签校验在形状校验之后进行,逐元素扫描
- 参数
features (Matrix) – 训练特征矩阵,n 行 d 列
targets (double[]) – 训练标签,每个元素必须是 0.0 或 1.0
- 返回
this
- 抛出
NullPointerException – features 或 targets 为 null
IllegalArgumentException – 标签不是 0/1,或行数与标签长度不符、数据含非有限值
- predictProbability(Matrix features) → double[]¶
输出每行属于正类的概率。
- 参数
features (Matrix) – 待预测特征矩阵,列数须等于训练特征数
- 返回
长度等于行数的概率数组,取值在 [0,1]
- 抛出
IllegalStateException – 尚未 fit
IllegalArgumentException – 列数不匹配或含非有限值
- predict(Matrix features) → double[]¶
以 0.5 为阈值输出 0/1 标签。
注意
内部先算概率再阈值化,与 predictProbability 结果一致
- 参数
features (Matrix) – 待预测特征矩阵
- 返回
每行 1.0 或 0.0,概率大于等于 0.5 判为 1.0
- 抛出
IllegalStateException – 尚未 fit
IllegalArgumentException – 列数不匹配或含非有限值
- lossHistory() → double[]¶
返回每个 epoch 的平均交叉熵。
注意
返回副本;未 fit 时为空数组
- 返回
长度为 epochs 的数组,元素是当轮更新前的平均损失
- weights() → double[]¶
返回权重副本。
注意
返回副本,修改它不影响模型
- 返回
长度为特征数的权重副本;未 fit 时返回空数组
- intercept() → double¶
返回截距项。
注意
截距不受 l2 惩罚,只按平均梯度更新
- 返回
标量截距;未 fit 时为 0.0
- kind() → ModelKind¶
返回模型类型标识。
- 返回
ModelKind.LOGISTIC_REGRESSION
- write(ModelWriter writer)¶
写入超参数、截距与权重。
注意
写入顺序为 learningRate、epochs、l2、特征数、截距、权重
注意
lossHistory 不写入流,read 后为空数组
- 参数
writer (ModelWriter) – 目标写入器,由调用方负责容器头与关闭
- 抛出
IllegalStateException – 尚未 fit
- read(ModelReader reader) → LogisticRegressionstatic¶
从序列化流重建 LogisticRegression 模型。
注意
超参数从流中还原并重新经过 Builder 校验
注意
lossHistory 为空数组,训练曲线不可恢复
- 参数
reader (ModelReader) – 已完成容器头解析的读取器
- 返回
已标记为拟合状态、可直接 predict 的实例
- 抛出
ModelFormatException – 特征数不为正
- final class Metrics¶
分类与回归指标,纯 Java 实现。
全部方法为静态方法,输入是两个等长 double[];长度不等或为空时抛 IllegalArgumentException。分类指标按 double 精确相等比较标签,因此预测必须是类别码(例如 0/1),传入概率会得到无意义的结果。
precision、recall、f1 用 positive 参数指定正类,分母为零时返回 0.0 而不是 NaN。rocAuc 单独约定输入:标签必须只含 0/1,分数可以是任意实数,采用并列取平均秩的 Mann-Whitney 统计量,等价于梯形法 ROC 面积。
示例double[] expected = {1, 0, 1, 1, 0}; double[] predicted = {1, 0, 0, 1, 0}; double accuracy = Metrics.accuracy(expected, predicted); double f1 = Metrics.f1(expected, predicted, 1.0); int[][] matrix = Metrics.confusionMatrix(expected, predicted); double auc = Metrics.rocAuc(expected, new double[]{0.9, 0.1, 0.4, 0.8, 0.2});注意
不修改输入数组
注意
macroF1 与 confusionMatrix 的类别集合取自 expected 的升序唯一值
注意
回归指标不做样本数之外的归一化,量纲随目标值
参见:basalt.ml.Estimators.Metric, basalt.ml.Estimator
方法
- accuracy(double[] expected, double[] predicted) → doublestatic¶
预测与期望完全相等的比例。
注意
用 == 比较 double,浮点近似值不会被判为相等
- 参数
expected (double[]) – 真实标签
predicted (double[]) – 预测标签,长度须与 expected 相同
- 返回
[0,1] 的准确率,即相等元素数除以样本数
- 抛出
IllegalArgumentException – 两个数组长度不一致或为空
- precision(double[] expected, double[] predicted, double positive) → doublestatic¶
指定正类的精确率。
- 参数
expected (double[]) – 真实标签
predicted (double[]) – 预测标签
positive (double) – 被视为正类的标签值
- 返回
TP/(TP+FP);没有任何预测为正类时返回 0.0
- 抛出
IllegalArgumentException – 两个数组长度不一致或为空
- recall(double[] expected, double[] predicted, double positive) → doublestatic¶
指定正类的召回率。
- 参数
expected (double[]) – 真实标签
predicted (double[]) – 预测标签
positive (double) – 被视为正类的标签值
- 返回
TP/(TP+FN);expected 中没有正类时返回 0.0
- 抛出
IllegalArgumentException – 两个数组长度不一致或为空
- f1(double[] expected, double[] predicted, double positive) → doublestatic¶
精确率与召回率的调和平均。
- 参数
expected (double[]) – 真实标签
predicted (double[]) – 预测标签
positive (double) – 被视为正类的标签值
- 返回
2PR/(P+R);P 与 R 同时为 0 时返回 0.0
- 抛出
IllegalArgumentException – 两个数组长度不一致或为空
- macroF1(double[] expected, double[] predicted) → doublestatic¶
按类别取 F1 的算术平均。
类别集合来自 expected 的升序唯一值,对每个类别分别作为正类计算 F1,再求平均。多分类问题常用该指标,可避免多数类主导。
注意
predicted 中若出现 expected 之外的新标签,不会被单独计为一类
- 参数
expected (double[]) – 真实标签,决定类别集合
predicted (double[]) – 预测标签
- 返回
[0,1] 的宏平均 F1
- 抛出
IllegalArgumentException – 两个数组长度不一致或为空
- confusionMatrix(double[] expected, double[] predicted) → int[][]static¶
返回以类别为行列的混淆矩阵。
行对应真实类别,列对应预测类别,行列顺序都是 expected 唯一值的升序,因此 matrix[i][j] 表示真实为第 i 类且被预测为第 j 类的样本数。
注意
对角线元素之和等于 accuracy 的分子
- 参数
expected (double[]) – 真实标签,决定矩阵维度与类别顺序
predicted (double[]) – 预测标签
- 返回
k×k 的 int 矩阵,k 为 expected 的唯一值个数
- 抛出
IllegalArgumentException – predicted 含 expected 之外的类别,或两数组长度不一致、为空
- rocAuc(double[] labels, double[] scores) → doublestatic¶
二分类 ROC 曲线下面积。
先按分数升序排序并给出秩,同分样本取平均秩,再用正类秩和减去 positives·(positives+1)/2 得到 U 统计量,最后除以 positives·negatives。
注意
并列分数按平均秩处理,结果与样本顺序无关
注意
只支持二分类;多分类需先做 one-vs-rest 拆分
- 参数
labels (double[]) – 真实标签,必须只含 0.0 与 1.0,其中 1 为正类
scores (double[]) – 实数打分,越大越倾向正类,可以是 logit 或概率
- 返回
[0,1] 的 AUC,0.5 相当于随机排序
- 抛出
IllegalArgumentException – 标签含 0/1 之外的值、缺少某一类,或两数组长度不一致、为空
- mse(double[] expected, double[] predicted) → doublestatic¶
均方误差。
- 参数
expected (double[]) – 真实值
predicted (double[]) – 预测值
- 返回
Σ(expected-predicted)²/n,非负
- 抛出
IllegalArgumentException – 两个数组长度不一致或为空
- rmse(double[] expected, double[] predicted) → doublestatic¶
均方根误差。
注意
门面 crossValidate 会对其取负号,使指标统一为越大越好
- 参数
expected (double[]) – 真实值
predicted (double[]) – 预测值
- 返回
mse 的平方根,与目标值同量纲
- 抛出
IllegalArgumentException – 两个数组长度不一致或为空
- mae(double[] expected, double[] predicted) → doublestatic¶
平均绝对误差。
- 参数
expected (double[]) – 真实值
predicted (double[]) – 预测值
- 返回
Σ|expected-predicted|/n,非负
- 抛出
IllegalArgumentException – 两个数组长度不一致或为空
- r2(double[] expected, double[] predicted) → doublestatic¶
决定系数。
以 expected 的均值为基准计算总平方和,返回 1 - SSres/SStot;模型比常数均值预测更差时结果为负。
注意
SStot 为 0(所有真实值相同)时:残差也为 0 返回 1.0,否则返回 0.0
- 参数
expected (double[]) – 真实值
predicted (double[]) – 预测值
- 返回
1 - SSres/SStot,上界为 1,可以为负
- 抛出
IllegalArgumentException – 两个数组长度不一致或为空
- final class MinMaxScaler implements Transformer, Estimator¶
按列线性映射到指定区间的缩放器。
fit 逐列扫描得到最小值与最大值,dataRange 记录极差,scale = (featureMax - featureMin) / dataRange,minOffset = featureMin - dataMin·scale;transform 计算 v·scale + minOffset,inverseTransform 用 (v - minOffset) / scale 还原。
极差不超过 1e-12 的常数列把缩放分母取 1.0,此时 scale 等于目标区间宽度、输出恒为 featureMin,不会产生除零或 NaN。clip 为 true 时 transform 的输出被截断到 [featureMin, featureMax],对训练分布之外的值同样生效。
示例Matrix x = Matrix.fromRows(new double[][]{{1, 10}, {2, 20}, {3, 30}}); MinMaxScaler scaler = MinMaxScaler.builder() .featureRange(-1.0, 1.0) .clip(true) .build() .fit(x); Matrix scaled = scaler.transform(x); Matrix restored = scaler.inverseTransform(scaled); double[] scale = scaler.scale();注意
目标区间默认 [0, 1],由 Builder.featureRange(min, max) 设置,要求有限且 min < max
注意
拟合统计量 dataMin、dataMax、dataRange、scale、minOffset 随模型一起序列化
注意
transform 与 inverseTransform 都要求列数等于拟合时的特征数
注意
inverseTransform 只做逆线性映射,clip 造成的截断无法还原
注意
同时实现 Transformer 与 Estimator,可放入 Pipeline
参见:basalt.ml.StandardScaler, basalt.ml.Transformer, basalt.ml.MinMaxScaler.Builder
方法
- builder() → Builderstatic¶
创建构建器,默认区间 [0, 1]、不截断。
- 返回
新的 Builder,字段取默认值
- fit(Matrix features) → MinMaxScaler¶
只用特征拟合,目标数组缺省为 null。
注意
等价于 fit(features, null)
- 参数
features (Matrix) – 训练特征矩阵,行是样本、列是特征
- 返回
this,便于链式调用
- 抛出
NullPointerException – features 为 null
IllegalArgumentException – features 含 NaN 或无穷
- fit(Matrix features, double[] ignoredTargets) → MinMaxScaler¶
逐列统计极值并算出缩放系数。
注意
单次扫描,时间 O(n·d)
注意
常数列的 dataRange 记为 0,但缩放分母取 1.0
- 参数
features (Matrix) – 训练特征矩阵,行是样本、列是特征
ignoredTargets (double[]) – 占位参数;缩放忽略监督目标,可为 null
- 返回
this,便于链式调用
- 抛出
NullPointerException – features 为 null
IllegalArgumentException – features 含 NaN 或无穷
- transform(Matrix features) → Matrix¶
按列线性映射到目标区间。
注意
clip 为 true 时输出被截断到 [featureMin, featureMax]
- 参数
features (Matrix) – 待变换特征矩阵,列数须等于拟合特征数
- 返回
与输入同形状的变换结果
- 抛出
NullPointerException – features 为 null
IllegalStateException – 尚未 fit
IllegalArgumentException – 列数不匹配或含非有限值
- inverseTransform(Matrix transformed) → Matrix¶
把缩放结果还原到原始量纲。
注意
按 (v - minOffset) / scale 逐元素计算,scale 恒为正
- 参数
transformed (Matrix) – 变换后的矩阵,列数须等于拟合特征数
- 返回
与输入同形状的还原结果
- 抛出
NullPointerException – transformed 为 null
IllegalStateException – 尚未 fit
IllegalArgumentException – 列数不匹配或含非有限值
- predict(Matrix features) → double[]¶
返回变换结果的扁平数组。
注意
等价于 transform(features).toArray(),clip 同样生效
- 参数
features (Matrix) – 待变换特征矩阵,列数须等于拟合特征数
- 返回
长度为 行数 × 特征数 的数组
- 抛出
NullPointerException – features 为 null
IllegalStateException – 尚未 fit
IllegalArgumentException – 列数不匹配或含非有限值
- dataMin() → double[]¶
返回拟合时各列最小值。
- 返回
长度等于特征数的数组副本
- 抛出
IllegalStateException – 尚未 fit
- dataMax() → double[]¶
返回拟合时各列最大值。
- 返回
长度等于特征数的数组副本
- 抛出
IllegalStateException – 尚未 fit
- dataRange() → double[]¶
返回各列极差。
- 返回
dataMax - dataMin 的数组副本;常数列为 0
- 抛出
IllegalStateException – 尚未 fit
- scale() → double[]¶
返回各列缩放系数。
注意
反变换需要除以该系数,因此它恒为正
- 返回
目标区间宽度与极差之比的数组副本;常数列等于区间宽度
- 抛出
IllegalStateException – 尚未 fit
- kind() → ModelKind¶
返回模型类型标识。
- 返回
ModelKind.MIN_MAX_SCALER
- write(ModelWriter writer)¶
写入目标区间、截断标志与全部拟合统计量。
注意
写入顺序为区间下界、上界、clip 字节、特征数、dataMin、dataMax、dataRange、scale、minOffset
注意
minOffset 一并写入,读取端无需重新推导
- 参数
writer (ModelWriter) – 目标写入器,由调用方负责容器头与关闭
- 抛出
IllegalStateException – 尚未 fit
- read(ModelReader reader) → MinMaxScalerstatic¶
从序列化流重建 MinMaxScaler。
注意
统计量直接读取,不重新扫描数据
- 参数
reader (ModelReader) – 已完成容器头解析的读取器
- 返回
可直接用于 transform 与 inverseTransform 的实例
- 抛出
ModelFormatException – 特征数不为正,或区间上界不大于下界
- final class OneHotEncoder implements Transformer, Estimator¶
把类别列展开为稠密 0/1 指示特征的编码器。
fit 对每个被标记为类别的列收集升序唯一值作为词表,并预先计算输出列偏移;未被指定的列原样透传,各占一个输出列。categoricalColumns 未设置时全部列都按类别处理。
transform 在每个类别块内把命中的位置置 1、其余为 0;handleUnknown 为 ERROR 时遇到词表外的值抛异常,为 IGNORE 时该样本的整块保持全 0。inverseTransform 对每个类别块取最大值的下标还原类别值,整块为 0 时输出 NaN。
示例Matrix x = Matrix.fromRows(new double[][]{ {0, 1.5}, {1, 2.5}, {2, 3.5} }); OneHotEncoder encoder = OneHotEncoder.builder() .categoricalColumns(0) .handleUnknown(OneHotEncoder.HandleUnknown.IGNORE) .build() .fit(x); Matrix encoded = encoder.transform(x); int width = encoder.outputFeatureCount(); Matrix back = encoder.inverseTransform(encoded);注意
handleUnknown 默认 ERROR,可在 Builder 中改为 IGNORE
注意
词表按 double 升序排列,比较用 Double.compare,因此 -0.0 与 0.0 被视为不同类别
注意
输出特征数等于各列词表长度之和,数值列按 1 计
注意
inverseTransform 只取 argmax,不校验输入是否为合法 one-hot
注意
类别词表与列偏移随模型一起序列化
参见:basalt.ml.LabelEncoder, basalt.ml.KBinsDiscretizer, basalt.ml.OneHotEncoder.Builder
方法
- builder() → Builderstatic¶
创建构建器,默认全部列编码、未知类别报错。
- 返回
新的 Builder,字段取默认值
- fit(Matrix features) → OneHotEncoder¶
只用特征拟合,目标数组缺省为 null。
注意
等价于 fit(features, null)
- 参数
features (Matrix) – 训练特征矩阵,行是样本、列是特征
- 返回
this,便于链式调用
- 抛出
NullPointerException – features 为 null
IllegalArgumentException – features 含 NaN 或无穷,或类别列下标越界
- fit(Matrix features, double[] ignoredTargets) → OneHotEncoder¶
收集每列的类别词表并计算输出布局。
注意
每个类别列做一次 TreeSet 收集,时间 O(n·d·log n)
注意
categoricalColumns 未设置时全部列按类别处理,数值列需显式排除
- 参数
features (Matrix) – 训练特征矩阵,n 行 d 列
ignoredTargets (double[]) – 占位参数;编码忽略监督目标,可为 null
- 返回
this,便于链式调用
- 抛出
NullPointerException – features 为 null
IllegalArgumentException – features 含 NaN 或无穷,或 categoricalColumns 中的下标越界
- transform(Matrix features) → Matrix¶
把类别列展开为 0/1 指示特征。
注意
数值列按原值透传,不做缩放或中心化
- 参数
features (Matrix) – 待编码矩阵,列数须等于拟合特征数
- 返回
行数不变、宽度为 outputFeatureCount() 的稠密矩阵
- 抛出
NullPointerException – features 为 null
IllegalStateException – 尚未 fit
IllegalArgumentException – 列数不匹配、含非有限值,或 handleUnknown 为 ERROR 时出现未知类别
- inverseTransform(Matrix transformed) → Matrix¶
从指示特征还原原始列。
注意
每个类别块取最大值对应的下标;整块不大于 0 时该格输出 NaN
- 参数
transformed (Matrix) – 编码后的矩阵,列数须等于输出特征数
- 返回
行数不变、宽度等于输入特征数的矩阵
- 抛出
NullPointerException – transformed 为 null
IllegalStateException – 尚未 fit
IllegalArgumentException – 列数不匹配或含非有限值
- predict(Matrix features) → double[]¶
返回编码结果的扁平数组。
注意
等价于 transform(features).toArray()
- 参数
features (Matrix) – 待编码矩阵,列数须等于拟合特征数
- 返回
长度为 行数 × 输出特征数 的数组
- 抛出
NullPointerException – features 为 null
IllegalStateException – 尚未 fit
IllegalArgumentException – 列数不匹配、含非有限值,或出现未知类别
- categories() → double[][]¶
返回每列的类别词表。
注意
每个子数组按升序排列,且为深拷贝
- 返回
长度为输入特征数的二维数组副本;数值列为空数组
- 抛出
IllegalStateException – 尚未 fit
- outputFeatureCount() → int¶
返回编码后的特征宽度。
注意
等于各列词表长度之和,数值列按 1 计
注意
不抛异常,可在拟合前查询(此时为 0)
- 返回
输出列数;未 fit 时为 0
- kind() → ModelKind¶
返回模型类型标识。
- 返回
ModelKind.ONE_HOT_ENCODER
- write(ModelWriter writer)¶
写入未知类别策略、特征数与逐列词表。
注意
每列依次写类别标志字节、词表长度与词表值,最后写 outputOffsets
注意
输入与输出特征数在词表之前写出,读取端可先分配空间
- 参数
writer (ModelWriter) – 目标写入器,由调用方负责容器头与关闭
- 抛出
IllegalStateException – 尚未 fit
- read(ModelReader reader) → OneHotEncoderstatic¶
从序列化流重建 OneHotEncoder。
注意
categoricalColumns 的原始配置不被保留,分类标志来自逐列写出的字节
- 参数
reader (ModelReader) – 已完成容器头解析的读取器
- 返回
可直接用于 transform 与 inverseTransform 的编码器
- 抛出
ModelFormatException – HandleUnknown 序数非法,或输入/输出特征数不为正
- final class PCA implements Estimator, Transformer, Persistable¶
中心化主成分分析,含协方差与 Gram 两条精确路径。
JACOBI 路径分解 p × p 协方差矩阵,代价为 O(n p²) 的协方差累加加若干次 Jacobi 扫描,适合 n ≫ p。GRAM 路径分解 n × n Gram 矩阵,再用 v = Xᵀu / ‖Xᵀu‖ 还原主方向,代价 O(n² p),适合 p > n 的宽表。
两条路径都输出正交归一的主方向与协方差尺度上的方差,结果在符号与数值误差范围内一致。主方向的符号按绝对值最大的分量为正固定,因此重复拟合可复现。
示例Matrix features = Matrix.fromRows(new double[][] { {2.5, 2.4}, {0.5, 0.7}, {2.2, 2.9}, {1.9, 2.2}, {3.1, 3.0}, {2.3, 2.7} }); PCA pca = PCA.builder() .components(1) .solver(EigenSolver.AUTO) .whiten(true) .build() .fit(features); Matrix projected = pca.transform(features); Matrix restored = pca.inverseTransform(projected); double[] ratio = pca.explainedVarianceRatio();注意
AUTO 在特征数大于样本数且样本数不超过 20000 时选 GRAM,否则选 JACOBI
注意
解释方差比的分母是全部 p 个特征方差之和,而非所选分量方差之和,因此前 k 个比值相加通常小于 1
注意
Gram 路径需要 n × n 的双精度矩阵,20000 样本即约 3.2 GB
注意
Jacobi 扫描以相对非对角范数判定收敛,收敛判据与矩阵整体尺度无关
参见:basalt.ml.EigenSolver, basalt.ml.Estimator, basalt.core.Persistable
方法
- builder() → Builderstatic¶
创建 PCA 构建器。
- 返回
参数取默认值的新 Builder 实例
- fit(Matrix features) → PCA¶
只用特征拟合,目标数组缺省为 null。
- 参数
features (Matrix) – 训练样本矩阵,行是样本、列是特征
- 返回
this,便于链式调用
- fit(Matrix features, double[] ignoredTargets) → PCA¶
中心化后做特征分解并保留前若干主成分。
先按列求均值并中心化,再按解析出的求解器计算特征分解;特征值截断为非负、按降序排序,保留前 components 个方向,总方差始终按全部特征累计。
- 参数
features (Matrix) – 训练样本矩阵,行是样本、列是特征;元素必须有限
ignoredTargets (double[]) – 占位参数;降维忽略监督目标,可为 null
- 返回
this,便于链式调用
- 抛出
IllegalArgumentException – features 为 null 或含非有限值;样本数小于 2;components 大于 min(样本数, 特征数);显式选择 GRAM 而样本数超过 20000
- transform(Matrix features) → Matrix¶
把样本投影到主成分坐标。
逐样本减去训练均值后与各主方向做点积。whiten 为 true 时每个投影再除以其主成分标准差 sqrt(max(特征值, 1e-12)),使各分量方差为 1。
- 参数
features (Matrix) – 样本矩阵,列数须与拟合时一致
- 返回
样本数 × components 的投影矩阵
- 抛出
IllegalStateException – 尚未拟合
IllegalArgumentException – 特征列数与拟合时不一致
- inverseTransform(Matrix transformed) → Matrix¶
把主成分坐标重建回原始特征空间。
先按主方向加权求和,再加回均值。白化模型会先把每个坐标乘回对应标准差,因此与 transform 互为逆变换(截断维度时是到子空间的正交投影)。
- 参数
transformed (Matrix) – 样本数 × components 的投影矩阵,列数须等于 components
- 返回
样本数 × 特征数 的重建矩阵
- 抛出
IllegalStateException – 尚未拟合
IllegalArgumentException – transformed 的列数不等于 components
- predict(Matrix features) → double[]¶
返回投影结果的扁平数组。
等价于 transform(features).toArray(),按行优先展开,便于接入只需要 double[] 的下游流程。
- 参数
features (Matrix) – 样本矩阵,列数须与拟合时一致
- 返回
长度为 样本数 × components 的数组
- 抛出
IllegalStateException – 尚未拟合
IllegalArgumentException – 特征列数与拟合时不一致
- explainedVariance() → double[]¶
返回各主成分的方差。
数值为协方差矩阵的特征值,已截断为非负,按降序排列,单位是原始特征的方差单位。内部数组在 fit 阶段分配,未拟合时不可调用。
- 返回
长度等于 components 的数组副本
- explainedVarianceRatio() → double[]¶
返回各主成分方差占总方差的比例。
分母是全部 p 个特征的方差之和,与保留的分量数无关,因此前 k 个比值之和通常小于 1。总方差不为正(例如全部特征为常数)时返回全 0。
- 返回
长度等于 components 的数组
- components() → Matrix¶
返回主方向矩阵。
注意
每行已归一化为单位长度,且绝对值最大的分量被固定为正号
注意
特征值过小、方向无法还原时该行全为 0
- 返回
components × 特征数 的矩阵,每行一个单位长度的主方向
- 抛出
IllegalStateException – 尚未拟合
- means() → double[]¶
返回拟合时各特征的均值。
注意
未拟合时内部均值为 null,调用会抛 NullPointerException
- 返回
长度等于特征数的数组副本
- solver() → EigenSolver¶
返回实际使用的求解器。
- 返回
AUTO 解析后的具体求解器;未拟合时为 null,由 read 重建的模型为 JACOBI
- kind() → ModelKind¶
返回模型类型标识。
- 返回
ModelKind.PCA
- write(ModelWriter writer)¶
写入分量数、特征数、白化标志、总方差、均值、特征值与主方向。
注意
tolerance 与 maxIterations 不写入流,read 后回到 Builder 默认值
- 参数
writer (ModelWriter) – 目标写入器,由调用方负责容器头与关闭
- 抛出
IllegalStateException – 尚未拟合
- read(ModelReader reader) → PCAstatic¶
从序列化流重建 PCA 模型。
注意
solver() 固定返回 JACOBI,原始求解器选择不被保留
- 参数
reader (ModelReader) – 已完成容器头解析的读取器
- 返回
可直接用于 transform 与 inverseTransform 的模型实例
- 抛出
ModelFormatException – 分量数或特征数不为正,或白化标志不是 0/1
- final class Pipeline implements Estimator, Transformer, Persistable¶
顺序串联预处理步骤与最终估计器的管道
fit 按声明顺序对每一步调用 fitTransform:该步先用当前矩阵拟合自身参数,再把同一份矩阵变换后交给下一步;挂了最终估计器时,用最后一步的输出与原始 targets 拟合该估计器。transform 与 predict 只调用各步的 transform,不会重新估计任何参数。
predict 先依次 transform 全部步骤,再交给最终估计器;未挂估计器但最后一步本身实现了 Estimator 时,直接把原始 features 交给该步的 predict,不再经过前面各步的变换。transform 在最终估计器也实现 Transformer 时会额外对它做一次变换,因此同一类型既能表达纯预处理管道,也能表达带输出变换的完整链路。
序列化先写步骤数,再对每步写名称、类型码、负载长度与负载,随后写一个字节标记是否存在最终估计器;存在时再写名称、类型码与负载。read 按类型码把每段负载交回 ModelCodec.readPayload 解码,因此预处理统计量与估计器权重在 .bsl 中是单个原子对象,加载后无需重新拟合。
示例Matrix x = Matrix.fromRows(new double[][]{ {1.0, Double.NaN}, {2.0, 3.0}, {3.0, 4.0}, {4.0, 5.5}}); double[] y = {1.0, 2.0, 3.0, 4.0}; Pipeline pipeline = Pipeline.builder() .addStep("impute", SimpleImputer.builder() .strategy(SimpleImputer.Strategy.MEAN).build()) .addStep("scale", StandardScaler.builder().build()) .estimator("ridge", Ridge.builder().alpha(0.5).build()) .build() .fit(x, y); double[] predictions = pipeline.predict(x); Matrix transformed = pipeline.transform(x); Path file = Path.of("pipeline.bsl"); ModelCodec.save(file, pipeline); Pipeline restored = ModelCodec.load(file, Pipeline.class);注意
构建时至少要有一个步骤或一个最终估计器,否则 build() 抛 IllegalArgumentException
注意
最终估计器必须实现 Persistable,否则 write 抛 IllegalStateException
注意
步骤名重复时 namedSteps() 中后写入者覆盖先写入者
注意
read 把步骤数限制在 [0, 10000],单个字符串长度限制在 [0, 65536] 字节
参见:basalt.ml.Transformer, basalt.ml.Estimator, basalt.ml.Pipeline.Step, basalt.io.ModelCodec
方法
- builder() → Builderstatic¶
创建管道构建器
- 返回
新的 Builder,初始无步骤、无估计器
- fit(Matrix features) → Pipeline¶
无监督拟合,等价于 targets 为 null
注意
需要目标值的步骤(如 SelectKBest)在此重载下会因 targets 为 null 抛 NullPointerException
- 参数
features (Matrix) – 训练特征矩阵
- 返回
this
- 抛出
NullPointerException – features 为 null
- fit(Matrix features, double[] targets) → Pipeline¶
逐步 fitTransform 后拟合最终估计器
每一步用当前矩阵调用 fitTransform,把输出作为下一步的输入;targets 原样传给每一步与最终估计器,最终估计器用最后一步的输出拟合。
注意
中间矩阵逐级替换,管道不保留各步的中间结果
- 参数
features (Matrix) – 训练特征矩阵,行数为样本数
targets (double[]) – 训练目标数组,长度须等于行数;无监督步骤可忽略
- 返回
this,各步与估计器均已完成拟合
- 抛出
NullPointerException – features 为 null
- transform(Matrix features) → Matrix¶
按顺序应用各步 transform,不重新拟合
若最终估计器实现 Transformer,还会再对它做一次 transform。
- 参数
features (Matrix) – 待变换特征矩阵,列数须与首步期望一致
- 返回
变换后的矩阵,列数由最后一步决定
- 抛出
NullPointerException – features 为 null
IllegalStateException – 任一步尚未拟合
IllegalArgumentException – 列数与某步期望不一致或含非有限值
- inverseTransform(Matrix transformed) → Matrix¶
逆序还原各步变换
先对最终估计器(若实现 Transformer)做 inverseTransform,再从最后一步向前逐级还原。未实现逆变换的步骤会抛 BasaltUnsupportedOperationException。
- 参数
transformed (Matrix) – 已变换矩阵,列数须与最后一步输出一致
- 返回
还原到输入空间的矩阵
- 抛出
NullPointerException – transformed 为 null
IllegalStateException – 任一步尚未拟合
basalt.BasaltUnsupportedOperationException – 某步未实现 inverseTransform
- predict(Matrix features) → double[]¶
变换后交由最终估计器预测
先依次 transform 各步,再由最终估计器预测。未挂估计器且最后一步实现 Estimator 时,把原始 features 交给该步的 predict;两者都没有时返回变换后矩阵的展平数组。
- 参数
features (Matrix) – 待预测特征矩阵
- 返回
长度等于行数的预测数组;无估计器时为展平的特征
- 抛出
NullPointerException – features 为 null
IllegalStateException – 任一步或最终估计器尚未拟合
IllegalArgumentException – 列数不匹配或含非有限值
- steps() → List<Step>¶
步骤列表
- 返回
不可变的 Step 列表,顺序与构建顺序一致
- estimator() → Estimator¶
最终估计器
- 返回
构建时指定的估计器;未挂估计器时为 null
- estimatorName() → String¶
最终估计器在管道中的名称
- 返回
名称;未挂估计器时为 null;无名称重载默认取 estimator
- namedSteps() → Map<String, Object>¶
步骤名到对象的映射
按插入顺序返回步骤名 → Transformer;挂了最终估计器时再追加其名称 → Estimator。
注意
名称重复时保留最后一次写入的对象
- 返回
不可修改的映射视图
- kind() → ModelKind¶
模型族标识
- 返回
固定为 ModelKind.PIPELINE
- write(ModelWriter writer)¶
写出步骤链与最终估计器
先写步骤数,再对每步写名称、类型码、负载长度与负载,负载由该步自己的 write 生成;随后写一个字节标记是否存在最终估计器,存在时再写名称、类型码与负载。
注意
每段负载写入独立缓冲区并加长度前缀,读取端据此切分
- 参数
writer (ModelWriter) – 目标二进制写入器
- 抛出
IllegalStateException – 最终估计器未实现 Persistable
- read(ModelReader reader) → Pipelinestatic¶
按类型码重建步骤链与估计器
- 参数
reader (ModelReader) – 定位在管道负载起始处的读取器
- 返回
重建的管道,各步参数已恢复
- 抛出
ModelFormatException – 步骤数越界、字符串长度越界、负载不是 Transformer/Estimator 或类型码未知
- final class PolynomialFeatures implements Transformer, Estimator¶
生成最高到 degree 的多项式与交互特征
fit 只记录输入特征数并按 degree、interactionOnly、includeBias 枚举列组合,不做任何数据统计,因此同参数下任意训练集得到相同的组合表。
每个输出列是一组输入列的乘积:interactionOnly 为 false 时组合内允许重复索引,得到 x_j^2 这类幂项;为 true 时索引严格递增,只保留不同特征的交互。includeBias 为 true 时额外输出一列常量 1,对应空组合。
transform 按组合表逐行求乘积;predict 返回展平结果,长度是 rows × 输出列数,而非每行一个值。
示例Matrix x = Matrix.fromRows(new double[][]{{1.0, 2.0}, {3.0, 4.0}}); PolynomialFeatures poly = PolynomialFeatures.builder() .degree(2) .interactionOnly(false) .includeBias(true) .build() .fit(x); Matrix expanded = poly.transform(x); int columns = poly.outputFeatureCount();注意
degree 默认 2,interactionOnly 默认 false,includeBias 默认 true
注意
输出列数只由输入特征数与三个参数决定,与样本量无关
注意
序列化只写四个字段,读回时按同样参数重新枚举组合表
参见:basalt.ml.Transformer, basalt.ml.StandardScaler, basalt.ml.Pipeline
方法
- builder() → Builderstatic¶
创建构建器,degree=2、含 bias、保留幂项
- 返回
新的 Builder,字段取默认值
- fit(Matrix features) → PolynomialFeatures¶
按特征数枚举列组合
- 参数
features (Matrix) – 训练特征矩阵,只使用其列数
- 返回
this
- 抛出
NullPointerException – features 为 null
IllegalArgumentException – 特征含 NaN 或无穷值
- fit(Matrix features, double[] ignoredTargets) → PolynomialFeatures¶
忽略目标值的拟合
- 参数
features (Matrix) – 训练特征矩阵,只使用其列数
ignoredTargets (double[]) – 被忽略,可为 null
- 返回
this
- 抛出
NullPointerException – features 为 null
IllegalArgumentException – 特征含 NaN 或无穷值
- transform(Matrix features) → Matrix¶
按组合表逐行求乘积
- 参数
features (Matrix) – 待变换矩阵,列数须等于拟合时的特征数
- 返回
rows × outputFeatureCount() 的新矩阵
- 抛出
IllegalStateException – 尚未 fit
IllegalArgumentException – 列数不匹配或含非有限值
- predict(Matrix features) → double[]¶
返回变换结果的展平数组
- 参数
features (Matrix) – 待变换矩阵,列数须等于拟合时的特征数
- 返回
长度为 rows × 输出列数的数组
- 抛出
IllegalStateException – 尚未 fit
IllegalArgumentException – 列数不匹配或含非有限值
- outputFeatureCount() → int¶
已枚举的输出列数
- 返回
输出列数,含 bias 列
- 抛出
IllegalStateException – 尚未 fit
- kind() → ModelKind¶
模型族标识
- 返回
固定为 ModelKind.POLYNOMIAL_FEATURES
- write(ModelWriter writer)¶
写出 degree、两个开关与输入特征数
组合表不落盘,read 时按同样参数重建。
- 参数
writer (ModelWriter) – 目标二进制写入器
- 抛出
IllegalStateException – 尚未 fit
- read(ModelReader reader) → PolynomialFeaturesstatic¶
按四个字段重建组合表
- 参数
reader (ModelReader) – 定位在负载起始处的读取器
- 返回
可直接 transform 的实例
- 抛出
ModelFormatException – degree < 1 或输入特征数 ≤ 0
- final class RFE implements Transformer, Estimator¶
按重要性递归剔除特征直到保留指定数量
每轮在当前保留的特征子集上通过工厂新建估计器并拟合,取其重要性——树模型的 featureImportances,或线性模型权重的绝对值——把重要性最低的 step 个特征标记为剔除;剩余数量不足 step 时只剔除到目标数量为止。
剔除轮次记录在 ranking 中:未被剔除的特征为 1,每经历一轮剔除加 1,因此数值越大表示越早被淘汰。循环结束后用保留特征重新拟合一个估计器作为最终模型;transform 只做列切片,predict 为切片后再预测。
重要性来源覆盖 DecisionTree、RandomForest、HistogramGradientBoosting 的 featureImportances,以及 Ridge、Lasso、LinearRegression、LogisticRegression、LinearSVM 的权重绝对值;其他估计器无法提供重要性,拟合时直接拒绝。
示例Matrix x = Matrix.fromRows(new double[][]{ {1.0, 0.5, 9.0}, {2.0, 1.5, 8.0}, {3.0, 1.0, 7.0}, {4.0, 2.0, 6.0}}); double[] y = {1.0, 2.0, 3.0, 4.0}; RFE rfe = RFE.builder(() -> Ridge.builder().alpha(0.1).build()) .nFeaturesToSelect(2) .step(1) .build() .fit(x, y); Matrix reduced = rfe.transform(x); boolean[] mask = rfe.support(); int[] ranking = rfe.ranking(); int[] indices = rfe.selectedIndices();注意
nFeaturesToSelect 默认 2、step 默认 1,两者都必须在构建时为正
注意
每轮都新建估计器,工厂必须返回未拟合的新实例
注意
kind() 复用 ModelKind.SELECT_K_BEST,类中没有 read,写入负载格式与 SelectKBest 一致
注意
总拟合次数为剔除轮数加一,轮数约为 ceil((p − k)/step)
参见:basalt.ml.SelectKBest, basalt.ml.Ridge, basalt.ml.RandomForest, basalt.ml.Transformer
方法
- builder(Supplier<Estimator> estimatorSupplier) → Builderstatic¶
指定估计器工厂并创建构建器
- 参数
estimatorSupplier (Supplier<Estimator>) – 每轮返回一个新的未拟合估计器
- 返回
新的 Builder,nFeaturesToSelect=2、step=1
- 抛出
NullPointerException – estimatorSupplier 为 null
- fit(Matrix features, double[] targets) → RFE¶
递归剔除特征并用保留列重拟合
每轮对当前子集新建估计器、拟合、取重要性并按升序剔除 step 个特征;循环结束后在保留列上再拟合一个估计器作为最终模型。
注意
最后一轮剔除数量可能少于 step,以恰好保留目标数量为准
- 参数
features (Matrix) – 训练特征矩阵,行数为样本数
targets (double[]) – 训练目标数组,长度须等于行数
- 返回
this,已完成剔除与最终拟合
- 抛出
NullPointerException – features 或 targets 为 null
IllegalArgumentException – 目标数量与行数不符、含非有限值、nFeaturesToSelect 超出 [1, 特征数],或估计器既不提供 featureImportances 也没有长度匹配的 weights
- transform(Matrix features) → Matrix¶
只保留入选列
- 参数
features (Matrix) – 待切片矩阵,列数须等于拟合时的特征数
- 返回
rows × nFeaturesToSelect 的新矩阵,列序与原始列序一致
- 抛出
IllegalStateException – 尚未 fit
IllegalArgumentException – 列数不匹配或含非有限值
- predict(Matrix features) → double[]¶
切片后交由最终估计器预测
- 参数
features (Matrix) – 待预测矩阵,列数须等于拟合时的特征数
- 返回
长度等于行数的预测数组
- 抛出
IllegalStateException – 尚未 fit
IllegalArgumentException – 列数不匹配或含非有限值
- support() → boolean[]¶
入选特征的布尔掩码
- 返回
长度为原始特征数的副本,true 表示保留
- 抛出
IllegalStateException – 尚未 fit
- ranking() → int[]¶
特征淘汰次序
入选特征为 1,每被剔除一轮加 1,数值越大淘汰越早。
- 返回
长度为原始特征数的副本
- 抛出
IllegalStateException – 尚未 fit
- selectedIndices() → int[]¶
入选列的原始下标,升序
- 返回
长度为 nFeaturesToSelect 的副本
- 抛出
IllegalStateException – 尚未 fit
- estimator() → Estimator¶
最终重拟合的估计器
- 返回
已拟合的估计器;尚未 fit 时为 null
- kind() → ModelKind¶
模型族标识
注意
与 SelectKBest 共用类型码,便于管道统一落盘
- 返回
固定为 ModelKind.SELECT_K_BEST
- write(ModelWriter writer)¶
写出保留数量、伪分数与入选下标
伪分数取 1/ranking,用于在只识别分数的读取端表达排序;类本身没有 read 方法。
- 参数
writer (ModelWriter) – 目标二进制写入器
- 抛出
IllegalStateException – 尚未 fit
- final class RandomForest implements Estimator, Persistable¶
自助聚合的直方图森林,节点级特征子采样
每棵树对行做有放回采样,随后在同一份全局 BinnedFeatures 上以直方图分裂生长。树之间相互独立,拟合通过 ForkJoinPool 并行,并行度由 threads 决定。
分类按各树叶标签投票,得到每类的得票比例后取最大者;回归取各树叶值的算术均值。行数乘树数不小于 2000 万时,预测与投票转交 Rust 内核,失败则回退 Java 路径。
OOB 分数只用对该行未被抽中的树计算:回归为 1 - SSE/SST,分类为多数投票的准确率。某行没有任何可用树或目标方差为零时返回 NaN。
示例Matrix x = Matrix.fromRows(new double[][]{ {0.0, 1.0}, {1.0, 1.0}, {1.0, 0.0}, {2.0, 0.0}, {2.0, 1.0}, {3.0, 0.0}, {3.0, 1.0}, {4.0, 0.0}}); double[] y = {0.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0, 0.0}; RandomForest forest = RandomForest.builder() .trees(50) .maxDepth(6) .minSamplesLeaf(1) .maxFeatures(1) .bins(64) .threads(4) .seed(42L) .task(TreeTask.CLASSIFICATION) .oob(true) .build() .fit(x, y); double[] label = forest.predict(x); Matrix probability = forest.predictProbability(x); double oob = forest.oobScore();注意
OOB 打开时,treeCount*rows 超过 800 万会拒绝拟合
注意
maxFeatures 为 0 时按 max(1, sqrt(featureCount)) 解析
注意
readState 重建的森林关闭 OOB,oobScore() 会抛 IllegalStateException
参见:basalt.ml.DecisionTree, basalt.ml.PackedTrees, basalt.ml.TreeTask
方法
- builder() → Builderstatic¶
创建构造器,参数全部取默认值
- 返回
新的 Builder 实例
- fit(Matrix features, double[] targets) → RandomForest¶
分箱一次并并行训练全部树
全量矩阵只分箱一次,各树在共享分箱上以自助采样行号生长。第 i 棵树的随机种子为 seed + i*31,自助采样序列由 seed + i*1000003 驱动;打开 OOB 时,每棵树还会对全量矩阵推理一次以记录袋外预测。
注意
并行度由 threads 决定,树之间无共享可变状态
注意
分类标签按升序去重,classes() 返回该顺序
- 参数
features (Matrix) – 训练特征矩阵,行数为样本数
targets (double[]) – 目标数组,长度须等于行数;分类为类别标签,回归为连续值
- 返回
this,已完成拟合
- 抛出
IllegalArgumentException – 目标数量与行数不一致、含非有限值,或 OOB 评估超过 800 万次树-行预测
- predict(Matrix features) → double[]¶
输出预测,分类为投票胜出的标签
回归对各树叶值取均值,可用原生内核一次算完整片森林;分类先取每类的平均得票比例,再按类别顺序取最大值,票数相同时取下标较小者。
- 参数
features (Matrix) – 特征矩阵,列数须等于拟合时的特征数
- 返回
长度为行数的预测数组
- 抛出
IllegalStateException – 尚未拟合
IllegalArgumentException – 列数不匹配或含非有限值
- predictProbability(Matrix features) → Matrix¶
输出各类得票比例矩阵
每棵树对一行预测一个叶标签,映射到类别列后累加 1/treeCount,因此每行元素之和为 1。叶标签必须能在 classes() 中二分查到,否则抛 IllegalStateException。
- 参数
features (Matrix) – 特征矩阵,列数须等于拟合时的特征数
- 返回
rows × classes 的矩阵,列顺序与 classes() 一致
- 抛出
IllegalStateException – 任务不是分类,或尚未拟合
IllegalArgumentException – 列数不匹配或含非有限值
- classes() → double[]¶
分类任务的类别标签,按升序排列
- 返回
类别标签副本;回归任务返回 null
- task() → TreeTask¶
构造时指定的任务类型
- 返回
CLASSIFICATION 或 REGRESSION
- oobScore() → double¶
袋外评估分数
回归为袋外预测的决定系数 1 - SSE/SST,分类为袋外多数投票的准确率。只用对该行未被抽中的树参与计算。
注意
启用 oob 但尚未拟合时返回 NaN,因为分数初值为 NaN
- 返回
OOB 分数;无可用袋外样本或 SST 为 0 时为 NaN
- 抛出
IllegalStateException – 构建时未启用 oob
- featureImportances() → double[]¶
森林级特征重要性,总和为 1
先对各树已归一化的重要性求平均,再对平均值整体归一化。单叶树的重要性全为 0,因此对结果没有贡献。
- 返回
长度为特征数的数组,总和为 1
- 抛出
IllegalStateException – 尚未拟合
- treeCount() → int¶
已拟合的树数
- 返回
树数;未拟合为 0
- writeState(ModelWriter writer)¶
写出任务、类别与逐棵树的状态
写入任务序号、特征数、类别数(回归写 0)与类别标签、树数,随后逐棵调用 DecisionTree.writeState。超参数与 OOB 配置不落盘。
- 参数
writer (ModelWriter) – 目标二进制写入器
- 抛出
IllegalStateException – 尚未拟合
- readState(ModelReader reader) → RandomForeststatic¶
从二进制流重建森林
注意
重建后 OOB 关闭,oobScore() 会抛 IllegalStateException
注意
重建后的特征重要性全为 0
- 参数
reader (ModelReader) – 已定位到本对象载荷起点的读取器
- 返回
新的 RandomForest 实例,已完成树拼接
- 抛出
ModelFormatException – 任务序号越界、分类森林缺少类别标签,或树数不在 [1, 100000]
- kind() → ModelKind¶
持久化类型标识
- 返回
ModelKind.RANDOM_FOREST
- write(ModelWriter writer)¶
按 Persistable 契约写模型
注意
实现为直接调用 writeState
- 参数
writer (ModelWriter) – 目标二进制写入器
- final class RandomizedSearchCV implements Estimator¶
按参数分布随机采样并交叉验证选优
fit 先按 cv 折数与 stratified 开关切分数据(打乱开启,种子取 seed),再用同一个 Random(seed) 为每次迭代从各参数分布各采一个值。每折都通过工厂新建估计器、拟合并预测,按 scoring 计算该折分数。
每次迭代记录参数、折分数均值与总体标准差(除以折数),存为 CandidateResult;均值严格更大才替换当前最优,因此并列时保留先出现的参数组。全部迭代结束后用最优参数在全量数据上重新拟合,作为最终模型。
参数分布由构建器的 paramChoices、paramUniform、paramLogUniform、paramIntRange 登记,采样在 fit 内按登记顺序进行,顺序固定使同一 seed 可复现。
示例Matrix x = Matrix.fromRows(new double[][]{ {0.0, 1.0}, {1.0, 1.0}, {1.0, 0.0}, {2.0, 0.0}, {2.0, 1.0}, {3.0, 0.0}, {3.0, 1.0}, {4.0, 0.0}}); double[] y = {0.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0, 0.0}; RandomizedSearchCV search = RandomizedSearchCV .builder(params -> Ridge.builder() .alpha((Double) params.get("alpha")).build()) .paramLogUniform("alpha", 1e-3, 10.0) .nIter(20) .cv(4) .scoring(basalt.ml.Estimators.Metric.R2) .seed(7L) .build() .fit(x, y); double[] predictions = search.predict(x); Map<String, Object> best = search.bestParams(); double score = search.bestScore();注意
默认 nIter=10、cv=5、scoring=ACCURACY、stratified=false、seed=42
注意
RMSE 以负值参与比较,使所有指标都按越大越好处理
注意
每次迭代每折都新建估计器,总拟合次数为 nIter × cv 再加一次全量拟合
注意
cvResults 只保存参数与分数,不保存各折模型
参见:basalt.ml.GridSearchCV, basalt.ml.StratifiedKFold, basalt.ml.DataSplit
方法
- builder(Function<Map<String, Object>, Estimator> estimatorFactory) → Builderstatic¶
指定估计器工厂并创建构建器
- 参数
estimatorFactory (Function<Map<String, Object>, Estimator>) – 把一组参数映射构造成未拟合估计器
- 返回
新的 Builder,字段取默认值
- 抛出
NullPointerException – estimatorFactory 为 null
- fit(Matrix features, double[] targets) → RandomizedSearchCV¶
随机采样、逐折评估后全量重拟合
每次迭代先采样一组参数,再在全部折上分别新建估计器、拟合、预测并评分;记录均值与标准差后与当前最优比较,最后用最优参数在全量数据上重拟合。
注意
同一 seed 下折划分与采样序列都可复现
- 参数
features (Matrix) – 训练特征矩阵,行数为样本数
targets (double[]) – 训练目标数组,长度须等于行数
- 返回
this,bestEstimator 已在全量数据上拟合
- 抛出
NullPointerException – features 或 targets 为 null
IllegalArgumentException – 目标数量与行数不符、含非有限值,或折数超出 [2, 行数]
- predict(Matrix features) → double[]¶
用最优参数的模型预测
- 参数
features (Matrix) – 待预测特征矩阵
- 返回
长度等于行数的预测数组
- 抛出
IllegalStateException – 尚未 fit
IllegalArgumentException – 列数不匹配或含非有限值
- bestEstimator() → Estimator¶
全量数据上重拟合的最优模型
- 返回
已拟合的估计器
- 抛出
IllegalStateException – 尚未 fit
- bestParams() → Map<String, Object>¶
最优参数组
- 返回
不可修改的参数映射,键为登记的参数名
- 抛出
IllegalStateException – 尚未 fit
- bestScore() → double¶
最优交叉验证均分
- 返回
折分数均值;scoring 为 RMSE 时取负值
- 抛出
IllegalStateException – 尚未 fit
- cvResults() → List<GridSearchCV.CandidateResult>¶
逐次迭代的评估记录
注意
尚未 fit 时返回空列表,不抛异常
- 返回
按迭代顺序排列的不可修改列表,元素为 GridSearchCV.CandidateResult
- final class Ridge implements Estimator, Persistable¶
Cholesky 求解的 L2 正则最小二乘。
fitIntercept 为 true 时先计算特征均值与目标均值,在中心化后的数据上累加 Gram 矩阵与右端项,对 Gram 对角线加 alpha 后用 Cholesky 分解解正规方程,最后用均值反推截距;为 false 时不中心化,直接对原始矩阵求解。
alpha 加在按行求和的 Gram 尺度上(未除以样本数),与按均方误差定义的 alpha 相差 n 倍。分解时对角元取 max(sum, 1e-12) 作为抖动,避免半正定退化导致 NaN。
示例Matrix x = Matrix.fromRows(new double[][]{{0, 0}, {0, 1}, {1, 0}, {1, 1}}); double[] y = {0.0, 1.0, 1.0, 2.0}; Ridge ridge = Ridge.builder() .alpha(0.5) .fitIntercept(true) .build() .fit(x, y); double[] coefficients = ridge.weights(); double bias = ridge.intercept(); double[] predictions = ridge.predict(x);注意
样本数不少于 512、特征数不少于 4 且原生内核可用时走 Rust 路径,调用失败则回退到纯 Java 实现
注意
原生路径的线程数取可用处理器数
注意
alpha 必须严格为正,0 会在 build() 时被拒绝
注意
训练与预测都是单次批量运算,不迭代
参见:basalt.ml.Lasso, basalt.ml.LinearRegression, basalt.ml.Ridge.Builder
方法
- builder() → Builderstatic¶
创建构建器,默认 alpha=1.0、拟合截距。
- 返回
新的 Builder,字段取默认值
- fit(Matrix features, double[] targets) → Ridge¶
组装正规方程并用 Cholesky 求解。
Gram 矩阵只累加上三角再对称填充,随后逐行加 alpha;Cholesky 得到下三角因子后先前代再回代,得到系数向量。
注意
纯 Java 路径的代价为 O(n·d²) 时间与 O(d²) 额外内存
注意
原生路径失败时静默回退,不抛异常
- 参数
features (Matrix) – 训练特征矩阵,n 行 d 列
targets (double[]) – 训练目标数组,长度等于 n
- 返回
this
- 抛出
NullPointerException – features 或 targets 为 null
IllegalArgumentException – 行数与目标长度不符,或数据含 NaN/无穷
- predict(Matrix features) → double[]¶
计算截距与系数的点积。
注意
逐行调用 VectorMath.dot,不做批量矩阵乘
- 参数
features (Matrix) – 待预测特征矩阵,列数须等于训练特征数
- 返回
长度等于行数的连续预测值
- 抛出
IllegalStateException – 尚未 fit
IllegalArgumentException – 列数不匹配或含非有限值
- weights() → double[]¶
返回回归系数副本。
- 返回
长度为特征数的系数副本
- 抛出
NullPointerException – 尚未 fit,内部数组为 null
- intercept() → double¶
返回截距项。
注意
截距不参与正则化,由 targetMean 减去各特征均值与系数的乘积得到
- 返回
标量截距;未 fit 或 fitIntercept 为 false 时为 0.0
- kind() → ModelKind¶
模型族标识
- 返回
固定为 ModelKind.RIDGE
- write(ModelWriter writer)¶
写出超参数、截距与系数
依次写 alpha、fitIntercept 标志字节、特征数、截距与系数数组,不写训练数据。
注意
字段顺序须与 read 严格对应,否则校验和通过但字段整体错位
- 参数
writer (ModelWriter) – 目标二进制写入器
- 抛出
IllegalStateException – 尚未 fit
- read(ModelReader reader) → Ridgestatic¶
按写入顺序重建线性模型
- 参数
reader (ModelReader) – 定位在负载起始处的读取器
- 返回
可直接 predict 的 Ridge 实例,alpha 与 fitIntercept 一并恢复
- 抛出
ModelFormatException – 特征数 ≤ 0 或负载截断
- final class SVC implements Estimator, Persistable¶
SMO 求解的核支持向量分类器,支持 OvR 多分类与 Platt 概率校准。
fit 对整个训练集计算一次核 Gram 矩阵并整体留作支持向量集合,随后用 SMO 求解对偶问题:外层遍历样本,内层挑选使 |E_i − E_j| 最大的样本做联合更新,并以 15% 概率改取随机合作样本以跳出平台;连续 5 轮无更新或达到 maxIterations 时停止。
核由 Kernel 描述:LINEAR 为内积,RBF 为 exp(−gamma·‖x−y‖²),POLY 为 (gamma·x·y + coef0)^degree,SIGMOID 为 tanh(gamma·x·y + coef0)。c 是对偶变量上界,越小正则越强;RBF 与 POLY 的 gamma 控制单点影响半径,越大决策边界越弯曲。
开启 probability(true) 后,fit 末尾对每个二分类子问题做 Platt 校准:标签先平滑(正类 (N₊+1)/(N₊+2),负类 1/(N₋+2)),再用带阻尼的牛顿法最小化负对数似然,求出 P(y=+1|f) = 1/(1+exp(A·f+B)) 的 A、B。多分类对每个 OvR 模型各自校准,再按概率和归一化。
注意
默认 kernel 为 rbf(1.0)、c=1.0、tolerance=1e-4、maxIterations=600、seed=42、probability=false
注意
未开启 probability 时调用 predictProbability 抛 IllegalStateException;校准参数 A、B 随模型一起序列化
注意
Gram 矩阵为 n×n,内存随样本数平方增长;预测对每个样本遍历全部训练行
注意
所有训练行都保留为支持向量,不做 alpha 为零的剪枝,模型体积与训练集同阶
注意
校准在训练集决策值上拟合,样本很少或数据近似可分时 |A| 会很大,概率贴近 0/1
方法
- builder() → Builderstatic¶
创建构建器,默认 RBF 核 gamma=1.0
- 返回
新的 Builder,字段取默认值
- fit(Matrix features, double[] targets) → SVC¶
计算 Gram 矩阵并用 SMO 求解对偶问题
类别标签按升序去重;二分类只训练一个模型,多分类为每个类别训练一个 One-vs-Rest 模型,系数按 alpha·y 存储以便预测时直接加权求和。
注意
Gram 矩阵一次算完并复用,每轮迭代的更新代价为 O(n)
- 参数
features (Matrix) – 训练特征矩阵,行数为样本数
targets (double[]) – 类别标签数组,长度须等于行数
- 返回
this,已完成训练
- 抛出
NullPointerException – features 或 targets 为 null
IllegalArgumentException – 目标数量与行数不符、含非有限值,或不同类别数少于 2
- decisionFunction(Matrix features) → double[]¶
输出未校准的判别值
二分类为 Σ alpha_i·y_i·K(x_i, x) + b,符号决定类别;多分类只返回第 0 个 One-vs-Rest 模型的判别值。
注意
数值是间隔而非概率,不能直接解释为置信度
- 参数
features (Matrix) – 待评估矩阵,列数须等于训练特征数
- 返回
长度等于行数的判别值,0 为二分类的决策边界
- 抛出
IllegalStateException – 尚未 fit
IllegalArgumentException – 列数不匹配或含非有限值
- predictProbability(Matrix features) → Matrix¶
返回校准后的类别概率,形状 [n, classes.length]
- 参数
features (Matrix) – 与训练集列数一致的特征矩阵
- 返回
每行之和为 1;二分类两列依次为 P(classes[0])、P(classes[1])
- 抛出
IllegalStateException – 构建时未开启 probability(true)
- predict(Matrix features) → double[]¶
输出预测类别标签
二分类按判别值是否不小于 0 取 classes[1] 或 classes[0];多分类对每个 One-vs-Rest 模型求判别值并取最大者,并列时取下标较小者。
- 参数
features (Matrix) – 待预测矩阵,列数须等于训练特征数
- 返回
长度等于行数的类别标签
- 抛出
IllegalStateException – 尚未 fit
IllegalArgumentException – 列数不匹配或含非有限值
- kernel() → Kernel¶
构建时指定的核函数
- 返回
Kernel 实例,含类型、gamma、degree 与 coef0
- probabilityEnabled() → boolean¶
是否启用了 Platt 概率校准
- 返回
构建时传入的 probability 标志
- classes() → double[]¶
训练期的类别标签,按升序排列
- 返回
类别标签副本;尚未 fit 时为 null
- kind() → ModelKind¶
模型族标识
- 返回
固定为 ModelKind.SVC
- write(ModelWriter writer)¶
写出核参数、超参数与全部对偶系数
依次写 Kernel、c、tolerance、maxIterations、seed、特征数、类别数与类别、支持向量行数与数据、模型数、逐个模型的 alpha 与截距。
注意
支持向量集合即全部训练行,负载大小与训练集同阶
- 参数
writer (ModelWriter) – 目标二进制写入器
- 抛出
IllegalStateException – 尚未 fit
- read(ModelReader reader) → SVCstatic¶
按写入顺序重建模型
- 参数
reader (ModelReader) – 定位在负载起始处的读取器
- 返回
可直接 predict 的实例,超参数一并恢复
- 抛出
ModelFormatException – 特征数 ≤ 0、类别数 < 2 或负载截断
- final class SelectKBest implements Transformer, Estimator¶
按单变量统计量保留得分最高的 k 个特征
fit 逐列计算评分,按分数降序排列(同分取原始下标较小者),保留前 k 列,再把入选下标升序排列。transform 只做列切片,predict 返回展平结果,两者都不重新计算分数。
三种口径各有适用范围:F_CLASSIF 是单因素方差分析的 F 值 MSB/MSW,自由度为 max(1, C−1) 与 max(1, n−C),用于分类目标;F_REGRESSION 先算特征与目标的 Pearson 相关系数 r,再转成 F = r²/(1−r²)·(n−2),用于回归目标;CHI2 把特征值视为非负计数,按类别累加观测与期望频数之差的卡方和,用于非负特征配分类目标。
组内均方为 0(特征在类内完全不变)时 F_CLASSIF 记 0 分以避免除零;相关系数分母退化时 F_REGRESSION 同样记 0 分。
示例Matrix x = Matrix.fromRows(new double[][]{ {1.0, 0.1, 5.0}, {1.2, 0.2, 4.9}, {3.0, 0.1, 5.1}, {3.1, 0.3, 5.0}}); double[] y = {0.0, 0.0, 1.0, 1.0}; SelectKBest selector = SelectKBest.builder() .k(2) .scoreFunc(SelectKBest.ScoreFunc.F_CLASSIF) .build() .fit(x, y); Matrix selected = selector.transform(x); double[] scores = selector.scores(); boolean[] support = selector.getSupport();注意
k 默认 5,scoreFunc 默认 F_CLASSIF
注意
CHI2 遇到负特征值直接抛 IllegalArgumentException
注意
各列评分相互独立,不考虑特征之间的相关性
注意
写入时保存 k、口径、特征数、全部分数与入选下标,读回无需重算
参见:basalt.ml.RFE, basalt.ml.Pipeline, basalt.ml.Transformer
方法
- builder() → Builderstatic¶
创建构建器,k=5、F_CLASSIF 口径
- 返回
新的 Builder,字段取默认值
- fit(Matrix features, double[] targets) → SelectKBest¶
计算逐列评分并选出前 k 列
评分按口径分派到方差分析、相关系数转 F 或卡方三种实现;排序后取前 k 个下标并升序整理。
注意
同分时保留原始下标较小的列
- 参数
features (Matrix) – 训练特征矩阵,行数为样本数
targets (double[]) – 目标数组,长度须等于行数;分类口径下按类别标签处理
- 返回
this,已确定入选列
- 抛出
NullPointerException – features 或 targets 为 null
IllegalArgumentException – 目标数量与行数不符、含非有限值、k 超出 [1, 特征数],或 CHI2 口径下特征含负值
- transform(Matrix features) → Matrix¶
只保留入选列
- 参数
features (Matrix) – 待切片矩阵,列数须等于拟合时的特征数
- 返回
rows × k 的新矩阵,列序按原始下标升序
- 抛出
IllegalStateException – 尚未 fit
IllegalArgumentException – 列数不匹配或含非有限值
- predict(Matrix features) → double[]¶
返回切片结果的展平数组
- 参数
features (Matrix) – 待切片矩阵,列数须等于拟合时的特征数
- 返回
长度为 rows × k 的数组
- 抛出
IllegalStateException – 尚未 fit
IllegalArgumentException – 列数不匹配或含非有限值
- scores() → double[]¶
每列的评分
- 返回
长度为原始特征数的副本,顺序与原始列一致
- 抛出
IllegalStateException – 尚未 fit
- selectedIndices() → int[]¶
入选列的原始下标,升序
- 返回
长度为 k 的副本
- 抛出
IllegalStateException – 尚未 fit
- getSupport() → boolean[]¶
入选特征的布尔掩码
- 返回
长度为原始特征数的数组,true 表示保留
- 抛出
IllegalStateException – 尚未 fit
- kind() → ModelKind¶
模型族标识
- 返回
固定为 ModelKind.SELECT_K_BEST
- write(ModelWriter writer)¶
写出 k、口径、特征数、分数与入选下标
- 参数
writer (ModelWriter) – 目标二进制写入器
- 抛出
IllegalStateException – 尚未 fit
- read(ModelReader reader) → SelectKBeststatic¶
按写入顺序重建选择器
- 参数
reader (ModelReader) – 定位在负载起始处的读取器
- 返回
可直接 transform 的实例,评分与入选列已恢复
- 抛出
ModelFormatException – k ≤ 0、特征数小于 k 或口径序号越界
- final class ShapExplainer¶
计算可加的 SHAP 归因值,满足 Σφ = f(x) − E[f]
构造时用背景数据集估计基准值:对背景矩阵逐行预测后取均值作为 baseValue,同时记录每列均值供线性路径使用。背景矩阵被复制保存,之后外部修改不影响解释器。
explain 对线性模型(LinearRegression、Ridge、Lasso)走闭式 LinearSHAP:φ_j = w_j·(x_j − E[X_j]),代价 O(p)。其他模型在特征数不超过 8 时枚举全部 2^p 个联盟并用 Shapley 权重精确求值;超过 8 时改用随机排列的蒙特卡洛采样,采样次数为 maxCoalitions。
三条路径都满足局部可加性:基准值加上同一行全部归因值之和等于该行预测值。蒙特卡洛路径在每条排列的最后一个特征上直接取真实预测,因此总和不因采样而偏移。
归因对象随模型类型切换:LogisticRegression 取 predictProbability,HistogramGradientBoosting 取 predictRaw,分类 RandomForest 取第 1 列概率,其余模型直接取 predict,保证归因值解释的是实际输出。
示例Matrix x = Matrix.fromRows(new double[][]{ {0.0, 1.0}, {1.0, 1.5}, {2.0, 0.5}, {3.0, 2.0}}); double[] y = {1.0, 2.0, 2.5, 3.5}; Ridge model = Ridge.builder().alpha(0.1).build().fit(x, y); ShapExplainer explainer = new ShapExplainer(model, x, 64, 42L); ShapExplainer.Explanation explanation = explainer.explain(x); double base = explanation.baseValue(); Matrix phi = explanation.shapValues(); double[] predictions = explanation.predictions(); double[] importance = explanation.meanAbsShap();注意
maxCoalitions 默认 64、seed 默认 42,采样次数必须不小于 4
注意
特征数 ≤ 8 时精确枚举,代价为 2^p × 背景行数 次预测,p 增大时增长极快
注意
背景矩阵列数必须与待解释矩阵一致,否则 explain 抛 IllegalArgumentException
注意
基准值是背景集预测均值,不是训练集目标均值
参见:basalt.ml.Ridge, basalt.ml.RandomForest, basalt.ml.HistogramGradientBoosting
构造器
- ShapExplainer(Estimator model, Matrix background)¶
以默认采样参数构造解释器
等价于 maxCoalitions=64、seed=42 的重载,构造时即对背景集推理一次以得到基准值。
- 参数
model (Estimator) – 待解释的已拟合估计器
background (Matrix) – 背景数据集,用于估计基准值与各列均值
- 抛出
NullPointerException – model 或 background 为 null
IllegalArgumentException – 背景矩阵含 NaN 或无穷值
- ShapExplainer(Estimator model, Matrix background, int maxCoalitions, long seed)¶
指定采样次数与随机种子构造解释器
背景矩阵被复制保存,列均值与基准值在构造阶段一次算好,后续 explain 复用。
注意
背景集预测在构造时执行一次,成本为背景行数次模型调用
- 参数
model (Estimator) – 待解释的已拟合估计器
background (Matrix) – 背景数据集,列数须与待解释数据一致
maxCoalitions (int) – 蒙特卡洛路径的排列采样次数,必须不小于 4
seed (long) – 排列采样的随机种子
- 抛出
NullPointerException – model 或 background 为 null
IllegalArgumentException – 背景矩阵含 NaN 或无穷值,或 maxCoalitions < 4
方法
- baseValue() → double¶
背景集预测均值
- 返回
基准值 E[f],即背景矩阵逐行预测的算术均值
- explain(Matrix instances) → Explanation¶
逐行计算归因值
返回记录含基准值、rows × p 的归因矩阵、逐行预测值与每列的平均绝对归因值。线性模型走闭式公式,特征数 ≤ 8 走联盟枚举,否则走蒙特卡洛采样。
注意
同一行归因值之和等于该行预测值减基准值
- 参数
instances (Matrix) – 待解释矩阵,列数须等于背景矩阵列数
- 返回
Explanation 记录,含 baseValue、shapValues、predictions 与 meanAbsShap
- 抛出
NullPointerException – instances 为 null
IllegalArgumentException – 列数与背景矩阵不一致或含非有限值
- final class SimpleImputer implements Transformer, Estimator¶
用列统计量填补 NaN 缺失值
fit 逐列收集非 NaN 值并按 strategy 求填充值:MEAN 为算术均值,MEDIAN 为排序后取中位(偶数个取中间两值均值),MOST_FREQUENT 取出现次数最多的值(并列时取数值较小者),CONSTANT 直接使用 fillValue。统计量按列数固定,与后续样本无关。
transform 只替换 NaN,其他值原样保留,不会重新估计统计量;因此训练期与推理期对同一缺失位置使用同一常量。缺失的唯一标记是 NaN,无穷值被视为非法数据而非缺失。
非 CONSTANT 策略下某列全为 NaN 时没有可估计的统计量,fit 直接拒绝;CONSTANT 策略不受此限制,因为填充值由参数给出。
示例Matrix x = Matrix.fromRows(new double[][]{ {1.0, Double.NaN}, {2.0, 3.0}, {Double.NaN, 4.0}, {4.0, 5.0}}); SimpleImputer imputer = SimpleImputer.builder() .strategy(SimpleImputer.Strategy.MEDIAN) .build() .fit(x); Matrix filled = imputer.transform(x); double[] statistics = imputer.statistics();注意
strategy 默认 MEAN、fillValue 默认 0.0,fillValue 必须有限
注意
transform 要求列数与 fit 时一致,不会自动补齐或截断
注意
统计量随模型落盘,读回后可直接 transform,无需原始训练数据
注意
无穷值在 fit 与 transform 中都会抛 IllegalArgumentException
参见:basalt.ml.StandardScaler, basalt.ml.Pipeline, basalt.ml.Transformer
方法
- builder() → Builderstatic¶
创建构建器,MEAN 策略、填充值 0.0
- 返回
新的 Builder,字段取默认值
- fit(Matrix features) → SimpleImputer¶
估计每列填充值,忽略目标值
注意
该重载内部以 targets=null 调用双参版本
- 参数
features (Matrix) – 训练特征矩阵,NaN 视为缺失
- 返回
this
- 抛出
NullPointerException – features 为 null
IllegalArgumentException – 含无穷值,或非 CONSTANT 策略下某列全为 NaN
- fit(Matrix features, double[] ignoredTargets) → SimpleImputer¶
估计每列填充值
逐列扫描非 NaN 值并按键 strategy 求统计量;CONSTANT 策略直接写入 fillValue。
注意
MOST_FREQUENT 并列时取数值较小者,因为按升序遍历频次表
- 参数
features (Matrix) – 训练特征矩阵,NaN 视为缺失
ignoredTargets (double[]) – 被忽略,可为 null
- 返回
this
- 抛出
NullPointerException – features 为 null
IllegalArgumentException – 含无穷值,或非 CONSTANT 策略下某列全为 NaN
- transform(Matrix features) → Matrix¶
用列统计量替换 NaN
- 参数
features (Matrix) – 待填补矩阵,列数须等于拟合时的列数
- 返回
同形状的新矩阵,NaN 位置换成对应列统计量
- 抛出
IllegalStateException – 尚未 fit
IllegalArgumentException – 列数不匹配或含无穷值
- predict(Matrix features) → double[]¶
返回填补结果的展平数组
- 参数
features (Matrix) – 待填补矩阵,列数须等于拟合时的列数
- 返回
长度为 rows × 列数的数组
- 抛出
IllegalStateException – 尚未 fit
IllegalArgumentException – 列数不匹配或含无穷值
- statistics() → double[]¶
每列的填充值
- 返回
长度为列数的副本,顺序与列一致
- 抛出
IllegalStateException – 尚未 fit
- strategy() → Strategy¶
构建时指定的填补策略
- 返回
MEAN、MEDIAN、MOST_FREQUENT 或 CONSTANT
- kind() → ModelKind¶
模型族标识
- 返回
固定为 ModelKind.SIMPLE_IMPUTER
- write(ModelWriter writer)¶
写出策略、填充值、列数与统计量
- 参数
writer (ModelWriter) – 目标二进制写入器
- 抛出
IllegalStateException – 尚未 fit
- read(ModelReader reader) → SimpleImputerstatic¶
按写入顺序重建填补器
- 参数
reader (ModelReader) – 定位在负载起始处的读取器
- 返回
可直接 transform 的实例
- 抛出
ModelFormatException – 策略序号越界或列数 ≤ 0
- final class StandardScaler implements Transformer, Estimator¶
按列去均值并缩放到单位方差
fit 逐列计算均值与总体方差(除以样本数,ddof=0),scale 取标准差;withStd 为 false 或标准差不超过 1e-12 时 scale 固定为 1.0,避免常量列除零。samplesSeen 记录参与统计的行数。
transform 按 z = (x − mean)/scale 逐元素计算,withMean 与 withStd 分别控制是否减均值、是否除标准差;inverseTransform 先乘 scale 再加 mean,两者互为逆运算。
拟合参数只在 fit 时估计,transform 与 inverseTransform 都不更新统计量;对训练时未出现的取值直接做线性映射,不裁剪也不截断,因此超出训练范围的值会产生绝对值更大的 z。
示例Matrix x = Matrix.fromRows(new double[][]{ {1.0, 10.0}, {2.0, 20.0}, {3.0, 30.0}, {4.0, 40.0}}); StandardScaler scaler = StandardScaler.builder() .withMean(true) .withStd(true) .build() .fit(x); Matrix z = scaler.transform(x); Matrix restored = scaler.inverseTransform(z); double[] mean = scaler.mean(); double[] scale = scaler.scale();注意
withMean 与 withStd 默认都为 true
注意
方差为总体方差,与样本方差相差 n/(n−1) 的系数
注意
常量列的 scale 为 1.0,该列变换后整体平移为零
注意
均值、缩放因子与方差随模型落盘,读回即可复现同一映射
参见:basalt.ml.MinMaxScaler, basalt.ml.SimpleImputer, basalt.ml.Pipeline
方法
- builder() → Builderstatic¶
创建构建器,减均值且除标准差
- 返回
新的 Builder,withMean 与 withStd 均为 true
- fit(Matrix features) → StandardScaler¶
估计每列均值与标准差
- 参数
features (Matrix) – 训练特征矩阵,行数为样本数
- 返回
this
- 抛出
NullPointerException – features 为 null
IllegalArgumentException – 特征含 NaN 或无穷值
- fit(Matrix features, double[] ignoredTargets) → StandardScaler¶
估计每列均值与标准差,忽略目标值
先累加求均值,再在中心化基础上累加平方和得到总体方差,最后取平方根作为 scale。
注意
两次遍历全矩阵,时间 O(n·d)、额外空间 O(d)
- 参数
features (Matrix) – 训练特征矩阵,行数为样本数
ignoredTargets (double[]) – 被忽略,可为 null
- 返回
this
- 抛出
NullPointerException – features 为 null
IllegalArgumentException – 特征含 NaN 或无穷值
- transform(Matrix features) → Matrix¶
按列标准化
- 参数
features (Matrix) – 待变换矩阵,列数须等于拟合时的列数
- 返回
同形状的新矩阵
- 抛出
IllegalStateException – 尚未 fit
IllegalArgumentException – 列数不匹配或含非有限值
- inverseTransform(Matrix transformed) → Matrix¶
还原到原始尺度
- 参数
transformed (Matrix) – 已标准化矩阵,列数须等于拟合时的列数
- 返回
同形状的新矩阵,与 transform 互为逆运算
- 抛出
IllegalStateException – 尚未 fit
IllegalArgumentException – 列数不匹配或含非有限值
- predict(Matrix features) → double[]¶
返回标准化结果的展平数组
- 参数
features (Matrix) – 待变换矩阵,列数须等于拟合时的列数
- 返回
长度为 rows × 列数的数组
- 抛出
IllegalStateException – 尚未 fit
IllegalArgumentException – 列数不匹配或含非有限值
- mean() → double[]¶
每列均值
- 返回
长度为列数的副本
- 抛出
IllegalStateException – 尚未 fit
- scale() → double[]¶
每列缩放因子
- 返回
长度为列数的副本;未启用 withStd 或标准差过小时为 1.0
- 抛出
IllegalStateException – 尚未 fit
- variance() → double[]¶
每列总体方差
- 返回
长度为列数的副本,除以样本数而非样本数减一
- 抛出
IllegalStateException – 尚未 fit
- samplesSeen() → int¶
参与统计的样本数
- 返回
fit 时的行数;尚未 fit 时为 0
- withMean() → boolean¶
是否减去均值
- 返回
构建时指定的开关
- withStd() → boolean¶
是否除以标准差
- 返回
构建时指定的开关
- kind() → ModelKind¶
模型族标识
- 返回
固定为 ModelKind.STANDARD_SCALER
- write(ModelWriter writer)¶
写出开关、列数、样本数与三个数组
依次写 withMean、withStd 两个标志字节,列数、样本数,随后写均值、缩放因子与方差。
- 参数
writer (ModelWriter) – 目标二进制写入器
- 抛出
IllegalStateException – 尚未 fit
- read(ModelReader reader) → StandardScalerstatic¶
按写入顺序重建缩放器
- 参数
reader (ModelReader) – 定位在负载起始处的读取器
- 返回
可直接 transform 的实例,三个数组均已恢复
- 抛出
ModelFormatException – 列数或样本数 ≤ 0
- final class StratifiedKFold¶
保持类别比例的分层 K 折划分器
split 按目标值把行号分组,组内可选打乱(种子取 seed),再用跨类别连续累加的轮转计数器把行号依次放入各折,使每折的类别比例接近整体;某一类的样本数少于折数时无法分层,直接拒绝。
返回的每个 Fold 含训练与测试两部分的特征矩阵与目标数组,训练部分由其余折按折序拼接,行序与原始数据不同。划分只读取目标值,不拟合任何模型。
示例Matrix x = Matrix.fromRows(new double[][]{ {0.0, 0.0}, {0.2, 0.1}, {1.0, 1.0}, {1.1, 0.9}, {2.0, 2.0}, {2.2, 1.8}}); double[] y = {0.0, 0.0, 1.0, 1.0, 2.0, 2.0}; StratifiedKFold cv = new StratifiedKFold(3, true, 42L); List<DataSplit.Fold> folds = cv.split(x, y); DataSplit.Fold first = folds.get(0); Matrix trainX = first.trainFeatures(); double[] testY = first.testTargets();注意
folds 必须不小于 2,split 时还要求不超过样本数
注意
单参构造等价于 shuffle=true、seed=42
注意
轮转计数器跨类别累加,分层是近似的:各类样本数不能整除折数时每折数量会差 1
注意
种子固定时同一实例多次 split 结果相同
参见:basalt.ml.DataSplit, basalt.ml.GridSearchCV, basalt.ml.RandomizedSearchCV
构造器
- StratifiedKFold(int folds)¶
使用默认打乱与种子构造划分器
注意
等价于 shuffle=true、seed=42
- 参数
folds (int) – 折数,必须不小于 2
- 抛出
IllegalArgumentException – folds < 2
- StratifiedKFold(int folds, boolean shuffle, long seed)¶
指定折数、打乱开关与种子
- 参数
folds (int) – 折数,必须不小于 2
shuffle (boolean) – 是否在分折前打乱每个类别内部的行序
seed (long) – 打乱使用的随机种子
- 抛出
IllegalArgumentException – folds < 2
方法
- folds() → int¶
折数
- 返回
构造时指定的折数
- shuffle() → boolean¶
是否在划分前打乱
- 返回
构造时指定的开关
- split(Matrix features, double[] targets) → List<DataSplit.Fold>¶
执行分层划分
按类别分组后轮转分配到各折,再以其余折拼接训练集。
- 参数
features (Matrix) – 特征矩阵,行数为样本数
targets (double[]) – 类别标签数组,长度须等于行数
- 返回
长度为 folds 的 Fold 列表,顺序与折号一致
- 抛出
NullPointerException – features 或 targets 为 null
IllegalArgumentException – 目标数量与行数不符、含非有限值、folds 超出 [2, 行数],或某类样本数少于折数
- interface Transformer extends Persistable¶
有状态特征预处理与特征工程步骤的统一契约
实现类在 fit 阶段从数据中学出统计量(均值、尺度、类别词表、缺失填充常数、分桶边界、被选中的特征掩码),在 transform 阶段用这些统计量改写特征矩阵。继承 Persistable 使统计量可以单独写入 .bsl 容器,也可以随 Pipeline 一起序列化,从而保证训练与线上推理的行为逐位一致。
fit(Matrix) 等价于 fit(features, null);fitTransform 先把特征交给 fit,再对同一批数据执行 transform,省去一次显式调用。inverseTransform 的默认实现直接抛 BasaltUnsupportedOperationException,只有映射可逆的变换(MinMaxScaler、LabelEncoder、特征选择等)才覆盖它。
示例MinMaxScaler scaler = MinMaxScaler.builder() .featureRange(0.0, 1.0) .build(); Matrix scaled = scaler.fitTransform(features); Matrix restored = scaler.inverseTransform(scaled);注意
fit 的实现必须返回自身或等价实例,默认的 fit(Matrix) 正是把返回值继续传给 fit(Matrix, double[])
注意
transform 不修改入参,返回新的 Matrix;列数由 fit 阶段记录的特征决定
注意
无监督变换忽略 targets,只有目标编码一类步骤会真正读取它
参见:basalt.ml.Pipeline, basalt.core.Persistable, basalt.core.Matrix
- enum TreeTask¶
单棵决策树的监督目标:分类或回归
CLASSIFICATION 用类别计数与 GINI 或 ENTROPY 评估分裂,叶值为多数类标签;REGRESSION 用和与平方和计算方差下降,叶值为均值。任务同时决定 fit 的编码方式、predict 的输出语义以及 Builder 对准则的校验。
示例DecisionTree regressor = DecisionTree.builder() .task(TreeTask.REGRESSION) .maxDepth(6) .build(); TreeTask task = regressor.task();注意
task 与 criterion 必须匹配,否则 DecisionTree.Builder.build() 抛 IllegalArgumentException
注意
RandomForest 与 DecisionTree 都把任务作为构造期常量,拟合后不可更改
参见:basalt.ml.DecisionTree, basalt.ml.ImpurityCriterion, basalt.ml.RandomForest
枚举成员
- CLASSIFICATION()¶
分类树,叶子输出类别或类分布
- REGRESSION()¶
回归树,叶子输出均值
- static final class AgglomerativeClustering.Builder¶
AgglomerativeClustering 的构建器。
只有两个参数:目标簇数 clusters 与连接准则 linkage,默认 2 与 WARD。clusters 在 setter 内立即校验为正,linkage 只做非空检查,build 直接返回未拟合实例,不再重复校验。
两个参数都可省略,AgglomerativeClustering.builder() 返回的构建器已带默认值,因此最简用法是 build 后直接 fit。
示例AgglomerativeClustering model = AgglomerativeClustering.builder() .clusters(3) .linkage(AgglomerativeClustering.Linkage.AVERAGE) .build(); model.fit(features); int[] labels = model.labels();注意
必填项:无;clusters 与 linkage 都有默认值
注意
fit 阶段会另外校验 clusters 不超过样本数,该约束不在 build 时检查
注意
链接准则决定合并代价的计算方式,选择前建议先做特征标准化
参见:basalt.ml.AgglomerativeClustering, basalt.ml.AgglomerativeClustering.Linkage
方法
- clusters(int clusters) → Builder¶
设置目标簇数,默认 2。
注意
此处即完成校验,非法值不会传播到 build
- 参数
clusters (int) – 期望保留的簇数,须为正;默认 2
- 返回
this,便于链式调用
- 抛出
IllegalArgumentException – clusters 小于等于 0
- linkage(Linkage linkage) → Builder¶
设置簇间连接准则,默认 WARD。
- 参数
linkage (Linkage) – Linkage 常量之一:WARD、COMPLETE、AVERAGE 或 SINGLE,非 null
- 返回
this,便于链式调用
- 抛出
NullPointerException – linkage 为 null
- build() → AgglomerativeClustering¶
用当前配置创建未拟合的聚类器。
注意
build 本身不校验,clusters 大于样本数的问题要等 fit 才抛出 IllegalArgumentException
- 返回
持有 clusters 与 linkage 的 AgglomerativeClustering 实例
- enum AgglomerativeClustering.Linkage¶
层次聚类的簇间连接准则
WARD 以两组样本数加权后的均值平方距离 (ni*nj/(ni+nj))*||mi-mj||^2 作为合并代价,倾向得到大小均衡的球状簇;SINGLE、COMPLETE、AVERAGE 直接以样本间距为依据,合并后分别取两组距离的最小、最大与按样本数加权平均。
四种准则都走同一套自底向上的贪心流程:每轮选出代价最小的一对活跃簇合并,直到活跃簇数降到 clusters。簇编号按活跃簇的成员下标顺序从 0 递增,predict 对非训练样本按最近的簇均值分配。
示例AgglomerativeClustering model = AgglomerativeClustering.builder() .clusters(4) .linkage(AgglomerativeClustering.Linkage.SINGLE) .build(); AgglomerativeClustering.Linkage used = model.linkage();注意
SINGLE 对噪声敏感,容易拉出长链状簇;WARD 与 AVERAGE 更稳健但要求特征量纲一致
注意
距离固定为欧氏距离,没有可切换的度量参数
注意
该常量决定构建器的默认值(WARD),拟合后不可更改
参见:basalt.ml.AgglomerativeClustering, basalt.ml.AgglomerativeClustering.Builder
枚举成员
- WARD()¶
最小化合并带来的簇内平方和增量
- COMPLETE()¶
取两簇间最远点距离
- AVERAGE()¶
取两簇间所有点对距离的均值
- SINGLE()¶
取两簇间最近点距离
- static final class DBSCAN.Builder¶
DBSCAN 的构建器,设置邻域半径、密度阈值与距离度量。
未显式设置时使用 eps = 0.5、minPoints = 5、DistanceMetric.EUCLIDEAN。各 setter 只赋值,参数校验集中在 build 中完成。
注意
eps 的单位与特征单位相同,特征未标准化时不同量纲的列会主导邻域判定
方法
- eps(double eps) → Builder¶
设置邻域半径 eps。
- 参数
eps (double) – 邻域半径,须为正且有限;默认 0.5
- 返回
this,便于链式调用
- minPoints(int minPoints) → Builder¶
设置核心点的最小邻域样本数。
- 参数
minPoints (int) – 阈值,须为正;默认 5,统计时包含点自身
- 返回
this,便于链式调用
- metric(DistanceMetric metric) → Builder¶
设置邻域查询与预测所用的距离度量。
- 参数
metric (DistanceMetric) – 距离函数,默认 DistanceMetric.EUCLIDEAN
- 返回
this,便于链式调用
- 抛出
NullPointerException – metric 为 null
- build() → DBSCAN¶
校验参数并创建 DBSCAN 实例。
- 返回
新的 DBSCAN 实例,尚未拟合
- 抛出
IllegalArgumentException – eps 非正或非有限,或 minPoints 非正
- record DataSplit.Fold¶
一折的训练与测试四元组。
record 组件依次为 trainFeatures、trainTargets、testFeatures、testTargets,全部由 DataSplit.kFold 新建,与输入数据不共享存储。
测试块是洗牌顺序上的连续区间,训练块由其余区间按同一顺序拼接,因此训练集与测试集内部的行序都是洗牌后的顺序,而不是原始顺序。
注意
记录本身不可变,但持有的 Matrix 内容仍可被修改
注意
各折测试块互不重叠,并集覆盖全部行
参见:
basalt.ml.DataSplit.kFold(Matrix, double[], int, long)
- record DataSplit.Holdout¶
一次 holdout 划分的四元组。
record 组件依次为 trainFeatures、trainTargets、testFeatures、testTargets,由 DataSplit.holdout 生成,四个字段都是独立副本。
测试集行数被夹到 [1, rows-1],两侧都保证非空,因此可以直接把四个组件交给 fit 与 predict,无需再判断边界。
注意
记录本身不可变,但持有的 Matrix 内容仍可被修改
注意
划分结果只由 seed 与输入行数决定,与标签分布无关
参见:
basalt.ml.DataSplit.holdout(Matrix, double[], double, long)
- static final class DecisionTree.Builder¶
DecisionTree 的流式构造器
默认值为 maxDepth 8、minSamplesSplit 2、minSamplesLeaf 1、criterion GINI、task CLASSIFICATION、maxFeatures 0(全部特征)、bins 64、seed 42。所有 setter 返回 this,build() 统一校验并返回未拟合的估计器。
criterion 一旦被显式设置就锁定,之后调用 task() 不会改写它;未显式设置时,task(REGRESSION) 自动切到 MSE,task(CLASSIFICATION) 自动切到 GINI。
示例DecisionTree tree = DecisionTree.builder() .task(TreeTask.REGRESSION) .maxDepth(5) .minSamplesSplit(4) .minSamplesLeaf(2) .maxFeatures(2) .bins(32) .seed(11L) .build();注意
maxDepth 为 0 表示根节点即叶,可用于得到常数模型
注意
minSamplesSplit 的下限是 2,低于该值在 build() 时被拒绝
参见:basalt.ml.DecisionTree, basalt.ml.ImpurityCriterion, basalt.ml.TreeTask
方法
- maxDepth(int maxDepth) → Builder¶
设置树的最大深度,默认 8
注意
深度从 0 起计,节点深度达到该值即停止分裂
- 参数
maxDepth (int) – 最大深度,须不小于 0;0 表示根节点直接成为叶
- 返回
this
- minSamplesSplit(int minSamplesSplit) → Builder¶
设置允许分裂的最小节点样本数,默认 2
- 参数
minSamplesSplit (int) – 节点样本数低于该值即转为叶,须不小于 2
- 返回
this
- minSamplesLeaf(int minSamplesLeaf) → Builder¶
设置每个子节点最少样本数,默认 1
注意
同时约束 fit 的入口:总样本数小于该值直接抛 IllegalArgumentException
- 参数
minSamplesLeaf (int) – 分裂后左右两侧各自的最小样本数,须不小于 1
- 返回
this
- criterion(ImpurityCriterion criterion) → Builder¶
设置不纯度准则,默认 GINI
注意
调用后标记为显式设置,后续 task() 不再覆盖该准则
- 参数
criterion (ImpurityCriterion) – 准则常量,非 null;其 task() 必须与最终 task 一致
- 返回
this
- 抛出
NullPointerException – criterion 为 null
- task(TreeTask task) → Builder¶
设置任务类型,默认 CLASSIFICATION
注意
未显式设置 criterion 时,同步切换为 MSE 或 GINI
- 参数
task (TreeTask) – CLASSIFICATION 或 REGRESSION,非 null
- 返回
this
- 抛出
NullPointerException – task 为 null
- maxFeatures(int maxFeatures) → Builder¶
设置每次分裂的候选特征数,默认 0
注意
小于特征数时,每个节点用部分洗牌抽取子集,随机源为 seed
- 参数
maxFeatures (int) – 候选特征数;0 表示使用全部特征,大于特征数时按特征数截断
- 返回
this
- bins(int maxBins) → Builder¶
设置单特征最大桶数,默认 64
- 参数
maxBins (int) – 桶数上限,取值 [2, 255]
- 返回
this
- seed(long seed) → Builder¶
设置特征子采样的随机种子,默认 42
注意
行选择不受该种子影响,fit 固定使用全部行
- 参数
seed (long) – 随机种子;仅影响 maxFeatures 的特征抽取
- 返回
this
- build() → DecisionTree¶
校验配置并创建估计器
- 返回
配置好的 DecisionTree,尚未拟合
- 抛出
IllegalArgumentException – maxDepth 小于 0、minSamplesSplit 小于 2、minSamplesLeaf 小于 1、maxFeatures 小于 0、bins 越界,或准则与任务不匹配
- enum Estimators.Algorithm¶
门面可选算法及其任务类型。
每个常量在构造时绑定一个 Task,门面据此判断是否需要 targets,并在交叉验证时拒绝无监督算法。常量覆盖分类 8 个、回归 5 个、无监督 3 个。
RANDOM_FOREST 与 RANDOM_FOREST_REGRESSOR 共用 RandomForest 实现,靠 task 切换回归模式;两个梯度提升常量分别绑定 LOGISTIC 与 SQUARED_ERROR 目标。
注意
枚举常量名即门面的算法名,重命名会破坏调用方编译
注意
task() 是唯一的实例方法,无参无副作用
参见:basalt.ml.Estimators.Task, basalt.ml.Estimators
枚举成员
- LINEAR_REGRESSION()¶
普通最小二乘线性回归,回归任务。
注意
对应 LinearRegression 的默认配置:lr=0.05、2000 轮
- LOGISTIC_REGRESSION()¶
二分类逻辑回归,分类任务。
注意
标签必须是 0/1,否则 fit 抛 IllegalArgumentException
- RIDGE()¶
L2 正则最小二乘,回归任务。
注意
对应 alpha=1.0 的默认配置
- LASSO()¶
L1 正则最小二乘,回归任务。
注意
对应 alpha=0.1、1000 轮坐标下降的默认配置
- KNN()¶
KNN 分类,分类任务。
注意
固定 k=5、欧氏距离
- KNN_REGRESSOR()¶
KNN 回归,回归任务。
注意
固定 k=5、欧氏距离,预测为邻居目标的均值
- DECISION_TREE()¶
单棵决策树分类,分类任务。
- RANDOM_FOREST()¶
随机森林分类,分类任务。
- RANDOM_FOREST_REGRESSOR()¶
随机森林回归,回归任务。
注意
复用 RandomForest 实现,通过 task(REGRESSION) 切换
- GRADIENT_BOOSTING()¶
直方图梯度提升分类,分类任务。
注意
绑定 LOGISTIC 目标
- GRADIENT_BOOSTING_REGRESSOR()¶
直方图梯度提升回归,回归任务。
注意
绑定 SQUARED_ERROR 目标
- GAUSSIAN_NAIVE_BAYES()¶
高斯朴素贝叶斯分类,分类任务。
- LINEAR_SVM()¶
PEGASOS 线性 SVM,分类任务。
注意
要求标签恰好两类,内部映射为 ±1
- SVC()¶
核支持向量分类,分类任务。
注意
基于 SMO 求解,支持 LINEAR、RBF、POLY、SIGMOID 核与 One-vs-Rest 多分类
注意
门面使用默认配置:rbf(1.0) 核、C=1.0、600 轮上限
- KERNEL_RIDGE()¶
核岭回归,回归任务。
注意
对偶方程 (K + alpha·I) 用 Cholesky 分解求解
注意
门面使用默认配置:rbf(1.0) 核、alpha=1.0
- KMEANS()¶
K 均值聚类,无监督任务。
注意
fit 忽略 targets,交叉验证会拒绝该算法
- PCA()¶
主成分分析,无监督任务。
注意
fit 只接收特征矩阵
- KERNEL_PCA()¶
核主成分分析,无监督任务。
注意
默认降维到 2 个主成分、rbf(1.0) 核
注意
fit 只接收特征矩阵,transform 输出降维后的张量
- DBSCAN()¶
密度聚类,无监督任务。
注意
门面以 null targets 调用 fit
- GAUSSIAN_MIXTURE()¶
高斯混合模型聚类,无监督任务。
注意
EM 迭代配 K-Means++ 初始化,默认 2 个分量与对角协方差
注意
predict 返回后验概率最大的分量下标
- AGGLOMERATIVE_CLUSTERING()¶
层次凝聚聚类,无监督任务。
注意
默认 2 个簇、WARD 连接准则
注意
连接准则支持 WARD、COMPLETE、AVERAGE、SINGLE
- ISOLATION_FOREST()¶
隔离森林异常检测,无监督任务。
注意
predict 返回 +1 表示正常、-1 表示异常
注意
门面使用默认配置:100 棵树、maxSamples=256、contamination=0.1
- KERNEL_DENSITY()¶
核密度估计,无监督任务。
注意
默认 GAUSSIAN 核、带宽 1.0
注意
fit 只接收特征矩阵,用 scoreSamples 评估逐样本对数似然
方法
- task() → Task¶
返回该算法所属的任务类型。
注意
门面用它在 fit 前判断是否需要 targets
- 返回
构造常量时绑定的 Task
- enum Estimators.Metric¶
交叉验证可选的评估指标。
四个常量分别转发到 Metrics.accuracy、Metrics.macroF1、Metrics.r2、Metrics.rmse,是门面与指标工具之间唯一的耦合点。
门面在累加前对 RMSE 取负号,因此四个指标的返回值都满足越大越好,交叉验证均值可以直接比较。
注意
ACCURACY 与 MACRO_F1 面向分类,R2 与 RMSE 面向回归;错配不会报错,只会得到无意义的数值
注意
指标在每折测试集上独立计算,不做加权平均
参见:basalt.ml.Metrics,
basalt.ml.Estimators.crossValidate(Algorithm, Matrix, double[], int, Metric)枚举成员
- ACCURACY()¶
分类准确率
- MACRO_F1()¶
宏平均 F1,各类别等权
- R2()¶
决定系数 R²
- RMSE()¶
均方根误差
- enum Estimators.Task¶
算法的任务类型分类。
CLASSIFICATION 与 REGRESSION 属于有监督任务,门面 fit 要求 targets 非空;UNSUPERVISED 允许 targets 为 null,但会被 crossValidate 拒绝。
该枚举只用于门面的分支判断,不参与具体估计器的实现。
注意
三个常量之间没有层级关系,判断一律用相等比较
参见:basalt.ml.Estimators.Algorithm
枚举成员
- CLASSIFICATION()¶
监督分类任务
- REGRESSION()¶
监督回归任务
- UNSUPERVISED()¶
无监督任务(聚类、降维)
- record FeatureImportance.PermutationResult¶
置换重要性的计算结果,含逐次重复的原始分数。
三个组件依次为 importancesMean、importancesStd 与 rawImportances:前者是每个特征在所有重复上的平均分数下降,第二个是同一组重复的标准差(按总体方差计算,除以重复次数),第三个是 [特征数][重复次数] 的原始下降量。
分数下降等于基线得分减去该列被打乱后的得分,因此越大表示该特征越重要。全部数值由 FeatureImportance.permutationImportance 计算并直接放入记录,没有再做归一化。
示例FeatureImportance.PermutationResult result = FeatureImportance.permutationImportance( model, features, targets, Estimators.Metric.ACCURACY, 10, 42L); int[] order = result.rankedFeaturesDescending(); double top = result.importancesMean()[order[0]];注意
下降为负说明打乱该列反而提升了指标,通常意味着该特征与目标无关或存在噪声
注意
rawImportances 的行对应特征列,列对应重复序号,排序与打乱都只发生在行方向上
注意
记录本身不可变,但持有的数组仍可被外部修改
参见:basalt.ml.FeatureImportance,
basalt.ml.FeatureImportance.permutationImportance(Estimator, Matrix, double[], Estimators.Metric, int, long)方法
- rankedFeaturesDescending() → int[]¶
按平均重要性从大到小返回特征下标。
注意
只比较 importancesMean,不改动记录内的原始数组
注意
平均重要性相同的特征保持列下标升序
- 返回
新的 int 数组,长度为特征数,元素为列下标,最靠前的最重要
- static final class GaussianMixture.Builder¶
GaussianMixture 的构建器。
五个超参数各有默认值:components 2、maxIterations 100、tolerance 1e-4、regCovar 1e-6、seed 42L。除 seed 外每个 setter 都会立即做正数/有限性校验,build 直接返回未拟合实例,不追加检查。
fit 阶段先用 KMeans(固定 30 轮、同一 seed)做 K-Means++ 初始化,再由 E 步与 M 步交替推进;协方差固定为对角形式,regCovar 是唯一的数值稳定手段。
示例GaussianMixture gmm = GaussianMixture.builder() .components(3) .maxIterations(200) .tolerance(1e-5) .regCovar(1e-6) .seed(7L) .build(); gmm.fit(features); double[] labels = gmm.predict(features);注意
必填项:无;五个参数都可省略
注意
fit 时 components 不能超过样本数,否则抛 IllegalArgumentException
注意
seed 只影响初始化,不改变 EM 的单调性,因此相同种子下结果可复现
注意
协方差为对角矩阵,特征间相关性不会被建模
参见:basalt.ml.GaussianMixture, basalt.ml.KMeans
方法
- components(int components) → Builder¶
设置混合成分个数,默认 2。
注意
fit 时还会校验 components 不超过样本数
- 参数
components (int) – 高斯成分个数,须为正;默认 2
- 返回
this,便于链式调用
- 抛出
IllegalArgumentException – components 小于等于 0
- covarianceType(CovarianceType covarianceType) → Builder¶
指定协方差参数化,默认 FULL
- 参数
covarianceType (CovarianceType) – FULL、TIED 或 DIAG;影响存储、求值成本与 AIC 的参数计数
- maxIterations(int maxIterations) → Builder¶
设置 EM 迭代上限,默认 100。
注意
达到上限仍未满足 tolerance 时 converged() 返回 false,参数取最后一轮的结果
- 参数
maxIterations (int) – 最大 EM 轮数,须为正;默认 100
- 返回
this,便于链式调用
- 抛出
IllegalArgumentException – maxIterations 小于等于 0
- tolerance(double tolerance) → Builder¶
设置收敛阈值,默认 1e-4。
注意
判据是 |lowerBound - 上一轮 lowerBound| <= tolerance,成立即停止并标记已收敛
- 参数
tolerance (double) – 相邻两轮每样本平均对数似然之差的上限,须为正且有限;默认 1e-4
- 返回
this,便于链式调用
- 抛出
IllegalArgumentException – tolerance 非正或非有限
- regCovar(double regCovar) → Builder¶
设置协方差正则项,默认 1e-6。
注意
初始化与每轮 M 步都会执行 variance = max(regCovar, variance + regCovar),避免方差塌缩到 0
注意
取值过大会把各成分的对角协方差压平,退化为球形簇
- 参数
regCovar (double) – 加到每个方差上的常数,须为正且有限;默认 1e-6
- 返回
this,便于链式调用
- 抛出
IllegalArgumentException – regCovar 非正或非有限
- seed(long seed) → Builder¶
设置初始化随机种子,默认 42。
注意
种子只传给内部的 K-Means++ 初始化,EM 本身是确定性的
注意
相同 seed 与数据重复 fit 得到相同参数
- 参数
seed (long) – 随机种子,默认 42;不做取值范围校验
- 返回
this,便于链式调用
- build() → GaussianMixture¶
用当前配置创建未拟合的估计器。
注意
参数校验全部在各自的 setter 内完成,build 不再重复检查
- 返回
持有全部超参数的 GaussianMixture 实例
- enum GaussianMixture.CovarianceType¶
GMM 的协方差参数化方式。
FULL 为每个分量估计独立的 p×p 协方差,能表达分量内的特征相关,参数最多;TIED 让所有分量共享一个矩阵,适合各簇形状相近、单簇样本偏少的场景;DIAG 只保留对角方差,参数最少、求值最快,但无法表达相关结构。
注意
三种参数化的参数个数差异直接反映在 aic/bic 上,可用同一份数据比较拟合代价
枚举成员
- FULL()¶
每个分量独立估计一个 p×p 协方差
- TIED()¶
所有分量共享一个 p×p 协方差
- DIAG()¶
每个分量只有 p 个方差(对角协方差)
- static final class GaussianNaiveBayes.Builder¶
GaussianNaiveBayes 的构建器。
唯一参数是方差平滑系数,默认 1e-9,与 scikit-learn 的 var_smoothing 同名同义。build 只校验该系数为正且有限,其余统计量在 fit 阶段产生。
方法
- varianceSmoothing(double varianceSmoothing) → Builder¶
设置方差平滑系数。
拟合时先乘以全体方差最大值得到 epsilon,再加到每个方差上,因此该系数对特征缩放不敏感;全部方差为 0 时 epsilon 直接取该系数本身。
- 参数
varianceSmoothing (double) – 平滑系数,须为正且有限;默认 1e-9
- 返回
this,便于链式调用
- build() → GaussianNaiveBayes¶
校验参数并创建估计器。
- 返回
新的 GaussianNaiveBayes 实例,尚未拟合
- 抛出
IllegalArgumentException – varianceSmoothing 非正或非有限
- static final class GridSearchCV.Builder¶
GridSearchCV 的构建器,登记参数网格与交叉验证策略。
构建器没有公开构造器,只能由 GridSearchCV.builder(estimatorFactory) 取得,估计器工厂在那一刻即为必填,空工厂直接抛 NullPointerException。参数网格用 param 逐项登记,fit 时按登记顺序做笛卡尔积。
其余四项都有默认值:scoring 为 Estimators.Metric.ACCURACY、cv 为 5、stratified 为 false、seed 为 42。build 只检查参数网格非空,配置错误主要靠各 setter 的即时校验拦下。
示例GridSearchCV search = GridSearchCV.builder(params -> DecisionTree.builder() .maxDepth((Integer) params.get("maxDepth")) .build()) .param("maxDepth", 3, 5, 8) .scoring(Estimators.Metric.ACCURACY) .cv(5) .stratified(true) .seed(42L) .build(); search.fit(features, targets);注意
必填项:至少一次 param 调用,否则 build 抛 IllegalArgumentException
注意
estimatorFactory 已被固定,构建器无法更换工厂
注意
工厂必须按参数 Map 返回未拟合的估计器,fit 会为每个候选、每一折各调用一次
参见:basalt.ml.GridSearchCV, basalt.ml.DataSplit, basalt.ml.Estimators.Metric
方法
- param(String name, Object... values) → Builder¶
登记一个超参数的候选值列表。
注意
同名参数再次登记会整表覆盖,而不是追加候选值
注意
多参数之间取笛卡尔积,候选总数等于各列表长度之积
- 参数
name (String) – 参数名,作为传给估计器工厂的 Map 键,非 null
values (Object...) – 候选值,可变参数,至少传入一个;非 null
- 返回
this,便于链式调用
- 抛出
NullPointerException – name 或 values 为 null
IllegalArgumentException – values 为空数组
- scoring(Estimators.Metric scoring) → Builder¶
设置交叉验证打分指标,默认 ACCURACY。
注意
RMSE 在内部取负号,因此四种指标统一为越大越好,最优候选直接取均值最大者
- 参数
scoring (Estimators.Metric) – Estimators.Metric 常量,可取 ACCURACY、MACRO_F1、R2 或 RMSE,非 null
- 返回
this,便于链式调用
- 抛出
NullPointerException – scoring 为 null
- cv(int cvFolds) → Builder¶
设置交叉验证折数,默认 5。
注意
每个候选都要训练 cvFolds 次,总训练次数为候选数乘以折数
- 参数
cvFolds (int) – 折数,须不小于 2;默认 5
- 返回
this,便于链式调用
- 抛出
IllegalArgumentException – cvFolds 小于 2
- stratified(boolean stratified) → Builder¶
设置是否按标签分层分折,默认 false。
注意
两种划分都会先洗牌,随机源为 seed
注意
类别极不均衡时建议开启,否则某折可能缺少某个类别
- 参数
stratified (boolean) – true 时走 DataSplit.stratifiedKFold,按类别比例分折;false 时走普通 K 折
- 返回
this,便于链式调用
- seed(long seed) → Builder¶
设置分折的随机种子,默认 42。
注意
只影响折划分,估计器自身的随机性需由参数网格控制
注意
给定 seed 与数据后所有候选共享同一套折,比较是公平的
- 参数
seed (long) – 随机种子,默认 42;不做取值范围校验
- 返回
this,便于链式调用
- build() → GridSearchCV¶
校验参数网格并创建搜索器。
注意
构建时把参数网格复制为新的 LinkedHashMap,之后对构建器的修改不影响已创建的实例
- 返回
新的 GridSearchCV 实例,尚未拟合
- 抛出
IllegalArgumentException – 参数网格为空,即从未调用过 param
- record GridSearchCV.CandidateResult¶
网格搜索中单个参数组合的交叉验证结果快照。
由 GridSearchCV.cvResults() 按网格笛卡尔积顺序返回。params 是该组合的超参数,meanScore 与 stdScore 为各折得分的均值与总体标准差(方差除以折数),foldScores 保留每折原始得分。
params 在构造时包装为不可修改的 LinkedHashMap,foldScores 直接引用传入数组,不做复制。
注意
得分方向统一为越大越好:RMSE 在累加前取负,不能与 Metrics.rmse 的原始值直接比较
注意
记录本身不校验 params 与估计器配置是否匹配,也不校验 foldScores 长度
参见:basalt.ml.GridSearchCV,
basalt.ml.GridSearchCV.cvResults()
- static final class HistogramGradientBoosting.Builder¶
HistogramGradientBoosting 的流式构造器
默认值为 algorithm XGBOOST、objective SQUARED_ERROR、iterations 100、learningRate 0.1、maxDepth 6、maxLeaves 31、bins 64、minSamplesLeaf 1、minChildWeight 1e-12、lambda 1.0、gamma 0、threads 为可用处理器数、featureFraction 1.0、validationFraction 0、earlyStoppingRounds 0、seed 42。
build() 集中校验数值范围与组合约束:早停必须配正的验证集比例,各比例参数有各自的半开区间。
示例HistogramGradientBoosting model = HistogramGradientBoosting.builder() .algorithm(BoostingAlgorithm.LIGHTGBM) .objective(BoostingObjective.SQUARED_ERROR) .iterations(300) .learningRate(0.05) .maxLeaves(31) .minChildWeight(1e-3) .lambda(1.0) .gamma(0.0) .featureFraction(0.8) .validationFraction(0.2) .earlyStoppingRounds(20) .threads(4) .seed(42L) .build();注意
maxLeaves 只在 LIGHTGBM 策略下生效,XGBOOST 由 maxDepth 决定形状
注意
lambda 参与叶权重与增益的分母,gamma 是每次分裂需超过的增益门槛
参见:basalt.ml.HistogramGradientBoosting, basalt.ml.BoostingAlgorithm, basalt.ml.BoostingObjective
方法
- algorithm(BoostingAlgorithm algorithm) → Builder¶
设置生长策略,默认 XGBOOST
- 参数
algorithm (BoostingAlgorithm) – XGBOOST(深度优先)或 LIGHTGBM(叶优先),非 null
- 返回
this
- 抛出
NullPointerException – algorithm 为 null
- objective(BoostingObjective objective) → Builder¶
设置目标函数,默认 SQUARED_ERROR
- 参数
objective (BoostingObjective) – SQUARED_ERROR 或 LOGISTIC,非 null
- 返回
this
- 抛出
NullPointerException – objective 为 null
- iterations(int iterations) → Builder¶
设置提升轮数,默认 100
- 参数
iterations (int) – 最大树数,须大于 0;早停可能提前结束
- 返回
this
- learningRate(double learningRate) → Builder¶
设置每棵树的收缩系数,默认 0.1
注意
原始得分为 baseScore 加上 learningRate 加权的各树叶值
- 参数
learningRate (double) – 叶值的缩放系数,须为正有限值
- 返回
this
- maxDepth(int maxDepth) → Builder¶
设置单棵树最大深度,默认 6
- 参数
maxDepth (int) – 深度上限,须大于 0;两种生长策略都受其约束
- 返回
this
- maxLeaves(int maxLeaves) → Builder¶
设置最大叶数,默认 31
注意
仅 LIGHTGBM 策略读取该值,XGBOOST 下不生效
- 参数
maxLeaves (int) – 叶数上限,须不小于 2
- 返回
this
- bins(int binCount) → Builder¶
设置单特征最大桶数,默认 64
- 参数
binCount (int) – 桶数上限,取值 [2, 255]
- 返回
this
- minSamplesLeaf(int minSamplesLeaf) → Builder¶
设置叶节点最小样本数,默认 1
- 参数
minSamplesLeaf (int) – 分裂后左右两侧各自的最小样本数,须大于 0
- 返回
this
- minChildWeight(double minChildWeight) → Builder¶
设置子节点 hessian 和下限,默认 1e-12
注意
LOGISTIC 目标的 hessian 很小,该值决定能否继续细分
- 参数
minChildWeight (double) – 左右子节点 hessian 之和的最小值,须为非负有限值
- 返回
this
- lambda(double lambda) → Builder¶
设置叶权重的 L2 正则系数,默认 1.0
- 参数
lambda (double) – 正则系数,须为非负有限值;作为 hessian 的加项出现
- 返回
this
- gamma(double gamma) → Builder¶
设置分裂所需的最小增益,默认 0
注意
增益扣除 gamma 后不大于 0 的候选不产生分裂
- 参数
gamma (double) – 每次分裂从增益中扣除的阈值,须为非负有限值
- 返回
this
- threads(int threads) → Builder¶
设置并行度,默认可用处理器数
- 参数
threads (int) – 工作线程数,须大于 0;同时决定直方图分块数
- 返回
this
- featureFraction(double featureFraction) → Builder¶
设置每轮特征采样比例,默认 1.0
注意
按 ceil(fraction*featureCount) 取整且至少 1 个,第 i 轮用 seed + i*7919 抽取
- 参数
featureFraction (double) – 每轮参与分裂搜索的特征比例,取值 (0, 1]
- 返回
this
- validationFraction(double validationFraction) → Builder¶
设置验证集比例,默认 0
注意
验证集大小取 round(rows*比例),下限 1,上限 rows-2,切分前用 seed 打乱行号
- 参数
validationFraction (double) – 切作验证集的样本比例,取值 [0, 0.5);0 表示不切分
- 返回
this
- earlyStoppingRounds(int earlyStoppingRounds) → Builder¶
设置早停容忍轮数,默认 0(关闭)
注意
大于 0 时必须同时给出正的 validationFraction,否则 build() 拒绝
- 参数
earlyStoppingRounds (int) – 验证损失连续无改善的轮数上限,须不小于 0
- 返回
this
- seed(long seed) → Builder¶
设置切分与特征采样种子,默认 42
- 参数
seed (long) – 随机种子;驱动验证集打乱与逐轮特征子集
- 返回
this
- build() → HistogramGradientBoosting¶
校验配置并创建估计器
- 返回
配置好的 HistogramGradientBoosting,尚未拟合
- 抛出
IllegalArgumentException – 轮数、深度、叶数、桶数、叶样本数或线程数越界,比例超出区间,早停缺少验证集,或学习率与正则项不是合法有限值
- static final class IsolationForest.Builder¶
IsolationForest 的流式构建器。
四个字段默认 trees=100、maxSamples=256、contamination=0.1、seed=42;setter 返回 this 以便串联,参数越界在 setter 内立即抛 IllegalArgumentException。
build() 以字段副本构造模型,不再做额外校验。maxSamples 只是上限,fit 时每棵树实际子采样 min(样本数, maxSamples) 行。
示例IsolationForest model = IsolationForest.builder() .trees(200) .maxSamples(128) .contamination(0.05) .seed(7L) .build();注意
contamination 不参与建树,只在 fit 末尾决定判定阈值:训练集异常分数升序排序后取 floor(rows × contamination) 位置
注意
树高上限为 ceil(log2(有效子采样数)),trees 与 maxSamples 直接决定内存占用与耗时
注意
构建器不是线程安全的,配置完成后应尽快 build()
参见:basalt.ml.IsolationForest,
basalt.ml.IsolationForest.anomalyScore(Matrix)方法
- trees(int trees) → Builder¶
设置隔离树数量。
- 参数
trees (int) – 树的数量,须为正;默认 100
- 返回
this,便于链式调用
- 抛出
IllegalArgumentException – trees <= 0
- maxSamples(int maxSamples) → Builder¶
设置每棵树的子采样规模上限。
fit 时实际子采样 min(样本数, maxSamples) 行,样本不足时该值被自动下调。
- 参数
maxSamples (int) – 子采样行数上限,须 >= 2;默认 256
- 返回
this,便于链式调用
- 抛出
IllegalArgumentException – maxSamples < 2
- contamination(double contamination) → Builder¶
设置预期异常比例。
该值不参与建树,只在 fit 结束时用于确定阈值:训练集异常分数升序排序后取 floor(rows × contamination) 位置的值作为 threshold,decisionFunction 与 predict 据此切分。
- 参数
contamination (double) – 预期异常占比,须落在 (0, 0.5) 开区间;默认 0.1
- 返回
this,便于链式调用
- 抛出
IllegalArgumentException – contamination <= 0、>= 0.5 或为 NaN
- seed(long seed) → Builder¶
设置子采样与切分点选择的随机种子。
- 参数
seed (long) – 随机种子;默认 42,相同种子与数据得到相同的树集合
- 返回
this,便于链式调用
- build() → IsolationForest¶
创建 IsolationForest 实例。
注意
参数已在各 setter 中校验,此处只转调私有构造器
- 返回
新的 IsolationForest,尚未拟合
- static final class KBinsDiscretizer.Builder¶
KBinsDiscretizer 的流式构建器。
三个字段默认 nBins=5、strategy=Strategy.QUANTILE、encode=Encode.ORDINAL;setter 返回 this,strategy 与 encode 在 setter 内立即做非空检查。
nBins 只决定分箱数,边界在 fit 时按策略从训练数据算出,缓存为每个特征一行的 binEdges。
示例KBinsDiscretizer discretizer = KBinsDiscretizer.builder() .nBins(10) .strategy(KBinsDiscretizer.Strategy.QUANTILE) .encode(KBinsDiscretizer.Encode.ONEHOT_DENSE) .build();注意
nBins < 2 在 setter 抛 IllegalArgumentException
注意
选择 ONEHOT_DENSE 后 transform 的输出列数变为输入列数 × nBins
注意
构建器不是线程安全的,配置完成后应尽快 build()
参见:basalt.ml.KBinsDiscretizer, basalt.ml.KBinsDiscretizer.Strategy, basalt.ml.KBinsDiscretizer.Encode
方法
- nBins(int nBins) → Builder¶
设置每个特征的分箱数。
- 参数
nBins (int) – 分箱数,须 >= 2;默认 5
- 返回
this,便于链式调用
- 抛出
IllegalArgumentException – nBins < 2
- strategy(Strategy strategy) → Builder¶
设置分箱边界的计算策略。
- 参数
strategy (Strategy) – Strategy 常量,默认 Strategy.QUANTILE
- 返回
this,便于链式调用
- 抛出
NullPointerException – strategy 为 null,在 setter 中立即抛出
- encode(Encode encode) → Builder¶
设置输出编码方式。
- 参数
encode (Encode) – Encode 常量,默认 Encode.ORDINAL
- 返回
this,便于链式调用
- 抛出
NullPointerException – encode 为 null,在 setter 中立即抛出
- build() → KBinsDiscretizer¶
创建 KBinsDiscretizer 实例。
注意
参数已在各 setter 中校验,此处只转调私有构造器
- 返回
新的 KBinsDiscretizer,尚未拟合
- enum KBinsDiscretizer.Encode¶
离散化结果的编码方式。
ORDINAL 输出与输入同形的箱序号矩阵,取值 0 到 nBins-1;ONEHOT_DENSE 把每个特征展开为 nBins 列,命中箱置 1、其余置 0,输出列数为原列数 × nBins。
inverseTransform 按编码自动选择还原方式:ORDINAL 取对应箱区间的中点,ONEHOT_DENSE 取响应最大的箱中点。
注意
ONEHOT_DENSE 使用稠密矩阵,不做稀疏存储,高 nBins 时内存占用按输出列数放大
注意
predict 返回 transform 结果的展平数组,维度取决于当前编码
参见:basalt.ml.KBinsDiscretizer, basalt.ml.KBinsDiscretizer.Strategy
枚举成员
- ORDINAL()¶
输出单个整数列,按分箱下标编码
- ONEHOT_DENSE()¶
每个特征展开为 nBins 列稠密独热编码
- enum KBinsDiscretizer.Strategy¶
分箱边界的计算策略。
UNIFORM 在每列最小值与最大值之间等宽切分;QUANTILE 对排序列按位置 (rows-1)·b/nBins 做线性插值取分位点;KMEANS 对单列跑 KMeans(clusters=nBins、50 轮、seed=42),再取相邻质心的中点作为边界。
三种策略都把首尾边界固定为列的最小值与最大值;常数列的内部边界全部退化为该常数。
注意
KMEANS 内部固定 50 轮与 seed=42,不受外部随机状态影响
注意
QUANTILE 的边界由训练数据决定,transform 时低于首边界或高于末边界恒落入首箱或末箱
参见:basalt.ml.KBinsDiscretizer, basalt.ml.KBinsDiscretizer.Encode, basalt.ml.KMeans
枚举成员
- UNIFORM()¶
等宽分箱,边界均匀铺满取值区间
- QUANTILE()¶
等频分箱,每个边界落在相同分位点
- KMEANS()¶
对单特征做一维 KMeans,用簇中心作边界
- static final class KMeans.Builder¶
KMeans 的构建器,设置簇数、迭代上限、收敛阈值与随机种子。
默认值:clusters = 8、maxIterations = 300、tolerance = 1e-6、seed = 42、restarts = 1、threads 取 CPU 核数。各 setter 只赋值,参数校验集中在 build 中完成。
注意
threads 只影响分配步的并行度,质心更新始终串行
方法
- clusters(int clusters) → Builder¶
设置簇数 k。
- 参数
clusters (int) – 簇数,须为正;默认 8,拟合时不得大于样本数
- 返回
this,便于链式调用
- maxIterations(int maxIterations) → Builder¶
设置单次重启的最大迭代轮数。
- 参数
maxIterations (int) – 迭代上限,须为正;默认 300
- 返回
this,便于链式调用
- tolerance(double tolerance) → Builder¶
设置质心位移的收敛阈值。
停止条件为全部质心各分量位移的平方和不超过 tolerance²,即质心矩阵的 Frobenius 位移范数不超过 tolerance。
- 参数
tolerance (double) – 收敛阈值,须非负且有限;默认 1e-6
- 返回
this,便于链式调用
- seed(long seed) → Builder¶
设置 K-Means++ 初始化的随机种子。
- 参数
seed (long) – 随机种子;默认 42,第 r 次重启实际使用 seed + 7919r
- 返回
this,便于链式调用
- restarts(int restarts) → Builder¶
设置独立重启次数。
每次重启单独初始化并跑满迭代,最终保留惯性最小的一次,代价近似线性增长。
- 参数
restarts (int) – 重启次数,须为正;默认 1
- 返回
this,便于链式调用
- threads(int threads) → Builder¶
设置分配步的并行度。
- 参数
threads (int) – 并行工作线程数,须为正;默认取可用处理器数
- 返回
this,便于链式调用
- build() → KMeans¶
校验参数并创建 KMeans 实例。
- 返回
新的 KMeans 实例,尚未拟合
- 抛出
IllegalArgumentException – clusters、maxIterations、restarts 或 threads 非正,或 tolerance 为负或非有限
- static final class KNearestNeighbors.Builder¶
KNearestNeighbors 的流式构建器。
两个字段在构建器内可变,setter 返回 this 以便串联。metric 在 setter 中立即做非空检查,k 的合法性推迟到 build() 校验。
默认 k=5、metric=DistanceMetric.EUCLIDEAN,与门面 Basalt.Algorithm.KNN 使用的配置一致。
示例KNearestNeighbors model = KNearestNeighbors.builder() .k(3) .metric(DistanceMetric.EUCLIDEAN) .build();注意
构建器不是线程安全的,配置完成后应尽快 build()
注意
build() 返回的实例持有字段副本,之后修改构建器不影响已建模型
参见:basalt.ml.KNearestNeighbors, basalt.ml.DistanceMetric
方法
- k(int k) → Builder¶
设置近邻个数。
注意
此处不校验,k <= 0 在 build() 时才抛异常
注意
k 大于训练样本数在 fit 时才被发现
- 参数
k (int) – 参与投票的邻居数,必须为正;默认 5
- 返回
this
- metric(DistanceMetric metric) → Builder¶
设置距离度量。
- 参数
metric (DistanceMetric) – 距离函数常量,默认 DistanceMetric.EUCLIDEAN
- 返回
this
- 抛出
NullPointerException – metric 为 null,在 setter 中立即抛出
- build() → KNearestNeighbors¶
校验参数并创建分类器。
- 返回
新的 KNearestNeighbors,尚未拟合
- 抛出
IllegalArgumentException – k <= 0
- static final class KNeighborsRegressor.Builder¶
KNeighborsRegressor 的流式构建器。
字段与分类版一致,metric 在 setter 中做非空检查,k 在 build() 中校验为正。默认 k=5、metric=DistanceMetric.EUCLIDEAN。
示例KNeighborsRegressor model = KNeighborsRegressor.builder() .k(5) .metric(DistanceMetric.MANHATTAN) .build();注意
构建器不是线程安全的
注意
已建模型持有字段副本,后续修改构建器无影响
参见:basalt.ml.KNeighborsRegressor, basalt.ml.DistanceMetric
方法
- k(int k) → Builder¶
设置参与平均的邻居数。
注意
k <= 0 在 build() 时才抛异常
- 参数
k (int) – 邻居数,必须为正;默认 5
- 返回
this
- metric(DistanceMetric metric) → Builder¶
设置距离度量。
- 参数
metric (DistanceMetric) – 距离函数常量,默认 DistanceMetric.EUCLIDEAN
- 返回
this
- 抛出
NullPointerException – metric 为 null,在 setter 中立即抛出
- build() → KNeighborsRegressor¶
校验参数并创建回归器。
- 返回
新的 KNeighborsRegressor,尚未拟合
- 抛出
IllegalArgumentException – k <= 0
- enum Kernel.Type¶
Kernel 支持的四种半正定核函数类型。
LINEAR 对应 x·y,RBF 对应 exp(-gamma·||x-y||²),POLY 对应 (gamma·x·y + coef0)^degree,SIGMOID 对应 tanh(gamma·x·y + coef0)。
枚举本身只标记求值分支,gamma、degree、coef0 三个参数由 Kernel 实例持有,通过 linear()/rbf()/poly()/sigmoid() 四个工厂方法装配。
注意
gamma 为 0 时 evaluate 会退化为 1/max(1, length),即按特征数自动取尺度
注意
POLY 的 degree 由 Kernel 构造器校验为不小于 1
注意
SIGMOID 并不保证半正定,使用时需自行确认适用性
枚举成员
- LINEAR()¶
线性核 x·y
- RBF()¶
高斯核 exp(−gamma·‖x−y‖²)
- POLY()¶
多项式核 (gamma·x·y + coef0)^degree
- SIGMOID()¶
S 形核 tanh(gamma·x·y + coef0)
- static final class KernelDensity.Builder¶
KernelDensity 的流式构建器。
只有带宽与核函数两个字段,且两个 setter 都在调用时立刻校验:bandwidth 必须是正的有限值,kernel 不可为 null。
默认 bandwidth=1.0、kernel=KernelType.GAUSSIAN,因此 builder().build() 直接得到一个可用配置,没有必填项;build() 只做字段拷贝,不做任何额外校验。
示例KernelDensity model = KernelDensity.builder() .bandwidth(0.5) .kernel(KernelDensity.KernelType.TOPHAT) .build();注意
setter 级校验意味着非法参数在链式调用中就会失败,而不是延后到 build()
注意
构建器不是线程安全的
方法
- bandwidth(double bandwidth) → Builder¶
设置核密度估计的带宽。
注意
带宽越小分布越尖锐,GAUSSIAN 与 TOPHAT 共用同一个带宽
- 参数
bandwidth (double) – 平滑尺度,必须为正的有限值;默认 1.0
- 返回
this
- 抛出
IllegalArgumentException – bandwidth 非有限或小于等于 0,在 setter 内立即抛出
- kernel(KernelType kernel) → Builder¶
设置核函数类型。
注意
同时决定 sample 的噪声形式:GAUSSIAN 用正态噪声,TOPHAT 用均匀噪声
- 参数
kernel (KernelType) – GAUSSIAN 为高斯核,TOPHAT 为超立方体核;默认 KernelType.GAUSSIAN
- 返回
this
- 抛出
NullPointerException – kernel 为 null
- build() → KernelDensity¶
创建核密度估计器。
注意
参数已在 setter 内校验,build() 不再抛异常
- 返回
新的 KernelDensity,尚未拟合
- enum KernelDensity.KernelType¶
核密度估计可用的核函数类型。
GAUSSIAN 用多元高斯核,评分时按带宽归一化并做对数域稳定化;TOPHAT 用半径等于 bandwidth 的超球指示核,落在球内的样本计入密度。
类型同时影响 sample 的采样噪声:GAUSSIAN 取正态随机数乘带宽,TOPHAT 取 [-1, 1] 均匀随机数乘带宽。
注意
TOPHAT 在球内无样本可命中时,scoreSamples 返回负无穷
注意
枚举序号会写入模型文件,取值顺序参与序列化格式
枚举成员
- GAUSSIAN()¶
高斯核,密度处处非零
- TOPHAT()¶
平顶核,只统计带宽内的样本
- static final class KernelPCA.Builder¶
KernelPCA 的流式构建器。
components 与 kernel 有默认值 2 与 Kernel.rbf(1.0),两个字段都无需显式设置;rbf 与 poly 是 kernel 的便捷写法,直接替换核字段,最后调用者生效。
maxIterations=60 与 tolerance=1e-12 是 Jacobi 特征分解的内部字段,构建器没有提供对应 setter,无法从外部调整。build() 只做字段拷贝,components 不得超过样本数这一约束在 fit() 中检查。
示例KernelPCA pca = KernelPCA.builder() .components(3) .rbf(0.5) .build();注意
components 在 setter 内校验为正,越界(大于训练样本数)在 fit() 才报错
注意
poly 的 degree 小于 1 由 Kernel 构造器拒绝
注意
构建器不是线程安全的
参见:basalt.ml.KernelPCA, basalt.ml.Kernel
方法
- components(int components) → Builder¶
设置保留的主成分个数。
注意
上限由训练样本数决定,超过时在 fit() 中抛 IllegalArgumentException
- 参数
components (int) – 降维后的维度,必须为正;默认 2
- 返回
this
- 抛出
IllegalArgumentException – components 小于等于 0,在 setter 内立即抛出
- kernel(Kernel kernel) → Builder¶
直接指定核函数对象。
注意
会覆盖此前通过 rbf 或 poly 设置的核
- 参数
kernel (Kernel) – 核函数实例,不可为 null;默认 Kernel.rbf(1.0)
- 返回
this
- 抛出
NullPointerException – kernel 为 null
- rbf(double gamma) → Builder¶
改用 RBF 核的便捷方法。
注意
等价于 kernel(Kernel.rbf(gamma))
- 参数
gamma (double) – 高斯核的缩放系数,必须为正的有限值
- 返回
this
- 抛出
IllegalArgumentException – gamma 非有限或小于等于 0
- poly(int degree, double gamma, double coef0) → Builder¶
改用多项式核的便捷方法。
注意
等价于 kernel(Kernel.poly(degree, gamma, coef0))
- 参数
degree (int) – 多项式次数,必须大于等于 1
gamma (double) – 缩放系数,必须为正的有限值
coef0 (double) – 常数项,必须为有限值
- 返回
this
- 抛出
IllegalArgumentException – gamma 非有限或小于等于 0、degree 小于 1、coef0 非有限
- build() → KernelPCA¶
创建核主成分分析估计器。
注意
build() 不做校验,components 与样本数的关系在 fit() 时检查
- 返回
新的 KernelPCA,尚未拟合
- static final class KernelRidge.Builder¶
KernelRidge 的流式构建器。
两个字段都有默认值:kernel 为 Kernel.rbf(1.0),alpha 为 1.0。kernel、rbf、poly 三个 setter 写入同一个核字段,后调用者生效。
alpha 加到 Gram 矩阵对角线上形成 (K + alpha·I),由 Cholesky 分解求解对偶系数。alpha 在 setter 内校验为正的有限值,build() 只构造实例、不重复校验。
示例KernelRidge model = KernelRidge.builder() .rbf(0.5) .alpha(0.1) .build();注意
没有必填项,builder().build() 得到 RBF 核、alpha=1.0 的可用模型
注意
alpha 过小会让对偶系统接近奇异,预测对训练数据扰动敏感
注意
构建器不是线程安全的
参见:basalt.ml.KernelRidge, basalt.ml.Kernel
方法
- kernel(Kernel kernel) → Builder¶
直接指定核函数对象。
注意
会覆盖此前通过 rbf 或 poly 设置的核
- 参数
kernel (Kernel) – 核函数实例,不可为 null;默认 Kernel.rbf(1.0)
- 返回
this
- 抛出
NullPointerException – kernel 为 null
- rbf(double gamma) → Builder¶
改用 RBF 核的便捷方法。
注意
等价于 kernel(Kernel.rbf(gamma))
- 参数
gamma (double) – 高斯核的缩放系数,必须为正的有限值
- 返回
this
- 抛出
IllegalArgumentException – gamma 非有限或小于等于 0
- poly(int degree, double gamma, double coef0) → Builder¶
改用多项式核的便捷方法。
注意
等价于 kernel(Kernel.poly(degree, gamma, coef0))
- 参数
degree (int) – 多项式次数,必须大于等于 1
gamma (double) – 缩放系数,必须为正的有限值
coef0 (double) – 常数项,必须为有限值
- 返回
this
- 抛出
IllegalArgumentException – gamma 非有限或小于等于 0、degree 小于 1、coef0 非有限
- alpha(double alpha) → Builder¶
设置岭回归正则强度。
注意
alpha 同时起数值稳定作用,过小时对偶系统接近奇异,解对扰动敏感
- 参数
alpha (double) – 加到 Gram 矩阵对角线上的系数,必须为正的有限值;默认 1.0
- 返回
this
- 抛出
IllegalArgumentException – alpha 非有限或小于等于 0,在 setter 内立即抛出
- build() → KernelRidge¶
创建核岭回归模型。
注意
参数已在 setter 内校验,build() 不再抛异常
- 返回
新的 KernelRidge,尚未拟合
- static final class Lasso.Builder¶
Lasso 的流式构建器。
三个字段分别控制正则强度、迭代上限与收敛阈值,setter 只赋值,全部校验集中在 build():alpha 允许 0,maxIterations 必须为正,tolerance 必须为正。
默认 alpha=0.1、maxIterations=1000、tolerance=1e-8。
示例Lasso model = Lasso.builder() .alpha(0.05) .maxIterations(1000) .tolerance(1e-8) .build();注意
alpha 的尺度是按行求和的,与按均方误差定义的强度相差 n 倍
注意
构建器不是线程安全的
方法
- alpha(double alpha) → Builder¶
设置 L1 正则强度。
注意
非有限或为负在 build() 时抛 IllegalArgumentException
注意
取 0 时不再收缩系数,退化为无正则坐标下降
- 参数
alpha (double) – 软阈值阈值,作用在按行求和的尺度上;允许 0,默认 0.1
- 返回
this
- maxIterations(int maxIterations) → Builder¶
设置坐标下降的最大扫描轮数。
注意
达到上限即停止,不报告未收敛
- 参数
maxIterations (int) – 整轮扫描次数上限,必须为正;默认 1000
- 返回
this
- tolerance(double tolerance) → Builder¶
设置收敛阈值。
- 参数
tolerance (double) – 单轮坐标更新的最大绝对变化小于该值即停止,默认 1e-8
- 返回
this
- 抛出
IllegalArgumentException – build() 时非有限或小于等于 0
- build() → Lasso¶
校验参数并创建模型。
- 返回
新的 Lasso,尚未拟合
- 抛出
IllegalArgumentException – alpha 非有限或为负、maxIterations <= 0、tolerance 非有限或 <= 0
- record LimeExplainer.LocalExplanation¶
LIME 对单个样本的局部解释结果。
explainInstance 在目标样本附近采样高斯扰动、按指数欧氏核加权,拟合带 L2 的加权 Ridge 线性代理模型后返回该记录:intercept 是代理截距,featureWeights 是各特征权重,localPrediction 是代理在目标样本上的取值,modelPrediction 是原模型对该样本的预测。
r2Fidelity 是加权 R²,衡量代理对黑盒模型局部的贴合程度;topFeatures 是按 |权重 × 特征标准差| 降序排列的特征下标。
注意
featureWeights 与 topFeatures 直接引用内部数组,record 不做防御性拷贝
注意
加权总平方和不超过 1e-15 时 r2Fidelity 取 1.0,其余情况截断到不小于 0
注意
记录是只读载体,不持有对原模型或训练数据的引用
- static final class LinearRegression.Builder¶
LinearRegression 的流式构建器。
四个字段控制梯度下降的步长、轮数、正则强度与是否拟合截距。setter 只赋值,校验集中在 build():learningRate 必须为正,l2 允许 0,epochs 必须为正。
默认 learningRate=0.05、epochs=2000、l2=0.0、fitIntercept=true。
示例LinearRegression model = LinearRegression.builder() .learningRate(0.01) .epochs(500) .l2(0.001) .fitIntercept(true) .build();注意
epochs 直接决定 lossHistory 的长度与 fit 的耗时
注意
构建器不是线程安全的
方法
- learningRate(double learningRate) → Builder¶
设置梯度下降步长。
注意
步长过大时 lossHistory 会震荡或发散,特征未标准化时尤其明显
- 参数
learningRate (double) – 每次整批更新的步长,必须为正;默认 0.05
- 返回
this
- epochs(int epochs) → Builder¶
设置全批量迭代轮数。
- 参数
epochs (int) – 遍历全部样本的次数,必须为正;默认 2000
- 返回
this
- 抛出
IllegalArgumentException – build() 时小于等于 0
- l2(double l2) → Builder¶
设置 L2 惩罚系数。
注意
梯度中加入 2·l2·w,截距不受影响
- 参数
l2 (double) – 权重惩罚强度,允许 0;默认 0.0(无正则)
- 返回
this
- fitIntercept(boolean fitIntercept) → Builder¶
设置是否拟合截距。
- 参数
fitIntercept (boolean) – true 时更新截距,false 时截距恒为 0;默认 true
- 返回
this
- build() → LinearRegression¶
校验参数并创建模型。
- 返回
新的 LinearRegression,尚未拟合
- 抛出
IllegalArgumentException – learningRate 非有限或 <= 0、l2 非有限或为负、epochs <= 0
- static final class LinearSVM.Builder¶
LinearSVM 的流式构建器。
lambda 控制正则强度并间接决定步长 1/(λ·t),epochs 是遍历轮数,seed 固定洗牌随机源。setter 只赋值,build() 校验 lambda 为正、epochs 为正。
默认 lambda=0.01、epochs=20、seed=42。
示例LinearSVM model = LinearSVM.builder() .lambda(0.001) .epochs(50) .seed(7L) .build();注意
相同 seed 与相同数据得到完全一致的训练轨迹
注意
构建器不是线程安全的
方法
- lambda(double lambda) → Builder¶
设置正则强度。
注意
值越小正则越弱、早期有效步长越大,收敛更快但更易震荡
- 参数
lambda (double) – L2 正则系数,步长按 1/(lambda*t) 计算,必须为正;默认 0.01
- 返回
this
- epochs(int epochs) → Builder¶
设置遍历训练集的轮数。
注意
累计步数 t 跨轮递增,不随 epoch 重置
- 参数
epochs (int) – 完整扫描次数,必须为正;默认 20
- 返回
this
- 抛出
IllegalArgumentException – build() 时小于等于 0
- seed(long seed) → Builder¶
设置洗牌随机种子。
注意
只影响样本访问顺序,不影响权重初值(恒为零)
- 参数
seed (long) – 每轮洗牌所用 Random 的种子;默认 42
- 返回
this
- build() → LinearSVM¶
校验参数并创建模型。
- 返回
新的 LinearSVM,尚未拟合
- 抛出
IllegalArgumentException – lambda 非有限或 <= 0、epochs <= 0
- static final class LogisticRegression.Builder¶
LogisticRegression 的流式构建器。
三个字段控制步长、轮数与 L2 强度。setter 只赋值,build() 校验 learningRate 为正、l2 非负、epochs 为正。
默认 learningRate=0.1、epochs=2000、l2=0.0。
示例LogisticRegression model = LogisticRegression.builder() .learningRate(0.1) .epochs(2000) .l2(0.001) .build();注意
没有 fitIntercept 开关,截距始终参与训练且不受正则
注意
构建器不是线程安全的
参见:basalt.ml.LogisticRegression
方法
- learningRate(double learningRate) → Builder¶
设置梯度下降步长。
注意
步长过大时交叉熵可能不降反升
- 参数
learningRate (double) – 每次整批更新的步长,必须为正;默认 0.1
- 返回
this
- epochs(int epochs) → Builder¶
设置全批量迭代轮数。
- 参数
epochs (int) – 遍历全部样本的次数,必须为正;默认 2000
- 返回
this
- 抛出
IllegalArgumentException – build() 时小于等于 0
- l2(double l2) → Builder¶
设置 L2 惩罚系数。
注意
以 2·l2·w 加入权重梯度,截距不受惩罚
- 参数
l2 (double) – 权重惩罚强度,允许 0;默认 0.0(无正则)
- 返回
this
- build() → LogisticRegression¶
校验参数并创建模型。
- 返回
新的 LogisticRegression,尚未拟合
- 抛出
IllegalArgumentException – learningRate 非有限或 <= 0、l2 非有限或为负、epochs <= 0
- static final class MinMaxScaler.Builder¶
MinMaxScaler 的流式构建器。
featureRange 决定缩放的目标区间,clip 决定是否把越界值截断回该区间。两个字段都有默认值,没有必填项。
默认 featureMin=0.0、featureMax=1.0、clip=false。featureRange 在 setter 内校验两端有限且 max > min,build() 只做字段拷贝。
示例MinMaxScaler scaler = MinMaxScaler.builder() .featureRange(-1.0, 1.0) .clip(true) .build();注意
常数特征列(极差不超过 1e-12)在 fit 时以 1.0 作分母,输出恒等于 featureMin
注意
clip 只影响 transform,不改变 fit 得到的 scale 与 minOffset
注意
构建器不是线程安全的
方法
- featureRange(double min, double max) → Builder¶
设置缩放的目标区间。
注意
区间可取负值或跨越 0,只要求 max > min
- 参数
min (double) – 目标区间下界,必须为有限值;默认 0.0
max (double) – 目标区间上界,必须为有限值且大于 min;默认 1.0
- 返回
this
- 抛出
IllegalArgumentException – min 或 max 非有限,或 max 不大于 min,在 setter 内立即抛出
- clip(boolean clip) → Builder¶
设置是否把结果裁剪到目标区间。
注意
只在 transform 生效,inverseTransform 直接按逆公式还原
- 参数
clip (boolean) – true 时 transform 将每个值截断到 [featureMin, featureMax];默认 false
- 返回
this
- build() → MinMaxScaler¶
创建最小最大缩放器。
注意
featureRange 已在 setter 内校验,build() 不再检查
- 返回
新的 MinMaxScaler,尚未拟合
- static final class OneHotEncoder.Builder¶
OneHotEncoder 的流式构建器。
handleUnknown 决定 transform 遇到训练时未见类别怎么办,categoricalColumns 指定哪些列按类别展开,其余列原样透传。
默认 handleUnknown=ERROR、categoricalColumns=null,后者表示所有列都按类别处理。两个字段都可省略;build() 不做校验,列下标是否越界要到 fit() 才检查。
示例OneHotEncoder encoder = OneHotEncoder.builder() .handleUnknown(OneHotEncoder.HandleUnknown.IGNORE) .categoricalColumns(0, 2) .build();注意
categoricalColumns 在 setter 内克隆,调用方之后修改原数组不会影响编码器
注意
IGNORE 下未见类别输出全零指示向量,inverseTransform 会把它还原为 NaN
注意
构建器不是线程安全的
方法
- handleUnknown(HandleUnknown handleUnknown) → Builder¶
设置未见类别的处理策略。
注意
只在 transform 阶段生效,fit 不受影响
- 参数
handleUnknown (HandleUnknown) – ERROR 抛异常,IGNORE 输出全零指示;默认 HandleUnknown.ERROR
- 返回
this
- 抛出
NullPointerException – handleUnknown 为 null
- categoricalColumns(int... columns) → Builder¶
指定按类别编码的列下标。
注意
setter 内克隆数组,调用方后续修改入参不影响构建器
注意
下标越界在 fit() 时抛 IllegalArgumentException,未指定的列原样透传
- 参数
columns (int...) – 类别列下标,从 0 开始;不调用或传 null 表示所有列都按类别处理
- 返回
this
- build() → OneHotEncoder¶
创建独热编码器。
注意
类别集合在 fit() 时按取值升序收集
- 返回
新的 OneHotEncoder,尚未拟合
- enum OneHotEncoder.HandleUnknown¶
transform 遇到未见类别时的处理策略。
ERROR 表示训练期未出现的类别值在 transform 阶段直接抛 IllegalArgumentException;IGNORE 表示为其输出全零指示向量,不报错。
该开关只影响 transform。fit 阶段按每一列的排序去重结果建立类别表,不涉及未见类别;inverseTransform 对全零行返回 NaN。
示例OneHotEncoder encoder = OneHotEncoder.builder() .handleUnknown(OneHotEncoder.HandleUnknown.IGNORE) .build();注意
ERROR 的校验逐行逐列进行,首个未见值即中断,不返回部分结果
注意
IGNORE 下未见类别与全零行无法区分,逆变换统一得到 NaN
参见:basalt.ml.OneHotEncoder, basalt.ml.OneHotEncoder.Builder
枚举成员
- ERROR()¶
transform 时遇到未见类别抛 IllegalArgumentException
- IGNORE()¶
未见类别编码为全 0 行
- static final class PCA.Builder¶
PCA 的构建器,设置分量数、求解器、扫描上限与白化开关。
默认值:components = 2、solver = AUTO、maxIterations = 60、tolerance = 1e-12、whiten = false。各 setter 只赋值,参数校验集中在 build 中完成。
注意
components 的上界依赖数据形状,只能在 fit 阶段校验
方法
- components(int components) → Builder¶
设置保留的主成分个数。
- 参数
components (int) – 分量数,须为正;默认 2,拟合时不得大于 min(样本数, 特征数)
- 返回
this,便于链式调用
- solver(EigenSolver solver) → Builder¶
设置特征分解求解器。
- 参数
solver (EigenSolver) – 求解器,默认 EigenSolver.AUTO
- 返回
this,便于链式调用
- 抛出
NullPointerException – solver 为 null
- maxIterations(int maxIterations) → Builder¶
设置 Jacobi 扫描的最大轮数。
- 参数
maxIterations (int) – 扫描上限,须为正;默认 60
- 返回
this,便于链式调用
- tolerance(double tolerance) → Builder¶
设置 Jacobi 扫描的收敛阈值。
收敛判据为 sqrt(Σ a_pq²) 不超过 tolerance · max(1, ‖A‖_F),其中求和覆盖全部非对角元素。
- 参数
tolerance (double) – 收敛阈值,须为正且有限;默认 1e-12
- 返回
this,便于链式调用
- whiten(boolean whiten) → Builder¶
设置是否白化投影结果。
白化把每个投影除以其主成分标准差,使各分量方差为 1;逆变换会乘回同一标准差。
- 参数
whiten (boolean) – true 表示白化;默认 false
- 返回
this,便于链式调用
- build() → PCA¶
校验参数并创建 PCA 实例。
- 返回
新的 PCA 实例,尚未拟合
- 抛出
IllegalArgumentException – components 或 maxIterations 非正,或 tolerance 非正或非有限
- static final class Pipeline.Builder¶
Pipeline 的构造器,按序追加步骤并挂接末端估计器。
初始状态为空步骤列表、无末端估计器。addStep 负责累积变换器,estimator 设置唯一的末端估计器;至少要有其中一项才能通过 build。
build() 只做空管线校验,其余约束推迟到运行期:步骤名重复、估计器不支持持久化都在后续调用或写入时才暴露。
示例Pipeline pipeline = Pipeline.builder() .addStep(PolynomialFeatures.builder().degree(2).build()) .estimator("ridge", Ridge.builder().alpha(1.0).build()) .build();注意
步骤顺序即执行顺序,transform 正向、inverseTransform 反向
注意
未命名步骤自动取 step0、step1 等名称
注意
构建器不是线程安全的
参见:basalt.ml.Pipeline, basalt.ml.Pipeline.Step
方法
- addStep(String name, Transformer transformer) → Builder¶
按给定名称追加一个变换步骤。
步骤按调用顺序排列,fit 时依次 fitTransform,transform 与 predict 时依次 transform,inverseTransform 时逆序回放。
注意
重名不会被拒绝,namedSteps() 中后写入者覆盖先写入者
- 参数
name (String) – 步骤名,用于 namedSteps() 与持久化;不可为 null
transformer (Transformer) – 变换器实例;不可为 null
- 返回
this,便于链式调用
- 抛出
NullPointerException – name 或 transformer 为 null
- addStep(Transformer transformer) → Builder¶
追加步骤并自动命名为 stepN。
名称取 "step" 拼上追加前的步骤数,首个步骤为 step0,其后依次递增。
- 参数
transformer (Transformer) – 变换器实例;不可为 null
- 返回
this,便于链式调用
- 抛出
NullPointerException – transformer 为 null
- estimator(String name, Estimator estimator) → Builder¶
设置具名末端估计器。
末端估计器在所有变换步骤之后拟合与预测,并作为 namedSteps() 的最后一项。
注意
重复调用会整体替换前一次的末端估计器与名称
- 参数
name (String) – 估计器名称,用于 namedSteps() 与持久化;不可为 null
estimator (Estimator) – 末端估计器;不可为 null
- 返回
this,便于链式调用
- 抛出
NullPointerException – name 或 estimator 为 null
- estimator(Estimator estimator) → Builder¶
设置末端估计器,名称固定为 estimator。
- 参数
estimator (Estimator) – 末端估计器;不可为 null
- 返回
this,便于链式调用
- 抛出
NullPointerException – estimator 为 null
- build() → Pipeline¶
校验并构建流水线。
注意
只校验非空,不检查步骤重名,也不检查估计器是否实现 Persistable
- 返回
配置好的 Pipeline,尚未拟合
- 抛出
IllegalArgumentException – 既没有步骤也没有末端估计器
- record Pipeline.Step¶
流水线中的具名步骤:名称与变换器的不可变组合。
紧凑构造器对 name 与 transformer 做非空校验,两者一旦写入即不可更改。步骤在列表中按插入顺序存放,Pipeline 依此顺序正向执行变换、反向执行逆变换。
steps() 返回不可变列表,元素即 Step 记录本身。
示例Pipeline.Step step = new Pipeline.Step("poly", PolynomialFeatures.builder().build());注意
name 参与 namedSteps() 的键与 .bsl 持久化,需自行保证唯一
注意
name 或 transformer 为 null 时构造抛 NullPointerException
- static final class PolynomialFeatures.Builder¶
PolynomialFeatures 的构造器,设置阶数与偏置项。
默认 degree = 2、interactionOnly = false、includeBias = true。degree 在 setter 调用时校验,build() 只做装配,没有额外校验。
输出列的组合集合在 fit 阶段按输入特征数生成,因此构建器本身不持有任何依赖数据的形状信息。
示例PolynomialFeatures poly = PolynomialFeatures.builder() .degree(3) .interactionOnly(false) .includeBias(true) .build();注意
列数随 degree 与特征数组合增长,高阶时输出维度会迅速膨胀
注意
interactionOnly 与 includeBias 均无取值范围约束
注意
构建器不是线程安全的
参见:basalt.ml.PolynomialFeatures
方法
- degree(int degree) → Builder¶
设置多项式最高阶数,默认 2。
阶数决定单项式的最大总次数,从 1 次逐层生成到该阶。
注意
该校验在 setter 内完成,不走 build()
- 参数
degree (int) – 最高阶数,须不小于 1;默认 2
- 返回
this,便于链式调用
- 抛出
IllegalArgumentException – degree 小于 1
- interactionOnly(boolean interactionOnly) → Builder¶
设置是否只生成纯交互项,默认 false。
开启后每个特征在同一次单项式中最多出现一次,输出仅含不同特征的乘积;关闭时允许特征重复,从而包含平方及更高次项。
注意
真实输出列数在 fit 时按输入特征数展开,构建阶段无法确定
- 参数
interactionOnly (boolean) – true 表示只生成不同特征的乘积;默认 false
- 返回
this,便于链式调用
- includeBias(boolean includeBias) → Builder¶
设置是否输出常数列,默认 true。
开启时在所有单项式之前插入一列取值恒为 1 的偏置列(对应空组合),关闭时输出从 1 次项开始。
- 参数
includeBias (boolean) – true 表示首列输出常数 1;默认 true
- 返回
this,便于链式调用
- build() → PolynomialFeatures¶
创建 PolynomialFeatures 实例。
注意
不做参数校验,degree 的合法性已在 setter 中过滤
- 返回
新的 PolynomialFeatures,尚未拟合
- static final class RFE.Builder¶
RFE 的构造器,设置保留特征数与淘汰步长。
默认 nFeaturesToSelect = 2、step = 1。估计器不直接传入,而是由 builder(Supplier) 提供的工厂在每轮消除与最终拟合时各创建一个新实例,保证每轮从干净状态训练。
两个 setter 在调用时校验下界,nFeaturesToSelect 的上界与估计器能力(featureImportances() 或线性 weights())要等 fit 才能判定。
示例RFE rfe = RFE.builder(() -> Ridge.builder().build()) .nFeaturesToSelect(3) .step(1) .build();注意
工厂会在 fit 过程中被反复调用,其返回的估计器必须可重复构造
注意
不支持重要性或线性权重的估计器在 fit 时抛 IllegalArgumentException
注意
构建器不是线程安全的
参见:basalt.ml.RFE, basalt.ml.SelectKBest
方法
- nFeaturesToSelect(int nFeaturesToSelect) → Builder¶
设置最终保留的特征数,默认 2。
注意
上界依赖数据列数,只能在 fit 阶段校验
- 参数
nFeaturesToSelect (int) – 保留特征数,须为正;默认 2,fit 时不得大于输入列数
- 返回
this,便于链式调用
- 抛出
IllegalArgumentException – nFeaturesToSelect 小于等于 0
- step(int step) → Builder¶
设置每轮淘汰的特征数,默认 1。
每轮实际淘汰 min(step, 剩余特征数 − 保留特征数) 个重要性最低的特征,最后不足一整步时按剩余量截断。
注意
step 越大,迭代轮数与估计器拟合次数越少,但排名粒度越粗
- 参数
step (int) – 每轮淘汰数,须为正;默认 1
- 返回
this,便于链式调用
- 抛出
IllegalArgumentException – step 小于等于 0
- build() → RFE¶
创建 RFE 实例。
注意
不做参数校验,两个 setter 已在调用时过滤非法值
- 返回
新的 RFE,尚未拟合
- static final class RandomForest.Builder¶
RandomForest 的流式构造器
默认值为 trees 100、maxDepth 8、minSamplesLeaf 1、maxFeatures 0(按平方根解析)、bins 64、threads 为可用处理器数、seed 42、task CLASSIFICATION、oob 关闭。build() 校验后返回未拟合的森林。
maxFeatures 的 0 值不在构造期解析,而是在 fit 时按 max(1, sqrt(featureCount)) 计算,因此特征数由训练数据决定。
示例RandomForest forest = RandomForest.builder() .trees(200) .maxDepth(10) .minSamplesLeaf(2) .maxFeatures(3) .bins(64) .threads(8) .seed(42L) .task(TreeTask.REGRESSION) .oob(true) .build();注意
threads 决定 ForkJoinPool 的并行度,须大于 0
注意
打开 oob 会增加每棵树一次全量推理的开销,并受 800 万次树-行预测上限约束
参见:basalt.ml.RandomForest, basalt.ml.TreeTask
方法
- trees(int treeCount) → Builder¶
设置树的数量,默认 100
注意
树数与行数的乘积决定 OOB 评估的规模上限
- 参数
treeCount (int) – 树数,须大于 0
- 返回
this
- maxDepth(int maxDepth) → Builder¶
设置每棵树的最大深度,默认 8
- 参数
maxDepth (int) – 深度上限,须不小于 0;0 表示单叶
- 返回
this
- minSamplesLeaf(int minSamplesLeaf) → Builder¶
设置叶节点最小样本数,默认 1
- 参数
minSamplesLeaf (int) – 分裂后左右两侧各自的最小样本数,须大于 0
- 返回
this
- maxFeatures(int maxFeatures) → Builder¶
设置每次分裂的候选特征数,默认 0
注意
大于特征数时由 DecisionTree 的候选抽取按特征数截断
- 参数
maxFeatures (int) – 候选特征数;0 表示在 fit 时解析为 max(1, sqrt(featureCount))
- 返回
this
- bins(int maxBins) → Builder¶
设置单特征最大桶数,默认 64
注意
全森林共用一份分箱,该值只在 fit 开始时使用一次
- 参数
maxBins (int) – 桶数上限,取值 [2, 255]
- 返回
this
- threads(int threads) → Builder¶
设置拟合并行度,默认可用处理器数
- 参数
threads (int) – 工作线程数,须大于 0
- 返回
this
- seed(long seed) → Builder¶
设置随机种子,默认 42
注意
自助采样序列由 seed + i*1000003 驱动,与树的特征种子相互独立
- 参数
seed (long) – 基础种子;第 i 棵树的种子为 seed + i*31
- 返回
this
- task(TreeTask task) → Builder¶
设置任务类型,默认 CLASSIFICATION
- 参数
task (TreeTask) – CLASSIFICATION 或 REGRESSION,非 null
- 返回
this
- 抛出
NullPointerException – task 为 null
- oob(boolean oob) → Builder¶
设置是否计算袋外分数,默认关闭
注意
打开后 treeCount*rows 超过 800 万,fit 抛 IllegalArgumentException
注意
关闭时 oobScore() 抛 IllegalStateException
- 参数
oob (boolean) – true 时每棵树额外对全量矩阵推理并累计袋外预测
- 返回
this
- build() → RandomForest¶
校验配置并创建森林
- 返回
配置好的 RandomForest,尚未拟合
- 抛出
IllegalArgumentException – 树数不大于 0、maxDepth 小于 0、minSamplesLeaf 不大于 0、maxFeatures 小于 0、threads 不大于 0,或 bins 越界
- static final class RandomizedSearchCV.Builder¶
随机搜索的构造器,登记参数分布与分折策略。
默认 nIter = 10、scoring = ACCURACY、cv = 5 折、stratified 关闭、seed = 42,分布表为空。四个 param* 方法在登记时即完成取值校验,把抽样函数写入按插入顺序保存的映射;build() 只要求至少登记一个分布。
fit 每轮按登记顺序对每个分布抽一次,全部用同一个 Random(seed) 驱动;分层开关决定采用分层 K 折还是普通 K 折,折划分同样使用该种子。每轮对全部折拟合并以折均值为该组参数的得分。
示例RandomizedSearchCV search = RandomizedSearchCV.builder( params -> Ridge.builder().alpha((Double) params.get("alpha")).build()) .paramLogUniform("alpha", 1e-3, 10.0) .nIter(20) .scoring(Estimators.Metric.R2) .cv(5) .seed(42L) .build();注意
同名参数重复登记会覆盖旧分布,但在映射中保留首次登记的位置
注意
paramUniform、paramLogUniform、paramIntRange 不校验 name 是否为 null,paramChoices 会校验
注意
均值并列时保留先出现的那一组,比较使用严格大于
注意
估计器工厂在每折与最终重训时都会被调用
参见:basalt.ml.RandomizedSearchCV, basalt.ml.RandomizedSearchCV.ParameterSampler, basalt.ml.GridSearchCV
方法
- paramChoices(String name, Object... choices) → Builder¶
登记离散候选列表,等概率有放回抽取。
每轮用共享随机源取一个下标,同一次搜索内同一候选值可以被重复抽中。候选数组在登记时克隆,之后修改原数组不影响抽样结果。
- 参数
name (String) – 参数名,须非 null
choices (Object...) – 候选值数组,至少一个元素,元素可为 null
- 返回
this,便于链式调用
- 抛出
NullPointerException – name 或 choices 为 null
IllegalArgumentException – choices 长度为 0
- paramUniform(String name, double low, double high) → Builder¶
登记 [low, high) 上的均匀分布。
抽样值为 low + U(0,1) · (high − low),区间上界取不到。
注意
不校验 name 是否为 null,也不校验端点是否有限
- 参数
name (String) – 参数名
low (double) – 区间下界,含
high (double) – 区间上界,不含,须严格大于 low
- 返回
this,便于链式调用
- 抛出
IllegalArgumentException – high 不大于 low
- paramLogUniform(String name, double low, double high) → Builder¶
登记对数均匀分布。
先在 log(low) 与 log(high) 之间均匀取值,再取指数还原,适合同一参数跨数量级搜索的场景。
- 参数
name (String) – 参数名
low (double) – 区间下界,须严格大于 0
high (double) – 区间上界,须严格大于 low
- 返回
this,便于链式调用
- 抛出
IllegalArgumentException – low 不大于 0,或 high 不大于 low
- paramIntRange(String name, int lowInclusive, int highInclusive) → Builder¶
登记闭区间上的均匀整数分布。
取值覆盖 lowInclusive 到 highInclusive 的全部整数,两端均可取到。
- 参数
name (String) – 参数名
lowInclusive (int) – 闭区间下界
highInclusive (int) – 闭区间上界,须不小于下界
- 返回
this,便于链式调用
- 抛出
IllegalArgumentException – highInclusive 小于 lowInclusive
- nIter(int nIter) → Builder¶
设置抽样迭代次数,默认 10。
注意
每轮对全部已登记分布各抽一次,并完成一整轮 cross-validation
- 参数
nIter (int) – 迭代轮数,须为正
- 返回
this,便于链式调用
- 抛出
IllegalArgumentException – nIter 小于等于 0
- scoring(Estimators.Metric scoring) → Builder¶
设置评分指标,默认 ACCURACY。
注意
搜索统一取折均值最大者,RMSE 这类越小越好的指标需自行留意方向
- 参数
scoring (Estimators.Metric) – 评分指标,可选 ACCURACY、MACRO_F1、R2、RMSE;默认 ACCURACY
- 返回
this,便于链式调用
- 抛出
NullPointerException – scoring 为 null
- cv(int cvFolds) → Builder¶
设置交叉验证折数,默认 5。
- 参数
cvFolds (int) – 折数,须不小于 2
- 返回
this,便于链式调用
- 抛出
IllegalArgumentException – cvFolds 小于 2
- stratified(boolean stratified) → Builder¶
设置是否分层分折,默认关闭。
开启时按目标值分层划分折,关闭时使用普通 K 折;两种方式都带同一个 seed 做洗牌。
- 参数
stratified (boolean) – true 表示分层 K 折;默认 false
- 返回
this,便于链式调用
- seed(long seed) → Builder¶
设置随机种子,默认 42。
注意
同一 seed 与同一数据下重复 fit 得到相同的折划分与抽样序列
- 参数
seed (long) – 随机种子,同时驱动分折与参数抽样
- 返回
this,便于链式调用
- build() → RandomizedSearchCV¶
校验并创建搜索器。
注意
nIter、cv、scoring 已在 setter 中校验,build 只检查分布表非空
- 返回
新的 RandomizedSearchCV,尚未拟合
- 抛出
IllegalArgumentException – 未登记任何参数分布
- interface RandomizedSearchCV.ParameterSampler¶
参数分布的抽样接口,单方法返回一个参数值。
函数式接口,唯一方法 sample(Random) 从外部传入的随机源抽取一个取值。Builder 的 paramChoices、paramUniform、paramLogUniform、paramIntRange 都以此为载体把分布登记进映射,fit 时每轮按登记顺序各调用一次。
随机源由 fit 统一创建并顺序传递,因此同一 seed 下抽样序列可复现。
注意
实现不应自行播种或缓存随机源,否则各轮取值会退化为重复
注意
返回值直接放进参数映射交给估计器工厂,fit 不做类型转换或校验
注意
抽样是有放回的,同一次搜索内可能抽到完全相同的参数组合
参见:basalt.ml.RandomizedSearchCV, basalt.ml.RandomizedSearchCV.Builder
- static final class Ridge.Builder¶
Ridge 的流式构建器。
alpha 是加在 Gram 矩阵对角线上的正则量,fitIntercept 决定是否中心化并反推截距。setter 只赋值,build() 只校验 alpha 为正。
默认 alpha=1.0、fitIntercept=true。
示例Ridge model = Ridge.builder() .alpha(0.1) .fitIntercept(true) .build();注意
alpha 不允许为 0;需要无正则解时改用 LinearRegression
注意
构建器不是线程安全的
方法
- alpha(double alpha) → Builder¶
设置 L2 正则强度。
注意
尺度是按行求和的,未除以样本数
- 参数
alpha (double) – 加到 Gram 对角线上的值,必须为正;默认 1.0
- 返回
this
- 抛出
IllegalArgumentException – build() 时非有限或小于等于 0
- fitIntercept(boolean fitIntercept) → Builder¶
设置是否中心化并拟合截距。
注意
为 false 时截距恒为 0.0,且 alpha 会压缩未中心化的系数
- 参数
fitIntercept (boolean) – true 时中心化特征与目标并反推截距,false 时直接解原始正规方程;默认 true
- 返回
this
- build() → Ridge¶
校验参数并创建模型。
- 返回
新的 Ridge,尚未拟合
- 抛出
IllegalArgumentException – alpha 非有限或小于等于 0
- static final class SVC.Builder¶
SVC 的构造器,设置核函数、惩罚系数与 SMO 参数。
默认 kernel = Kernel.rbf(1.0)、c = 1.0、tolerance = 1e-4、maxIterations = 600、seed = 42。核函数只有一个字段,kernel、rbf、poly、linear 四个 setter 互相覆盖。
c、tolerance、maxIterations 以及 rbf/poly 的 gamma 在 setter 调用时即校验并抛异常;build() 只把五个字段装进实例,没有额外检查。
示例SVC model = SVC.builder() .rbf(0.5) .c(1.0) .tolerance(1e-4) .maxIterations(600) .seed(42L) .build();注意
kernel 与 rbf、poly、linear 写同一字段,最终生效的是最后一次调用
注意
poly 的 degree 下界与 coef0 有限性由 Kernel 构造器校验
注意
松容差加小迭代上限会得到欠拟合的解,且不会报错
参见:basalt.ml.SVC, basalt.ml.Kernel
方法
- kernel(Kernel kernel) → Builder¶
设置核函数对象,默认 rbf(1.0)。
注意
与 rbf、poly、linear 共用同一字段,后调用者覆盖先调用者
- 参数
kernel (Kernel) – 核函数实例,不可为 null;默认 Kernel.rbf(1.0)
- 返回
this,便于链式调用
- 抛出
NullPointerException – kernel 为 null
- rbf(double gamma) → Builder¶
改用 RBF 核并设置 gamma。
核函数为 K(x, y) = exp(−gamma · ‖x − y‖²),gamma 越大决策边界越贴合训练点。
- 参数
gamma (double) – RBF 的带宽倒数,须为正且有限
- 返回
this,便于链式调用
- 抛出
IllegalArgumentException – gamma 非有限或小于等于 0
- poly(int degree, double gamma, double coef0) → Builder¶
改用多项式核并设置阶数、gamma 与常数项。
核函数为 K(x, y) = (gamma · x·y + coef0)^degree,coef0 控制低阶项的相对权重。
- 参数
degree (int) – 多项式阶数,须不小于 1
gamma (double) – 内积缩放系数,须为正且有限
coef0 (double) – 常数项,须有限,可为负
- 返回
this,便于链式调用
- 抛出
IllegalArgumentException – gamma 非正或非有限,degree 小于 1,或 coef0 非有限
- linear() → Builder¶
改用线性核。
核函数退化为内积 K(x, y) = x·y,不引入 gamma、degree、coef0 等超参数。
- 返回
this,便于链式调用
- probability(boolean probability) → Builder¶
开启 Platt 概率校准,默认关闭
- 参数
probability (boolean) – true 时 fit 末尾为每个二分类子问题额外拟合一组 A、B
- c(double c) → Builder¶
设置惩罚系数 C,默认 1.0。
C 同时充当每个拉格朗日乘子的上界,值越大对间隔违例越不宽容,越容易过拟合。
- 参数
c (double) – 惩罚系数,须为正且有限
- 返回
this,便于链式调用
- 抛出
IllegalArgumentException – c 非有限或小于等于 0
- tolerance(double tolerance) → Builder¶
设置 SMO 的 KKT 违例容差,默认 1e-4。
仅当样本的 y·E 超出 ±tolerance 且乘子未顶到 0 或 C 时才触发一次乘子更新,容差越小收敛越慢、解越精确。
- 参数
tolerance (double) – 违例阈值,须为正且有限
- 返回
this,便于链式调用
- 抛出
IllegalArgumentException – tolerance 非有限或小于等于 0
- maxIterations(int maxIterations) → Builder¶
设置每个二分类子问题的最大迭代轮数,默认 600。
达到上限即停止,即使尚未满足收敛条件;连续 5 轮扫描都没有乘子更新时也会提前退出。
注意
多分类按 One-vs-Rest 展开,每个子问题独立计数
- 参数
maxIterations (int) – 迭代上限,须为正
- 返回
this,便于链式调用
- 抛出
IllegalArgumentException – maxIterations 小于等于 0
- seed(long seed) → Builder¶
设置随机种子,默认 42。
种子只用于第二个乘子的启发式挑选:15% 的概率改为随机选点,其余情况取误差差最大的点。
注意
同一 seed 下训练结果可复现
- 参数
seed (long) – 基础种子;第 m 个子问题使用 seed + m·101
- 返回
this,便于链式调用
- build() → SVC¶
创建 SVC 实例。
注意
不做额外校验,全部约束已在各 setter 中完成
- 返回
新的 SVC,尚未拟合
- static final class SelectKBest.Builder¶
SelectKBest 的构造器,设置保留数与评分函数。
默认 k = 5、scoreFunc = F_CLASSIF。两个 setter 在调用时校验下界与空值,build() 只做装配。
k 的上界与 CHI2 的非负性要求都依赖训练数据,推迟到 fit 阶段才校验;不满足时抛 IllegalArgumentException。
示例SelectKBest selector = SelectKBest.builder() .k(10) .scoreFunc(SelectKBest.ScoreFunc.F_CLASSIF) .build();注意
分数并列时按列索引升序优先,selectedIndices() 最终按升序返回
注意
F_CLASSIF 与 CHI2 把目标视为离散类别,F_REGRESSION 把目标视为连续值
注意
构建器不是线程安全的
参见:basalt.ml.SelectKBest, basalt.ml.RFE
方法
- k(int k) → Builder¶
设置保留的特征数,默认 5。
注意
上界依赖数据列数,只能在 fit 阶段校验
- 参数
k (int) – 保留特征数,须为正;默认 5,fit 时不得大于输入列数
- 返回
this,便于链式调用
- 抛出
IllegalArgumentException – k 小于等于 0
- scoreFunc(ScoreFunc scoreFunc) → Builder¶
设置评分函数,默认 F_CLASSIF。
F_CLASSIF 用单因素方差分析衡量类间差异,F_REGRESSION 用相关系数换算 F 值,CHI2 用列联表的卡方统计量。
注意
CHI2 要求全部特征非负,否则 fit 抛 IllegalArgumentException
- 参数
scoreFunc (ScoreFunc) – F_CLASSIF、F_REGRESSION 或 CHI2;默认 F_CLASSIF
- 返回
this,便于链式调用
- 抛出
NullPointerException – scoreFunc 为 null
- build() → SelectKBest¶
创建 SelectKBest 实例。
注意
不做参数校验,k 与 scoreFunc 已在 setter 中过滤
- 返回
新的 SelectKBest,尚未拟合
- enum SelectKBest.ScoreFunc¶
特征打分的统计检验:分类 F、回归 F、卡方
F_CLASSIF 把 targets 的每个不同取值视为一个类别,用组间均方与组内均方之比作为分数,组内均方不足 1e-15 时记 0.0;F_REGRESSION 计算特征与连续目标的相关系数,再换算成 F 值;CHI2 按类别累加特征值,与按类别先验算出的期望值比较,得到卡方统计量。
三种分数都在 fit 阶段一次算出,SelectKBest 按分数降序排列后取前 k 个下标,再按下标升序保存。分数只用于排序,不做显著性判定,也不计算 p 值。
注意
CHI2 要求特征值非负,遇到负值在 fit 阶段抛 IllegalArgumentException。
注意
F_CLASSIF 与 CHI2 把 targets 的每个不同取值当作类别标签;F_REGRESSION 假定 targets 为连续值。
注意
常数特征的分数为 0.0,与目标无关的特征同样得 0.0,排序时按特征下标升序稳定排列。
参见:basalt.ml.SelectKBest, basalt.ml.Estimator
枚举成员
- F_CLASSIF()¶
单因素方差分析 F 值,用于分类标签
- F_REGRESSION()¶
回归 F 值(方差解释比),用于连续标签
- CHI2()¶
卡方统计量,要求非负特征与分类标签
- record ShapExplainer.Explanation¶
一次解释的结果:基准值、SHAP 矩阵、预测与平均绝对值
baseValue 是背景数据集上模型输出的均值;shapValues 为 rows×cols 的矩阵,第 i 行各列之和加 baseValue 等于 predictions[i],这是解释器在各条计算路径上都强制满足的局部有效性。predictions 保存模型在该批样本上的标量输出,分类模型取正类概率或原始得分。
meanAbsShap 是各特征跨样本的绝对 SHAP 均值,长度等于特征数,可直接用于特征重要性排序;它由 shapValues 现算,不含额外信息。
注意
shapValues 是 explain 中新分配的 Matrix,与输入实例不共享存储。
注意
行和与 predictions 的一致性受浮点累加误差影响,比较时需留出容差。
注意
record 不复制数组,构造后修改 predictions 或 meanAbsShap 会改变记录内容。
- static final class SimpleImputer.Builder¶
构造 SimpleImputer,设置缺失值策略与常数填充值
默认策略为 MEAN,fillValue 为 0.0;fillValue 只在 CONSTANT 策略下写入统计量,其他策略即使设置也不影响结果。builder() 每次返回新实例,可反复调用 build 得到互相独立的估计器。
策略与填充值都会被序列化:write 依次写策略序数、填充值、特征数与该列的统计量数组,read 按同样顺序还原,因此非法序数或非正特征数会在读取阶段抛 ModelFormatException。
示例SimpleImputer imputer = SimpleImputer.builder() .strategy(SimpleImputer.Strategy.CONSTANT) .fillValue(-1.0) .build(); imputer.fit(features); Matrix filled = imputer.transform(features);注意
构造期不做任何数据检查,缺失值的判定与统计量计算都发生在 fit。
注意
build 不复制 Builder 之外的输入,之后修改 Builder 不会影响已建实例。
参见:basalt.ml.SimpleImputer, basalt.ml.SimpleImputer.Strategy, basalt.ml.StandardScaler.Builder
方法
- strategy(Strategy strategy) → Builder¶
设置填充策略,默认 MEAN
策略只在 fit 阶段影响每列统计量的计算方式;transform 对所有策略一视同仁,把 NaN 位置替换成该列统计量。
- 参数
strategy (Strategy) – 缺失值填充方式,取 MEAN、MEDIAN、MOST_FREQUENT 或 CONSTANT,不允许 null
- 返回
this,便于链式配置
- 抛出
NullPointerException – strategy 为 null
- fillValue(double fillValue) → Builder¶
设置 CONSTANT 策略使用的填充常数
校验在设置时完成,非法值不会留到 fit。非 CONSTANT 策略下该值仍被保存并写入模型文件,但不参与统计量计算。
- 参数
fillValue (double) – 替换缺失值所用的常数,必须有限(不得为 NaN 或无穷)
- 返回
this,便于链式配置
- 抛出
IllegalArgumentException – fillValue 为 NaN 或无穷
- build() → SimpleImputer¶
创建配置好的估计器实例
构造器只拷贝策略与填充值,不分配统计数组;统计量在 fit 时按列生成。
注意
未拟合的实例调用 transform 或 statistics 会抛 IllegalStateException。
- 返回
持有当前策略与填充值的 SimpleImputer,尚未拟合
- enum SimpleImputer.Strategy¶
缺失值填充策略:均值、中位数、众数、常数
MEAN 用该列非缺失值的算术平均;MEDIAN 对非缺失值排序后取中位数,个数为偶数时取中间两个的均值;MOST_FREQUENT 取出现次数最多的值,并列时取数值较小者,因为频次统计基于 TreeMap 的有序遍历。CONSTANT 直接用 fillValue 填充,完全不读取数据。
每列的统计量在 fit 时一次算好并缓存,transform 阶段只做查表替换:NaN 位置写入统计量,有限值原样保留,遇到无穷值则报错。
注意
除 CONSTANT 外,某列全为 NaN 时 fit 抛 IllegalArgumentException,因为没有可用样本。
注意
非缺失位置出现无穷值时 fit 与 transform 都抛 IllegalArgumentException。
注意
策略随模型一起序列化,read 时按序数还原,序数越界由 ModelFormatException 拒绝。
参见:basalt.ml.SimpleImputer, basalt.ml.SimpleImputer.Builder
枚举成员
- MEAN()¶
用该列非缺失值的均值填充
- MEDIAN()¶
用该列非缺失值的中位数填充
- MOST_FREQUENT()¶
用该列出现次数最多的值填充
- CONSTANT()¶
用固定常量填充(缺失指示列另算)
- static final class StandardScaler.Builder¶
构造 StandardScaler,设置是否中心化与是否缩放
withMean 与 withStd 默认都为 true,对应 z = (x - u) / s。两个开关只影响 transform 与 inverseTransform 的步骤,拟合阶段的均值、方差与 scale 始终计算,并被序列化。
两个开关可以任意组合:都关闭时 transform 直接返回输入的副本,只关闭 withStd 时输出为 x - u,只关闭 withMean 时输出为 x / s。
示例StandardScaler scaler = StandardScaler.builder() .withMean(true) .withStd(true) .build(); scaler.fit(train); Matrix standardized = scaler.transform(test); Matrix restored = scaler.inverseTransform(standardized);注意
拟合使用有偏方差(ddof=0),与 sklearn.preprocessing.StandardScaler 的默认行为一致。
注意
开关值以单字节写入模型文件,read 时按字节非零判断,因此来回读写不会丢失配置。
参见:basalt.ml.StandardScaler, basalt.ml.SimpleImputer.Builder
方法
- withMean(boolean withMean) → Builder¶
设置是否减去列均值
关闭后只做缩放,transform 输出 x / scale,inverseTransform 输出 x * scale。拟合阶段仍会计算均值并写进模型文件,只是变换时不再使用。
- 参数
withMean (boolean) – true 时 transform 减去均值、inverseTransform 加回均值;默认 true
- 返回
this,便于链式配置
- withStd(boolean withStd) → Builder¶
设置是否除以列标准差
缩放因子是总体标准差(ddof=0)。某列标准差不超过 1e-12 时该列 scale 记为 1.0,避免除零,因此常数特征不会被放大。
- 参数
withStd (boolean) – true 时按标准差缩放,默认 true;与 withMean 互相独立
- 返回
this,便于链式配置
- build() → StandardScaler¶
创建配置好的标准化器
构造器只保存两个开关,不分配统计数组,也不校验开关组合。
注意
未拟合时调用 transform、inverseTransform 或 mean、scale、variance 会抛 IllegalStateException。
- 返回
持有当前开关设置的 StandardScaler,尚未拟合
包内可见类型
以下类型没有 public 修饰符,但出现在公开签名中,因此一并列出。它们不是稳定 API,跨版本可能变化。
- final class BinnedFeatures¶
共享的分位分桶特征表示,树模型在桶上做分裂搜索
DecisionTree.fit、RandomForest.fit 与 HistogramGradientBoosting.fit 都先调用 build 把稠密特征离散成 byte 桶号;随机森林随后把同一份结果传给包内的 DecisionTree.fitBinned,避免为每棵树重复分桶与复制矩阵。
每个特征至多 maxBins 个桶,阈值取相邻顺序统计量的中点,判定语义为 value <= threshold 归左。原生内核可用且行数不少于 512、列数不少于 2 时走 NativeKernels.binFeaturesChecked,否则走 Java 排序路径。
build 还会校验 maxBins 落在 [2, 255](MAX_BINS),越界抛 IllegalArgumentException。
注意
中点按 a/2 + b/2 计算,避免两个极大有限值相加溢出;回退分支保证阈值仍严格落在 [a, b) 内。
- final class MlChecks¶
估计器共用的输入校验方法集合
各估计器的 fit 与 predict 入口通过 features、trainingData、predictionData 统一检查空引用、样本数与目标数一致、特征列数与拟合时一致,以及数组内所有取值有限;参数不合法抛 IllegalArgumentException,模型未拟合抛 IllegalStateException。
positiveFinite 与 nonNegativeFinite 供各 Builder 的 build() 校验超参数,因此非法学习率、容差一类问题在构建阶段就暴露,而不是等到训练。
- final class PackedTrees¶
把多棵树拼接成连续数组,供原生集成预测器读取
RandomForest 与 HistogramGradientBoosting 在训练结束以及 read 反序列化后调用 pack,把每棵 TreeModel 的 feature、threshold、left、right、value 平铺进一组数组,offsets 记录第 i 棵树的起始下标。
预测时整组数组一次性传给原生集成内核,避免逐棵树跨 JNI 调用;copyInto 在搬运时把子节点下标加上偏移,因此拼接后的树之间可以互相跳转。
注意
offsets 长度为树数加一,最后一项等于总节点数。
- final class TreeModel¶
扁平的数组式回归/分类树,推理为纯下标游走
节点存放在 feature、threshold、left、right、value 五个平行数组中,feature 为 -1 表示叶节点;predict 从 0 号节点开始按 value <= threshold 选择左右子节点,直到叶节点返回其值,不做对象分发。
DecisionTree、RandomForest、HistogramGradientBoosting 与 IsolationForest 共用这一表示,write 与 read 通过 ModelWriter/ModelReader 落盘,模型文件与内存布局一一对应,读回时校验节点数与子节点范围。
- private static final class DecisionTree.Workspace¶
一次 CART 拟合复用的直方图缓冲区
fitBinned 在完成类别编码后构造一次,随后的递归建树反复在其上累计统计量;按任务类型分支:分类保存每特征每桶的类别计数与左右计数,回归保存和、平方和与样本数。
缓冲区大小由 BinnedFeatures.maxBinCount 与特征数决定,随节点递归传递,避免在每个节点内部重新分配。
Workspace 也持有编码后的类别下标与回归目标数组,使分裂评估只依赖这一个对象。
- private static final class HistogramGradientBoosting.HistogramWorkspace¶
Java 直方图累加的分块暂存区
accumulateHistogramJava 在需要并行时按线程数切块,workspace 保存每个分块的 gradient、hessian、count 数组;clear 只清活动特征对应的桶区间,reduce 把各分块累加到 0 号块,再拷回目标直方图。
实例在 fit 时按特征数、最大桶数与线程数创建,训练结束置空;countAtOrBelow 与 subtractHistogram 也借用它的 maxBins 计算桶偏移。
- private record HistogramGradientBoosting.LeafCandidate¶
best-leaf-first 增长时优先队列中的待分裂叶节点
buildLeafWise 维护一个按 decision.gain 降序的优先队列,每次取出增益最大的候选展开;候选携带该节点的样本下标、深度、分裂决策与已算好的直方图,展开或丢弃时直方图归还池。
深度达到 maxDepth 或样本数不足 2 * minSamplesLeaf 时不再入队,避免无意义的分裂搜索;左右子节点生成后各自重新入队,直到叶数达到 maxLeaves。
- private static final class HistogramGradientBoosting.NodeHistogram¶
单节点的一阶/二阶梯度与样本计数直方图
由三组等长数组组成,下标为 feature * maxBins + bin;rentHistogram 从 histogramPool 借出,建树过程用完即归还,以减少每轮迭代在节点上的分配。
父子节点之间采用 LightGBM 的减法技巧:只累加较小的子节点,较大的子节点由父直方图减去小子节点得到,因此同一份缓冲区会在递归中多次复用。
- private record HistogramGradientBoosting.SplitDecision¶
一次分裂扫描的结果:特征、阈值、桶号与增益
bestSplit 在节点直方图上枚举桶边界并返回增益最大的候选;buildDepthWise 与 buildLeafWise 依据 gain 是否大于 0 判定该节点保持为叶,partition 则用 bin 把样本分到左右两支。
threshold 是写入 TreeModel 供推理比较的实数边界,bin 是训练期分桶下标,两者语义不同,不能互相替代。
- private record KMeans.Run¶
单次 k-means 重启的质心、惯性与迭代轮数
runOnce 用 k-means++ 选取初始质心后迭代到质心位移不超过 tolerance 的平方或达到 maxIterations,返回质心数组、各样本到所属质心平方距离之和(惯性)以及实际完成的轮数。
fit 对 restarts 次运行按惯性取最小者写入模型字段,Run 只作为这一次比较的载体,不对外暴露。
- private record KNearestNeighbors.Neighbor¶
分类 k 近邻的候选:距离与标签
predict 逐行扫描训练集,把 (距离, 标签) 放入按距离降序的小顶堆,堆大小超过 k 即弹出最远者;遍历结束后堆内即为 k 个最近邻,用于多数投票。
投票出现平票时取标签较小者,因此结果对标签的数值顺序有确定依赖。
- private record KNeighborsRegressor.Neighbor¶
回归 k 近邻的候选:距离与目标值
predict 逐行扫描训练集,把 (距离, 目标值) 放入按距离降序的堆并保持至多 k 个元素,最后对堆内 target 求和并除以堆的实际大小。
训练样本少于 k 时堆中只有实际找到的邻居,均值按堆的实际大小计算,而不是按 k。
- private record PCA.EigenDecomposition¶
对称矩阵对角化的特征值与特征向量
jacobi 做循环 Jacobi 对角化后返回该结果:eigenvalues 取收敛矩阵的对角线,eigenvectors 按行存放,第 i 个特征向量是矩阵的第 i 列。
fitCovariance 与 fitGram 都按特征值降序取前 componentCount 个分量;Gram 路径还会用 sqrt(特征值) 归一化特征向量,把样本空间的主成分转回特征空间。
- private record SVC.BinarySmoResult¶
一个二分类子问题的 SMO 解:系数与偏置
fit 对二分类建立一个子问题、对多分类按 one-vs-rest 每类建立一个,每个子问题调用 fitBinarySmo 得到该结果:alpha 长度等于样本数,bias 是决策函数偏置。
写回模型时 alpha 会先乘以标签 y[i] 存入 alphas[m],bias 直接写入 intercepts[m],推理时按同类顺序组合各子问题的输出。