Sklearn-源码解析-书-v1-0-二十九-

Sklearn 源码解析(书)v1.0(二十九)

feature_extraction_ref-from-text. However, note that a better way is to refer using

the :mod: directive, e.g., :mod:sklearn.feature_extraction for the module and

:mod:sklearn.feature_extraction.text for the section. Only in case that a section

is not a particular submodule does the hook become useful, e.g., the "Loaders" section

under sklearn.datasets.

"""

API_REFERENCE = {

"sklearn": {

"short_summary": "Settings and information tools.",

"description": None,

"sections": [

{

"title": None,

"autosummary": [

"config_context",

"get_config",

"set_config",

"show_versions",

],

},

],

},

"sklearn.base": {

"short_summary": "Base classes and utility functions.",

"description": None,

"sections": [

{

"title": None,

"autosummary": [

"BaseEstimator",

"BiclusterMixin",

"ClassNamePrefixFeaturesOutMixin",

"ClassifierMixin",

"ClusterMixin",

"DensityMixin",

"MetaEstimatorMixin",

"OneToOneFeatureMixin",

"OutlierMixin",

"RegressorMixin",

"TransformerMixin",

"clone",

"is_classifier",

"is_clusterer",

"is_regressor",

"is_outlier_detector",

],

}

],

},

"sklearn.calibration": {

"short_summary": "Probability calibration.",

"description": _get_guide("calibration"),

"sections": [

{

"title": None,

"autosummary": ["CalibratedClassifierCV", "calibration_curve"],

},

{

"title": "Visualization",

"autosummary": ["CalibrationDisplay"],

},

],

},

"sklearn.cluster": {

"short_summary": "Clustering.",

"description": _get_guide("clustering", "biclustering"),

"sections": [

{

"title": None,

"autosummary": [

"AffinityPropagation",

"AgglomerativeClustering",

"Birch",

"BisectingKMeans",

"DBSCAN",

"FeatureAgglomeration",

"HDBSCAN",

"KMeans",

"MeanShift",

"MiniBatchKMeans",

"OPTICS",

"SpectralBiclustering",

"SpectralClustering",

"SpectralCoclustering",

"affinity_propagation",

"cluster_optics_dbscan",

"cluster_optics_xi",

"compute_optics_graph",

"dbscan",

"estimate_bandwidth",

"k_means",

"kmeans_plusplus",

"mean_shift",

"spectral_clustering",

"ward_tree",

],

},

],

},

"sklearn.compose": {

"short_summary": "Composite estimators.",

"description": _get_guide("combining_estimators"),

"sections": [

{

"title": None,

"autosummary": [

"ColumnTransformer",

"TransformedTargetRegressor",

"make_column_selector",

"make_column_transformer",

],

},

],

},

"sklearn.covariance": {

"short_summary": "Covariance estimation.",

"description": _get_guide("covariance"),

"sections": [

{

"title": None,

"autosummary": [

"EllipticEnvelope",

"EmpiricalCovariance",

"GraphicalLasso",

"GraphicalLassoCV",

"LedoitWolf",

"MinCovDet",

"OAS",

"ShrunkCovariance",

"empirical_covariance",

"graphical_lasso",

"ledoit_wolf",

"ledoit_wolf_shrinkage",

"oas",

"shrunk_covariance",

],

},

],

},

"sklearn.cross_decomposition": {

"short_summary": "Cross decomposition.",

"description": _get_guide("cross_decomposition"),

"sections": [

{

"title": None,

"autosummary": ["CCA", "PLSCanonical", "PLSRegression", "PLSSVD"],

},

],

},

"sklearn.datasets": {

"short_summary": "Datasets.",

"description": _get_guide("datasets"),

"sections": [

{

"title": "Loaders",

"autosummary": [

"clear_data_home",

"dump_svmlight_file",

"fetch_20newsgroups",

"fetch_20newsgroups_vectorized",

"fetch_california_housing",

"fetch_covtype",

"fetch_file",

"fetch_kddcup99",

"fetch_lfw_pairs",

"fetch_lfw_people",

"fetch_olivetti_faces",

"fetch_openml",

"fetch_rcv1",

"fetch_species_distributions",

"get_data_home",

"load_breast_cancer",

"load_diabetes",

"load_digits",

"load_files",

"load_iris",

"load_linnerud",

"load_sample_image",

"load_sample_images",

"load_svmlight_file",

"load_svmlight_files",

"load_wine",

],

},

{

"title": "Sample generators",

"autosummary": [

"make_biclusters",

"make_blobs",

"make_checkerboard",

"make_circles",

"make_classification",

"make_friedman1",

"make_friedman2",

"make_friedman3",

"make_gaussian_quantiles",

"make_hastie_10_2",

"make_low_rank_matrix",

"make_multilabel_classification",

"make_regression",

"make_s_curve",

"make_sparse_coded_signal",

"make_sparse_spd_matrix",

"make_sparse_uncorrelated",

"make_sppd_matrix",

"make_swiss_roll",

],

},

],

},

"sklearn.decomposition": {

"short_summary": "Matrix decomposition.",

"description": _get_guide("decompositions"),

"sections": [

{

"title": None,

"autosummary": [

"DictionaryLearning",

"FactorAnalysis",

"FastICA",

"IncrementalPCA",

"KernelPCA",

"LatentDirichletAllocation",

"MiniBatchDictionaryLearning",

"MiniBatchNMF",

"MiniBatchSparsePCA",

"NMF",

"PCA",

"SparseCoder",

"SparsePCA",

"TruncatedSVD",

"dict_learning",

"dict_learning_online",

"fastica",

"non_negative_factorization",

"sparse_encode",

],

},

],

},

"sklearn.discriminant_analysis": {

"short_summary": "Discriminant analysis.",

"description": _get_guide("lda_qda"),

"sections": [

{

"title": None,

"autosummary": [

"LinearDiscriminantAnalysis",

"QuadraticDiscriminantAnalysis",

],

},

],

},

"sklearn.dummy": {

"short_summary": "Dummy estimators.",

"description": _get_guide("model_evaluation"),

"sections": [

{

"title": None,

"autosummary": ["DummyClassifier", "DummyRegressor"],

},

],

},

"sklearn.ensemble": {

"short_summary": "Ensemble methods.",

"description": _get_guide("ensemble"),

"sections": [

{

"title": None,

"autosummary": [

"AdaBoostClassifier",

"AdaBoostRegressor",

"BaggingClassifier",

"BaggingRegressor",

"ExtraTreesClassifier",

"ExtraTreesRegressor",

"GradientBoostingClassifier",

"GradientBoostingRegressor",

"HistGradientBoostingClassifier",

"HistGradientBoostingRegressor",

"IsolationForest",

"RandomForestClassifier",

"RandomForestRegressor",

"RandomTreesEmbedding",

"StackingClassifier",

"StackingRegressor",

"VotingClassifier",

"VotingRegressor",

],

},

],

},

"sklearn.exceptions": {

"short_summary": "Exceptions and warnings.",

"description": None,

"sections": [

{

"title": None,

"autosummary": [

"ConvergenceWarning",

"DataConversionWarning",

"DataDimensionalityWarning",

"EfficiencyWarning",

"FitFailedWarning",

"InconsistentVersionWarning",

"NotFittedError",

"UndefinedMetricWarning",

"EstimatorCheckFailedWarning",

],

},

],

},

"sklearn.experimental": {

"short_summary": "Experimental tools.",

"description": None,

"sections": [

{

"title": None,

"autosummary": ["enable_halving_search_cv", "enable_iterative_imputer"],

},

],

},

"sklearn.feature_extraction": {

"short_summary": "Feature extraction.",

"description": _get_guide("feature_extraction"),

"sections": [

{

"title": None,

"autosummary": ["DictVectorizer", "FeatureHasher"],

},

{

"title": "From images",

"description": _get_submodule("sklearn.feature_extraction", "image"),

"autosummary": [

"image.PatchExtractor",

"image.extract_patches_2d",

"image.grid_to_graph",

"image.img_to_graph",

"image.reconstruct_from_patches_2d",

],

},

{

"title": "From text",

"description": _get_submodule("sklearn.feature_extraction", "text"),

"autosummary": [

"text.CountVectorizer",

"text.HashingVectorizer",

"text.TfidfTransformer",

"text.TfidfVectorizer",

],

},

],

},

"sklearn.feature_selection": {

"short_summary": "Feature selection.",

"description": _get_guide("feature_selection"),

"sections": [

{

"title": None,

"autosummary": [

"GenericUnivariateSelect",

"RFE",

"RFECV",

"SelectFdr",

"SelectFpr",

"SelectFromModel",

"SelectFwe",

"SelectKBest",

"SelectPercentile",

"SelectorMixin",

"SequentialFeatureSelector",

"VarianceThreshold",

"chi2",

"f_classif",

"f_regression",

"mutual_info_classif",

"mutual_info_regression",

"r_regression",

],

},

],

},

"sklearn.frozen": {

"short_summary": "Frozen estimators.",

"description": None,

"sections": [

{

"title": None,

"autosummary": ["FrozenEstimator"],

},

],

},

"sklearn.gaussian_process": {

"short_summary": "Gaussian processes.",

"description": _get_guide("gaussian_process"),

"sections": [

{

"title": None,

"autosummary": [

"GaussianProcessClassifier",

"GaussianProcessRegressor",

],

},

{

"title": "Kernels",

"description": _get_submodule("sklearn.gaussian_process", "kernels"),

"autosummary": [

"kernels.CompoundKernel",

"kernels.ConstantKernel",

"kernels.DotProduct",

"kernels.ExpSineSquared",

"kernels.Exponentiation",

"kernels.Hyperparameter",

"kernels.Kernel",

"kernels.Matern",

"kernels.PairwiseKernel",

"kernels.Product",

"kernels.RBF",

"kernels.RationalQuadratic",

"kernels.Sum",

"kernels.WhiteKernel",

],

},

],

},

"sklearn.impute": {

"short_summary": "Imputation.",

"description": _get_guide("impute"),

"sections": [

{

"title": None,

"autosummary": [

"IterativeImputer",

"KNNImputer",

"MissingIndicator",

"SimpleImputer",

],

},

],

},

"sklearn.inspection": {

"short_summary": "Inspection.",

"description": _get_guide("inspection"),

"sections": [

{

"title": None,

"autosummary": ["partial_dependence", "permutation_importance"],

},

{

"title": "Plotting",

"autosummary": ["DecisionBoundaryDisplay", "PartialDependenceDisplay"],

},

],

},

"sklearn.isotonic": {

"short_summary": "Isotonic regression.",

"description": _get_guide("isotonic"),

"sections": [

{

"title": None,

"autosummary": [

"IsotonicRegression",

"check_increasing",

"isotonic_regression",

],

},

],

},

"sklearn.kernel_approximation": {

"short_summary": "Kernel approximation.",

"description": _get_guide("kernel_approximation"),

"sections": [

{

"title": None,

"autosummary": [

"AdditiveChi2Sampler",

"Nystroem",

"PolynomialCountSketch",

"RBFSampler",

"SkewedChi2Sampler",

],

},

],

},

"sklearn.kernel_ridge": {

"short_summary": "Kernel ridge regression.",

"description": _get_guide("kernel_ridge"),

"sections": [

{

"title": None,

"autosummary": ["KernelRidge"],

},

],

},

"sklearn.linear_model": {

"short_summary": "Generalized linear models.",

"description": (

_get_guide("linear_model")

+ "\n\nThe following subsections are only rough guidelines: the same "

"estimator can fall into multiple categories, depending on its parameters."

),

"sections": [

{

"title": "Linear classifiers",

"autosummary": [

"LogisticRegression",

"LogisticRegressionCV",

"PassiveAggressiveClassifier", # TODO(1.10): remove

"Perceptron",

"RidgeClassifier",

"RidgeClassifierCV",

"SGDClassifier",

"SGDOneClassSVM",

],

},

{

"title": "Classical linear regressors",

"autosummary": ["LinearRegression", "Ridge", "RidgeCV", "SGDRegressor"],

},

{

"title": "Regressors with variable selection",

"description": (

"The following estimators have built-in variable selection fitting "

"procedures, but any estimator using an L1 or elastic-net penalty "

"also performs variable selection: typically "

":class:~linear_model.SGDRegressor or "

":class:~sklearn.linear_model.SGDClassifier with an appropriate "

"penalty."

),

"autosummary": [

"ElasticNet",

"ElasticNetCV",

"Lars",

"LarsCV",

"Lasso",

"LassoCV",

"LassoLars",

"LassoLarsCV",

"LassoLarsIC",

"OrthogonalMatchingPursuit",

"OrthogonalMatchingPursuitCV",

],

},

{

"title": "Bayesian regressors",

"autosummary": ["ARDRegression", "BayesianRidge"],

},

{

"title": "Multi-task linear regressors with variable selection",

"description": (

"These estimators fit multiple regression problems (or tasks)"

" jointly, while inducing sparse coefficients. While the inferred"

" coefficients may differ between the tasks, they are constrained"

" to agree on the features that are selected (non-zero"

" coefficients)."

),

"autosummary": [

"MultiTaskElasticNet",

"MultiTaskElasticNetCV",

"MultiTaskLasso",

"MultiTaskLassoCV",

],

},

{

"title": "Outlier-robust regressors",

"description": (

"Any estimator using the Huber loss would also be robust to "

"outliers, e.g., :class:~linear_model.SGDRegressor with "

"loss='huber'."

),

"autosummary": [

"HuberRegressor",

"QuantileRegressor",

"RANSACRegressor",

"TheilSenRegressor",

],

},

{

"title": "Generalized linear models (GLM) for regression",

"description": (

"These models allow for response variables to have error "

"distributions other than a normal distribution."

),

"autosummary": [

"GammaRegressor",

"PoissonRegressor",

"TweedieRegressor",

],

},

{

"title": "Miscellaneous",

"autosummary": [

"PassiveAggressiveRegressor", # TODO(1.10): remove

"enet_path",

"lars_path",

"lars_path_gram",

"lasso_path",

"orthogonal_mp",

"orthogonal_mp_gram",

"ridge_regression",

],

},

],

},

"sklearn.manifold": {

"short_summary": "Manifand learning.",

"description": _get_guide("manifold"),

"sections": [

{

"title": None,

"autosummary": [

"ClassicalMDS",

"Isomap",

"LocallyLinearEmbedding",

"MDS",

"SpectralEmbedding",

"TSNE",

"locally_linear_embedding",

"smacof",

"spectral_embedding",

"trustworthiness",

],

},

],

},

"sklearn.metrics": {

"short_summary": "Metrics.",

"description": _get_guide("model_evaluation", "metrics"),

"sections": [

{

"title": "Model selection interface",

"description": _get_guide("scoring_parameter"),

"autosummary": [

"check_scoring",

"get_scorer",

"get_scorer_names",

"make_scorer",

],

},

{

"title": "Classification metrics",

"description": _get_guide("classification_metrics"),

"autosummary": [

"accuracy_score",

"auc",

"average_precision_score",

"balanced_accuracy_score",

"brier_score_loss",

"class_likelihood_ratios",

"classification_report",

"cohen_kappa_score",

"confusion_matrix",

"confusion_matrix_at_thresholds",

"d2_brier_score",

"d2_log_loss_score",

"dcg_score",

"det_curve",

"f1_score",

"fbeta_score",

"hamming_loss",

"hinge_loss",

"jaccard_score",

"log_loss",

"matthews_corrcoef",

"multilabel_confusion_matrix",

"ndcg_score",

"precision_recall_curve",

"precision_recall_fscore_support",

"precision_score",

"recall_score",

"roc_auc_score",

"roc_curve",

"top_k_accuracy_score",

"zero_one_loss",

],

},

{

"title": "Regression metrics",

"description": _get_guide("regression_metrics"),

"autosummary": [

"d2_absolute_error_score",

"d2_pinball_score",

"d2_tweedie_score",

"explained_variance_score",

"max_error",

"mean_absolute_error",

"mean_absolute_percentage_error",

"mean_gamma_deviance",

"mean_pinball_loss",

"mean_poisson_deviance",

"mean_squared_error",

"mean_squared_log_error",

"mean_tweedie_deviance",

"median_absolute_error",

"r2_score",

"root_mean_squared_error",

"root_mean_squared_log_error",

],

},

{

"title": "Multilabel ranking metrics",

"description": _get_guide("multilabel_ranking_metrics"),

"autosummary": [

"coverage_error",

"label_ranking_average_precision_score",

"label_ranking_loss",

],

},

{

"title": "Clustering metrics",

"description": (

_get_submodule("sklearn.metrics", "cluster")

+ "\n\n"

+ _get_guide("clustering_evaluation")

),

"autosummary": [

"adjusted_mutual_info_score",

"adjusted_rand_score",

"calinski_harabasz_score",

"cluster.contingency_matrix",

"cluster.pair_confusion_matrix",

"completeness_score",

"davies_bouldin_score",

"fowlkes_mallows_score",

"homogeneity_completeness_v_measure",

"homogeneity_score",

"mutual_info_score",

"normalized_mutual_info_score",

"rand_score",

"silhouette_samples",

"silhouette_score",

"v_measure_score",

],

},

{

"title": "Biclustering metrics",

"description": _get_guide("biclustering_evaluation"),

"autosummary": ["consensus_score"],

},

{

"title": "Distance metrics",

"autosummary": ["DistanceMetric"],

},

{

"title": "Pairwise metrics",

"description": (

_get_submodule("sklearn.metrics", "pairwise")

+ "\n\n"

+ _get_guide("metrics")

),

"autosummary": [

"pairwise.additive_chi2_kernel",

"pairwise.chi2_kernel",

"pairwise.cosine_distances",

"pairwise.cosine_similarity",

"pairwise.distance_metrics",

"pairwise.haversine_distances",

"pairwise.kernel_metrics",

"pairwise.laplacian_kernel",

"pairwise.linear_kernel",

"pairwise.manhattan_distances",

"pairwise.paired_cosine_distances",

"pairwise.paired_distances",

"pairwise.paired_manhattan_distances",

"pairwise.pairwise_kernels",

"pairwise.polynomial_kernel",

"pairwise.rbf_kernel",

"pairwise.sigmoid_kernel",

"pairwise_distances",

"pairwise_distances_argmin",

"pairwise_distances_argmin_min",

"pairwise_distances_chunked",

],

},

{

"title": "Plotting",

"description": _get_guide("visualizations"),

"autosummary": [

"ConfusionMatrixDisplay",

"DetCurveDisplay",

"PrecisionRecallDisplay",

"PredictionErrorDisplay",

"RocCurveDisplay",

],

},

],

},

"sklearn.mixture": {

"short_summary": "Gaussian mixture models.",

"description": _get_guide("mixture"),

"sections": [

{

"title": None,

"autosummary": ["BayesianGaussianMixture", "GaussianMixture"],

},

],

},

"sklearn.model_selection": {

"short_summary": "Model selection.",

"description": _get_guide("cross_validation", "grid_search", "learning_curve"),

"sections": [

{

"title": "Splitters",

"autosummary": [

"GroupKFold",

"GroupShuffleSplit",

"KFold",

"LeaveOneGroupOut",

"LeaveOneOut",

"LeavePGroupsOut",

"LeavePOut",

"PredefinedSplit",

"RepeatedKFold",

"RepeatedStratifiedKFold",

"ShuffleSplit",

"StratifiedKFold",

"StratifiedShuffleSplit",

"TimeSeriesSplit",

"check_cv",

"train_test_split",

],

},

{

"title": "Hyper-parameter optimizers",

"autosummary": [

"GridSearchCV",

"HalvingGridSearchCV",

"HalvingRandomSearchCV",

"ParameterGrid",

"ParameterSampler",

"RandomizedSearchCV",

],

},

{

"title": "Post-fit model tuning",

"autosummary": [

"FixedThresholdClassifier",

"TunedThresholdClassifierCV",

],

},

{

"title": "Model validation",

"autosummary": [

"cross_val_predict",

"cross_val_score",

"cross_validate",

"learning_curve",

"permutation_test_score",

"validation_curve",

],

},

{

"title": "Visualization",

"autosummary": ["LearningCurveDisplay", "ValidationCurveDisplay"],

},

],

},

"sklearn.multiclass": {

"short_summary": "Multiclass classification.",

"description": _get_guide("multiclass_classification"),

"sections": [

{

"title": None,

"autosummary": [

"OneVsOneClassifier",

"OneVsRestClassifier",

"OutputCodeClassifier",

],

},

],

},

"sklearn.multioutput": {

"short_summary": "Multioutput regression and classification.",

"description": _get_guide(

"multilabel_classification",

"multiclass_multioutput_classification",

"multioutput_regression",

),

"sections": [

{

"title": None,

"autosummary": [

"ClassifierChain",

"MultiOutputClassifier",

"MultiOutputRegressor",

"RegressorChain",

],

},

],

},

"sklearn.naive_bayes": {

"short_summary": "Naive Bayes.",

"description": _get_guide("naive_bayes"),

"sections": [

{

"title": None,

"autosummary": [

"BernoulliNB",

"CategoricalNB",

"ComplementNB",

"GaussianNB",

"MultinomialNB",

],

},

],

},

"sklearn.neighbors": {

"short_summary": "Nearest neighbors.",

"description": _get_guide("neighbors"),

"sections": [

{

"title": None,

"autosummary": [

"BallTree",

"KDTree",

"KNeighborsClassifier",

"KNeighborsRegressor",

"KNeighborsTransformer",

"KernelDensity",

"LocalOutlierFactor",

"NearestCentroid",

"NearestNeighbors",

"NeighborhoodComponentsAnalysis",

"RadiusNeighborsClassifier",

"RadiusNeighborsRegressor",

"RadiusNeighborsTransformer",

"kneighbors_graph",

"radius_neighbors_graph",

"sort_graph_by_row_values",

],

},

],

},

"sklearn.neural_network": {

"short_summary": "Neural network models.",

"description": _get_guide(

"neural_networks_supervised", "neural_networks_unsupervised"

),

"sections": [

{

"title": None,

"autosummary": ["BernoulliRBM", "MLPClassifier", "MLPRegressor"],

},

],

},

"sklearn.pipeline": {

"short_summary": "Pipeline.",

"description": _get_guide("combining_estimators"),

"sections": [

{

"title": None,

"autosummary": [

"FeatureUnion",

"Pipeline",

"make_pipeline",

"make_union",

],

},

],

},

"sklearn.preprocessing": {

"short_summary": "Preprocessing and normalization.",

"description": _get_guide("preprocessing"),

"sections": [

{

"title": None,

"autosummary": [

"Binarizer",

"FunctionTransformer",

"KBinsDiscretizer",

"KernelCenterer",

"LabelBinarizer",

"LabelEncoder",

"MaxAbsScaler",

"MinMaxScaler",

"MultiLabelBinarizer",

"Normalizer",

"OneHotEncoder",

"OrdinalEncoder",

"PolynomialFeatures",

"PowerTransformer",

"QuantileTransformer",

"RobustScaler",

"StandardScaler",

"TargetEncoder",

"add_dummy_feature",

"binarize",

"label_binarize",

"maxabs_scale",

"minmax_scale",

"normalize",

"power_transform",

"quantile_transform",

"robust_scale",

"scale",

],

},

],

},

"sklearn.random_projection": {

"short_summary": "Random projection.",

"description": _get_guide("random_projection"),

"sections": [

{

"title": None,

"autosummary": [

"GaussianRandomProjection",

"SparseRandomProjection",

"johnson_lindenstrauss_min_dim",

],

},

],

},

"sklearn.semi_supervised": {

"short_summary": "Semi-supervised learning.",

"description": _get_guide("semi_supervised"),

"sections": [

{

"title": None,

"autosummary": [

"LabelPropagation",

"LabelSpreading",

"SelfTrainingClassifier",

],

},

],

},

"sklearn.svm": {

"short_summary": "Support vector machines.",

"description": _get_guide("svm"),

"sections": [

{

"title": None,

"autosummary": [

"LinearSVC",

"LinearSVR",

"NuSVC",

"NuSVR",

"OneClassSVM",

"SVC",

"SVR",

"l1_min_c",

],

},

],

},

"sklearn.tree": {

"short_summary": "Decision trees.",

"description": _get_guide("tree"),

"sections": [

{

"title": None,

"autosummary": [

"DecisionTreeClassifier",

"DecisionTreeRegressor",

"ExtraTreeClassifier",

"ExtraTreeRegressor",

],

},

{

"title": "Exporting",

"autosummary": ["export_graphviz", "export_text"],

},

{

"title": "Plotting",

"autosummary": ["plot_tree"],

},

],

},

"sklearn.utils": {

"short_summary": "Utilities.",

"description": _get_guide("developers-utils", is_developer=True),

"sections": [

{

"title": None,

"autosummary": [

"Bunch",

"_safe_indexing",

"as_float_array",

"assert_all_finite",

"deprecated",

"estimator_html_repr",

"gen_batches",

"gen_even_slices",

"indexable",

"murmurhash3_32",

"resample",

"safe_mask",

"safe_sqr",

"shuffle",

"Tags",

"InputTags",

"TargetTags",

"ClassifierTags",

"RegressorTags",

"TransformerTags",

"get_tags",

],

},

{

"title": "Input and parameter validation",

"description": _get_submodule("sklearn.utils", "validation"),

"autosummary": [

"check_X_y",

"check_array",

"check_consistent_length",

"check_random_state",

"check_scalar",

"validation.check_is_fitted",

"validation.check_memory",

"validation.check_symmetric",

"validation.column_or_1d",

"validation.has_fit_parameter",

"validation.validate_data",

],

},

{

"title": "Meta-estimators",

"description": _get_submodule("sklearn.utils", "metaestimators"),

"autosummary": ["metaestimators.available_if"],

},

{

"title": "Weight handling based on class labels",

"description": _get_submodule("sklearn.utils", "class_weight"),

"autosummary": [

"class_weight.compute_class_weight",

"class_weight.compute_sample_weight",

],

},

{

"title": "Dealing with multiclass target in classifiers",

"description": _get_submodule("sklearn.utils", "multiclass"),

"autosummary": [

"multiclass.is_multilabel",

"multiclass.type_of_target",

"multiclass.unique_labels",

],

},

{

"title": "Optimal mathematical operations",

"description": _get_submodule("sklearn.utils", "extmath"),

"autosummary": [

"extmath.density",

"extmath.fast_logdet",

"extmath.randomized_range_finder",

"extmath.randomized_svd",

"extmath.safe_sparse_dot",

"extmath.weighted_mode",

],

},

{

"title": "Working with sparse matrices and arrays",

"description": _get_submodule("sklearn.utils", "sparsefuncs"),

"autosummary": [

"sparsefuncs.incr_mean_variance_axis",

"sparsefuncs.inplace_column_scale",

"sparsefuncs.inplace_csr_column_scale",

"sparsefuncs.inplace_csr_column_scale",

"sparsefuncs.inplace_swap_column",

"sparsefuncs.inplace_swap_row",

"sparsefuncs.mean_variance_axis",

],

},

{

"title": None,

"description": _get_submodule("sklearn.utils", "sparsefuncs_fast"),

"autosummary": [

"sparsefuncs_fast.inplace_csr_row_normalize_l1",

"sparsefuncs_fast.inplace_csr_row_normalize_l2",

],

},

{

"title": "Working with graphs",

"description": _get_submodule("sklearn.utils", "graph"),

"autosummary": ["graph.single_source_shortest_path_length"],

},

{

"title": "Random sampling",

"description": _get_submodule("sklearn.utils", "random"),

"autosummary": ["random.sample_without_replacement"],

},

{

"title": "Auxiliary functions that operate on arrays",

"description": _get_submodule("sklearn.utils", "arrayfuncs"),

"autosummary": ["arrayfuncs.min_pos"],

},

{

"title": "Metadata routing",

"description": (

_get_submodule("sklearn.utils", "metadata_routing")

+ "\n\n"

+ _get_guide("metadata_routing")

),

"autosummary": [

"metadata_routing.MetadataRequest",

"metadata_routing.MetadataRouter",

"metadata_routing.MethodMapping",

"metadata_routing.get_routing_for_object",

"metadata_routing.process_routing",

],

},

{

"title": "Discovering scikit-learn objects",

"description": _get_submodule("sklearn.utils", "discovery"),

"autosummary": [

"discovery.all_displays",

"discovery.all_estimators",

"discovery.all_functions",

],

},

{

"title": "API compatibility checkers",

"description": _get_submodule("sklearn.utils", "estimator_checks"),

"autosummary": [

"estimator_checks.check_estimator",

"estimator_checks.parametrize_with_checks",

"estimator_checks.estimator_checks_generator",

],

},

{

"title": "Parallel computing",

"description": _get_submodule("sklearn.utils", "parallel"),

"autosummary": [

"parallel.Parallel",

"parallel.delayed",

],

},

],

},

}

"""

