snowflake-ml-python 1.3.1__py3-none-any.whl → 1.4.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- snowflake/ml/_internal/env_utils.py +11 -1
- snowflake/ml/_internal/human_readable_id/adjectives.txt +128 -0
- snowflake/ml/_internal/human_readable_id/animals.txt +128 -0
- snowflake/ml/_internal/human_readable_id/hrid_generator.py +40 -0
- snowflake/ml/_internal/human_readable_id/hrid_generator_base.py +135 -0
- snowflake/ml/_internal/utils/formatting.py +1 -1
- snowflake/ml/_internal/utils/identifier.py +3 -1
- snowflake/ml/_internal/utils/sql_identifier.py +2 -6
- snowflake/ml/feature_store/feature_store.py +166 -184
- snowflake/ml/feature_store/feature_view.py +12 -24
- snowflake/ml/fileset/sfcfs.py +56 -50
- snowflake/ml/fileset/stage_fs.py +48 -13
- snowflake/ml/model/_client/model/model_version_impl.py +6 -49
- snowflake/ml/model/_client/ops/model_ops.py +78 -29
- snowflake/ml/model/_client/sql/model.py +23 -2
- snowflake/ml/model/_client/sql/model_version.py +22 -1
- snowflake/ml/model/_deploy_client/image_builds/server_image_builder.py +1 -3
- snowflake/ml/model/_deploy_client/snowservice/deploy.py +5 -2
- snowflake/ml/model/_model_composer/model_composer.py +7 -5
- snowflake/ml/model/_model_composer/model_manifest/model_manifest.py +19 -54
- snowflake/ml/model/_model_composer/model_manifest/model_manifest_schema.py +8 -1
- snowflake/ml/model/_model_composer/model_method/infer_table_function.py_template +1 -1
- snowflake/ml/model/_model_composer/model_method/model_method.py +6 -10
- snowflake/ml/model/_packager/model_handlers/catboost.py +206 -0
- snowflake/ml/model/_packager/model_handlers/lightgbm.py +218 -0
- snowflake/ml/model/_packager/model_handlers/sklearn.py +3 -0
- snowflake/ml/model/_packager/model_handlers/snowmlmodel.py +13 -1
- snowflake/ml/model/_packager/model_handlers/xgboost.py +1 -1
- snowflake/ml/model/_packager/model_meta/_core_requirements.py +1 -1
- snowflake/ml/model/_packager/model_meta/model_meta.py +36 -6
- snowflake/ml/model/_packager/model_meta/model_meta_schema.py +20 -1
- snowflake/ml/model/_packager/model_meta_migrator/migrator_plans.py +3 -1
- snowflake/ml/model/_packager/model_packager.py +2 -2
- snowflake/ml/model/{_model_composer/model_runtime/_runtime_requirements.py → _packager/model_runtime/_snowml_inference_alternative_requirements.py} +1 -1
- snowflake/ml/model/_packager/model_runtime/model_runtime.py +137 -0
- snowflake/ml/model/custom_model.py +3 -1
- snowflake/ml/model/type_hints.py +21 -2
- snowflake/ml/modeling/_internal/estimator_utils.py +16 -11
- snowflake/ml/modeling/_internal/local_implementations/pandas_handlers.py +4 -1
- snowflake/ml/modeling/_internal/model_specifications.py +3 -1
- snowflake/ml/modeling/_internal/snowpark_implementations/distributed_hpo_trainer.py +545 -0
- snowflake/ml/modeling/_internal/snowpark_implementations/snowpark_handlers.py +8 -5
- snowflake/ml/modeling/calibration/calibrated_classifier_cv.py +195 -123
- snowflake/ml/modeling/cluster/affinity_propagation.py +195 -123
- snowflake/ml/modeling/cluster/agglomerative_clustering.py +195 -123
- snowflake/ml/modeling/cluster/birch.py +195 -123
- snowflake/ml/modeling/cluster/bisecting_k_means.py +195 -123
- snowflake/ml/modeling/cluster/dbscan.py +195 -123
- snowflake/ml/modeling/cluster/feature_agglomeration.py +195 -123
- snowflake/ml/modeling/cluster/k_means.py +195 -123
- snowflake/ml/modeling/cluster/mean_shift.py +195 -123
- snowflake/ml/modeling/cluster/mini_batch_k_means.py +195 -123
- snowflake/ml/modeling/cluster/optics.py +195 -123
- snowflake/ml/modeling/cluster/spectral_biclustering.py +195 -123
- snowflake/ml/modeling/cluster/spectral_clustering.py +195 -123
- snowflake/ml/modeling/cluster/spectral_coclustering.py +195 -123
- snowflake/ml/modeling/compose/column_transformer.py +195 -123
- snowflake/ml/modeling/compose/transformed_target_regressor.py +195 -123
- snowflake/ml/modeling/covariance/elliptic_envelope.py +195 -123
- snowflake/ml/modeling/covariance/empirical_covariance.py +195 -123
- snowflake/ml/modeling/covariance/graphical_lasso.py +195 -123
- snowflake/ml/modeling/covariance/graphical_lasso_cv.py +195 -123
- snowflake/ml/modeling/covariance/ledoit_wolf.py +195 -123
- snowflake/ml/modeling/covariance/min_cov_det.py +195 -123
- snowflake/ml/modeling/covariance/oas.py +195 -123
- snowflake/ml/modeling/covariance/shrunk_covariance.py +195 -123
- snowflake/ml/modeling/decomposition/dictionary_learning.py +195 -123
- snowflake/ml/modeling/decomposition/factor_analysis.py +195 -123
- snowflake/ml/modeling/decomposition/fast_ica.py +195 -123
- snowflake/ml/modeling/decomposition/incremental_pca.py +195 -123
- snowflake/ml/modeling/decomposition/kernel_pca.py +195 -123
- snowflake/ml/modeling/decomposition/mini_batch_dictionary_learning.py +195 -123
- snowflake/ml/modeling/decomposition/mini_batch_sparse_pca.py +195 -123
- snowflake/ml/modeling/decomposition/pca.py +195 -123
- snowflake/ml/modeling/decomposition/sparse_pca.py +195 -123
- snowflake/ml/modeling/decomposition/truncated_svd.py +195 -123
- snowflake/ml/modeling/discriminant_analysis/linear_discriminant_analysis.py +195 -123
- snowflake/ml/modeling/discriminant_analysis/quadratic_discriminant_analysis.py +195 -123
- snowflake/ml/modeling/ensemble/ada_boost_classifier.py +195 -123
- snowflake/ml/modeling/ensemble/ada_boost_regressor.py +195 -123
- snowflake/ml/modeling/ensemble/bagging_classifier.py +195 -123
- snowflake/ml/modeling/ensemble/bagging_regressor.py +195 -123
- snowflake/ml/modeling/ensemble/extra_trees_classifier.py +195 -123
- snowflake/ml/modeling/ensemble/extra_trees_regressor.py +195 -123
- snowflake/ml/modeling/ensemble/gradient_boosting_classifier.py +195 -123
- snowflake/ml/modeling/ensemble/gradient_boosting_regressor.py +195 -123
- snowflake/ml/modeling/ensemble/hist_gradient_boosting_classifier.py +195 -123
- snowflake/ml/modeling/ensemble/hist_gradient_boosting_regressor.py +195 -123
- snowflake/ml/modeling/ensemble/isolation_forest.py +195 -123
- snowflake/ml/modeling/ensemble/random_forest_classifier.py +195 -123
- snowflake/ml/modeling/ensemble/random_forest_regressor.py +195 -123
- snowflake/ml/modeling/ensemble/stacking_regressor.py +195 -123
- snowflake/ml/modeling/ensemble/voting_classifier.py +195 -123
- snowflake/ml/modeling/ensemble/voting_regressor.py +195 -123
- snowflake/ml/modeling/feature_selection/generic_univariate_select.py +195 -123
- snowflake/ml/modeling/feature_selection/select_fdr.py +195 -123
- snowflake/ml/modeling/feature_selection/select_fpr.py +195 -123
- snowflake/ml/modeling/feature_selection/select_fwe.py +195 -123
- snowflake/ml/modeling/feature_selection/select_k_best.py +195 -123
- snowflake/ml/modeling/feature_selection/select_percentile.py +195 -123
- snowflake/ml/modeling/feature_selection/sequential_feature_selector.py +195 -123
- snowflake/ml/modeling/feature_selection/variance_threshold.py +195 -123
- snowflake/ml/modeling/framework/_utils.py +8 -1
- snowflake/ml/modeling/framework/base.py +24 -6
- snowflake/ml/modeling/gaussian_process/gaussian_process_classifier.py +195 -123
- snowflake/ml/modeling/gaussian_process/gaussian_process_regressor.py +195 -123
- snowflake/ml/modeling/impute/iterative_imputer.py +195 -123
- snowflake/ml/modeling/impute/knn_imputer.py +195 -123
- snowflake/ml/modeling/impute/missing_indicator.py +195 -123
- snowflake/ml/modeling/impute/simple_imputer.py +4 -15
- snowflake/ml/modeling/kernel_approximation/additive_chi2_sampler.py +195 -123
- snowflake/ml/modeling/kernel_approximation/nystroem.py +195 -123
- snowflake/ml/modeling/kernel_approximation/polynomial_count_sketch.py +195 -123
- snowflake/ml/modeling/kernel_approximation/rbf_sampler.py +195 -123
- snowflake/ml/modeling/kernel_approximation/skewed_chi2_sampler.py +195 -123
- snowflake/ml/modeling/kernel_ridge/kernel_ridge.py +195 -123
- snowflake/ml/modeling/lightgbm/lgbm_classifier.py +198 -125
- snowflake/ml/modeling/lightgbm/lgbm_regressor.py +198 -125
- snowflake/ml/modeling/linear_model/ard_regression.py +195 -123
- snowflake/ml/modeling/linear_model/bayesian_ridge.py +195 -123
- snowflake/ml/modeling/linear_model/elastic_net.py +195 -123
- snowflake/ml/modeling/linear_model/elastic_net_cv.py +195 -123
- snowflake/ml/modeling/linear_model/gamma_regressor.py +195 -123
- snowflake/ml/modeling/linear_model/huber_regressor.py +195 -123
- snowflake/ml/modeling/linear_model/lars.py +195 -123
- snowflake/ml/modeling/linear_model/lars_cv.py +195 -123
- snowflake/ml/modeling/linear_model/lasso.py +195 -123
- snowflake/ml/modeling/linear_model/lasso_cv.py +195 -123
- snowflake/ml/modeling/linear_model/lasso_lars.py +195 -123
- snowflake/ml/modeling/linear_model/lasso_lars_cv.py +195 -123
- snowflake/ml/modeling/linear_model/lasso_lars_ic.py +195 -123
- snowflake/ml/modeling/linear_model/linear_regression.py +195 -123
- snowflake/ml/modeling/linear_model/logistic_regression.py +195 -123
- snowflake/ml/modeling/linear_model/logistic_regression_cv.py +195 -123
- snowflake/ml/modeling/linear_model/multi_task_elastic_net.py +195 -123
- snowflake/ml/modeling/linear_model/multi_task_elastic_net_cv.py +195 -123
- snowflake/ml/modeling/linear_model/multi_task_lasso.py +195 -123
- snowflake/ml/modeling/linear_model/multi_task_lasso_cv.py +195 -123
- snowflake/ml/modeling/linear_model/orthogonal_matching_pursuit.py +195 -123
- snowflake/ml/modeling/linear_model/passive_aggressive_classifier.py +195 -123
- snowflake/ml/modeling/linear_model/passive_aggressive_regressor.py +195 -123
- snowflake/ml/modeling/linear_model/perceptron.py +195 -123
- snowflake/ml/modeling/linear_model/poisson_regressor.py +195 -123
- snowflake/ml/modeling/linear_model/ransac_regressor.py +195 -123
- snowflake/ml/modeling/linear_model/ridge.py +195 -123
- snowflake/ml/modeling/linear_model/ridge_classifier.py +195 -123
- snowflake/ml/modeling/linear_model/ridge_classifier_cv.py +195 -123
- snowflake/ml/modeling/linear_model/ridge_cv.py +195 -123
- snowflake/ml/modeling/linear_model/sgd_classifier.py +195 -123
- snowflake/ml/modeling/linear_model/sgd_one_class_svm.py +195 -123
- snowflake/ml/modeling/linear_model/sgd_regressor.py +195 -123
- snowflake/ml/modeling/linear_model/theil_sen_regressor.py +195 -123
- snowflake/ml/modeling/linear_model/tweedie_regressor.py +195 -123
- snowflake/ml/modeling/manifold/isomap.py +195 -123
- snowflake/ml/modeling/manifold/mds.py +195 -123
- snowflake/ml/modeling/manifold/spectral_embedding.py +195 -123
- snowflake/ml/modeling/manifold/tsne.py +195 -123
- snowflake/ml/modeling/mixture/bayesian_gaussian_mixture.py +195 -123
- snowflake/ml/modeling/mixture/gaussian_mixture.py +195 -123
- snowflake/ml/modeling/model_selection/grid_search_cv.py +42 -18
- snowflake/ml/modeling/model_selection/randomized_search_cv.py +42 -18
- snowflake/ml/modeling/multiclass/one_vs_one_classifier.py +195 -123
- snowflake/ml/modeling/multiclass/one_vs_rest_classifier.py +195 -123
- snowflake/ml/modeling/multiclass/output_code_classifier.py +195 -123
- snowflake/ml/modeling/naive_bayes/bernoulli_nb.py +195 -123
- snowflake/ml/modeling/naive_bayes/categorical_nb.py +195 -123
- snowflake/ml/modeling/naive_bayes/complement_nb.py +195 -123
- snowflake/ml/modeling/naive_bayes/gaussian_nb.py +195 -123
- snowflake/ml/modeling/naive_bayes/multinomial_nb.py +195 -123
- snowflake/ml/modeling/neighbors/k_neighbors_classifier.py +195 -123
- snowflake/ml/modeling/neighbors/k_neighbors_regressor.py +195 -123
- snowflake/ml/modeling/neighbors/kernel_density.py +195 -123
- snowflake/ml/modeling/neighbors/local_outlier_factor.py +195 -123
- snowflake/ml/modeling/neighbors/nearest_centroid.py +195 -123
- snowflake/ml/modeling/neighbors/nearest_neighbors.py +195 -123
- snowflake/ml/modeling/neighbors/neighborhood_components_analysis.py +195 -123
- snowflake/ml/modeling/neighbors/radius_neighbors_classifier.py +195 -123
- snowflake/ml/modeling/neighbors/radius_neighbors_regressor.py +195 -123
- snowflake/ml/modeling/neural_network/bernoulli_rbm.py +195 -123
- snowflake/ml/modeling/neural_network/mlp_classifier.py +195 -123
- snowflake/ml/modeling/neural_network/mlp_regressor.py +195 -123
- snowflake/ml/modeling/pipeline/pipeline.py +4 -4
- snowflake/ml/modeling/preprocessing/binarizer.py +1 -5
- snowflake/ml/modeling/preprocessing/k_bins_discretizer.py +1 -5
- snowflake/ml/modeling/preprocessing/label_encoder.py +1 -5
- snowflake/ml/modeling/preprocessing/max_abs_scaler.py +1 -5
- snowflake/ml/modeling/preprocessing/min_max_scaler.py +10 -12
- snowflake/ml/modeling/preprocessing/normalizer.py +1 -5
- snowflake/ml/modeling/preprocessing/one_hot_encoder.py +1 -5
- snowflake/ml/modeling/preprocessing/ordinal_encoder.py +1 -5
- snowflake/ml/modeling/preprocessing/polynomial_features.py +195 -123
- snowflake/ml/modeling/preprocessing/robust_scaler.py +1 -5
- snowflake/ml/modeling/preprocessing/standard_scaler.py +11 -11
- snowflake/ml/modeling/semi_supervised/label_propagation.py +195 -123
- snowflake/ml/modeling/semi_supervised/label_spreading.py +195 -123
- snowflake/ml/modeling/svm/linear_svc.py +195 -123
- snowflake/ml/modeling/svm/linear_svr.py +195 -123
- snowflake/ml/modeling/svm/nu_svc.py +195 -123
- snowflake/ml/modeling/svm/nu_svr.py +195 -123
- snowflake/ml/modeling/svm/svc.py +195 -123
- snowflake/ml/modeling/svm/svr.py +195 -123
- snowflake/ml/modeling/tree/decision_tree_classifier.py +195 -123
- snowflake/ml/modeling/tree/decision_tree_regressor.py +195 -123
- snowflake/ml/modeling/tree/extra_tree_classifier.py +195 -123
- snowflake/ml/modeling/tree/extra_tree_regressor.py +195 -123
- snowflake/ml/modeling/xgboost/xgb_classifier.py +195 -123
- snowflake/ml/modeling/xgboost/xgb_regressor.py +195 -123
- snowflake/ml/modeling/xgboost/xgbrf_classifier.py +195 -123
- snowflake/ml/modeling/xgboost/xgbrf_regressor.py +195 -123
- snowflake/ml/registry/_manager/model_manager.py +5 -1
- snowflake/ml/registry/model_registry.py +99 -26
- snowflake/ml/registry/registry.py +3 -2
- snowflake/ml/version.py +1 -1
- {snowflake_ml_python-1.3.1.dist-info → snowflake_ml_python-1.4.1.dist-info}/METADATA +94 -55
- {snowflake_ml_python-1.3.1.dist-info → snowflake_ml_python-1.4.1.dist-info}/RECORD +218 -212
- snowflake/ml/model/_model_composer/model_runtime/model_runtime.py +0 -97
- {snowflake_ml_python-1.3.1.dist-info → snowflake_ml_python-1.4.1.dist-info}/LICENSE.txt +0 -0
- {snowflake_ml_python-1.3.1.dist-info → snowflake_ml_python-1.4.1.dist-info}/WHEEL +0 -0
- {snowflake_ml_python-1.3.1.dist-info → snowflake_ml_python-1.4.1.dist-info}/top_level.txt +0 -0
@@ -33,6 +33,15 @@ from snowflake.ml.modeling._internal.transformer_protocols import (
|
|
33
33
|
BatchInferenceKwargsTypedDict,
|
34
34
|
ScoreKwargsTypedDict
|
35
35
|
)
|
36
|
+
from snowflake.ml.model._signatures import utils as model_signature_utils
|
37
|
+
from snowflake.ml.model.model_signature import (
|
38
|
+
BaseFeatureSpec,
|
39
|
+
DataType,
|
40
|
+
FeatureSpec,
|
41
|
+
ModelSignature,
|
42
|
+
_infer_signature,
|
43
|
+
_rename_signature_with_snowflake_identifiers,
|
44
|
+
)
|
36
45
|
|
37
46
|
from snowflake.ml.modeling._internal.model_transformer_builder import ModelTransformerBuilder
|
38
47
|
|
@@ -43,16 +52,6 @@ from snowflake.ml.modeling._internal.estimator_utils import (
|
|
43
52
|
validate_sklearn_args,
|
44
53
|
)
|
45
54
|
|
46
|
-
from snowflake.ml.model.model_signature import (
|
47
|
-
DataType,
|
48
|
-
FeatureSpec,
|
49
|
-
ModelSignature,
|
50
|
-
_infer_signature,
|
51
|
-
_rename_signature_with_snowflake_identifiers,
|
52
|
-
BaseFeatureSpec,
|
53
|
-
)
|
54
|
-
from snowflake.ml.model._signatures import utils as model_signature_utils
|
55
|
-
|
56
55
|
_PROJECT = "ModelDevelopment"
|
57
56
|
# Derive subproject from module name by removing "sklearn"
|
58
57
|
# and converting module name from underscore to CamelCase
|
@@ -233,12 +232,7 @@ class Birch(BaseTransformer):
|
|
233
232
|
)
|
234
233
|
return selected_cols
|
235
234
|
|
236
|
-
|
237
|
-
project=_PROJECT,
|
238
|
-
subproject=_SUBPROJECT,
|
239
|
-
custom_tags=dict([("autogen", True)]),
|
240
|
-
)
|
241
|
-
def fit(self, dataset: Union[DataFrame, pd.DataFrame]) -> "Birch":
|
235
|
+
def _fit(self, dataset: Union[DataFrame, pd.DataFrame]) -> "Birch":
|
242
236
|
"""Build a CF Tree for the input data
|
243
237
|
For more details on this function, see [sklearn.cluster.Birch.fit]
|
244
238
|
(https://scikit-learn.org/stable/modules/generated/sklearn.cluster.Birch.html#sklearn.cluster.Birch.fit)
|
@@ -265,12 +259,14 @@ class Birch(BaseTransformer):
|
|
265
259
|
|
266
260
|
self._snowpark_cols = dataset.select(self.input_cols).columns
|
267
261
|
|
268
|
-
|
262
|
+
# If we are already in a stored procedure, no need to kick off another one.
|
269
263
|
if SNOWML_SPROC_ENV in os.environ:
|
270
264
|
statement_params = telemetry.get_function_usage_statement_params(
|
271
265
|
project=_PROJECT,
|
272
266
|
subproject=_SUBPROJECT,
|
273
|
-
function_name=telemetry.get_statement_params_full_func_name(
|
267
|
+
function_name=telemetry.get_statement_params_full_func_name(
|
268
|
+
inspect.currentframe(), Birch.__class__.__name__
|
269
|
+
),
|
274
270
|
api_calls=[Session.call],
|
275
271
|
custom_tags=dict([("autogen", True)]) if self._autogenerated else None,
|
276
272
|
)
|
@@ -291,7 +287,7 @@ class Birch(BaseTransformer):
|
|
291
287
|
)
|
292
288
|
self._sklearn_object = model_trainer.train()
|
293
289
|
self._is_fitted = True
|
294
|
-
self.
|
290
|
+
self._generate_model_signatures(dataset)
|
295
291
|
return self
|
296
292
|
|
297
293
|
def _batch_inference_validate_snowpark(
|
@@ -367,7 +363,9 @@ class Birch(BaseTransformer):
|
|
367
363
|
# when it is classifier, infer the datatype from label columns
|
368
364
|
if expected_type_inferred == "" and 'predict' in self.model_signatures:
|
369
365
|
# Batch inference takes a single expected output column type. Use the first columns type for now.
|
370
|
-
label_cols_signatures = [
|
366
|
+
label_cols_signatures = [
|
367
|
+
row for row in self.model_signatures['predict'].outputs if row.name in self.output_cols
|
368
|
+
]
|
371
369
|
if len(label_cols_signatures) == 0:
|
372
370
|
error_str = f"Output columns {self.output_cols} do not match model signatures {self.model_signatures['predict'].outputs}."
|
373
371
|
raise exceptions.SnowflakeMLException(
|
@@ -375,25 +373,22 @@ class Birch(BaseTransformer):
|
|
375
373
|
original_exception=ValueError(error_str),
|
376
374
|
)
|
377
375
|
|
378
|
-
expected_type_inferred = convert_sp_to_sf_type(
|
379
|
-
label_cols_signatures[0].as_snowpark_type()
|
380
|
-
)
|
376
|
+
expected_type_inferred = convert_sp_to_sf_type(label_cols_signatures[0].as_snowpark_type())
|
381
377
|
|
382
378
|
self._deps = self._batch_inference_validate_snowpark(dataset=dataset, inference_method=inference_method)
|
383
|
-
assert isinstance(
|
379
|
+
assert isinstance(
|
380
|
+
dataset._session, Session
|
381
|
+
) # mypy does not recognize the check in _batch_inference_validate_snowpark()
|
384
382
|
|
385
383
|
transform_kwargs = dict(
|
386
|
-
session
|
387
|
-
dependencies
|
388
|
-
drop_input_cols
|
389
|
-
expected_output_cols_type
|
384
|
+
session=dataset._session,
|
385
|
+
dependencies=self._deps,
|
386
|
+
drop_input_cols=self._drop_input_cols,
|
387
|
+
expected_output_cols_type=expected_type_inferred,
|
390
388
|
)
|
391
389
|
|
392
390
|
elif isinstance(dataset, pd.DataFrame):
|
393
|
-
transform_kwargs = dict(
|
394
|
-
snowpark_input_cols = self._snowpark_cols,
|
395
|
-
drop_input_cols = self._drop_input_cols
|
396
|
-
)
|
391
|
+
transform_kwargs = dict(snowpark_input_cols=self._snowpark_cols, drop_input_cols=self._drop_input_cols)
|
397
392
|
|
398
393
|
transform_handlers = ModelTransformerBuilder.build(
|
399
394
|
dataset=dataset,
|
@@ -435,7 +430,7 @@ class Birch(BaseTransformer):
|
|
435
430
|
Transformed dataset.
|
436
431
|
"""
|
437
432
|
super()._check_dataset_type(dataset)
|
438
|
-
inference_method="transform"
|
433
|
+
inference_method = "transform"
|
439
434
|
|
440
435
|
# This dictionary contains optional kwargs for batch inference. These kwargs
|
441
436
|
# are specific to the type of dataset used.
|
@@ -472,17 +467,14 @@ class Birch(BaseTransformer):
|
|
472
467
|
assert isinstance(dataset._session, Session) # mypy does not recognize the check in _batch_inference_validate_snowpark()
|
473
468
|
|
474
469
|
transform_kwargs = dict(
|
475
|
-
session
|
476
|
-
dependencies
|
477
|
-
drop_input_cols
|
478
|
-
expected_output_cols_type
|
470
|
+
session=dataset._session,
|
471
|
+
dependencies=self._deps,
|
472
|
+
drop_input_cols=self._drop_input_cols,
|
473
|
+
expected_output_cols_type=expected_dtype,
|
479
474
|
)
|
480
475
|
|
481
476
|
elif isinstance(dataset, pd.DataFrame):
|
482
|
-
transform_kwargs = dict(
|
483
|
-
snowpark_input_cols = self._snowpark_cols,
|
484
|
-
drop_input_cols = self._drop_input_cols
|
485
|
-
)
|
477
|
+
transform_kwargs = dict(snowpark_input_cols=self._snowpark_cols, drop_input_cols=self._drop_input_cols)
|
486
478
|
|
487
479
|
transform_handlers = ModelTransformerBuilder.build(
|
488
480
|
dataset=dataset,
|
@@ -501,7 +493,11 @@ class Birch(BaseTransformer):
|
|
501
493
|
return output_df
|
502
494
|
|
503
495
|
@available_if(original_estimator_has_callable("fit_predict")) # type: ignore[misc]
|
504
|
-
def fit_predict(
|
496
|
+
def fit_predict(
|
497
|
+
self,
|
498
|
+
dataset: Union[DataFrame, pd.DataFrame],
|
499
|
+
output_cols_prefix: str = "fit_predict_",
|
500
|
+
) -> Union[DataFrame, pd.DataFrame]:
|
505
501
|
""" Perform clustering on `X` and returns cluster labels
|
506
502
|
For more details on this function, see [sklearn.cluster.Birch.fit_predict]
|
507
503
|
(https://scikit-learn.org/stable/modules/generated/sklearn.cluster.Birch.html#sklearn.cluster.Birch.fit_predict)
|
@@ -528,7 +524,9 @@ class Birch(BaseTransformer):
|
|
528
524
|
)
|
529
525
|
output_result, fitted_estimator = model_trainer.train_fit_predict(
|
530
526
|
drop_input_cols=self._drop_input_cols,
|
531
|
-
expected_output_cols_list=
|
527
|
+
expected_output_cols_list=(
|
528
|
+
self.output_cols if self.output_cols else self._get_output_column_names(output_cols_prefix)
|
529
|
+
),
|
532
530
|
)
|
533
531
|
self._sklearn_object = fitted_estimator
|
534
532
|
self._is_fitted = True
|
@@ -545,6 +543,62 @@ class Birch(BaseTransformer):
|
|
545
543
|
assert self._sklearn_object is not None
|
546
544
|
return self._sklearn_object.embedding_
|
547
545
|
|
546
|
+
|
547
|
+
def _get_output_column_names(self, output_cols_prefix: str, output_cols: Optional[List[str]] = None) -> List[str]:
|
548
|
+
""" Returns the list of output columns for predict_proba(), decision_function(), etc.. functions.
|
549
|
+
Returns a list with output_cols_prefix as the only element if the estimator is not a classifier.
|
550
|
+
"""
|
551
|
+
output_cols_prefix = identifier.resolve_identifier(output_cols_prefix)
|
552
|
+
# The following condition is introduced for kneighbors methods, and not used in other methods
|
553
|
+
if output_cols:
|
554
|
+
output_cols = [
|
555
|
+
identifier.concat_names([output_cols_prefix, identifier.resolve_identifier(c)])
|
556
|
+
for c in output_cols
|
557
|
+
]
|
558
|
+
elif getattr(self._sklearn_object, "classes_", None) is None:
|
559
|
+
output_cols = [output_cols_prefix]
|
560
|
+
elif self._sklearn_object is not None:
|
561
|
+
classes = self._sklearn_object.classes_
|
562
|
+
if isinstance(classes, numpy.ndarray):
|
563
|
+
output_cols = [f'{output_cols_prefix}{str(c)}' for c in classes.tolist()]
|
564
|
+
elif isinstance(classes, list) and len(classes) > 0 and isinstance(classes[0], numpy.ndarray):
|
565
|
+
# If the estimator is a multioutput estimator, classes_ will be a list of ndarrays.
|
566
|
+
output_cols = []
|
567
|
+
for i, cl in enumerate(classes):
|
568
|
+
# For binary classification, there is only one output column for each class
|
569
|
+
# ndarray as the two classes are complementary.
|
570
|
+
if len(cl) == 2:
|
571
|
+
output_cols.append(f'{output_cols_prefix}{i}_{cl[0]}')
|
572
|
+
else:
|
573
|
+
output_cols.extend([
|
574
|
+
f'{output_cols_prefix}{i}_{c}' for c in cl.tolist()
|
575
|
+
])
|
576
|
+
else:
|
577
|
+
output_cols = []
|
578
|
+
|
579
|
+
# Make sure column names are valid snowflake identifiers.
|
580
|
+
assert output_cols is not None # Make MyPy happy
|
581
|
+
rv = [identifier.rename_to_valid_snowflake_identifier(c) for c in output_cols]
|
582
|
+
|
583
|
+
return rv
|
584
|
+
|
585
|
+
def _align_expected_output_names(
|
586
|
+
self, method: str, dataset: DataFrame, expected_output_cols_list: List[str], output_cols_prefix: str
|
587
|
+
) -> List[str]:
|
588
|
+
# in case the inferred output column names dimension is different
|
589
|
+
# we use one line of snowpark dataframe and put it into sklearn estimator using pandas
|
590
|
+
output_df_pd = getattr(self, method)(dataset.limit(1).to_pandas(), output_cols_prefix)
|
591
|
+
output_df_columns = list(output_df_pd.columns)
|
592
|
+
output_df_columns_set: Set[str] = set(output_df_columns) - set(dataset.columns)
|
593
|
+
if self.sample_weight_col:
|
594
|
+
output_df_columns_set -= set(self.sample_weight_col)
|
595
|
+
# if the dimension of inferred output column names is correct; use it
|
596
|
+
if len(expected_output_cols_list) == len(output_df_columns_set):
|
597
|
+
return expected_output_cols_list
|
598
|
+
# otherwise, use the sklearn estimator's output
|
599
|
+
else:
|
600
|
+
return sorted(list(output_df_columns_set), key=lambda x: output_df_columns.index(x))
|
601
|
+
|
548
602
|
@available_if(original_estimator_has_callable("predict_proba")) # type: ignore[misc]
|
549
603
|
@telemetry.send_api_usage_telemetry(
|
550
604
|
project=_PROJECT,
|
@@ -575,24 +629,28 @@ class Birch(BaseTransformer):
|
|
575
629
|
# are specific to the type of dataset used.
|
576
630
|
transform_kwargs: BatchInferenceKwargsTypedDict = dict()
|
577
631
|
|
632
|
+
expected_output_cols = self._get_output_column_names(output_cols_prefix)
|
633
|
+
|
578
634
|
if isinstance(dataset, DataFrame):
|
579
635
|
self._deps = self._batch_inference_validate_snowpark(
|
580
636
|
dataset=dataset,
|
581
637
|
inference_method=inference_method,
|
582
638
|
)
|
583
|
-
assert isinstance(
|
639
|
+
assert isinstance(
|
640
|
+
dataset._session, Session
|
641
|
+
) # mypy does not recognize the check in _batch_inference_validate_snowpark()
|
584
642
|
transform_kwargs = dict(
|
585
643
|
session=dataset._session,
|
586
644
|
dependencies=self._deps,
|
587
|
-
drop_input_cols
|
645
|
+
drop_input_cols=self._drop_input_cols,
|
588
646
|
expected_output_cols_type="float",
|
589
647
|
)
|
648
|
+
expected_output_cols = self._align_expected_output_names(
|
649
|
+
inference_method, dataset, expected_output_cols, output_cols_prefix
|
650
|
+
)
|
590
651
|
|
591
652
|
elif isinstance(dataset, pd.DataFrame):
|
592
|
-
transform_kwargs = dict(
|
593
|
-
snowpark_input_cols = self._snowpark_cols,
|
594
|
-
drop_input_cols = self._drop_input_cols
|
595
|
-
)
|
653
|
+
transform_kwargs = dict(snowpark_input_cols=self._snowpark_cols, drop_input_cols=self._drop_input_cols)
|
596
654
|
|
597
655
|
transform_handlers = ModelTransformerBuilder.build(
|
598
656
|
dataset=dataset,
|
@@ -604,7 +662,7 @@ class Birch(BaseTransformer):
|
|
604
662
|
output_df: DATAFRAME_TYPE = transform_handlers.batch_inference(
|
605
663
|
inference_method=inference_method,
|
606
664
|
input_cols=self.input_cols,
|
607
|
-
expected_output_cols=
|
665
|
+
expected_output_cols=expected_output_cols,
|
608
666
|
**transform_kwargs
|
609
667
|
)
|
610
668
|
return output_df
|
@@ -634,7 +692,8 @@ class Birch(BaseTransformer):
|
|
634
692
|
Output dataset with log probability of the sample for each class in the model.
|
635
693
|
"""
|
636
694
|
super()._check_dataset_type(dataset)
|
637
|
-
inference_method="predict_log_proba"
|
695
|
+
inference_method = "predict_log_proba"
|
696
|
+
expected_output_cols = self._get_output_column_names(output_cols_prefix)
|
638
697
|
|
639
698
|
# This dictionary contains optional kwargs for batch inference. These kwargs
|
640
699
|
# are specific to the type of dataset used.
|
@@ -645,18 +704,20 @@ class Birch(BaseTransformer):
|
|
645
704
|
dataset=dataset,
|
646
705
|
inference_method=inference_method,
|
647
706
|
)
|
648
|
-
assert isinstance(
|
707
|
+
assert isinstance(
|
708
|
+
dataset._session, Session
|
709
|
+
) # mypy does not recognize the check in _batch_inference_validate_snowpark()
|
649
710
|
transform_kwargs = dict(
|
650
711
|
session=dataset._session,
|
651
712
|
dependencies=self._deps,
|
652
|
-
drop_input_cols
|
713
|
+
drop_input_cols=self._drop_input_cols,
|
653
714
|
expected_output_cols_type="float",
|
654
715
|
)
|
716
|
+
expected_output_cols = self._align_expected_output_names(
|
717
|
+
inference_method, dataset, expected_output_cols, output_cols_prefix
|
718
|
+
)
|
655
719
|
elif isinstance(dataset, pd.DataFrame):
|
656
|
-
transform_kwargs = dict(
|
657
|
-
snowpark_input_cols = self._snowpark_cols,
|
658
|
-
drop_input_cols = self._drop_input_cols
|
659
|
-
)
|
720
|
+
transform_kwargs = dict(snowpark_input_cols=self._snowpark_cols, drop_input_cols=self._drop_input_cols)
|
660
721
|
|
661
722
|
transform_handlers = ModelTransformerBuilder.build(
|
662
723
|
dataset=dataset,
|
@@ -669,7 +730,7 @@ class Birch(BaseTransformer):
|
|
669
730
|
output_df: DATAFRAME_TYPE = transform_handlers.batch_inference(
|
670
731
|
inference_method=inference_method,
|
671
732
|
input_cols=self.input_cols,
|
672
|
-
expected_output_cols=
|
733
|
+
expected_output_cols=expected_output_cols,
|
673
734
|
**transform_kwargs
|
674
735
|
)
|
675
736
|
return output_df
|
@@ -695,30 +756,34 @@ class Birch(BaseTransformer):
|
|
695
756
|
Output dataset with results of the decision function for the samples in input dataset.
|
696
757
|
"""
|
697
758
|
super()._check_dataset_type(dataset)
|
698
|
-
inference_method="decision_function"
|
759
|
+
inference_method = "decision_function"
|
699
760
|
|
700
761
|
# This dictionary contains optional kwargs for batch inference. These kwargs
|
701
762
|
# are specific to the type of dataset used.
|
702
763
|
transform_kwargs: BatchInferenceKwargsTypedDict = dict()
|
703
764
|
|
765
|
+
expected_output_cols = self._get_output_column_names(output_cols_prefix)
|
766
|
+
|
704
767
|
if isinstance(dataset, DataFrame):
|
705
768
|
self._deps = self._batch_inference_validate_snowpark(
|
706
769
|
dataset=dataset,
|
707
770
|
inference_method=inference_method,
|
708
771
|
)
|
709
|
-
assert isinstance(
|
772
|
+
assert isinstance(
|
773
|
+
dataset._session, Session
|
774
|
+
) # mypy does not recognize the check in _batch_inference_validate_snowpark()
|
710
775
|
transform_kwargs = dict(
|
711
776
|
session=dataset._session,
|
712
777
|
dependencies=self._deps,
|
713
|
-
drop_input_cols
|
778
|
+
drop_input_cols=self._drop_input_cols,
|
714
779
|
expected_output_cols_type="float",
|
715
780
|
)
|
781
|
+
expected_output_cols = self._align_expected_output_names(
|
782
|
+
inference_method, dataset, expected_output_cols, output_cols_prefix
|
783
|
+
)
|
716
784
|
|
717
785
|
elif isinstance(dataset, pd.DataFrame):
|
718
|
-
transform_kwargs = dict(
|
719
|
-
snowpark_input_cols = self._snowpark_cols,
|
720
|
-
drop_input_cols = self._drop_input_cols
|
721
|
-
)
|
786
|
+
transform_kwargs = dict(snowpark_input_cols=self._snowpark_cols, drop_input_cols=self._drop_input_cols)
|
722
787
|
|
723
788
|
transform_handlers = ModelTransformerBuilder.build(
|
724
789
|
dataset=dataset,
|
@@ -731,7 +796,7 @@ class Birch(BaseTransformer):
|
|
731
796
|
output_df: DATAFRAME_TYPE = transform_handlers.batch_inference(
|
732
797
|
inference_method=inference_method,
|
733
798
|
input_cols=self.input_cols,
|
734
|
-
expected_output_cols=
|
799
|
+
expected_output_cols=expected_output_cols,
|
735
800
|
**transform_kwargs
|
736
801
|
)
|
737
802
|
return output_df
|
@@ -760,12 +825,14 @@ class Birch(BaseTransformer):
|
|
760
825
|
Output dataset with probability of the sample for each class in the model.
|
761
826
|
"""
|
762
827
|
super()._check_dataset_type(dataset)
|
763
|
-
inference_method="score_samples"
|
828
|
+
inference_method = "score_samples"
|
764
829
|
|
765
830
|
# This dictionary contains optional kwargs for batch inference. These kwargs
|
766
831
|
# are specific to the type of dataset used.
|
767
832
|
transform_kwargs: BatchInferenceKwargsTypedDict = dict()
|
768
833
|
|
834
|
+
expected_output_cols = self._get_output_column_names(output_cols_prefix)
|
835
|
+
|
769
836
|
if isinstance(dataset, DataFrame):
|
770
837
|
self._deps = self._batch_inference_validate_snowpark(
|
771
838
|
dataset=dataset,
|
@@ -778,6 +845,9 @@ class Birch(BaseTransformer):
|
|
778
845
|
drop_input_cols = self._drop_input_cols,
|
779
846
|
expected_output_cols_type="float",
|
780
847
|
)
|
848
|
+
expected_output_cols = self._align_expected_output_names(
|
849
|
+
inference_method, dataset, expected_output_cols, output_cols_prefix
|
850
|
+
)
|
781
851
|
|
782
852
|
elif isinstance(dataset, pd.DataFrame):
|
783
853
|
transform_kwargs = dict(
|
@@ -796,7 +866,7 @@ class Birch(BaseTransformer):
|
|
796
866
|
output_df: DATAFRAME_TYPE = transform_handlers.batch_inference(
|
797
867
|
inference_method=inference_method,
|
798
868
|
input_cols=self.input_cols,
|
799
|
-
expected_output_cols=
|
869
|
+
expected_output_cols=expected_output_cols,
|
800
870
|
**transform_kwargs
|
801
871
|
)
|
802
872
|
return output_df
|
@@ -941,50 +1011,84 @@ class Birch(BaseTransformer):
|
|
941
1011
|
)
|
942
1012
|
return output_df
|
943
1013
|
|
1014
|
+
|
1015
|
+
|
1016
|
+
def to_sklearn(self) -> Any:
|
1017
|
+
"""Get sklearn.cluster.Birch object.
|
1018
|
+
"""
|
1019
|
+
if self._sklearn_object is None:
|
1020
|
+
self._sklearn_object = self._create_sklearn_object()
|
1021
|
+
return self._sklearn_object
|
1022
|
+
|
1023
|
+
def to_xgboost(self) -> Any:
|
1024
|
+
raise exceptions.SnowflakeMLException(
|
1025
|
+
error_code=error_codes.METHOD_NOT_ALLOWED,
|
1026
|
+
original_exception=AttributeError(
|
1027
|
+
modeling_error_messages.UNSUPPORTED_MODEL_CONVERSION.format(
|
1028
|
+
"to_xgboost()",
|
1029
|
+
"to_sklearn()"
|
1030
|
+
)
|
1031
|
+
),
|
1032
|
+
)
|
1033
|
+
|
1034
|
+
def to_lightgbm(self) -> Any:
|
1035
|
+
raise exceptions.SnowflakeMLException(
|
1036
|
+
error_code=error_codes.METHOD_NOT_ALLOWED,
|
1037
|
+
original_exception=AttributeError(
|
1038
|
+
modeling_error_messages.UNSUPPORTED_MODEL_CONVERSION.format(
|
1039
|
+
"to_lightgbm()",
|
1040
|
+
"to_sklearn()"
|
1041
|
+
)
|
1042
|
+
),
|
1043
|
+
)
|
944
1044
|
|
945
|
-
def
|
1045
|
+
def _get_dependencies(self) -> List[str]:
|
1046
|
+
return self._deps
|
1047
|
+
|
1048
|
+
|
1049
|
+
def _generate_model_signatures(self, dataset: Union[DataFrame, pd.DataFrame]) -> None:
|
946
1050
|
self._model_signature_dict = dict()
|
947
1051
|
|
948
1052
|
PROB_FUNCTIONS = ["predict_log_proba", "predict_proba", "decision_function"]
|
949
1053
|
|
950
|
-
inputs = list(_infer_signature(dataset[self.input_cols], "input"))
|
1054
|
+
inputs = list(_infer_signature(dataset[self.input_cols], "input", use_snowflake_identifiers=True))
|
951
1055
|
outputs: List[BaseFeatureSpec] = []
|
952
1056
|
if hasattr(self, "predict"):
|
953
1057
|
# keep mypy happy
|
954
|
-
assert self._sklearn_object is not None and hasattr(self._sklearn_object, "_estimator_type")
|
1058
|
+
assert self._sklearn_object is not None and hasattr(self._sklearn_object, "_estimator_type")
|
955
1059
|
# For classifier, the type of predict is the same as the type of label
|
956
|
-
if self._sklearn_object._estimator_type ==
|
957
|
-
|
1060
|
+
if self._sklearn_object._estimator_type == "classifier":
|
1061
|
+
# label columns is the desired type for output
|
958
1062
|
outputs = list(_infer_signature(dataset[self.label_cols], "output", use_snowflake_identifiers=True))
|
959
1063
|
# rename the output columns
|
960
1064
|
outputs = list(model_signature_utils.rename_features(outputs, self.output_cols))
|
961
|
-
self._model_signature_dict["predict"] = ModelSignature(
|
962
|
-
|
963
|
-
|
1065
|
+
self._model_signature_dict["predict"] = ModelSignature(
|
1066
|
+
inputs, ([] if self._drop_input_cols else inputs) + outputs
|
1067
|
+
)
|
964
1068
|
# For mixture models that use the density mixin, `predict` returns the argmax of the log prob.
|
965
1069
|
# For outlier models, returns -1 for outliers and 1 for inliers.
|
966
|
-
# Clusterer returns int64 cluster labels.
|
1070
|
+
# Clusterer returns int64 cluster labels.
|
967
1071
|
elif self._sklearn_object._estimator_type in ["DensityEstimator", "clusterer", "outlier_detector"]:
|
968
1072
|
outputs = [FeatureSpec(dtype=DataType.INT64, name=c) for c in self.output_cols]
|
969
|
-
self._model_signature_dict["predict"] = ModelSignature(
|
970
|
-
|
971
|
-
|
972
|
-
|
1073
|
+
self._model_signature_dict["predict"] = ModelSignature(
|
1074
|
+
inputs, ([] if self._drop_input_cols else inputs) + outputs
|
1075
|
+
)
|
1076
|
+
|
973
1077
|
# For regressor, the type of predict is float64
|
974
|
-
elif self._sklearn_object._estimator_type ==
|
1078
|
+
elif self._sklearn_object._estimator_type == "regressor":
|
975
1079
|
outputs = [FeatureSpec(dtype=DataType.DOUBLE, name=c) for c in self.output_cols]
|
976
|
-
self._model_signature_dict["predict"] = ModelSignature(
|
977
|
-
|
978
|
-
|
979
|
-
|
1080
|
+
self._model_signature_dict["predict"] = ModelSignature(
|
1081
|
+
inputs, ([] if self._drop_input_cols else inputs) + outputs
|
1082
|
+
)
|
1083
|
+
|
980
1084
|
for prob_func in PROB_FUNCTIONS:
|
981
1085
|
if hasattr(self, prob_func):
|
982
1086
|
output_cols_prefix: str = f"{prob_func}_"
|
983
1087
|
output_column_names = self._get_output_column_names(output_cols_prefix)
|
984
1088
|
outputs = [FeatureSpec(dtype=DataType.DOUBLE, name=c) for c in output_column_names]
|
985
|
-
self._model_signature_dict[prob_func] = ModelSignature(
|
986
|
-
|
987
|
-
|
1089
|
+
self._model_signature_dict[prob_func] = ModelSignature(
|
1090
|
+
inputs, ([] if self._drop_input_cols else inputs) + outputs
|
1091
|
+
)
|
988
1092
|
|
989
1093
|
# Output signature names may still need to be renamed, since they were not created with `_infer_signature`.
|
990
1094
|
items = list(self._model_signature_dict.items())
|
@@ -997,10 +1101,10 @@ class Birch(BaseTransformer):
|
|
997
1101
|
"""Returns model signature of current class.
|
998
1102
|
|
999
1103
|
Raises:
|
1000
|
-
|
1104
|
+
SnowflakeMLException: If estimator is not fitted, then model signature cannot be inferred
|
1001
1105
|
|
1002
1106
|
Returns:
|
1003
|
-
Dict
|
1107
|
+
Dict with each method and its input output signature
|
1004
1108
|
"""
|
1005
1109
|
if self._model_signature_dict is None:
|
1006
1110
|
raise exceptions.SnowflakeMLException(
|
@@ -1008,35 +1112,3 @@ class Birch(BaseTransformer):
|
|
1008
1112
|
original_exception=RuntimeError("Estimator not fitted before accessing property model_signatures!"),
|
1009
1113
|
)
|
1010
1114
|
return self._model_signature_dict
|
1011
|
-
|
1012
|
-
def to_sklearn(self) -> Any:
|
1013
|
-
"""Get sklearn.cluster.Birch object.
|
1014
|
-
"""
|
1015
|
-
if self._sklearn_object is None:
|
1016
|
-
self._sklearn_object = self._create_sklearn_object()
|
1017
|
-
return self._sklearn_object
|
1018
|
-
|
1019
|
-
def to_xgboost(self) -> Any:
|
1020
|
-
raise exceptions.SnowflakeMLException(
|
1021
|
-
error_code=error_codes.METHOD_NOT_ALLOWED,
|
1022
|
-
original_exception=AttributeError(
|
1023
|
-
modeling_error_messages.UNSUPPORTED_MODEL_CONVERSION.format(
|
1024
|
-
"to_xgboost()",
|
1025
|
-
"to_sklearn()"
|
1026
|
-
)
|
1027
|
-
),
|
1028
|
-
)
|
1029
|
-
|
1030
|
-
def to_lightgbm(self) -> Any:
|
1031
|
-
raise exceptions.SnowflakeMLException(
|
1032
|
-
error_code=error_codes.METHOD_NOT_ALLOWED,
|
1033
|
-
original_exception=AttributeError(
|
1034
|
-
modeling_error_messages.UNSUPPORTED_MODEL_CONVERSION.format(
|
1035
|
-
"to_lightgbm()",
|
1036
|
-
"to_sklearn()"
|
1037
|
-
)
|
1038
|
-
),
|
1039
|
-
)
|
1040
|
-
|
1041
|
-
def _get_dependencies(self) -> List[str]:
|
1042
|
-
return self._deps
|