193 lines
10 KiB
Plaintext
193 lines
10 KiB
Plaintext
---
|
|
description: Enforces best practices and coding standards for scikit-learn projects, promoting maintainability, performance, and security. This rule provides guidelines on code organization, common patterns, performance optimization, testing, and common pitfalls.
|
|
globs: *.py
|
|
---
|
|
# Scikit-learn Best Practices and Coding Standards
|
|
|
|
This document outlines best practices and coding standards for developing with scikit-learn, aiming to improve code quality, maintainability, performance, and security.
|
|
|
|
## 1. Code Organization and Structure
|
|
|
|
- **Directory Structure:**
|
|
- Organize your project into logical modules or components. A typical structure might include:
|
|
- `src/`: Source code for your project.
|
|
- `models/`: Contains the implementation of machine learning models.
|
|
- `features/`: Feature engineering and processing logic.
|
|
- `utils/`: Utility functions and helper modules.
|
|
- `data/`: Datasets used for training and testing.
|
|
- `raw/`: Original, unprocessed data.
|
|
- `processed/`: Cleaned and preprocessed data.
|
|
- `notebooks/`: Jupyter notebooks for experimentation and analysis.
|
|
- `tests/`: Unit and integration tests.
|
|
- `scripts/`: Scripts for training, evaluation, and deployment.
|
|
- `config/`: Configuration files (e.g., YAML, JSON).
|
|
- Example:
|
|
|
|
|
|
project_root/
|
|
├── src/
|
|
│ ├── models/
|
|
│ │ ├── __init__.py
|
|
│ │ ├── model_1.py
|
|
│ │ └── model_2.py
|
|
│ ├── features/
|
|
│ │ ├── __init__.py
|
|
│ │ ├── feature_engineering.py
|
|
│ │ └── feature_selection.py
|
|
│ ├── utils/
|
|
│ │ ├── __init__.py
|
|
│ │ └── helpers.py
|
|
│ ├── __init__.py
|
|
│ └── main.py
|
|
├── data/
|
|
│ ├── raw/
|
|
│ │ └── data.csv
|
|
│ └── processed/
|
|
│ └── processed_data.csv
|
|
├── notebooks/
|
|
│ └── exploratory_data_analysis.ipynb
|
|
├── tests/
|
|
│ ├── __init__.py
|
|
│ ├── test_models.py
|
|
│ └── test_features.py
|
|
├── scripts/
|
|
│ ├── train.py
|
|
│ └── evaluate.py
|
|
├── config/
|
|
│ └── config.yaml
|
|
├── README.md
|
|
└── requirements.txt
|
|
|
|
|
|
- **File Naming Conventions:**
|
|
- Use descriptive and consistent names for files and modules.
|
|
- Prefer snake_case for Python files and variables (e.g., `model_training.py`, `n_samples`).
|
|
|
|
- **Module Organization:**
|
|
- Each module should have a clear and specific purpose.
|
|
- Use `__init__.py` files to define packages and modules within directories.
|
|
- Minimize dependencies between modules to improve maintainability.
|
|
|
|
- **Component Architecture:**
|
|
- Design your application with loosely coupled components.
|
|
- Implement interfaces or abstract classes to define contracts between components.
|
|
- Use dependency injection to manage dependencies and promote testability.
|
|
|
|
- **Code Splitting Strategies:**
|
|
- Split large files into smaller, more manageable modules.
|
|
- Group related functions and classes into modules based on functionality.
|
|
- Consider splitting code based on layers (e.g., data access, business logic, presentation).
|
|
|
|
## 2. Common Patterns and Anti-patterns
|
|
|
|
- **Design Patterns:**
|
|
- **Pipeline:** Use scikit-learn's `Pipeline` class to chain together multiple data preprocessing and modeling steps. This helps prevent data leakage and ensures consistent data transformations.
|
|
- **Model Selection:** Employ techniques like cross-validation and grid search to select the best model and hyperparameters for your data. Use `GridSearchCV` or `RandomizedSearchCV`.
|
|
- **Ensemble Methods:** Leverage ensemble methods like Random Forests, Gradient Boosting, and Voting Classifiers to improve model accuracy and robustness.
|
|
- **Custom Transformers:** Create custom transformers using `BaseEstimator` and `TransformerMixin` to encapsulate complex feature engineering logic.
|
|
|
|
- **Recommended Approaches:**
|
|
- **Data Preprocessing:** Always split your data into training and testing sets *before* any preprocessing steps.
|
|
- **Feature Scaling:** Apply appropriate feature scaling techniques (e.g., StandardScaler, MinMaxScaler) to numerical features before training models.
|
|
- **Categorical Encoding:** Use one-hot encoding or ordinal encoding for categorical features.
|
|
- **Missing Value Imputation:** Handle missing values using imputation techniques like mean, median, or k-NN imputation.
|
|
- **Model Persistence:** Save trained models to disk using `joblib` or `pickle` for later use.
|
|
|
|
- **Anti-patterns and Code Smells:**
|
|
- **Data Leakage:** Avoid data leakage by preprocessing the entire dataset before splitting into training and testing sets.
|
|
- **Overfitting:** Be cautious of overfitting by using regularization techniques and cross-validation.
|
|
- **Ignoring Data Distributions:** Always visualize and understand data distributions before applying transformations or choosing models.
|
|
- **Hardcoding Parameters:** Avoid hardcoding parameters directly in the code. Use configuration files or command-line arguments instead.
|
|
- **Ignoring Warnings:** Pay attention to scikit-learn warnings, as they often indicate potential problems with your code or data.
|
|
|
|
- **State Management:**
|
|
- Use classes to encapsulate state and behavior related to models or data processing steps.
|
|
- Avoid global variables and mutable state whenever possible.
|
|
- Use immutable data structures where appropriate to prevent unintended side effects.
|
|
|
|
- **Error Handling:**
|
|
- Use try-except blocks to handle exceptions and prevent your application from crashing.
|
|
- Log errors and warnings to a file or logging service.
|
|
- Provide informative error messages to users.
|
|
- Implement retry mechanisms for transient errors.
|
|
|
|
## 3. Performance Considerations
|
|
|
|
- **Optimization Techniques:**
|
|
- **Vectorization:** Utilize NumPy's vectorized operations to perform calculations on entire arrays instead of looping through individual elements. Use `.values` from pandas DataFrames when passing to scikit-learn.
|
|
- **Memory Optimization:** Minimize memory usage by using appropriate data types (e.g., `int8`, `float32`) and avoiding unnecessary copies of data.
|
|
- **Algorithm Selection:** Choose efficient algorithms that are well-suited for your data and task. For example, use `MiniBatchKMeans` for large datasets.
|
|
- **Parallelization:** Use scikit-learn's built-in support for parallel processing to speed up training and prediction.
|
|
|
|
- **Memory Management:**
|
|
- Use memory profiling tools to identify memory leaks and optimize memory usage.
|
|
- Release unused memory by deleting variables or using the `gc` module.
|
|
- Use data streaming techniques for large datasets that don't fit into memory.
|
|
|
|
- **Lazy Loading Strategies:**
|
|
- Load data and models only when they are needed.
|
|
- Use generators or iterators to process large datasets in chunks.
|
|
|
|
## 4. Security Best Practices
|
|
|
|
- **Common Vulnerabilities:**
|
|
- **Model Poisoning:** Protect against model poisoning attacks by validating input data and sanitizing user-provided data.
|
|
- **Adversarial Attacks:** Be aware of adversarial attacks that can manipulate model predictions. Consider using techniques like adversarial training to improve model robustness.
|
|
|
|
- **Input Validation:**
|
|
- Validate all input data to ensure it conforms to the expected format and range.
|
|
- Sanitize user-provided data to prevent injection attacks.
|
|
|
|
- **Data Protection:**
|
|
- Encrypt sensitive data at rest and in transit.
|
|
- Use access control mechanisms to restrict access to data and models.
|
|
|
|
## 5. Testing Approaches
|
|
|
|
- **Unit Testing:**
|
|
- Write unit tests for individual functions and classes.
|
|
- Use mocking to isolate components and test them in isolation.
|
|
- Assert that your code produces the expected output for different inputs.
|
|
|
|
- **Integration Testing:**
|
|
- Write integration tests to verify that different components work together correctly.
|
|
- Test the interaction between your code and external dependencies.
|
|
|
|
- **Test Organization:**
|
|
- Organize your tests into a separate directory (e.g., `tests`).
|
|
- Use descriptive names for your test files and functions.
|
|
|
|
- **Mocking and Stubbing:**
|
|
- Use mocking libraries like `unittest.mock` or `pytest-mock` to create mock objects for testing.
|
|
- Use stubs to replace complex dependencies with simpler implementations.
|
|
|
|
## 6. Common Pitfalls and Gotchas
|
|
|
|
- **Data Type Mismatches:** Ensure that the data types of your input features are compatible with the model you are using.
|
|
- **Feature Scaling Issues:** Use the correct scaling method for your features, understanding how each scaler behaves.
|
|
- **Improper Cross-Validation:** Make sure the cross-validation strategy you choose is appropriate for your dataset and model.
|
|
- **Version Compatibility:** Be aware of compatibility issues between different versions of scikit-learn and its dependencies.
|
|
|
|
## 7. Tooling and Environment
|
|
|
|
- **Recommended Development Tools:**
|
|
- **IDE:** Use an IDE like VS Code, PyCharm, or JupyterLab.
|
|
- **Version Control:** Use Git for version control.
|
|
- **Package Manager:** Use pip or Conda for managing dependencies.
|
|
- **Virtual Environments:** Create virtual environments for each project to isolate dependencies.
|
|
|
|
- **Linting and Formatting:**
|
|
- Use linters like pylint or flake8 to enforce code style and identify potential errors.
|
|
- Use formatters like black or autopep8 to automatically format your code.
|
|
|
|
- **CI/CD Integration:**
|
|
- Integrate your code with a CI/CD system like Jenkins, Travis CI, or CircleCI.
|
|
- Automatically run tests and linters on every commit.
|
|
- Deploy your application to a production environment automatically.
|
|
|
|
## General Coding Style
|
|
- Use underscores to separate words in non-class names: `n_samples` rather than `nsamples`.
|
|
- Avoid multiple statements on one line.
|
|
- Use relative imports for references inside scikit-learn (except for unit tests, which should use absolute imports).
|
|
|
|
By following these best practices, you can write cleaner, more maintainable, and more efficient scikit-learn code. |