CONFIGURING DEPRECATED_API_REFERENCE

====================================

DEPRECATED_API_REFERENCE maps each deprecation target version to a corresponding

autosummary block. It will be placed at the bottom of the API index page under the

"Recently deprecated" section. Essentially, the rendered section would look like the

following:

|------------------------------------------|

| To be removed in {{ version_1 }} |

| -------------------------------- |

| {{ autosummary_1 }} |

| |

| To be removed in {{ version_2 }} |

| -------------------------------- |

| {{ autosummary_2 }} |

| |

| More versions... |

|------------------------------------------|

Note that the autosummary here assumes that the current module is sklearn, i.e., if

sklearn.utils.Memory is deprecated, one should put utils.Memory in the "entries"

slot of the autosummary block.

Example:

DEPRECATED_API_REFERENCE = {

"0.24": [

"model_selection.fit_grid_point",

"utils.safe_indexing",

],

}

"""

DEPRECATED_API_REFERENCE = {} # type: ignore[var-annotated]


这段代码定义了scikit-learn API文档的自动生成配置,通过API_REFERENCE和DEPRECATED_API_REFERENCE两个字典控制哪些模块和哪些已弃用接口需要生成文档,并提供了辅助函数来生成对应的.rst文件。[/content]

[content]
## 68.5 文档测试守卫 —— conftest.py 的"环境体检站"

**核心配置:`doc/conftest.py`**
- `pytest_configure(config)`:注册自定义标记(`slow`、`network`、`matplotlib` 等)
- `pytest_collection_modifyitems(config, items)`:核心跳过逻辑
  - 检查 `matplotlib` 可用性,不可用时跳过 `@pytest.mark.matplotlib` 测试
  - 检查 `pandas`/`polars` 版本,不满足最低版本时跳过相关测试
  - 检查网络连通性,离线环境跳过 `@pytest.mark.network` 测试
  - 基于 `SKLEARN_SKIP_NETWORK_TESTS` 环境变量强制跳过网络测试
- `matplotlib` fixture:强制使用 `Agg` 非交互式后端,避免图形界面依赖
- `fetch_openml_data` fixture:缓存 OpenML 数据集下载,支持离线测试

源码路径:`doc/conftest.py` - `__main__`(1-200行)

[content]
import os
from os import environ
from os.path import exists, join

import pytest
from _pytest.doctest import DoctestItem

from sklearn.datasets import get_data_home
from sklearn.datasets._base import _pkl_filepath
from sklearn.datasets._twenty_newsgroups import CACHE_NAME
from sklearn.utils._testing import SkipTest, check_skip_network
from sklearn.utils.fixes import np_base_version, parse_version, sp_version


def setup_labeled_faces():
    data_home = get_data_home()
    if not exists(join(data_home, "lfw_home")):
        raise SkipTest("Skipping dataset loading doctests")


def setup_rcv1():
    check_skip_network()
    # skip the test in rcv1.rst if the dataset is not already loaded
    rcv1_dir = join(get_data_home(), "RCV1")
    if not exists(rcv1_dir):
        raise SkipTest("Download RCV1 dataset to run this test.")


def setup_twenty_newsgroups():
    cache_path = _pkl_filepath(get_data_home(), CACHE_NAME)
    if not exists(cache_path):
        raise SkipTest("Skipping dataset loading doctests")


def setup_working_with_text_data():
    check_skip_network()
    cache_path = _pkl_filepath(get_data_home(), CACHE_NAME)
    if not exists(cache_path):
        raise SkipTest("Skipping dataset loading doctests")


def setup_loading_other_datasets():
    try:
        import pandas  # noqa: F401
    except ImportError:
        raise SkipTest("Skipping loading_other_datasets.rst, pandas not installed")

    # checks SKLEARN_SKIP_NETWORK_TESTS to see if test should run
    run_network_tests = environ.get("SKLEARN_SKIP_NETWORK_TESTS", "1") == "0"
    if not run_network_tests:
        raise SkipTest(
            "Skipping loading_other_datasets.rst, tests can be "
            "enabled by setting SKLEARN_SKIP_NETWORK_TESTS=0"
        )


def setup_compose():
    try:
        import pandas  # noqa: F401
    except ImportError:
        raise SkipTest("Skipping compose.rst, pandas not installed")


def setup_impute():
    try:
        import pandas  # noqa: F401
    except ImportError:
        raise SkipTest("Skipping impute.rst, pandas not installed")


def setup_grid_search():
    try:
        import pandas  # noqa: F401
    except ImportError:
        raise SkipTest("Skipping grid_search.rst, pandas not installed")


def setup_preprocessing():
    try:
        import pandas  # noqa: F401
    except ImportError:
        raise SkipTest("Skipping preprocessing.rst, pandas not installed")


def skip_if_matplotlib_not_installed(fname):
    try:
        import matplotlib  # noqa: F401
    except ImportError:
        basename = os.path.basename(fname)
        raise SkipTest(f"Skipping doctests for {basename}, matplotlib not installed")


def skip_if_cupy_not_installed(fname):
    try:
        import cupy  # noqa: F401
    except ImportError:
        basename = os.path.basename(fname)
        raise SkipTest(f"Skipping doctests for {basename}, cupy not installed")


def pytest_runtest_setup(item):
    fname = item.fspath.strpath
    # normalize filename to use forward slashes on Windows for easier handling
    # later
    fname = fname.replace(os.sep, "/")

    is_index = fname.endswith("datasets/index.rst")
    if fname.endswith("datasets/labeled_faces.rst") or is_index:
        setup_labeled_faces()
    elif fname.endswith("datasets/rcv1.rst") or is_index:
        setup_rcv1()
    elif fname.endswith("datasets/twenty_newsgroups.rst") or is_index:
        setup_twenty_newsgroups()
    elif fname.endswith("modules/compose.rst") or is_index:
        setup_compose()
    elif fname.endswith("datasets/loading_other_datasets.rst"):
        setup_loading_other_datasets()
    elif fname.endswith("modules/impute.rst"):
        setup_impute()
    elif fname.endswith("modules/grid_search.rst"):
        setup_grid_search()
    elif fname.endswith("modules/preprocessing.rst"):
        setup_preprocessing()

    rst_files_requiring_matplotlib = [
        "modules/partial_dependence.rst",
        "modules/tree.rst",
    ]
    for each in rst_files_requiring_matplotlib:
        if fname.endswith(each):
            skip_if_matplotlib_not_installed(fname)

    if fname.endswith("array_api.rst"):
        skip_if_cupy_not_installed(fname)


def pytest_configure(config):
    # Use matplotlib agg backend during the tests including doctests
    try:
        import matplotlib

        matplotlib.use("agg")
    except ImportError:
        pass


def pytest_collection_modifyitems(config, items):
    """Called after collect is completed.

    Parameters
    ----------
    config : pytest config
    items : list of collected items
    """
    skip_doctests = False
    if np_base_version < parse_version("2"):
        # TODO: configure numpy to output scalar arrays as regular Python scalars
        # once possible to improve readability of the tests docstrings.
        # https://numpy.org/neps/nep-0051-scalar-representation.html#implementation
        reason = "Due to NEP 51 numpy scalar repr has changed in numpy 2"
        skip_doctests = True

    if sp_version < parse_version("1.14"):
        reason = "Scipy sparse matrix repr has changed in scipy 1.14"
        skip_doctests = True

    # Normally doctest has the entire module's scope. Here we set globs to an empty dict
    # to remove the module's scope:
    # https://docs.python.org/3/library/doctest.html#what-s-the-execution-context
    for item in items:
        if isinstance(item, DoctestItem):
            item.dtest.globs = {}

    if skip_doctests:
        skip_marker = pytest.mark.skip(reason=reason)

        for item in items:
            if isinstance(item, DoctestItem):
                item.add_marker(skip_marker)

这段代码定义了scikit-learn文档测试的环境配置和条件跳过机制,通过fixture和钩子函数确保文档示例在不同环境下能够稳健运行,特别是处理了数据集加载、网络连接、依赖版本等常见问题。[/content]

[content]

68.2 自定义 Sphinx 扩展 —— 打造文档的"专属工具箱"

7 个定制扩展实现原理

  • allow_nan_estimators.py:重写 numpydoc 的类成员过滤逻允,允许在估计器列表中显示返回 NaN 的方法(如 predict_proba

  • autoshortsummary.py:实现 .. autoshortsummary:: 指令,自动提取类/函数文档字符串首句生成简短摘要表绪

  • doi_role.py:注册 :doi: 角色,解析 DOI 字符串生成指向 https://doi.org/ 的超链接节点

  • dropdown_anchors.py:为 HTML 输出中的下拉菜肴(dropdown 指令)生成稳定的锚点 ID,支持深度链接

  • github_link.py:实现 .. github:: 指令与 github_link 角色,根据源码路径生成指向 GitHub 对应行的链接

  • override_pst_pagetoc.py:覆盖 pydata_sphinx_theme 的页面目录模板,自定义侧边栏 TOC 显示层级与样式

  • sphinx_issues.py:注册 :issue::pr::commit: 角色,自动生成指向 GitHub Issue/PR/Commit 的链接

源码路径:doc/sphinxext/allow_nan_estimators.py - __main__(1-100行)

源码路径:doc/sphinxext/autoshortsummary.py - __main__(1-150行)

源码路径:doc/sphinxext/doi_role.py - __main__(1-80行)

源码路径:doc/sphinxext/dropdown_anchors.py - __main__(1-100行)

源码路径:doc/sphinxext/github_link.py - __main__(1-200行)

源码路径:doc/sphinxext/override_pst_pagetoc.py - __main__(1-100行)

源码路径:doc/sphinxext/sphinx_issues.py - __main__(1-100行)

[content]

from contextlib import suppress

from docutils import nodes

from docutils.parsers.rst import Directive

from sklearn.utils import all_estimators

from sklearn.utils._test_common.instance_generator import _construct_instances

from sklearn.utils._testing import SkipTest

class AllowNanEstimators(Directive):

@staticmethod

def make_paragraph_for_estimator_type(estimator_type):

intro = nodes.list_item()

intro += nodes.strong(text="Estimators that allow NaN values for type ")

intro += nodes.literal(text=f"{estimator_type}")

intro += nodes.strong(text=":\n")

exists = False

lst = nodes.bullet_list()

for name, est_class in all_estimators(type_filter=estimator_type):

with suppress(SkipTest):

Here we generate the text only for one instance. This directive

should not be used for meta-estimators where tags depend on the

sub-estimator.

est = next(_construct_instances(est_class))

if est.sklearn_tags().input_tags.allow_nan:

module_name = ".".join(est_class.module.split(".")[:2])

class_title = f"{est_class.name}"

class_url = f"./generated/{module_name}.{class_title}.html"

item = nodes.list_item()

para = nodes.paragraph()

para += nodes.reference(

class_title, text=class_title, internal=False, refuri=class_url

)

exists = True

item += para

lst += item

intro += lst

return [intro] if exists else None

def run(self):

lst = nodes.bullet_list()

for i in ["cluster", "regressor", "classifier", "transformer"]:

item = self.make_paragraph_for_estimator_type(i)

if item is not None:

lst += item

return [lst]

def setup(app):

app.add_directive("allow_nan_estimators", AllowNanEstimators)

return {

"version": "0.1",

"parallel_read_safe": True,

"parallel_write_safe": True,

}


这段代码实现了一个Sphinx指令`allow_nan_estimators`,用于在文档中列出那些允许输入NaN值的估计器类型。它通过检查估计器的标签来确定是否允许NaN输入,并生成带有链接的列表项。[/content]

[content]
from sphinx.ext.autodoc import ModuleLevelDocumenter


class ShortSummaryDocumenter(ModuleLevelDocumenter):
    """An autodocumenter that only renders the short summary of the object."""

    # Defines the usage: .. autoshortsummary:: {{ object }}
    objtype = "shortsummary"

    # Disable content indentation
    content_indent = ""

    # Avoid being selected as the default documenter for some objects, because we are
    # returning `can_document_member` as True for all objects
    priority = -99

    @classmethod
    def can_document_member(cls, member, membername, isattr, parent):
        """Allow documenting any object."""
        return True

    def get_object_members(self, want_all):
        """Document no members."""
        return (False, [])

    def add_directive_header(self, sig):
        """Override default behavior to add no directive header or options."""
        pass

    def add_content(self, more_content):
        """Override default behavior to add only the first line of the docstring.

        Modified based on the part of processing docstrings in the original
        implementation of this method.

        https://github.com/sphinx-doc/sphinx/blob/faa33a53a389f6f8bc1f6ae97d6015fa92393c4a/sphinx/ext/autodoc/__init__.py#L609-L622
        """
        sourcename = self.get_sourcename()
        docstrings = self.get_doc()

        if docstrings is not None:
            if not docstrings:
                docstrings.append([])
            # Get the first non-empty line of the processed docstring; this could lead
            # to unexpected results if the object does not have a short summary line.
            short_summary = next(
                (s for s in self.process_doc(docstrings) if s), "<no summary>"
            )
            self.add_line(short_summary, sourcename, 0)


def setup(app):
    app.add_autodocumenter(ShortSummaryDocumenter)

这段代码实现了一个Sphinx自动文档生成器ShortSummaryDocumenter,它只输出对象文档字符串的第一行作为摘要,用于在API参考中创建简洁的摘要表格。[/content]

[content]

"""

