Skip to content

Commit

Permalink
Include 3.0 features
Browse files Browse the repository at this point in the history
  • Loading branch information
FlorianJacta committed Sep 25, 2023
1 parent 0bf10e1 commit b4de32b
Show file tree
Hide file tree
Showing 8 changed files with 83 additions and 64 deletions.
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -45,29 +45,21 @@ def compute_metrics(historical_data, predicted_data):
mae = mean_absolute_error(historical_to_compare, predicted_data)
return rmse, mae


def create_predictions_dataset(predictions_baseline, predictions_ml, day, n_predictions, cleaned_data):
print("Creating predictions dataset...")

# Set arbitrarily the time window for the chart as 5 times the number of predictions
window = 5 * n_predictions


# Create the historical dataset that will be displayed
new_length = len(cleaned_data[cleaned_data["Date"] < day]) + n_predictions
temp_df = cleaned_data[:new_length]
temp_df = temp_df[-window:].reset_index(drop=True)
historical_data = cleaned_data[:new_length].reset_index(drop=True)

# Create the series that will be used in the concat
historical_values = pd.Series(temp_df["Value"], name="Historical values")
predicted_values_ml = pd.Series([np.NaN] * len(temp_df), name="Predicted values ML")
predicted_values_ml[-len(predictions_ml):] = predictions_ml
predicted_values_baseline = pd.Series([np.NaN] * len(temp_df), name="Predicted values Baseline")
predicted_values_baseline[-len(predictions_baseline):] = predictions_baseline
create_series = lambda data, name: pd.Series([np.NaN] * (len(historical_data)), name=name).fillna({i: val for i, val in enumerate(data, len(historical_data)-n_predictions)})

predictions_dataset = pd.concat([
historical_data["Date"],
historical_data["Value"].rename("Historical values"),
create_series(predictions_ml, "Predicted values ML"),
create_series(predictions_baseline, "Predicted values Baseline")
], axis=1)

# Create the predictions dataset
# Columns : [Date, Historical values, Predicted values]
predictions_dataset = pd.concat([temp_df["Date"],
historical_values,
predicted_values_ml,
predicted_values_baseline], axis=1)

return predictions_dataset
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,4 @@ def on_change(state, var_name: str, var_value):
if __name__ == "__main__":
tp.Core().run()
gui = Gui(pages=pages)
gui.run(title="Taipy Application", port=3455)
gui.run(title="Taipy Application")
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,12 @@

<|{scenario}|scenario|on_submission_change=submission_change|>

<|{predictions_dataset}|chart|x=Date|y[1]=Historical values|type[1]=bar|y[2]=Predicted values ML|y[3]=Predicted values Baseline|>
<|{predictions_dataset}|chart|x=Date|y[1]=Historical values|type[1]=bar|y[2]=Predicted values ML|y[3]=Predicted values Baseline|>

# Data Node Exploration

<|layout|columns=1 5|
<|{data_node}|data_node_selector|>

<|{data_node}|data_node|>
|>
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,22 @@


