River: Online Machine Learning in Python

repository·main·Indexed 27 days ago

https://github.com/online-ml/river

River is a Python library for online machine learning on streaming data, enabling models to learn sequentially from new data points without revisiting historical data. It is designed for production environments and handling concept drift, utilizing Python dictionaries as the primary data format. The library provides a wide range of algorithms including linear models, decision trees, anomaly detection, and time series forecasting, along with utilities for feature extraction, preprocessing, and progressive model validation.

Tokens
16.3K
Snippets
53
Records
80
Agent score
91%

What's inside River

  1. Understand the core capabilities of River

    main

    River is a library designed for online machine learning, focusing on processing data one sample at a time. This makes it suitable for streaming data applications where batch processing is inconvenient. Key capabilities include:

    • Streaming Data Processing: All tools can be updated with a single observation at a time.
    • Concept Drift Adaptation: Many models are specifically designed to be robust against concept drift in dynamic environments where data evolves.
    • General Purpose ML: Supports regression, classification, and unsupervised learning.
    • Ad hoc Tasks: Can be used for computing online metrics and concept drift detection.
    • Python Integration: Designed to work seamlessly with Python dictionaries, making it ideal for web applications handling JSON payloads.
  2. River Algorithm Families and Utilities

    main

    River provides online implementations for various machine learning tasks and utilities:

    Algorithms:

    • Linear models (with various optimizers)
    • Decision trees and random forests
    • (Approximate) nearest neighbors
    • Anomaly detection
    • Drift detection
    • Recommender systems
    • Time series forecasting
    • Bandits
    • Factorization machines
    • Imbalanced learning
    • Clustering
    • Bagging/boosting/stacking
    • Active learning

    Utilities:

    • Feature extraction and selection
    • Online statistics and metrics
    • Preprocessing
    • Built-in datasets
    • Progressive model validation
    • Model pipelines
  3. Understand Online Processing and Data Streams

    main

    River is designed for online machine learning, where models operate on data streams (sequences of individual elements/samples) rather than large batches.

    Key concepts include:

    • Online Processing: Training a model by teaching it one sample at a time. Unlike batch learning, online models are stateful, dynamic objects that do not need to revisit past data.
    • Reactive Data Streams: Data that comes to you (e.g., a user visiting a website) which you must react to.
    • Proactive Data Streams: Data you control (e.g., reading from a file) where you decide the speed and order of processing.
    • Concept Drift: Changes in the underlying data distribution over time. Online models are better suited to handle drift because they continuously learn and adapt, whereas batch models typically require retraining from scratch.
  4. Compare River with scikit-learn for online learning

    main

    While scikit-learn provides partial_fit for incremental learning, there are key differences when compared to River:

    • Granularity: sklearn algorithms are often optimized for mini-batch learning, whereas River is optimized for pure streaming contexts where observations arrive one by one.
    • Performance: River is generally faster in streaming contexts because it avoids the heavy data-checking overhead found in sklearn.
    • Feature Handling: sklearn typically assumes a fixed number of features. River uses dictionaries for observations, allowing you to add or drop features dynamically during the stream.
  5. Understand River's input validation approach

    main

    River follows the Pythonic EAFP (Easier to Ask for Forgiveness than Permission) principle rather than the LBYL (Look Before You Leap) style used by libraries like scikit-learn.

    Implication for users: River does minimal runtime input validation to maintain high performance and code readability. Users must ensure they provide sane, well-formatted inputs to avoid runtime errors.

  6. Add a CodSpeed Python benchmark

    main

    To add a new Python benchmark for CodSpeed, copy this template into benchmarks/codspeed/python/test_<module>.py. Note: Keep the benchmark name stable after it lands to preserve CodSpeed history.

    from __future__ import annotations
    
    import pytest
    
    from river import <module>
    
    from workloads import binary_stream  # or regression_stream, scalar_series, ...
    
    pytestmark = pytest.mark.benchmark(group="<module>")
    
    
    def test_<estimator>_learn(benchmark) -> None:
        stream = binary_stream()
    
        def run() -> None:
            model = <module>.<Estimator>(seed=42)
            for x, y in stream:
                model.learn_one(x, y)
    
        benchmark(run)
  7. Install River with mini-batch support (pandas extra)

    main

    River's core online interface (learn_one / predict_one) does not require pandas. However, the mini-batch interface (learn_many, predict_many, predict_proba_many, transform_many) is built on top of pandas.DataFrame and pandas.Series. To use these mini-batch methods, you must install the pandas extra.

    If you attempt to call a mini-batch method without pandas installed, River will raise an ImportError.

    pip install "river[pandas]"
    # or
    uv add "river[pandas]"
  8. Install River

    main

    River requires Python 3.11 or above. You can install the core library using pip.

    If you need the mini-batch interface (which includes methods like learn_many, predict_many, predict_proba_many, and transform_many), you must opt-in to the pandas dependency by installing the [pandas] extra.

  9. Save and load River models

    main

    River models can be serialized using standard Python serialization libraries like pickle. For more complex objects, the library authors also recommend using dill or cloudpickle.

    >>> from river import ensemble
    >>> import pickle
    
    >>> model = ensemble.ARFClassifier()
    
    # save
    >>> with open('model.pkl', 'wb') as f:
    ...     pickle.dump(model, f)
    
    # load
    >>> with open('model.pkl', 'rb') as f:
    ...     model = pickle.load(f)
  10. Run CodSpeed benchmarks locally

    main

    CodSpeed runs Python pytest benchmarks and Rust criterion benchmarks. You can run them locally using make:

    • make benchmark: Runs all Python benchmarks (local walltime table).
    • make benchmark K=logistic: Filters Python benchmarks by a pytest -k expression.
    • make benchmark-rust: Runs all Rust criterion benchmarks.
    • make benchmark-rust BENCH=stats_bench: Runs a specific Rust benchmark target.
    make benchmark                      # all Python benchmarks, local walltime table
    make benchmark K=logistic           # filter by pytest -k expression
    make benchmark-rust                 # all Rust criterion benches
    make benchmark-rust BENCH=stats_bench