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
@@ -34,6 +34,15 @@ from snowflake.ml.modeling._internal.transformer_protocols import (
|
|
34
34
|
BatchInferenceKwargsTypedDict,
|
35
35
|
ScoreKwargsTypedDict
|
36
36
|
)
|
37
|
+
from snowflake.ml.model._signatures import utils as model_signature_utils
|
38
|
+
from snowflake.ml.model.model_signature import (
|
39
|
+
BaseFeatureSpec,
|
40
|
+
DataType,
|
41
|
+
FeatureSpec,
|
42
|
+
ModelSignature,
|
43
|
+
_infer_signature,
|
44
|
+
_rename_signature_with_snowflake_identifiers,
|
45
|
+
)
|
37
46
|
|
38
47
|
from snowflake.ml.modeling._internal.model_transformer_builder import ModelTransformerBuilder
|
39
48
|
|
@@ -44,16 +53,6 @@ from snowflake.ml.modeling._internal.estimator_utils import (
|
|
44
53
|
validate_sklearn_args,
|
45
54
|
)
|
46
55
|
|
47
|
-
from snowflake.ml.model.model_signature import (
|
48
|
-
DataType,
|
49
|
-
FeatureSpec,
|
50
|
-
ModelSignature,
|
51
|
-
_infer_signature,
|
52
|
-
_rename_signature_with_snowflake_identifiers,
|
53
|
-
BaseFeatureSpec,
|
54
|
-
)
|
55
|
-
from snowflake.ml.model._signatures import utils as model_signature_utils
|
56
|
-
|
57
56
|
_PROJECT = "ModelDevelopment"
|
58
57
|
# Derive subproject from module name by removing "sklearn"
|
59
58
|
# and converting module name from underscore to CamelCase
|
@@ -206,12 +205,7 @@ class SelectKBest(BaseTransformer):
|
|
206
205
|
)
|
207
206
|
return selected_cols
|
208
207
|
|
209
|
-
|
210
|
-
project=_PROJECT,
|
211
|
-
subproject=_SUBPROJECT,
|
212
|
-
custom_tags=dict([("autogen", True)]),
|
213
|
-
)
|
214
|
-
def fit(self, dataset: Union[DataFrame, pd.DataFrame]) -> "SelectKBest":
|
208
|
+
def _fit(self, dataset: Union[DataFrame, pd.DataFrame]) -> "SelectKBest":
|
215
209
|
"""Run score function on (X, y) and get the appropriate features
|
216
210
|
For more details on this function, see [sklearn.feature_selection.SelectKBest.fit]
|
217
211
|
(https://scikit-learn.org/stable/modules/generated/sklearn.feature_selection.SelectKBest.html#sklearn.feature_selection.SelectKBest.fit)
|
@@ -238,12 +232,14 @@ class SelectKBest(BaseTransformer):
|
|
238
232
|
|
239
233
|
self._snowpark_cols = dataset.select(self.input_cols).columns
|
240
234
|
|
241
|
-
|
235
|
+
# If we are already in a stored procedure, no need to kick off another one.
|
242
236
|
if SNOWML_SPROC_ENV in os.environ:
|
243
237
|
statement_params = telemetry.get_function_usage_statement_params(
|
244
238
|
project=_PROJECT,
|
245
239
|
subproject=_SUBPROJECT,
|
246
|
-
function_name=telemetry.get_statement_params_full_func_name(
|
240
|
+
function_name=telemetry.get_statement_params_full_func_name(
|
241
|
+
inspect.currentframe(), SelectKBest.__class__.__name__
|
242
|
+
),
|
247
243
|
api_calls=[Session.call],
|
248
244
|
custom_tags=dict([("autogen", True)]) if self._autogenerated else None,
|
249
245
|
)
|
@@ -264,7 +260,7 @@ class SelectKBest(BaseTransformer):
|
|
264
260
|
)
|
265
261
|
self._sklearn_object = model_trainer.train()
|
266
262
|
self._is_fitted = True
|
267
|
-
self.
|
263
|
+
self._generate_model_signatures(dataset)
|
268
264
|
return self
|
269
265
|
|
270
266
|
def _batch_inference_validate_snowpark(
|
@@ -338,7 +334,9 @@ class SelectKBest(BaseTransformer):
|
|
338
334
|
# when it is classifier, infer the datatype from label columns
|
339
335
|
if expected_type_inferred == "" and 'predict' in self.model_signatures:
|
340
336
|
# Batch inference takes a single expected output column type. Use the first columns type for now.
|
341
|
-
label_cols_signatures = [
|
337
|
+
label_cols_signatures = [
|
338
|
+
row for row in self.model_signatures['predict'].outputs if row.name in self.output_cols
|
339
|
+
]
|
342
340
|
if len(label_cols_signatures) == 0:
|
343
341
|
error_str = f"Output columns {self.output_cols} do not match model signatures {self.model_signatures['predict'].outputs}."
|
344
342
|
raise exceptions.SnowflakeMLException(
|
@@ -346,25 +344,22 @@ class SelectKBest(BaseTransformer):
|
|
346
344
|
original_exception=ValueError(error_str),
|
347
345
|
)
|
348
346
|
|
349
|
-
expected_type_inferred = convert_sp_to_sf_type(
|
350
|
-
label_cols_signatures[0].as_snowpark_type()
|
351
|
-
)
|
347
|
+
expected_type_inferred = convert_sp_to_sf_type(label_cols_signatures[0].as_snowpark_type())
|
352
348
|
|
353
349
|
self._deps = self._batch_inference_validate_snowpark(dataset=dataset, inference_method=inference_method)
|
354
|
-
assert isinstance(
|
350
|
+
assert isinstance(
|
351
|
+
dataset._session, Session
|
352
|
+
) # mypy does not recognize the check in _batch_inference_validate_snowpark()
|
355
353
|
|
356
354
|
transform_kwargs = dict(
|
357
|
-
session
|
358
|
-
dependencies
|
359
|
-
drop_input_cols
|
360
|
-
expected_output_cols_type
|
355
|
+
session=dataset._session,
|
356
|
+
dependencies=self._deps,
|
357
|
+
drop_input_cols=self._drop_input_cols,
|
358
|
+
expected_output_cols_type=expected_type_inferred,
|
361
359
|
)
|
362
360
|
|
363
361
|
elif isinstance(dataset, pd.DataFrame):
|
364
|
-
transform_kwargs = dict(
|
365
|
-
snowpark_input_cols = self._snowpark_cols,
|
366
|
-
drop_input_cols = self._drop_input_cols
|
367
|
-
)
|
362
|
+
transform_kwargs = dict(snowpark_input_cols=self._snowpark_cols, drop_input_cols=self._drop_input_cols)
|
368
363
|
|
369
364
|
transform_handlers = ModelTransformerBuilder.build(
|
370
365
|
dataset=dataset,
|
@@ -406,7 +401,7 @@ class SelectKBest(BaseTransformer):
|
|
406
401
|
Transformed dataset.
|
407
402
|
"""
|
408
403
|
super()._check_dataset_type(dataset)
|
409
|
-
inference_method="transform"
|
404
|
+
inference_method = "transform"
|
410
405
|
|
411
406
|
# This dictionary contains optional kwargs for batch inference. These kwargs
|
412
407
|
# are specific to the type of dataset used.
|
@@ -443,17 +438,14 @@ class SelectKBest(BaseTransformer):
|
|
443
438
|
assert isinstance(dataset._session, Session) # mypy does not recognize the check in _batch_inference_validate_snowpark()
|
444
439
|
|
445
440
|
transform_kwargs = dict(
|
446
|
-
session
|
447
|
-
dependencies
|
448
|
-
drop_input_cols
|
449
|
-
expected_output_cols_type
|
441
|
+
session=dataset._session,
|
442
|
+
dependencies=self._deps,
|
443
|
+
drop_input_cols=self._drop_input_cols,
|
444
|
+
expected_output_cols_type=expected_dtype,
|
450
445
|
)
|
451
446
|
|
452
447
|
elif isinstance(dataset, pd.DataFrame):
|
453
|
-
transform_kwargs = dict(
|
454
|
-
snowpark_input_cols = self._snowpark_cols,
|
455
|
-
drop_input_cols = self._drop_input_cols
|
456
|
-
)
|
448
|
+
transform_kwargs = dict(snowpark_input_cols=self._snowpark_cols, drop_input_cols=self._drop_input_cols)
|
457
449
|
|
458
450
|
transform_handlers = ModelTransformerBuilder.build(
|
459
451
|
dataset=dataset,
|
@@ -472,7 +464,11 @@ class SelectKBest(BaseTransformer):
|
|
472
464
|
return output_df
|
473
465
|
|
474
466
|
@available_if(original_estimator_has_callable("fit_predict")) # type: ignore[misc]
|
475
|
-
def fit_predict(
|
467
|
+
def fit_predict(
|
468
|
+
self,
|
469
|
+
dataset: Union[DataFrame, pd.DataFrame],
|
470
|
+
output_cols_prefix: str = "fit_predict_",
|
471
|
+
) -> Union[DataFrame, pd.DataFrame]:
|
476
472
|
""" Method not supported for this class.
|
477
473
|
|
478
474
|
|
@@ -497,7 +493,9 @@ class SelectKBest(BaseTransformer):
|
|
497
493
|
)
|
498
494
|
output_result, fitted_estimator = model_trainer.train_fit_predict(
|
499
495
|
drop_input_cols=self._drop_input_cols,
|
500
|
-
expected_output_cols_list=
|
496
|
+
expected_output_cols_list=(
|
497
|
+
self.output_cols if self.output_cols else self._get_output_column_names(output_cols_prefix)
|
498
|
+
),
|
501
499
|
)
|
502
500
|
self._sklearn_object = fitted_estimator
|
503
501
|
self._is_fitted = True
|
@@ -514,6 +512,62 @@ class SelectKBest(BaseTransformer):
|
|
514
512
|
assert self._sklearn_object is not None
|
515
513
|
return self._sklearn_object.embedding_
|
516
514
|
|
515
|
+
|
516
|
+
def _get_output_column_names(self, output_cols_prefix: str, output_cols: Optional[List[str]] = None) -> List[str]:
|
517
|
+
""" Returns the list of output columns for predict_proba(), decision_function(), etc.. functions.
|
518
|
+
Returns a list with output_cols_prefix as the only element if the estimator is not a classifier.
|
519
|
+
"""
|
520
|
+
output_cols_prefix = identifier.resolve_identifier(output_cols_prefix)
|
521
|
+
# The following condition is introduced for kneighbors methods, and not used in other methods
|
522
|
+
if output_cols:
|
523
|
+
output_cols = [
|
524
|
+
identifier.concat_names([output_cols_prefix, identifier.resolve_identifier(c)])
|
525
|
+
for c in output_cols
|
526
|
+
]
|
527
|
+
elif getattr(self._sklearn_object, "classes_", None) is None:
|
528
|
+
output_cols = [output_cols_prefix]
|
529
|
+
elif self._sklearn_object is not None:
|
530
|
+
classes = self._sklearn_object.classes_
|
531
|
+
if isinstance(classes, numpy.ndarray):
|
532
|
+
output_cols = [f'{output_cols_prefix}{str(c)}' for c in classes.tolist()]
|
533
|
+
elif isinstance(classes, list) and len(classes) > 0 and isinstance(classes[0], numpy.ndarray):
|
534
|
+
# If the estimator is a multioutput estimator, classes_ will be a list of ndarrays.
|
535
|
+
output_cols = []
|
536
|
+
for i, cl in enumerate(classes):
|
537
|
+
# For binary classification, there is only one output column for each class
|
538
|
+
# ndarray as the two classes are complementary.
|
539
|
+
if len(cl) == 2:
|
540
|
+
output_cols.append(f'{output_cols_prefix}{i}_{cl[0]}')
|
541
|
+
else:
|
542
|
+
output_cols.extend([
|
543
|
+
f'{output_cols_prefix}{i}_{c}' for c in cl.tolist()
|
544
|
+
])
|
545
|
+
else:
|
546
|
+
output_cols = []
|
547
|
+
|
548
|
+
# Make sure column names are valid snowflake identifiers.
|
549
|
+
assert output_cols is not None # Make MyPy happy
|
550
|
+
rv = [identifier.rename_to_valid_snowflake_identifier(c) for c in output_cols]
|
551
|
+
|
552
|
+
return rv
|
553
|
+
|
554
|
+
def _align_expected_output_names(
|
555
|
+
self, method: str, dataset: DataFrame, expected_output_cols_list: List[str], output_cols_prefix: str
|
556
|
+
) -> List[str]:
|
557
|
+
# in case the inferred output column names dimension is different
|
558
|
+
# we use one line of snowpark dataframe and put it into sklearn estimator using pandas
|
559
|
+
output_df_pd = getattr(self, method)(dataset.limit(1).to_pandas(), output_cols_prefix)
|
560
|
+
output_df_columns = list(output_df_pd.columns)
|
561
|
+
output_df_columns_set: Set[str] = set(output_df_columns) - set(dataset.columns)
|
562
|
+
if self.sample_weight_col:
|
563
|
+
output_df_columns_set -= set(self.sample_weight_col)
|
564
|
+
# if the dimension of inferred output column names is correct; use it
|
565
|
+
if len(expected_output_cols_list) == len(output_df_columns_set):
|
566
|
+
return expected_output_cols_list
|
567
|
+
# otherwise, use the sklearn estimator's output
|
568
|
+
else:
|
569
|
+
return sorted(list(output_df_columns_set), key=lambda x: output_df_columns.index(x))
|
570
|
+
|
517
571
|
@available_if(original_estimator_has_callable("predict_proba")) # type: ignore[misc]
|
518
572
|
@telemetry.send_api_usage_telemetry(
|
519
573
|
project=_PROJECT,
|
@@ -544,24 +598,28 @@ class SelectKBest(BaseTransformer):
|
|
544
598
|
# are specific to the type of dataset used.
|
545
599
|
transform_kwargs: BatchInferenceKwargsTypedDict = dict()
|
546
600
|
|
601
|
+
expected_output_cols = self._get_output_column_names(output_cols_prefix)
|
602
|
+
|
547
603
|
if isinstance(dataset, DataFrame):
|
548
604
|
self._deps = self._batch_inference_validate_snowpark(
|
549
605
|
dataset=dataset,
|
550
606
|
inference_method=inference_method,
|
551
607
|
)
|
552
|
-
assert isinstance(
|
608
|
+
assert isinstance(
|
609
|
+
dataset._session, Session
|
610
|
+
) # mypy does not recognize the check in _batch_inference_validate_snowpark()
|
553
611
|
transform_kwargs = dict(
|
554
612
|
session=dataset._session,
|
555
613
|
dependencies=self._deps,
|
556
|
-
drop_input_cols
|
614
|
+
drop_input_cols=self._drop_input_cols,
|
557
615
|
expected_output_cols_type="float",
|
558
616
|
)
|
617
|
+
expected_output_cols = self._align_expected_output_names(
|
618
|
+
inference_method, dataset, expected_output_cols, output_cols_prefix
|
619
|
+
)
|
559
620
|
|
560
621
|
elif isinstance(dataset, pd.DataFrame):
|
561
|
-
transform_kwargs = dict(
|
562
|
-
snowpark_input_cols = self._snowpark_cols,
|
563
|
-
drop_input_cols = self._drop_input_cols
|
564
|
-
)
|
622
|
+
transform_kwargs = dict(snowpark_input_cols=self._snowpark_cols, drop_input_cols=self._drop_input_cols)
|
565
623
|
|
566
624
|
transform_handlers = ModelTransformerBuilder.build(
|
567
625
|
dataset=dataset,
|
@@ -573,7 +631,7 @@ class SelectKBest(BaseTransformer):
|
|
573
631
|
output_df: DATAFRAME_TYPE = transform_handlers.batch_inference(
|
574
632
|
inference_method=inference_method,
|
575
633
|
input_cols=self.input_cols,
|
576
|
-
expected_output_cols=
|
634
|
+
expected_output_cols=expected_output_cols,
|
577
635
|
**transform_kwargs
|
578
636
|
)
|
579
637
|
return output_df
|
@@ -603,7 +661,8 @@ class SelectKBest(BaseTransformer):
|
|
603
661
|
Output dataset with log probability of the sample for each class in the model.
|
604
662
|
"""
|
605
663
|
super()._check_dataset_type(dataset)
|
606
|
-
inference_method="predict_log_proba"
|
664
|
+
inference_method = "predict_log_proba"
|
665
|
+
expected_output_cols = self._get_output_column_names(output_cols_prefix)
|
607
666
|
|
608
667
|
# This dictionary contains optional kwargs for batch inference. These kwargs
|
609
668
|
# are specific to the type of dataset used.
|
@@ -614,18 +673,20 @@ class SelectKBest(BaseTransformer):
|
|
614
673
|
dataset=dataset,
|
615
674
|
inference_method=inference_method,
|
616
675
|
)
|
617
|
-
assert isinstance(
|
676
|
+
assert isinstance(
|
677
|
+
dataset._session, Session
|
678
|
+
) # mypy does not recognize the check in _batch_inference_validate_snowpark()
|
618
679
|
transform_kwargs = dict(
|
619
680
|
session=dataset._session,
|
620
681
|
dependencies=self._deps,
|
621
|
-
drop_input_cols
|
682
|
+
drop_input_cols=self._drop_input_cols,
|
622
683
|
expected_output_cols_type="float",
|
623
684
|
)
|
685
|
+
expected_output_cols = self._align_expected_output_names(
|
686
|
+
inference_method, dataset, expected_output_cols, output_cols_prefix
|
687
|
+
)
|
624
688
|
elif isinstance(dataset, pd.DataFrame):
|
625
|
-
transform_kwargs = dict(
|
626
|
-
snowpark_input_cols = self._snowpark_cols,
|
627
|
-
drop_input_cols = self._drop_input_cols
|
628
|
-
)
|
689
|
+
transform_kwargs = dict(snowpark_input_cols=self._snowpark_cols, drop_input_cols=self._drop_input_cols)
|
629
690
|
|
630
691
|
transform_handlers = ModelTransformerBuilder.build(
|
631
692
|
dataset=dataset,
|
@@ -638,7 +699,7 @@ class SelectKBest(BaseTransformer):
|
|
638
699
|
output_df: DATAFRAME_TYPE = transform_handlers.batch_inference(
|
639
700
|
inference_method=inference_method,
|
640
701
|
input_cols=self.input_cols,
|
641
|
-
expected_output_cols=
|
702
|
+
expected_output_cols=expected_output_cols,
|
642
703
|
**transform_kwargs
|
643
704
|
)
|
644
705
|
return output_df
|
@@ -664,30 +725,34 @@ class SelectKBest(BaseTransformer):
|
|
664
725
|
Output dataset with results of the decision function for the samples in input dataset.
|
665
726
|
"""
|
666
727
|
super()._check_dataset_type(dataset)
|
667
|
-
inference_method="decision_function"
|
728
|
+
inference_method = "decision_function"
|
668
729
|
|
669
730
|
# This dictionary contains optional kwargs for batch inference. These kwargs
|
670
731
|
# are specific to the type of dataset used.
|
671
732
|
transform_kwargs: BatchInferenceKwargsTypedDict = dict()
|
672
733
|
|
734
|
+
expected_output_cols = self._get_output_column_names(output_cols_prefix)
|
735
|
+
|
673
736
|
if isinstance(dataset, DataFrame):
|
674
737
|
self._deps = self._batch_inference_validate_snowpark(
|
675
738
|
dataset=dataset,
|
676
739
|
inference_method=inference_method,
|
677
740
|
)
|
678
|
-
assert isinstance(
|
741
|
+
assert isinstance(
|
742
|
+
dataset._session, Session
|
743
|
+
) # mypy does not recognize the check in _batch_inference_validate_snowpark()
|
679
744
|
transform_kwargs = dict(
|
680
745
|
session=dataset._session,
|
681
746
|
dependencies=self._deps,
|
682
|
-
drop_input_cols
|
747
|
+
drop_input_cols=self._drop_input_cols,
|
683
748
|
expected_output_cols_type="float",
|
684
749
|
)
|
750
|
+
expected_output_cols = self._align_expected_output_names(
|
751
|
+
inference_method, dataset, expected_output_cols, output_cols_prefix
|
752
|
+
)
|
685
753
|
|
686
754
|
elif isinstance(dataset, pd.DataFrame):
|
687
|
-
transform_kwargs = dict(
|
688
|
-
snowpark_input_cols = self._snowpark_cols,
|
689
|
-
drop_input_cols = self._drop_input_cols
|
690
|
-
)
|
755
|
+
transform_kwargs = dict(snowpark_input_cols=self._snowpark_cols, drop_input_cols=self._drop_input_cols)
|
691
756
|
|
692
757
|
transform_handlers = ModelTransformerBuilder.build(
|
693
758
|
dataset=dataset,
|
@@ -700,7 +765,7 @@ class SelectKBest(BaseTransformer):
|
|
700
765
|
output_df: DATAFRAME_TYPE = transform_handlers.batch_inference(
|
701
766
|
inference_method=inference_method,
|
702
767
|
input_cols=self.input_cols,
|
703
|
-
expected_output_cols=
|
768
|
+
expected_output_cols=expected_output_cols,
|
704
769
|
**transform_kwargs
|
705
770
|
)
|
706
771
|
return output_df
|
@@ -729,12 +794,14 @@ class SelectKBest(BaseTransformer):
|
|
729
794
|
Output dataset with probability of the sample for each class in the model.
|
730
795
|
"""
|
731
796
|
super()._check_dataset_type(dataset)
|
732
|
-
inference_method="score_samples"
|
797
|
+
inference_method = "score_samples"
|
733
798
|
|
734
799
|
# This dictionary contains optional kwargs for batch inference. These kwargs
|
735
800
|
# are specific to the type of dataset used.
|
736
801
|
transform_kwargs: BatchInferenceKwargsTypedDict = dict()
|
737
802
|
|
803
|
+
expected_output_cols = self._get_output_column_names(output_cols_prefix)
|
804
|
+
|
738
805
|
if isinstance(dataset, DataFrame):
|
739
806
|
self._deps = self._batch_inference_validate_snowpark(
|
740
807
|
dataset=dataset,
|
@@ -747,6 +814,9 @@ class SelectKBest(BaseTransformer):
|
|
747
814
|
drop_input_cols = self._drop_input_cols,
|
748
815
|
expected_output_cols_type="float",
|
749
816
|
)
|
817
|
+
expected_output_cols = self._align_expected_output_names(
|
818
|
+
inference_method, dataset, expected_output_cols, output_cols_prefix
|
819
|
+
)
|
750
820
|
|
751
821
|
elif isinstance(dataset, pd.DataFrame):
|
752
822
|
transform_kwargs = dict(
|
@@ -765,7 +835,7 @@ class SelectKBest(BaseTransformer):
|
|
765
835
|
output_df: DATAFRAME_TYPE = transform_handlers.batch_inference(
|
766
836
|
inference_method=inference_method,
|
767
837
|
input_cols=self.input_cols,
|
768
|
-
expected_output_cols=
|
838
|
+
expected_output_cols=expected_output_cols,
|
769
839
|
**transform_kwargs
|
770
840
|
)
|
771
841
|
return output_df
|
@@ -910,50 +980,84 @@ class SelectKBest(BaseTransformer):
|
|
910
980
|
)
|
911
981
|
return output_df
|
912
982
|
|
983
|
+
|
984
|
+
|
985
|
+
def to_sklearn(self) -> Any:
|
986
|
+
"""Get sklearn.feature_selection.SelectKBest object.
|
987
|
+
"""
|
988
|
+
if self._sklearn_object is None:
|
989
|
+
self._sklearn_object = self._create_sklearn_object()
|
990
|
+
return self._sklearn_object
|
991
|
+
|
992
|
+
def to_xgboost(self) -> Any:
|
993
|
+
raise exceptions.SnowflakeMLException(
|
994
|
+
error_code=error_codes.METHOD_NOT_ALLOWED,
|
995
|
+
original_exception=AttributeError(
|
996
|
+
modeling_error_messages.UNSUPPORTED_MODEL_CONVERSION.format(
|
997
|
+
"to_xgboost()",
|
998
|
+
"to_sklearn()"
|
999
|
+
)
|
1000
|
+
),
|
1001
|
+
)
|
1002
|
+
|
1003
|
+
def to_lightgbm(self) -> Any:
|
1004
|
+
raise exceptions.SnowflakeMLException(
|
1005
|
+
error_code=error_codes.METHOD_NOT_ALLOWED,
|
1006
|
+
original_exception=AttributeError(
|
1007
|
+
modeling_error_messages.UNSUPPORTED_MODEL_CONVERSION.format(
|
1008
|
+
"to_lightgbm()",
|
1009
|
+
"to_sklearn()"
|
1010
|
+
)
|
1011
|
+
),
|
1012
|
+
)
|
913
1013
|
|
914
|
-
def
|
1014
|
+
def _get_dependencies(self) -> List[str]:
|
1015
|
+
return self._deps
|
1016
|
+
|
1017
|
+
|
1018
|
+
def _generate_model_signatures(self, dataset: Union[DataFrame, pd.DataFrame]) -> None:
|
915
1019
|
self._model_signature_dict = dict()
|
916
1020
|
|
917
1021
|
PROB_FUNCTIONS = ["predict_log_proba", "predict_proba", "decision_function"]
|
918
1022
|
|
919
|
-
inputs = list(_infer_signature(dataset[self.input_cols], "input"))
|
1023
|
+
inputs = list(_infer_signature(dataset[self.input_cols], "input", use_snowflake_identifiers=True))
|
920
1024
|
outputs: List[BaseFeatureSpec] = []
|
921
1025
|
if hasattr(self, "predict"):
|
922
1026
|
# keep mypy happy
|
923
|
-
assert self._sklearn_object is not None and hasattr(self._sklearn_object, "_estimator_type")
|
1027
|
+
assert self._sklearn_object is not None and hasattr(self._sklearn_object, "_estimator_type")
|
924
1028
|
# For classifier, the type of predict is the same as the type of label
|
925
|
-
if self._sklearn_object._estimator_type ==
|
926
|
-
|
1029
|
+
if self._sklearn_object._estimator_type == "classifier":
|
1030
|
+
# label columns is the desired type for output
|
927
1031
|
outputs = list(_infer_signature(dataset[self.label_cols], "output", use_snowflake_identifiers=True))
|
928
1032
|
# rename the output columns
|
929
1033
|
outputs = list(model_signature_utils.rename_features(outputs, self.output_cols))
|
930
|
-
self._model_signature_dict["predict"] = ModelSignature(
|
931
|
-
|
932
|
-
|
1034
|
+
self._model_signature_dict["predict"] = ModelSignature(
|
1035
|
+
inputs, ([] if self._drop_input_cols else inputs) + outputs
|
1036
|
+
)
|
933
1037
|
# For mixture models that use the density mixin, `predict` returns the argmax of the log prob.
|
934
1038
|
# For outlier models, returns -1 for outliers and 1 for inliers.
|
935
|
-
# Clusterer returns int64 cluster labels.
|
1039
|
+
# Clusterer returns int64 cluster labels.
|
936
1040
|
elif self._sklearn_object._estimator_type in ["DensityEstimator", "clusterer", "outlier_detector"]:
|
937
1041
|
outputs = [FeatureSpec(dtype=DataType.INT64, name=c) for c in self.output_cols]
|
938
|
-
self._model_signature_dict["predict"] = ModelSignature(
|
939
|
-
|
940
|
-
|
941
|
-
|
1042
|
+
self._model_signature_dict["predict"] = ModelSignature(
|
1043
|
+
inputs, ([] if self._drop_input_cols else inputs) + outputs
|
1044
|
+
)
|
1045
|
+
|
942
1046
|
# For regressor, the type of predict is float64
|
943
|
-
elif self._sklearn_object._estimator_type ==
|
1047
|
+
elif self._sklearn_object._estimator_type == "regressor":
|
944
1048
|
outputs = [FeatureSpec(dtype=DataType.DOUBLE, name=c) for c in self.output_cols]
|
945
|
-
self._model_signature_dict["predict"] = ModelSignature(
|
946
|
-
|
947
|
-
|
948
|
-
|
1049
|
+
self._model_signature_dict["predict"] = ModelSignature(
|
1050
|
+
inputs, ([] if self._drop_input_cols else inputs) + outputs
|
1051
|
+
)
|
1052
|
+
|
949
1053
|
for prob_func in PROB_FUNCTIONS:
|
950
1054
|
if hasattr(self, prob_func):
|
951
1055
|
output_cols_prefix: str = f"{prob_func}_"
|
952
1056
|
output_column_names = self._get_output_column_names(output_cols_prefix)
|
953
1057
|
outputs = [FeatureSpec(dtype=DataType.DOUBLE, name=c) for c in output_column_names]
|
954
|
-
self._model_signature_dict[prob_func] = ModelSignature(
|
955
|
-
|
956
|
-
|
1058
|
+
self._model_signature_dict[prob_func] = ModelSignature(
|
1059
|
+
inputs, ([] if self._drop_input_cols else inputs) + outputs
|
1060
|
+
)
|
957
1061
|
|
958
1062
|
# Output signature names may still need to be renamed, since they were not created with `_infer_signature`.
|
959
1063
|
items = list(self._model_signature_dict.items())
|
@@ -966,10 +1070,10 @@ class SelectKBest(BaseTransformer):
|
|
966
1070
|
"""Returns model signature of current class.
|
967
1071
|
|
968
1072
|
Raises:
|
969
|
-
|
1073
|
+
SnowflakeMLException: If estimator is not fitted, then model signature cannot be inferred
|
970
1074
|
|
971
1075
|
Returns:
|
972
|
-
Dict
|
1076
|
+
Dict with each method and its input output signature
|
973
1077
|
"""
|
974
1078
|
if self._model_signature_dict is None:
|
975
1079
|
raise exceptions.SnowflakeMLException(
|
@@ -977,35 +1081,3 @@ class SelectKBest(BaseTransformer):
|
|
977
1081
|
original_exception=RuntimeError("Estimator not fitted before accessing property model_signatures!"),
|
978
1082
|
)
|
979
1083
|
return self._model_signature_dict
|
980
|
-
|
981
|
-
def to_sklearn(self) -> Any:
|
982
|
-
"""Get sklearn.feature_selection.SelectKBest object.
|
983
|
-
"""
|
984
|
-
if self._sklearn_object is None:
|
985
|
-
self._sklearn_object = self._create_sklearn_object()
|
986
|
-
return self._sklearn_object
|
987
|
-
|
988
|
-
def to_xgboost(self) -> Any:
|
989
|
-
raise exceptions.SnowflakeMLException(
|
990
|
-
error_code=error_codes.METHOD_NOT_ALLOWED,
|
991
|
-
original_exception=AttributeError(
|
992
|
-
modeling_error_messages.UNSUPPORTED_MODEL_CONVERSION.format(
|
993
|
-
"to_xgboost()",
|
994
|
-
"to_sklearn()"
|
995
|
-
)
|
996
|
-
),
|
997
|
-
)
|
998
|
-
|
999
|
-
def to_lightgbm(self) -> Any:
|
1000
|
-
raise exceptions.SnowflakeMLException(
|
1001
|
-
error_code=error_codes.METHOD_NOT_ALLOWED,
|
1002
|
-
original_exception=AttributeError(
|
1003
|
-
modeling_error_messages.UNSUPPORTED_MODEL_CONVERSION.format(
|
1004
|
-
"to_lightgbm()",
|
1005
|
-
"to_sklearn()"
|
1006
|
-
)
|
1007
|
-
),
|
1008
|
-
)
|
1009
|
-
|
1010
|
-
def _get_dependencies(self) -> List[str]:
|
1011
|
-
return self._deps
|