scenario = None
data_node = None
day = dt.datetime(2021, 7, 26)
n_predictions = 40
max_capacity = 200
predictions_dataset = {"Date":[0],
predictions_dataset = {"Date":[dt.datetime(2021, 7, 26)],
"Predicted values ML":[0],
"Predicted values Baseline":[0],
"Historical values":[0]}

def submission_change(state, submittable, details: dict):
print(f"submission_change(state, submittable: {submittable}, details: {details})")
notify(state, "info", f"submission_change(state, submittable: {submittable}, details: {details})")
if details['submission_status'] == 'COMPLETED':
notify(state, "success", 'Scenario completed!')
state['scenario'].on_change(state, 'scenario', state.scenario)
else:
notify(state, "error", 'Something went wrong!')


def save(state):
print("Saving scenario...")
Expand All @@ -44,7 +49,7 @@ def on_change(state, var_name, var_value):
state.max_capacity = state.scenario.max_capacity.read()

if state.scenario.full_predictions.is_ready_for_reading:
state.predictions_dataset = state.scenario.full_predictions.read()
state.predictions_dataset = state.scenario.full_predictions.read()[-200:]
else:
state.predictions_dataset = predictions_dataset

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,22 +85,25 @@ containing the date, historical values, ML predicted values, and baseline predic

```python
def create_predictions_dataset(predictions_baseline, predictions_ml, day, n_predictions, cleaned_data):
....

# Columns : [Date, Historical values, Predicted values (ml and baseline)]
predictions_dataset = pd.concat([temp_df["Date"],
historical_values,
predicted_values_ml,
predicted_values_baseline], axis=1)
print("Creating predictions dataset...")

...

predictions_dataset = pd.concat([
historical_data["Date"],
historical_data["Value"].rename("Historical values"),
create_series(predictions_ml, "Predicted values ML"),
create_series(predictions_baseline, "Predicted values Baseline")
], axis=1)

return predictions_dataset
```

## Entire code (algorithms/algorithms.py)

Chaining all the functions together can be represented as a following graph:

![Execution Graph](config_toml.png){ width=300 style="margin:auto;display:block" }
![Execution Graph](config_toml.png){ width=700 style="margin:auto;display:block" }

```python
# For the sake of clarity, we have used an AutoRegressive model rather than a pure ML model such as:
Expand Down Expand Up @@ -153,28 +156,19 @@ def compute_metrics(historical_data, predicted_data):

def create_predictions_dataset(predictions_baseline, predictions_ml, day, n_predictions, cleaned_data):
print("Creating predictions dataset...")

# Set arbitrarily the time window for the chart as 5 times the number of predictions
window = 5 * n_predictions


# Create the historical dataset that will be displayed
new_length = len(cleaned_data[cleaned_data["Date"] < day]) + n_predictions
temp_df = cleaned_data[:new_length]
temp_df = temp_df[-window:].reset_index(drop=True)

# Create the series that will be used in the concat
historical_values = pd.Series(temp_df["Value"], name="Historical values")
predicted_values_ml = pd.Series([np.NaN] * len(temp_df), name="Predicted values ML")
predicted_values_ml[-len(predictions_ml):] = predictions_ml
predicted_values_baseline = pd.Series([np.NaN] * len(temp_df), name="Predicted values Baseline")
predicted_values_baseline[-len(predictions_baseline):] = predictions_baseline

# Create the predictions dataset
# Columns : [Date, Historical values, Predicted values]
predictions_dataset = pd.concat([temp_df["Date"],
historical_values,
predicted_values_ml,
predicted_values_baseline], axis=1)

historical_data = cleaned_data[:new_length].reset_index(drop=True)

create_series = lambda data, name: pd.Series([np.NaN] * (len(historical_data)), name=name).fillna({i: val for i, val in enumerate(data, len(historical_data)-n_predictions)})

predictions_dataset = pd.concat([
historical_data["Date"],
historical_data["Value"].rename("Historical values"),
create_series(predictions_ml, "Predicted values ML"),
create_series(predictions_baseline, "Predicted values Baseline")
], axis=1)

return predictions_dataset
```
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ of items sold in a given store on a 15-min basis.

The graph below represents the scenario to configure, where tasks are in orange and data nodes in blue.

![Configuration](config_toml.png){ width=300 style="margin:auto;display:block" }
![Configuration](config_toml.png){ width=700 style="margin:auto;display:block" }


### Input Data Nodes configuration
Expand Down Expand Up @@ -193,7 +193,7 @@ from algos.algos import *

path_to_csv = "data/dataset.csv"

# Datanodes (3.1)
# Datanodes
## Input Data Nodes
initial_dataset_cfg = Config.configure_data_node(id="initial_dataset",
storage_type="csv",
Expand All @@ -220,9 +220,7 @@ full_predictions_cfg = Config.configure_data_node(id="full_predictions")
metrics_baseline_cfg = Config.configure_data_node(id="metrics_baseline")
metrics_ml_cfg = Config.configure_data_node(id="metrics_ml")

# Functions (3.2)

# Tasks (3.3)
# Tasks
clean_data_task_cfg = Config.configure_task(id="task_clean_data",
function=clean_data,
input=initial_dataset_cfg,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,17 @@ The Scenario Page is constructed using a combination of Markdown and Python code
<br/> <|Save|button|on_action=save|active={scenario}|>
|>

<|{scenario}|scenario|>
<|{scenario}|scenario|on_submission_change=submission_change|>

<|{predictions_dataset}|chart|x=Date|y[1]=Historical values|type[1]=bar|y[2]=Predicted values ML|y[3]=Predicted values Baseline|>

# Data Node Exploration

<|layout|columns=1 5|
<|{data_node}|data_node_selector|>

<|{data_node}|data_node|>
|>
```

The Markdown section outlines the arrangement and elements of the Scenario Page. It consists of the following components:
Expand All @@ -60,14 +68,18 @@ A number input field where users can set the desired number of predictions to be

A button that triggers the "save" action when clicked. It is used to save the selected scenario and parameter values.

- **Scenario Section**: `<|{scenario}|scenario|>`
- **Scenario Section**: `<|{scenario}|scenario|on_submission_change=submission_change|>`

A section that displays information about the currently selected scenario. It includes details about the scenario, properties, and the ability to delete or submit the scenario.
A section that displays information about the currently selected scenario. It includes details about the scenario, properties, and the ability to delete or submit the scenario. When the scenario status is changed, `submission_change` is called with information on the scenario.

- **Predictions Chart**: `<|{predictions_dataset}|chart|...|>`

A chart that displays historical values and the predicted values obtained from machine learning and baseline methods. It shows how well the predictions align with the historical data.

- **Data Node Exploration**: `<|{data_node}|data_node_selector|> <|{data_node}|data_node_selector|>`

This is where the detailed information and history about the selected data node is presented. Depending on the nature of the data node, this could display raw data in a tabular format, visualizations, texts, or dates. If the format allows it, the user can directly write new values in the data node.


## Python Code (pages/scenario/scenario.py)

Expand All @@ -80,6 +92,7 @@ import pandas as pd


scenario = None
data_node = None
day = dt.datetime(2021, 7, 26)
n_predictions = 40
max_capacity = 200
Expand All @@ -88,7 +101,12 @@ predictions_dataset = {"Date":[0],
"Predicted values Baseline":[0],
"Historical values":[0]}


def submission_change(state, submittable, details: dict):
if details['submission_status'] == 'COMPLETED':
notify(state, "success", 'Scenario completed!')
state['scenario'].on_change(state, 'scenario', state.scenario)
else:
notify(state, "error", 'Something went wrong!')

def save(state):
print("Saving scenario...")
Expand Down Expand Up @@ -125,7 +143,7 @@ It includes the following components:

- **Global Variables**:

The global variables *scenario*, *day*, *n_predictions*, *max_capacity*, and *predictions_dataset* are defined. These variables store the initial state of the application.
The global variables *scenario*, *data_node*, *day*, *n_predictions*, *max_capacity*, and *predictions_dataset* are defined. These variables store the initial state of the application.

- **Save Function**:

Expand All @@ -134,6 +152,10 @@ When the user clicks the "Save" button, this function gets activated.
It receives the page's state as input, converts the date format to the correct one,
adjusts the scenario parameters accordingly, and then informs the user with a success message.

- **Submission Status Change**

The `submission_change` function is designed to handle feedback when a scenario submission completes. It takes in the current state, the submitted object, and details regarding the submission. If the submission is successful ('*COMPLETED*'), it sends a success notification to the user and triggers an update on the *scenario* object. In the event of a failure, it provides an error notification, alerting the user that something went wrong.

- **On Change Function**:

The `on_change` function is called when any variable on the page changes its value. It monitors the changes in the scenario variable and updates the other variables accordingly. It also checks if the *full_predictions* are ready for reading and updates the *predictions_dataset*` accordingly.
Expand Down

0 comments on commit b4de32b

Please sign in to comment.