Source code for qsarkit.models._neural_network

"""Multi-layer perceptron regressor with QSAR-sane defaults."""

from __future__ import annotations

from typing import Optional, Tuple, Union

from sklearn.neural_network import MLPRegressor

__all__ = ["NeuralNetworkQSAR"]


[docs] class NeuralNetworkQSAR(MLPRegressor): """Feed-forward neural network regressor tuned with QSAR-sane defaults. A thin subclass of :class:`sklearn.neural_network.MLPRegressor` that keeps the full parent parameter set but defaults to a two-hidden-layer architecture with early stopping and moderate L2 regularization — settings that guard against the overfitting risk of neural networks on the small-to-medium (hundreds to low thousands of compounds) QSAR datasets typical of real drug-discovery projects, where a network with the scikit-learn defaults (a single 100-unit layer, no regularization, no early stopping) would otherwise happily memorize the training set. Parameters ---------- hidden_layer_sizes : tuple of int, default (100, 50) Sizes of the hidden layers. Two layers give the network enough capacity for non-linear structure-activity relationships without the data requirements of a deeper architecture. activation : {"identity", "logistic", "tanh", "relu"}, default "relu" Activation function of the hidden layers. alpha : float, default 1e-3 L2 regularization strength, an order of magnitude above scikit-learn's default to counter overfitting on small QSAR datasets. early_stopping : bool, default True Hold out part of the training data and stop when validation score stops improving, which is a cheap and effective safeguard against overfitting on limited QSAR data. random_state : int, optional Seed for reproducible weight initialization and data shuffling. Examples -------- >>> from sklearn.datasets import make_regression >>> X, y = make_regression(n_samples=60, n_features=5, random_state=0) >>> model = NeuralNetworkQSAR(max_iter=200, random_state=0).fit(X, y) >>> model.predict(X).shape (60,) References ---------- - Winkler, D. A. (2004). "Neural Networks as Robust Tools in Drug Design and Analysis." Mol. Biotechnol., 27(2), 139-167. https://doi.org/10.1385/MB:27:2:139 """ def __init__( self, loss: str = "squared_error", hidden_layer_sizes: Tuple[int, ...] = (100, 50), activation: str = "relu", *, solver: str = "adam", alpha: float = 1e-3, batch_size: Union[str, int] = "auto", learning_rate: str = "constant", learning_rate_init: float = 0.001, power_t: float = 0.5, max_iter: int = 200, shuffle: bool = True, random_state: Optional[int] = None, tol: float = 1e-4, verbose: bool = False, warm_start: bool = False, momentum: float = 0.9, nesterovs_momentum: bool = True, early_stopping: bool = True, validation_fraction: float = 0.1, beta_1: float = 0.9, beta_2: float = 0.999, epsilon: float = 1e-8, n_iter_no_change: int = 10, max_fun: int = 15000, ) -> None: super().__init__( loss=loss, hidden_layer_sizes=hidden_layer_sizes, activation=activation, solver=solver, alpha=alpha, batch_size=batch_size, learning_rate=learning_rate, learning_rate_init=learning_rate_init, power_t=power_t, max_iter=max_iter, shuffle=shuffle, random_state=random_state, tol=tol, verbose=verbose, warm_start=warm_start, momentum=momentum, nesterovs_momentum=nesterovs_momentum, early_stopping=early_stopping, validation_fraction=validation_fraction, beta_1=beta_1, beta_2=beta_2, epsilon=epsilon, n_iter_no_change=n_iter_no_change, max_fun=max_fun, )