blackboxops 0.1.5
Auto generate a fully functional Machine Learning pipeline
Requires Python: >=3.7,<4.0

# BlackBox Ops

Auto generate a fully functional Machine Learning pipeline with publish-ready output

# Usage

Installation
```
pip install blackboxops --upgrade
```

Use
* For trainable models

    ```
    python -m blackboxops --name ProjectName
    ```

* For non-trainable models (e.g. deterministic algorithm)
    ```
    python -m blackboxops --name ProjectName --noflow
    ```

# Output

Obtain tree structure (as of 2/17/2020)
```
.
├── ProjectName
│   ├── __init__.py
│   ├── architecture.py
│   ├── bookkeeper
│   │   └── __init__.py
│   ├── model
│   │   └── __init__.py
│   └── performance
│       └── __init__.py
├── README.md
├── doc
│   └── img
│       ├── main_architecture.png
│       └── model_pipeline.png
├── flow
│   ├── __set_version.py
│   ├── data_pipeline
│   │   └── __init__.py
│   ├── flow
│   │   └── __init__.py
│   ├── sandbox.py
│   ├── tracker
│   │   ├── __init__.py
│   │   └── templates
│   │       └── index.html
│   └── tracker_server.py
└── tests
    ├── __init__.py
    ├── test_ProjectName.py
    ├── test_methods.py
    └── test_performance.py
```

# Model Pipeline
This project is based on the following concepts

![ML Architecture](doc/img/model_pipeline.png "ML Architecture")

# Python Architecture
The architecture of the code generated

![ML Architecture](doc/img/main_architecture.png "ML Architecture")




# Key Concepts

## Versioning
Every (ready to deploy) model follows the following versioning convention
<center>
Major.Minor.Score
</center>

Where
* Major: tracks the software around this model, as well as its interface. As long as changes are backward compatible, this shouldn't change.
* Minor: Changes to the model that don't break backwards compatibility. A typical case: changing the performance metric.
* Score: this is autogenerated by the model, where `0` literally means _"never trained"_ and `9999` means _"model reached perfect accuracy"_. Every trained model generates a score and deployments are based on **best score**.

Every models starts its life with version `0.1.0`

## Project Structure
Once the project is packaged and ready to ship (typically via a wheel), the portion of the code that gets shipped is

```
├── ProjectName
│   │
│   ├── architecture.py
│   │
│   ├── __init__.py
│   ├── bookkeeper
│   │   └── __init__.py
│   ├── model
│   │   └── __init__.py
│   └── performance
│       └── __init__.py
```
where the classes `bookkeeper` and `performance` take care of the background working of the model and `model` is the class exposed with its interface fully defined in `architecture.py`. If everything is working in the way it is supposed to work, the file `architecture.py` is the only code you should interact with.

Once your model has been deployed, you could use it in your scripts (after it has been `pip install`ed) as

```
import ProjectName

mdl = ProjectName.Model()

...

y = mdl.some_method_defined_by_you(X)

```

## Model Usage

There are three functions that are required for the user to define at `ProjectName/architecture.py`, namely

* `version()`
* `backend_performance()`
* `backend_model()`
* `interface_methods()`

## architecture.version()
This method is a one line denoting the major `M` and minor `m` versioning of the model as
```
# Architecture Version
def version():
    return(
        '0.1' # M=0, m=1
    )
```
Later in this document, we'll see how the full version of a model has the form

```
M.m.xxxx # Major.Minor.Score
```
where `score` is fully determined by the training of the model. More on how these values are set later with the introduction of the class `ModelMutable`