-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
8,808 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
#If you have windows, install twofish | ||
#twofish | ||
hopsworks | ||
joblib | ||
scikit-learn==1.1.1 | ||
seaborn | ||
dataframe-image | ||
modal | ||
gradio==3.14 |
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
Citation Request: | ||
This dataset is public available for research. The details are described in [Cortez et al., 2009]. | ||
Please include this citation if you plan to use this database: | ||
|
||
P. Cortez, A. Cerdeira, F. Almeida, T. Matos and J. Reis. | ||
Modeling wine preferences by data mining from physicochemical properties. | ||
In Decision Support Systems, Elsevier, 47(4):547-553. ISSN: 0167-9236. | ||
|
||
Available at: [@Elsevier] http://dx.doi.org/10.1016/j.dss.2009.05.016 | ||
[Pre-press (pdf)] http://www3.dsi.uminho.pt/pcortez/winequality09.pdf | ||
[bib] http://www3.dsi.uminho.pt/pcortez/dss09.bib | ||
|
||
1. Title: Wine Quality | ||
|
||
2. Sources | ||
Created by: Paulo Cortez (Univ. Minho), Antonio Cerdeira, Fernando Almeida, Telmo Matos and Jose Reis (CVRVV) @ 2009 | ||
|
||
3. Past Usage: | ||
|
||
P. Cortez, A. Cerdeira, F. Almeida, T. Matos and J. Reis. | ||
Modeling wine preferences by data mining from physicochemical properties. | ||
In Decision Support Systems, Elsevier, 47(4):547-553. ISSN: 0167-9236. | ||
|
||
In the above reference, two datasets were created, using red and white wine samples. | ||
The inputs include objective tests (e.g. PH values) and the output is based on sensory data | ||
(median of at least 3 evaluations made by wine experts). Each expert graded the wine quality | ||
between 0 (very bad) and 10 (very excellent). Several data mining methods were applied to model | ||
these datasets under a regression approach. The support vector machine model achieved the | ||
best results. Several metrics were computed: MAD, confusion matrix for a fixed error tolerance (T), | ||
etc. Also, we plot the relative importances of the input variables (as measured by a sensitivity | ||
analysis procedure). | ||
|
||
4. Relevant Information: | ||
|
||
The two datasets are related to red and white variants of the Portuguese "Vinho Verde" wine. | ||
For more details, consult: http://www.vinhoverde.pt/en/ or the reference [Cortez et al., 2009]. | ||
Due to privacy and logistic issues, only physicochemical (inputs) and sensory (the output) variables | ||
are available (e.g. there is no data about grape types, wine brand, wine selling price, etc.). | ||
|
||
These datasets can be viewed as classification or regression tasks. | ||
The classes are ordered and not balanced (e.g. there are munch more normal wines than | ||
excellent or poor ones). Outlier detection algorithms could be used to detect the few excellent | ||
or poor wines. Also, we are not sure if all input variables are relevant. So | ||
it could be interesting to test feature selection methods. | ||
|
||
5. Number of Instances: red wine - 1599; white wine - 4898. | ||
|
||
6. Number of Attributes: 11 + output attribute | ||
|
||
Note: several of the attributes may be correlated, thus it makes sense to apply some sort of | ||
feature selection. | ||
|
||
7. Attribute information: | ||
|
||
For more information, read [Cortez et al., 2009]. | ||
|
||
Input variables (based on physicochemical tests): | ||
1 - fixed acidity | ||
2 - volatile acidity | ||
3 - citric acid | ||
4 - residual sugar | ||
5 - chlorides | ||
6 - free sulfur dioxide | ||
7 - total sulfur dioxide | ||
8 - density | ||
9 - pH | ||
10 - sulphates | ||
11 - alcohol | ||
Output variable (based on sensory data): | ||
12 - quality (score between 0 and 10) | ||
|
||
8. Missing Attribute Values: None |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
import os | ||
import modal | ||
|
||
LOCAL=True | ||
|
||
if LOCAL == False: | ||
stub = modal.Stub() | ||
hopsworks_image = modal.Image.debian_slim().pip_install(["hopsworks","joblib","seaborn","scikit-learn==1.2.2","dataframe-image"]) | ||
@stub.function(image=hopsworks_image, schedule=modal.Period(days=1), secret=modal.Secret.from_name("hopsworks api key")) | ||
def f(): | ||
g() | ||
|
||
def g(): | ||
import pandas as pd | ||
import hopsworks | ||
import joblib | ||
import datetime | ||
from PIL import Image | ||
from datetime import datetime | ||
import dataframe_image as dfi | ||
from sklearn.metrics import confusion_matrix | ||
from matplotlib import pyplot | ||
import seaborn as sns | ||
import requests | ||
|
||
project = hopsworks.login() | ||
fs = project.get_feature_store() | ||
|
||
mr = project.get_model_registry() | ||
model = mr.get_model("iris_model", version=2) | ||
model_dir = model.download() | ||
model = joblib.load(model_dir + "/iris_model.pkl") | ||
|
||
feature_view = fs.get_feature_view(name="iris", version=1) | ||
batch_data = feature_view.get_batch_data() | ||
|
||
y_pred = model.predict(batch_data) | ||
#print(y_pred) | ||
offset = 1 | ||
flower = y_pred[y_pred.size-offset] | ||
flower_url = "https://raw.githubusercontent.com/featurestoreorg/serverless-ml-course/main/src/01-module/assets/" + flower + ".png" | ||
print("Flower predicted: " + flower) | ||
img = Image.open(requests.get(flower_url, stream=True).raw) | ||
img.save("./latest_iris.png") | ||
dataset_api = project.get_dataset_api() | ||
dataset_api.upload("./latest_iris.png", "Resources/images", overwrite=True) | ||
|
||
iris_fg = fs.get_feature_group(name="iris", version=1) | ||
df = iris_fg.read() | ||
#print(df) | ||
label = df.iloc[-offset]["variety"] | ||
label_url = "https://raw.githubusercontent.com/featurestoreorg/serverless-ml-course/main/src/01-module/assets/" + label + ".png" | ||
print("Flower actual: " + label) | ||
img = Image.open(requests.get(label_url, stream=True).raw) | ||
img.save("./actual_iris.png") | ||
dataset_api.upload("./actual_iris.png", "Resources/images", overwrite=True) | ||
|
||
monitor_fg = fs.get_or_create_feature_group(name="iris_predictions", | ||
version=1, | ||
primary_key=["datetime"], | ||
description="Iris flower Prediction/Outcome Monitoring" | ||
) | ||
|
||
now = datetime.now().strftime("%m/%d/%Y, %H:%M:%S") | ||
data = { | ||
'prediction': [flower], | ||
'label': [label], | ||
'datetime': [now], | ||
} | ||
monitor_df = pd.DataFrame(data) | ||
monitor_fg.insert(monitor_df, write_options={"wait_for_job" : False}) | ||
|
||
history_df = monitor_fg.read() | ||
# Add our prediction to the history, as the history_df won't have it - | ||
# the insertion was done asynchronously, so it will take ~1 min to land on App | ||
history_df = pd.concat([history_df, monitor_df]) | ||
|
||
|
||
df_recent = history_df.tail(4) | ||
dfi.export(df_recent, './df_recent.png', table_conversion = 'matplotlib') | ||
dataset_api.upload("./df_recent.png", "Resources/images", overwrite=True) | ||
|
||
predictions = history_df[['prediction']] | ||
labels = history_df[['label']] | ||
|
||
# Only create the confusion matrix when our iris_predictions feature group has examples of all 3 iris flowers | ||
print("Number of different flower predictions to date: " + str(predictions.value_counts().count())) | ||
if predictions.value_counts().count() == 3: | ||
results = confusion_matrix(labels, predictions) | ||
|
||
df_cm = pd.DataFrame(results, ['True Setosa', 'True Versicolor', 'True Virginica'], | ||
['Pred Setosa', 'Pred Versicolor', 'Pred Virginica']) | ||
|
||
cm = sns.heatmap(df_cm, annot=True) | ||
fig = cm.get_figure() | ||
fig.savefig("./confusion_matrix.png") | ||
dataset_api.upload("./confusion_matrix.png", "Resources/images", overwrite=True) | ||
else: | ||
print("You need 3 different flower predictions to create the confusion matrix.") | ||
print("Run the batch inference pipeline more times until you get 3 different iris flower predictions") | ||
|
||
|
||
if __name__ == "__main__": | ||
if LOCAL == True : | ||
g() | ||
else: | ||
with stub.run(): | ||
f() | ||
|
Oops, something went wrong.