迁移指南:MLlib (机器学习)
- 从 MLlib 3.5 升级到 4.0
- 从 MLlib 2.4 升级到 3.0
- 从 MLlib 2.2 升级到 2.3
- 从 MLlib 2.1 升级到 2.2
- 从 MLlib 2.0 升级到 2.1
- 从 MLlib 1.6 升级到 2.0
- 从 MLlib 1.5 升级到 1.6
- 从 MLlib 1.4 升级到 1.5
- 从 MLlib 1.3 升级到 1.4
- 从 MLlib 1.2 升级到 1.3
- 从 MLlib 1.1 升级到 1.2
- 从 MLlib 1.0 升级到 1.1
- 从 MLlib 0.9 升级到 1.0
请注意,本迁移指南描述了 MLlib 特有的项目。在将 MLlib 迁移到更高版本的基于 DataFrame 的 API 时,许多 SQL 迁移项目也适用。请参阅 迁移指南:SQL、Datasets 和 DataFrame。
从 MLlib 3.5 升级到 4.0
重大变更
无重大变更。
弃用和行为变更
弃用
无弃用。
行为变更
- SPARK-51132:PMML 模型导出所导出的 PMML 格式模型的 PMML XML 模式版本已从
PMML-4_3升级到PMML-4_4。
从 MLlib 2.4 升级到 3.0
重大变更
- 在 2.3 中已弃用的
OneHotEncoder在 3.0 中已移除,OneHotEncoderEstimator现已重命名为OneHotEncoder。 - 在 2.3 中已弃用的
org.apache.spark.ml.image.ImageSchema.readImages在 3.0 中已移除,请改用spark.read.format('image')。 - 在 2.1 中已弃用的、带参数 Int
runs的org.apache.spark.mllib.clustering.KMeans.train在 3.0 中已移除。请改用不带runs的train方法。 - 在 2.0 中已弃用的
org.apache.spark.mllib.classification.LogisticRegressionWithSGD在 3.0 中已移除,请改用org.apache.spark.ml.classification.LogisticRegression或spark.mllib.classification.LogisticRegressionWithLBFGS。 - 在 2.1 中已弃用的
org.apache.spark.mllib.feature.ChiSqSelectorModel.isSorted在 3.0 中已移除,不适用于子类使用。 - 在 2.0 中已弃用的
org.apache.spark.mllib.regression.RidgeRegressionWithSGD在 3.0 中已移除,请改用elasticNetParam= 0.0 的org.apache.spark.ml.regression.LinearRegression。请注意,RidgeRegressionWithSGD的默认regParam为 0.01,而LinearRegression的默认regParam为 0.0。 - 在 2.0 中已弃用的
org.apache.spark.mllib.regression.LassoWithSGD在 3.0 中已移除,请改用elasticNetParam= 1.0 的org.apache.spark.ml.regression.LinearRegression。请注意,LassoWithSGD的默认regParam为 0.01,而LinearRegression的默认regParam为 0.0。 - 在 2.0 中已弃用的
org.apache.spark.mllib.regression.LinearRegressionWithSGD在 3.0 中已移除,请改用org.apache.spark.ml.regression.LinearRegression或LBFGS。 - 在 2.1 中已弃用的
org.apache.spark.mllib.clustering.KMeans.getRuns和setRuns在 3.0 中已移除,自 Spark 2.0.0 起已无效果。 - 在 2.4 中已弃用的
org.apache.spark.ml.LinearSVCModel.setWeightCol在 3.0 中已移除,不适用于用户。 - 从 3.0 开始,
org.apache.spark.ml.classification.MultilayerPerceptronClassificationModel扩展了MultilayerPerceptronParams以公开训练参数。因此,MultilayerPerceptronClassificationModel中的layers已从Array[Int]更改为IntArrayParam。用户应使用MultilayerPerceptronClassificationModel.getLayers而不是MultilayerPerceptronClassificationModel.layers来检索层的大小。 - 在 2.4.5 中已弃用的
org.apache.spark.ml.classification.GBTClassifier.numTrees在 3.0 中已移除,请改用getNumTrees。 - 在 2.4 中已弃用的
org.apache.spark.ml.clustering.KMeansModel.computeCost在 3.0 中已移除,请改用ClusteringEvaluator。 - 在 2.0 中已弃用的
org.apache.spark.mllib.evaluation.MulticlassMetrics中的成员变量precision在 3.0 中已移除。请改用accuracy。 - 在 2.0 中已弃用的
org.apache.spark.mllib.evaluation.MulticlassMetrics中的成员变量recall在 3.0 中已移除。请改用accuracy。 - 在 2.0 中已弃用的
org.apache.spark.mllib.evaluation.MulticlassMetrics中的成员变量fMeasure在 3.0 中已移除。请改用accuracy。 - 在 2.0 中已弃用的
org.apache.spark.ml.util.GeneralMLWriter.context在 3.0 中已移除,请改用session。 - 在 2.0 中已弃用的
org.apache.spark.ml.util.MLWriter.context在 3.0 中已移除,请改用session。 - 在 2.0 中已弃用的
org.apache.spark.ml.util.MLReader.context在 3.0 中已移除,请改用session。 abstract class UnaryTransformer[IN, OUT, T <: UnaryTransformer[IN, OUT, T]]在 3.0 中已更改为abstract class UnaryTransformer[IN: TypeTag, OUT: TypeTag, T <: UnaryTransformer[IN, OUT, T]]。
弃用和行为变更
弃用
- SPARK-11215:
StringIndexerModel中的labels已弃用,并将在 3.1.0 中移除。请改用labelsArray。 - SPARK-25758:
BisectingKMeansModel中的computeCost已弃用,并将在未来版本中移除。请改用ClusteringEvaluator。
行为变更
- SPARK-11215:在 Spark 2.4 及以前版本中,当在
StringIndexer中将frequencyDesc或frequencyAsc指定为stringOrderType参数时,如果频率相同,字符串的顺序是未定义的。从 Spark 3.0 开始,频率相同的字符串会按字母顺序进一步排序。并且从 Spark 3.0 开始,StringIndexer支持编码多列。 - SPARK-20604:在 3.0 之前版本中,
Imputer要求输入列为 Double 或 Float 类型。在 3.0 中,此限制已解除,因此Imputer可以处理所有数字类型。 - SPARK-23469:在 Spark 3.0 中,
HashingTFTransformer 使用修正的 murmur3 哈希函数实现来将元素哈希到向量。Spark 3.0 中的HashingTF会将元素映射到向量中与 Spark 2 中不同的位置。然而,用 Spark 2.x 创建并用 Spark 3.0 加载的HashingTF仍将使用以前的哈希函数,并且行为不会改变。 - SPARK-28969:PySpark 的
OneVsRestModel中的setClassifier方法已在 3.0 中移除,以与 Scala 实现保持一致。调用方在创建模型后不应需要设置分类器。 - SPARK-25790:PCA 在 Spark 3.0 中增加了对超过 65535 列矩阵的支持。
- SPARK-28927:以前,当在非确定性输入数据上拟合 ALS 模型时,如果发生重新运行,用户可能会看到由输入/输出用户/项目块不匹配导致的 ArrayIndexOutOfBoundsException。从 3.0 开始,将抛出带有更清晰消息的 SparkException,并且原始的 ArrayIndexOutOfBoundsException 将被包装。
- SPARK-29232:在 3.0 之前版本中,
RandomForestRegressionModel不会更新底层 DecisionTreeRegressionModels 的参数映射。这在 3.0 中已修复。
从 MLlib 2.2 升级到 2.3
重大变更
- 逻辑回归模型摘要的类和特质层次结构已更改,以使其更清晰并更好地适应多类摘要的添加。对于将
LogisticRegressionTrainingSummary强制转换为BinaryLogisticRegressionTrainingSummary的用户代码,这是一个重大更改。用户应改用model.binarySummary方法。有关更多详细信息,请参阅 SPARK-17139(注意:这是一个ExperimentalAPI)。这不会影响 Python 的summary方法,该方法在多项式和二元情况下仍然可以正常工作。
弃用和行为变更
弃用
OneHotEncoder已弃用,并将在3.0中移除。它已被新的OneHotEncoderEstimator取代(参见 SPARK-13030)。**注意**:OneHotEncoderEstimator将在3.0中重命名为OneHotEncoder(但OneHotEncoderEstimator将保留为别名)。
行为变更
- SPARK-21027:
OneVsRest中使用的默认并行度现在设置为 1(即串行)。在2.2及更早版本中,并行度设置为 Scala 中的默认线程池大小。 - SPARK-22156:当
numIterations设置大于1时,Word2Vec的学习率更新不正确。这将导致2.3及更早版本之间的训练结果不同。 - SPARK-21681:修复了多项式逻辑回归中的一个边缘案例错误,该错误导致某些特征方差为零时系数不正确。
- SPARK-16957:树算法现在使用中点作为分裂值。这可能会改变模型训练的结果。
- SPARK-14657:修复了
RFormula在没有截距的情况下生成的特征与 R 中的输出不一致的问题。这可能会改变此场景中的模型训练结果。
从 MLlib 2.1 升级到 2.2
重大变更
无重大变更。
弃用和行为变更
弃用
无弃用。
行为变更
- SPARK-19787:
ALS.train方法(标记为DeveloperApi)的regParam默认值从1.0更改为0.1。**注意**:这不会影响ALSEstimator 或 Model,也不会影响 MLlib 的ALS类。 - SPARK-14772:修复了 Python 和 Scala API 在
Param.copy方法上的不一致问题。 - SPARK-11569:
StringIndexer现在以与未见值相同的方式处理NULL值。以前,无论handleInvalid参数的设置如何,都会抛出异常。
从 MLlib 2.0 升级到 2.1
重大变更
已移除的弃用方法
feature.ChiSqSelectorModel中的setLabelColclassification.RandomForestClassificationModel中的numTrees(现在指名为numTrees的 Param)regression.RandomForestRegressionModel中的numTrees(现在指名为numTrees的 Param)regression.LinearRegressionSummary中的modelPipelineStage中的validateParamsEvaluator中的validateParams
弃用和行为变更
弃用
- SPARK-18592:弃用
DecisionTreeClassificationModel、GBTClassificationModel、RandomForestClassificationModel、DecisionTreeRegressionModel、GBTRegressionModel和RandomForestRegressionModel的所有 Param setter 方法,除了输入/输出列 Param。
行为变更
- SPARK-17870:修复
ChiSqSelector的一个 bug,该 bug 可能会改变其结果。现在ChiSquareSelector使用 pValue 而不是原始统计量来选择固定数量的顶级特征。 - SPARK-3261:在 k 个不同质心不可用或未被选择的情况下,
KMeans返回的聚类中心可能少于 k 个。 - SPARK-17389:
KMeans将 k-means|| 初始化模式的默认步数从 5 减少到 2。
从 MLlib 1.6 升级到 2.0
重大变更
Spark 2.0 中有几项重大变更,具体如下。
基于 DataFrame 的 API 的线性代数类
Spark 的线性代数依赖已移至一个新项目 mllib-local(参见 SPARK-13944)。作为此更改的一部分,线性代数类被复制到新的包 spark.ml.linalg。现在,spark.ml 中的基于 DataFrame 的 API 依赖于 spark.ml.linalg 类,导致了一些重大变更,主要体现在各种模型类中(参见 SPARK-14810 了解完整列表)。
注意: spark.mllib 中基于 RDD 的 API 继续依赖于以前的包 spark.mllib.linalg。
转换向量和矩阵
虽然大多数管道组件支持加载的向后兼容性,但 Spark 2.0 之前版本中包含向量或矩阵列的一些现有 DataFrames 和管道可能需要迁移到新的 spark.ml 向量和矩阵类型。spark.mllib.util.MLUtils 中提供了用于将 DataFrame 列从 spark.mllib.linalg 转换为 spark.ml.linalg 类型(反之亦然)的实用工具。
还提供了用于转换单个向量和矩阵实例的实用方法。使用 mllib.linalg.Vector / mllib.linalg.Matrix 上的 asML 方法进行转换为 ml.linalg 类型,并使用 mllib.linalg.Vectors.fromML / mllib.linalg.Matrices.fromML 进行转换为 mllib.linalg 类型。
from pyspark.mllib.util import MLUtils
# convert DataFrame columns
convertedVecDF = MLUtils.convertVectorColumnsToML(vecDF)
convertedMatrixDF = MLUtils.convertMatrixColumnsToML(matrixDF)
# convert a single vector or matrix
mlVec = mllibVec.asML()
mlMat = mllibMat.asML()有关更多详细信息,请参阅 MLUtils Python 文档。
import org.apache.spark.mllib.util.MLUtils
// convert DataFrame columns
val convertedVecDF = MLUtils.convertVectorColumnsToML(vecDF)
val convertedMatrixDF = MLUtils.convertMatrixColumnsToML(matrixDF)
// convert a single vector or matrix
val mlVec: org.apache.spark.ml.linalg.Vector = mllibVec.asML
val mlMat: org.apache.spark.ml.linalg.Matrix = mllibMat.asML有关更多详细信息,请参阅 MLUtils Scala 文档。
import org.apache.spark.mllib.util.MLUtils;
import org.apache.spark.sql.Dataset;
// convert DataFrame columns
Dataset<Row> convertedVecDF = MLUtils.convertVectorColumnsToML(vecDF);
Dataset<Row> convertedMatrixDF = MLUtils.convertMatrixColumnsToML(matrixDF);
// convert a single vector or matrix
org.apache.spark.ml.linalg.Vector mlVec = mllibVec.asML();
org.apache.spark.ml.linalg.Matrix mlMat = mllibMat.asML();有关更多详细信息,请参阅 MLUtils Java 文档。
已移除的弃用方法
spark.mllib 和 spark.ml 包中移除了几个已弃用的方法
ml.evaluation.BinaryClassificationEvaluator中的setScoreColspark.ml中LinearRegression和LogisticRegression中的weightsmllib.optimization.LBFGS中的setMaxNumIterations(标记为DeveloperApi)mllib.rdd.RDDFunctions中的treeReduce和treeAggregate(这些函数直接在RDD上可用,并被标记为DeveloperApi)mllib.tree.configuration.Strategy中的defaultStrategymllib.tree.Node中的buildmllib.util.MLUtils中用于多类和加载/保存标记数据方法的 libsvm 加载器
重大变更的完整列表可在 SPARK-14810 中找到。
弃用和行为变更
弃用
spark.mllib 和 spark.ml 包中的弃用包括
- SPARK-14984:在
spark.ml.regression.LinearRegressionSummary中,model字段已弃用。 - SPARK-13784:在
spark.ml.regression.RandomForestRegressionModel和spark.ml.classification.RandomForestClassificationModel中,numTrees参数已弃用,取而代之的是getNumTrees方法。 - SPARK-13761:在
spark.ml.param.Params中,validateParams方法已弃用。我们将重写方法中的所有功能移至相应的transformSchema。 - SPARK-14829:在
spark.mllib包中,LinearRegressionWithSGD、LassoWithSGD、RidgeRegressionWithSGD和LogisticRegressionWithSGD已弃用。我们建议用户使用spark.ml.regression.LinearRegression和spark.ml.classification.LogisticRegression。 - SPARK-14900:在
spark.mllib.evaluation.MulticlassMetrics中,参数precision、recall和fMeasure已弃用,取而代之的是accuracy。 - SPARK-15644:在
spark.ml.util.MLReader和spark.ml.util.MLWriter中,context方法已弃用,取而代之的是session。 - 在
spark.ml.feature.ChiSqSelectorModel中,setLabelCol方法已弃用,因为它未被ChiSqSelectorModel使用。
行为变更
spark.mllib 和 spark.ml 包中的行为变更包括
- SPARK-7780:
spark.mllib.classification.LogisticRegressionWithLBFGS现在直接调用spark.ml.classification.LogisticRegression进行二元分类。这将引入spark.mllib.classification.LogisticRegressionWithLBFGS的以下行为变更- 使用 L1/L2 Updater 训练二元分类模型时,截距将不进行正则化。
- 如果用户设置不使用正则化,则无论是否进行特征缩放,训练都将以相同的收敛速度返回相同的解。
- SPARK-13429:为了提供与
spark.ml.classification.LogisticRegression更好且一致的结果,spark.mllib.classification.LogisticRegressionWithLBFGS的默认值convergenceTol已从 1E-4 更改为 1E-6。 - SPARK-12363:修复了
PowerIterationClustering的一个 bug,这可能会改变其结果。 - SPARK-13048:如果正在使用检查点,使用
EM优化器 的LDA默认会保留最后一个检查点。 - SPARK-12153:
Word2Vec现在尊重句子边界。以前,它没有正确处理它们。 - SPARK-10574:
HashingTF在spark.ml和spark.mllib中都使用MurmurHash3作为默认哈希算法。 - SPARK-14768:PySpark
Param的expectedType参数已移除。 - SPARK-14931:一些默认的
Param值(在 Scala 和 Python 的管道中不匹配)已更改。 - SPARK-13600:
QuantileDiscretizer现在使用spark.sql.DataFrameStatFunctions.approxQuantile来查找分割点(以前使用自定义采样逻辑)。相同输入数据和参数的输出桶将有所不同。
从 MLlib 1.5 升级到 1.6
spark.mllib 或 spark.ml 包中没有重大 API 更改,但有弃用和行为变更。
弃用
- SPARK-11358:在
spark.mllib.clustering.KMeans中,runs参数已弃用。 - SPARK-10592:在
spark.ml.classification.LogisticRegressionModel和spark.ml.regression.LinearRegressionModel中,weights字段已弃用,取而代之的是新名称coefficients。这有助于消除与赋予算法的实例(行)“权重”的歧义。
行为变更
- SPARK-7770:
spark.mllib.tree.GradientBoostedTrees:validationTol在 1.6 中语义已更改。以前,它是一个错误绝对变化的阈值。现在,它类似于GradientDescent的convergenceTol的行为:对于大错误,它使用相对误差(相对于前一个错误);对于小错误(< 0.01),它使用绝对误差。 - SPARK-11069:
spark.ml.feature.RegexTokenizer:以前,它在标记化之前不会将字符串转换为小写。现在,默认情况下它会转换为小写,并提供一个不转换的选项。这与更简单的Tokenizer转换器的行为相匹配。
从 MLlib 1.4 升级到 1.5
在 spark.mllib 包中,没有重大 API 更改,但有一些行为更改
- SPARK-9005:
RegressionMetrics.explainedVariance返回平均回归平方和。 - SPARK-8600:
NaiveBayesModel.labels变为排序。 - SPARK-3382:
GradientDescent具有默认收敛容差1e-3,因此迭代可能比 1.4 更早结束。
在 spark.ml 包中,存在一个重大 API 更改和一个行为更改
- SPARK-9268:由于 Scala 编译器错误,Java 的 varargs 支持已从
Params.setDefault中移除。 - SPARK-10097:添加了
Evaluator.isLargerBetter以指示指标排序。像 RMSE 这样的指标不再像 1.4 中那样翻转符号。
从 MLlib 1.3 升级到 1.4
在 spark.mllib 包中,有几项重大变更,但都发生在 DeveloperApi 或 Experimental API 中
- 梯度提升树
- (重大变更)
Loss.gradient方法的签名已更改。这仅对编写了自己的 GBT 损失的用户有影响。 - (重大变更)由于对案例类字段的修改,案例类
BoostingStrategy的apply和copy方法已更改。这可能对使用BoostingStrategy设置 GBT 参数的用户产生影响。
- (重大变更)
- (重大变更)
LDA.run的返回值已更改。它现在返回一个抽象类LDAModel,而不是具体类DistributedLDAModel。LDAModel类型的对象仍然可以转换为适当的具体类型,具体取决于优化算法。
在 spark.ml 包中,发生了几项主要的 API 更改,包括
Param和其他用于指定参数的 API- 管道组件的
uid唯一 ID - 某些类的重组
由于 spark.ml API 在 Spark 1.3 中是 Alpha 组件,我们不在此处列出所有更改。但是,自 1.4 以来,spark.ml 不再是 Alpha 组件,我们将为未来版本提供任何 API 更改的详细信息。
从 MLlib 1.2 升级到 1.3
在 spark.mllib 包中,有几项重大变更。第一项变更(在 ALS 中)是唯一一项不在标记为 Alpha 或 Experimental 的组件中的变更。
- (重大变更)在
ALS中,冗余方法solveLeastSquares已移除。DeveloperApi方法analyzeBlocks也已移除。 - (重大变更)
StandardScalerModel仍然是一个 Alpha 组件。其中,variance方法已被std方法取代。要计算原始variance方法返回的列方差值,只需将std返回的标准差值平方即可。 - (重大变更)
StreamingLinearRegressionWithSGD仍然是一个实验性组件。其中有两项变更- 接受参数的构造函数已被移除,取而代之的是使用默认构造函数和参数设置方法的构建器模式。
- 变量
model不再是公共的。
- (重大变更)
DecisionTree仍然是一个实验性组件。在它及其相关类中,有几项变更- 在
DecisionTree中,已弃用的类方法train已移除。(对象/静态train方法仍然存在。) - 在
Strategy中,checkpointDir参数已移除。检查点仍然受支持,但必须在调用树和树集成训练之前设置检查点目录。
- 在
PythonMLlibAPI(Scala/Java 和 Python 之间用于 MLlib 的接口)以前是公共 API,但现在是私有的,声明为private[python]。这从未打算用于外部使用。- 在线性回归(包括 Lasso 和 Ridge 回归)中,平方损失现在除以 2。因此,为了产生与 1.2 中相同的结果,正则化参数需要除以 2,步长需要乘以 2。
在 spark.ml 包中,主要的 API 更改来自 Spark SQL。我们在此列出最重要的更改
- 旧的 SchemaRDD 已被 DataFrame 取代,API 有所修改。
spark.ml中所有以前使用 SchemaRDD 的算法现在都使用 DataFrame。 - 在 Spark 1.2 中,我们通过调用
import sqlContext._(其中sqlContext是SQLContext的实例)将LabeledPoint的RDD隐式转换为SchemaRDD。这些隐式已移动,因此我们现在调用import sqlContext.implicits._。 - SQL 的 Java API 也相应地发生了变化。有关详细信息,请参阅上面的示例和 Spark SQL 编程指南。
其他更改在 LogisticRegression 中
scoreCol输出列(默认值为“score”)已重命名为probabilityCol(默认值为“probability”)。类型最初是Double(表示类别 1.0 的概率),但现在是Vector(表示每个类别的概率,以支持未来的多分类)。- 在 Spark 1.2 中,
LogisticRegressionModel不包含截距。在 Spark 1.3 中,它包含截距;但是,它将始终为 0.0,因为它使用 spark.mllib.LogisticRegressionWithLBFGS 的默认设置。使用截距的选项将在未来添加。
从 MLlib 1.1 升级到 1.2
MLlib v1.2 中唯一的 API 更改在 DecisionTree 中,它在 MLlib 1.2 中仍然是实验性 API
-
(重大变更)分类的 Scala API 接受一个命名参数,用于指定类的数量。在 MLlib v1.1 中,此参数在 Python 中称为
numClasses,在 Scala 中称为numClassesForClassification。在 MLlib v1.2 中,这两个名称都设置为numClasses。此numClasses参数可通过Strategy或DecisionTree静态trainClassifier和trainRegressor方法指定。 -
(重大变更)
Node的 API 已更改。这通常不应影响用户代码,除非用户手动构造决策树(而不是使用trainClassifier或trainRegressor方法)。树Node现在包含更多信息,包括预测标签的概率(用于分类)。 -
打印方法的输出已更改。
toString(Scala/Java) 和__repr__(Python) 方法以前会打印完整模型;现在它们打印摘要。对于完整模型,请使用toDebugString。
Spark 发行版中的示例和 决策树指南 中的示例已相应更新。
从 MLlib 1.0 升级到 1.1
MLlib v1.1 中唯一的 API 更改在 DecisionTree 中,它在 MLlib 1.1 中仍然是实验性 API
-
(重大变更)树深度的含义已更改 1,以与 scikit-learn 和 rpart 中树的实现相匹配。在 MLlib v1.0 中,深度为 1 的树有 1 个叶节点,深度为 2 的树有 1 个根节点和 2 个叶节点。在 MLlib v1.1 中,深度为 0 的树有 1 个叶节点,深度为 1 的树有 1 个根节点和 2 个叶节点。此深度由
Strategy中的maxDepth参数或通过DecisionTree静态trainClassifier和trainRegressor方法指定。 -
(非重大变更)我们建议使用新添加的
trainClassifier和trainRegressor方法来构建DecisionTree,而不是使用旧的参数类Strategy。这些新的训练方法明确区分分类和回归,并将专门的参数类型替换为简单的String类型。
新推荐的 trainClassifier 和 trainRegressor 的示例在 决策树指南 中给出。
从 MLlib 0.9 升级到 1.0
在 MLlib v1.0 中,我们以统一的方式支持密集和稀疏输入,这引入了一些重大更改。如果您的数据是稀疏的,请将其存储为稀疏格式而不是密集格式,以利用存储和计算中的稀疏性。详细信息如下所述。