doilinks


Extension to add links to DOIs. With this extension you can use e.g.

:doi:`10.1016/S0022-2836(05)80360-2` in your documents. This will

create a link to a DOI resolver

(``https://doi.org/10.1016/S0022-2836(05)80360-2``).

The link caption will be the raw DOI.

You can also give an explicit caption, e.g.

:doi:`Basic local alignment search tool <10.1016/S0022-2836(05)80360-2>`.

:copyright: Copyright 2015  Jon Lund Steffensen. Based on extlinks by

    the Sphinx team.

:license: BSD.

"""

from docutils import nodes, utils

from sphinx.util.nodes import split_explicit_title

def reference_role(typ, rawtext, text, lineno, inliner, options={}, content=[]):

    text = utils.unescape(text)

    has_explicit_title, title, part = split_explicit_title(text)

    if typ in ["arXiv", "arxiv"]:

        full_url = "https://arxiv.org/abs/" + part

        if not has_explicit_title:

            title = "arXiv:" + part

        pnode = nodes.reference(title, title, internal=False, refuri=full_url)

        return [pnode], []

    if typ in ["doi", "DOI"]:

        full_url = "https://doi.org/" + part

        if not has_explicit_title:

            title = "DOI:" + part

        pnode = nodes.reference(title, title, internal=False, refuri=full_url)

        return [pnode], []

def setup_link_role(app):

    app.add_role("arxiv", reference_role, override=True)

    app.add_role("arXiv", reference_role, override=True)

    app.add_role("doi", reference_role, override=True)

    app.add_role("DOI", reference_role, override=True)

def setup(app):

    app.connect("builder-inited", setup_link_role)

    return {"version": "0.1", "parallel_read_safe": True}

```

这段代码实现了一个Sphinx扩展,添加了`:doi:`角色,用于在文档中创建指向DOI解析器的超链接,同时也支持`:arxiv:`角色链接到arXiv论文。[/content]

[content]
import re

from docutils import nodes
from sphinx.transforms.post_transforms import SphinxPostTransform
from sphinx_design.dropdown import dropdown_main


class DropdownAnchorAdder(SphinxPostTransform):
    """Insert anchor links to the sphinx-design dropdowns.

    Some of the dropdowns were originally headers that had automatic anchors, so we
    need to make sure that the old anchors still work. See the original implementation
    (in JS): https://github.com/scikit-learn/scikit-learn/pull/27409

    The anchor links are inserted at the end of the node with class "sd-summary-text"
    which includes only the title text part of the dropdown (no icon, markers, etc).
    """

    default_priority = 9999  # Apply later than everything else
    formats = ["html"]

    def run(self):
        """Run the post transformation."""
        # Counter to store the duplicated summary text to add it as a suffix in the
        # anchor ID
        anchor_id_counters = {}

        for sd_dropdown in self.document.findall(dropdown_main):
            # Grab the summary text node
            sd_summary_text = sd_dropdown.next_node(
                lambda node: "sd-summary-text" in node.get("classes", [])
            )

            # Concatenate the text of relevant nodes as the title text
            title_text = "".join(node.astext() for node in sd_summary_text.children)

            # The ID uses the first line, lowercased, with spaces replaced by dashes;
            # suffix the anchor ID with a counter if it already exists
            anchor_id = re.sub(r"\s+", "-", title_text.strip().split("\n")[0]).lower()
            if anchor_id in anchor_id_counters:
                anchor_id_counters[anchor_id] += 1
                anchor_id = f"{anchor_id}-{anchor_id_counters[anchor_id]}"
            else:
                anchor_id_counters[anchor_id] = 1
            sd_dropdown["ids"].append(anchor_id)

            # Create the anchor element and insert after the title text; we do this
            # directly with raw HTML
            anchor_html = (
                f'<a class="headerlink" href="#{anchor_id}" '
                'title="Link to this dropdown">#</a>'
            )
            anchor_node = nodes.raw("", anchor_html, format="html")
            sd_summary_text.append(anchor_node)


def setup(app):
    app.add_post_transform(DropdownAnchorAdder)

```
posted @ 2026-09-04 04:07  绝不原创的飞龙  阅读(3)  评论(0)    收藏  举报