From 70f8d14fb81199ad71b619ad628c6f730cbddcea Mon Sep 17 00:00:00 2001 From: zgolebiewska Date: Tue, 30 Apr 2024 10:49:32 +0200 Subject: [PATCH] Added model.py --- Dockerfile | 8 +- model.py | 40 ++++++++++ orange_quality_model_tf.h5 | Bin 0 -> 34656 bytes predictions_tf.json | 149 +++++++++++++++++++++++++++++++++++++ 4 files changed, 195 insertions(+), 2 deletions(-) create mode 100644 model.py create mode 100644 orange_quality_model_tf.h5 create mode 100644 predictions_tf.json diff --git a/Dockerfile b/Dockerfile index a56cd7d..876ae88 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,9 +2,13 @@ FROM ubuntu:latest RUN apt-get update && apt-get install -y python3-pip unzip coreutils -RUN pip install --user kaggle pandas +RUN pip install --user kaggle pandas scikit-learn tensorflow WORKDIR /app COPY ./data_processing.sh ./ -COPY ./OrangeQualityData.csv ./ \ No newline at end of file +COPY ./OrangeQualityData.csv ./ +COPY ./orange_quality_model_tf.h5 ./ +COPY ./predictions_tf.json ./ + +CMD ["python3", "data_processing.sh"] diff --git a/model.py b/model.py new file mode 100644 index 0000000..efa1509 --- /dev/null +++ b/model.py @@ -0,0 +1,40 @@ +import tensorflow as tf +import pandas as pd +from sklearn.preprocessing import LabelEncoder, StandardScaler +from sklearn.model_selection import train_test_split +import json + +df = pd.read_csv('OrangeQualityData.csv') + +encoder = LabelEncoder() +df["Color"] = encoder.fit_transform(df["Color"]) +df["Variety"] = encoder.fit_transform(df["Variety"]) +df["Blemishes"] = df["Blemishes (Y/N)"].apply(lambda x: 1 if x.startswith("Y") else 0) + +df.drop(columns=["Blemishes (Y/N)"], inplace=True) + +X = df.drop(columns=["Quality (1-5)"]) +y = df["Quality (1-5)"] + +X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) + +scaler = StandardScaler() +X_train_scaled = scaler.fit_transform(X_train) +X_test_scaled = scaler.transform(X_test) + +model = tf.keras.Sequential([ + tf.keras.layers.Dense(64, activation='relu', input_shape=(X_train_scaled.shape[1],)), + tf.keras.layers.Dense(32, activation='relu'), + tf.keras.layers.Dense(1) +]) + +model.compile(optimizer='sgd', loss='mse') + +history = model.fit(X_train_scaled, y_train, epochs=100, verbose=0, validation_data=(X_test_scaled, y_test)) + +model.save('orange_quality_model_tf.h5') + +predictions = model.predict(X_test_scaled) + +with open('predictions_tf.json', 'w') as f: + json.dump(predictions.tolist(), f, indent=4) diff --git a/orange_quality_model_tf.h5 b/orange_quality_model_tf.h5 new file mode 100644 index 0000000000000000000000000000000000000000..b46b150479223489f35ff02ac33ff5e65e10fe40 GIT binary patch literal 34656 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