misterkilgore commited on
Commit
62af78c
·
verified ·
1 Parent(s): 5f03a96

Upload 4 files

Browse files
Files changed (4) hide show
  1. app.py +49 -0
  2. model_training.ipynb +1 -0
  3. readme.md +21 -0
  4. requirements.txt +5 -0
app.py ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import pandas as pd
3
+ import numpy as np
4
+ import joblib
5
+ import os
6
+
7
+ # Carica il modello
8
+ model = joblib.load('house_price_model.joblib')
9
+
10
+ # Carica i nomi delle feature
11
+ with open('feature_names.txt', 'r') as f:
12
+ feature_names = [line.strip() for line in f.readlines()]
13
+
14
+ def predict_prices(csv_file):
15
+ # Leggi il file CSV
16
+ df = pd.read_csv(csv_file.name)
17
+
18
+ # Verifica che il file contenga le colonne necessarie
19
+ missing_cols = [col for col in feature_names if col not in df.columns]
20
+ if missing_cols:
21
+ return f"Errore: Il file CSV manca delle seguenti colonne: {', '.join(missing_cols)}"
22
+
23
+ # Seleziona solo le colonne necessarie nell'ordine corretto
24
+ input_data = df[feature_names]
25
+
26
+ # Fai la previsione
27
+ predictions = model.predict(input_data)
28
+
29
+ # Aggiungi le previsioni al DataFrame originale
30
+ df['predicted_price'] = predictions
31
+
32
+ # Salva il risultato in un nuovo file CSV
33
+ result_path = "predictions_result.csv"
34
+ df.to_csv(result_path, index=False)
35
+
36
+ return result_path
37
+
38
+ # Crea l'interfaccia Gradio
39
+ iface = gr.Interface(
40
+ fn=predict_prices,
41
+ inputs=gr.File(label="Carica un file CSV con le caratteristiche delle case"),
42
+ outputs=gr.File(label="Scarica i risultati"),
43
+ title="Previsione Prezzi Case",
44
+ description=f"Carica un file CSV contenente le seguenti colonne: {', '.join(feature_names)}. "
45
+ "Il modello prevederà il prezzo per ogni casa e restituirà un nuovo file CSV con i risultati."
46
+ )
47
+
48
+ # Avvia l'app
49
+ iface.launch()
model_training.ipynb ADDED
@@ -0,0 +1 @@
 
 
1
+ {"nbformat":4,"nbformat_minor":0,"metadata":{"colab":{"provenance":[],"authorship_tag":"ABX9TyNBjldI+sEf3alrGTO/Spin"},"kernelspec":{"name":"python3","display_name":"Python 3"},"language_info":{"name":"python"}},"cells":[{"cell_type":"code","execution_count":8,"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"id":"vBSz9RYyudoZ","executionInfo":{"status":"ok","timestamp":1740665464218,"user_tz":-60,"elapsed":11884,"user":{"displayName":"Michele Cantoni","userId":"10582761587185035813"}},"outputId":"3e26604c-7f2e-4a0d-8b61-8aef97ec87b6"},"outputs":[{"output_type":"stream","name":"stdout","text":["R² score: 0.8053\n","RMSE: 0.5051\n"]}],"source":["import numpy as np\n","import pandas as pd\n","from sklearn.model_selection import train_test_split\n","from sklearn.ensemble import RandomForestRegressor\n","from sklearn.preprocessing import StandardScaler\n","from sklearn.pipeline import Pipeline\n","from sklearn.metrics import root_mean_squared_error\n","import joblib\n","\n","# Per questo esempio, usiamo il dataset California Housing\n","from sklearn.datasets import fetch_california_housing\n","\n","# Carica i dati\n","housing = fetch_california_housing()\n","X = pd.DataFrame(housing.data, columns=housing.feature_names)\n","y = housing.target\n","\n","# Dividi in training e test set\n","X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)\n","\n","# Crea una pipeline con standardizzazione e modello\n","pipeline = Pipeline([\n"," ('scaler', StandardScaler()),\n"," ('regressor', RandomForestRegressor(n_estimators=100, random_state=42))\n","])\n","\n","# Addestra il modello\n","pipeline.fit(X_train, y_train)\n","\n","# Valuta il modello\n","score = pipeline.score(X_test, y_test)\n","y_pred = pipeline.predict(X_test)\n","print(f\"R² score: {score:.4f}\")\n","print(f\"RMSE: {root_mean_squared_error(y_pred,y_test):.4f}\")\n","\n","# Salva il modello\n","joblib.dump(pipeline, 'house_price_model.joblib')\n","\n","# Salva anche una descrizione delle feature per riferimento futuro\n","feature_names = housing.feature_names\n","with open('feature_names.txt', 'w') as f:\n"," for feature in feature_names:\n"," f.write(f\"{feature}\\n\")\n","\n","with open('description.txt', 'w') as f:\n"," f.write(housing['DESCR'])"]},{"cell_type":"code","source":[],"metadata":{"colab":{"base_uri":"https://localhost:8080/","height":424},"id":"XLztU8FUu_sf","executionInfo":{"status":"ok","timestamp":1740665382445,"user_tz":-60,"elapsed":61,"user":{"displayName":"Michele Cantoni","userId":"10582761587185035813"}},"outputId":"d94db415-9014-4fbc-e9cf-95fcaec8f86a"},"execution_count":7,"outputs":[{"output_type":"execute_result","data":{"text/plain":[" MedInc HouseAge AveRooms AveBedrms Population AveOccup Latitude \\\n","0 8.3252 41.0 6.984127 1.023810 322.0 2.555556 37.88 \n","1 8.3014 21.0 6.238137 0.971880 2401.0 2.109842 37.86 \n","2 7.2574 52.0 8.288136 1.073446 496.0 2.802260 37.85 \n","3 5.6431 52.0 5.817352 1.073059 558.0 2.547945 37.85 \n","4 3.8462 52.0 6.281853 1.081081 565.0 2.181467 37.85 \n","... ... ... ... ... ... ... ... \n","20635 1.5603 25.0 5.045455 1.133333 845.0 2.560606 39.48 \n","20636 2.5568 18.0 6.114035 1.315789 356.0 3.122807 39.49 \n","20637 1.7000 17.0 5.205543 1.120092 1007.0 2.325635 39.43 \n","20638 1.8672 18.0 5.329513 1.171920 741.0 2.123209 39.43 \n","20639 2.3886 16.0 5.254717 1.162264 1387.0 2.616981 39.37 \n","\n"," Longitude \n","0 -122.23 \n","1 -122.22 \n","2 -122.24 \n","3 -122.25 \n","4 -122.25 \n","... ... \n","20635 -121.09 \n","20636 -121.21 \n","20637 -121.22 \n","20638 -121.32 \n","20639 -121.24 \n","\n","[20640 rows x 8 columns]"],"text/html":["\n"," <div id=\"df-37d6d979-0beb-476d-85b5-18e590983116\" class=\"colab-df-container\">\n"," <div>\n","<style scoped>\n"," .dataframe tbody tr th:only-of-type {\n"," vertical-align: middle;\n"," }\n","\n"," .dataframe tbody tr th {\n"," vertical-align: top;\n"," }\n","\n"," .dataframe thead th {\n"," text-align: right;\n"," }\n","</style>\n","<table border=\"1\" class=\"dataframe\">\n"," <thead>\n"," <tr style=\"text-align: right;\">\n"," <th></th>\n"," <th>MedInc</th>\n"," <th>HouseAge</th>\n"," <th>AveRooms</th>\n"," <th>AveBedrms</th>\n"," <th>Population</th>\n"," <th>AveOccup</th>\n"," <th>Latitude</th>\n"," <th>Longitude</th>\n"," </tr>\n"," </thead>\n"," <tbody>\n"," <tr>\n"," <th>0</th>\n"," <td>8.3252</td>\n"," <td>41.0</td>\n"," <td>6.984127</td>\n"," <td>1.023810</td>\n"," <td>322.0</td>\n"," <td>2.555556</td>\n"," <td>37.88</td>\n"," <td>-122.23</td>\n"," </tr>\n"," <tr>\n"," <th>1</th>\n"," <td>8.3014</td>\n"," <td>21.0</td>\n"," <td>6.238137</td>\n"," <td>0.971880</td>\n"," <td>2401.0</td>\n"," <td>2.109842</td>\n"," <td>37.86</td>\n"," <td>-122.22</td>\n"," </tr>\n"," <tr>\n"," <th>2</th>\n"," <td>7.2574</td>\n"," <td>52.0</td>\n"," <td>8.288136</td>\n"," <td>1.073446</td>\n"," <td>496.0</td>\n"," <td>2.802260</td>\n"," <td>37.85</td>\n"," <td>-122.24</td>\n"," </tr>\n"," <tr>\n"," <th>3</th>\n"," <td>5.6431</td>\n"," <td>52.0</td>\n"," <td>5.817352</td>\n"," <td>1.073059</td>\n"," <td>558.0</td>\n"," <td>2.547945</td>\n"," <td>37.85</td>\n"," <td>-122.25</td>\n"," </tr>\n"," <tr>\n"," <th>4</th>\n"," <td>3.8462</td>\n"," <td>52.0</td>\n"," <td>6.281853</td>\n"," <td>1.081081</td>\n"," <td>565.0</td>\n"," <td>2.181467</td>\n"," <td>37.85</td>\n"," <td>-122.25</td>\n"," </tr>\n"," <tr>\n"," <th>...</th>\n"," <td>...</td>\n"," <td>...</td>\n"," <td>...</td>\n"," <td>...</td>\n"," <td>...</td>\n"," <td>...</td>\n"," <td>...</td>\n"," <td>...</td>\n"," </tr>\n"," <tr>\n"," <th>20635</th>\n"," <td>1.5603</td>\n"," <td>25.0</td>\n"," <td>5.045455</td>\n"," <td>1.133333</td>\n"," <td>845.0</td>\n"," <td>2.560606</td>\n"," <td>39.48</td>\n"," <td>-121.09</td>\n"," </tr>\n"," <tr>\n"," <th>20636</th>\n"," <td>2.5568</td>\n"," <td>18.0</td>\n"," <td>6.114035</td>\n"," <td>1.315789</td>\n"," <td>356.0</td>\n"," <td>3.122807</td>\n"," <td>39.49</td>\n"," <td>-121.21</td>\n"," </tr>\n"," <tr>\n"," <th>20637</th>\n"," <td>1.7000</td>\n"," <td>17.0</td>\n"," <td>5.205543</td>\n"," <td>1.120092</td>\n"," <td>1007.0</td>\n"," <td>2.325635</td>\n"," <td>39.43</td>\n"," <td>-121.22</td>\n"," </tr>\n"," <tr>\n"," <th>20638</th>\n"," <td>1.8672</td>\n"," <td>18.0</td>\n"," <td>5.329513</td>\n"," <td>1.171920</td>\n"," <td>741.0</td>\n"," <td>2.123209</td>\n"," <td>39.43</td>\n"," <td>-121.32</td>\n"," </tr>\n"," <tr>\n"," <th>20639</th>\n"," <td>2.3886</td>\n"," <td>16.0</td>\n"," <td>5.254717</td>\n"," <td>1.162264</td>\n"," <td>1387.0</td>\n"," <td>2.616981</td>\n"," <td>39.37</td>\n"," <td>-121.24</td>\n"," </tr>\n"," </tbody>\n","</table>\n","<p>20640 rows × 8 columns</p>\n","</div>\n"," <div class=\"colab-df-buttons\">\n","\n"," <div class=\"colab-df-container\">\n"," <button class=\"colab-df-convert\" onclick=\"convertToInteractive('df-37d6d979-0beb-476d-85b5-18e590983116')\"\n"," title=\"Convert this dataframe to an interactive table.\"\n"," style=\"display:none;\">\n","\n"," <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\" viewBox=\"0 -960 960 960\">\n"," <path d=\"M120-120v-720h720v720H120Zm60-500h600v-160H180v160Zm220 220h160v-160H400v160Zm0 220h160v-160H400v160ZM180-400h160v-160H180v160Zm440 0h160v-160H620v160ZM180-180h160v-160H180v160Zm440 0h160v-160H620v160Z\"/>\n"," </svg>\n"," </button>\n","\n"," <style>\n"," .colab-df-container {\n"," display:flex;\n"," gap: 12px;\n"," }\n","\n"," .colab-df-convert {\n"," background-color: #E8F0FE;\n"," border: none;\n"," border-radius: 50%;\n"," cursor: pointer;\n"," display: none;\n"," fill: #1967D2;\n"," height: 32px;\n"," padding: 0 0 0 0;\n"," width: 32px;\n"," }\n","\n"," .colab-df-convert:hover {\n"," background-color: #E2EBFA;\n"," box-shadow: 0px 1px 2px rgba(60, 64, 67, 0.3), 0px 1px 3px 1px rgba(60, 64, 67, 0.15);\n"," fill: #174EA6;\n"," }\n","\n"," .colab-df-buttons div {\n"," margin-bottom: 4px;\n"," }\n","\n"," [theme=dark] .colab-df-convert {\n"," background-color: #3B4455;\n"," fill: #D2E3FC;\n"," }\n","\n"," [theme=dark] .colab-df-convert:hover {\n"," background-color: #434B5C;\n"," box-shadow: 0px 1px 3px 1px rgba(0, 0, 0, 0.15);\n"," filter: drop-shadow(0px 1px 2px rgba(0, 0, 0, 0.3));\n"," fill: #FFFFFF;\n"," }\n"," </style>\n","\n"," <script>\n"," const buttonEl =\n"," document.querySelector('#df-37d6d979-0beb-476d-85b5-18e590983116 button.colab-df-convert');\n"," buttonEl.style.display =\n"," google.colab.kernel.accessAllowed ? 'block' : 'none';\n","\n"," async function convertToInteractive(key) {\n"," const element = document.querySelector('#df-37d6d979-0beb-476d-85b5-18e590983116');\n"," const dataTable =\n"," await google.colab.kernel.invokeFunction('convertToInteractive',\n"," [key], {});\n"," if (!dataTable) return;\n","\n"," const docLinkHtml = 'Like what you see? Visit the ' +\n"," '<a target=\"_blank\" href=https://colab.research.google.com/notebooks/data_table.ipynb>data table notebook</a>'\n"," + ' to learn more about interactive tables.';\n"," element.innerHTML = '';\n"," dataTable['output_type'] = 'display_data';\n"," await google.colab.output.renderOutput(dataTable, element);\n"," const docLink = document.createElement('div');\n"," docLink.innerHTML = docLinkHtml;\n"," element.appendChild(docLink);\n"," }\n"," </script>\n"," </div>\n","\n","\n","<div id=\"df-1570c1d3-0cb6-48fa-9c9d-9aa90f30c4fd\">\n"," <button class=\"colab-df-quickchart\" onclick=\"quickchart('df-1570c1d3-0cb6-48fa-9c9d-9aa90f30c4fd')\"\n"," title=\"Suggest charts\"\n"," style=\"display:none;\">\n","\n","<svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\"viewBox=\"0 0 24 24\"\n"," width=\"24px\">\n"," <g>\n"," <path d=\"M19 3H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zM9 17H7v-7h2v7zm4 0h-2V7h2v10zm4 0h-2v-4h2v4z\"/>\n"," </g>\n","</svg>\n"," </button>\n","\n","<style>\n"," .colab-df-quickchart {\n"," --bg-color: #E8F0FE;\n"," --fill-color: #1967D2;\n"," --hover-bg-color: #E2EBFA;\n"," --hover-fill-color: #174EA6;\n"," --disabled-fill-color: #AAA;\n"," --disabled-bg-color: #DDD;\n"," }\n","\n"," [theme=dark] .colab-df-quickchart {\n"," --bg-color: #3B4455;\n"," --fill-color: #D2E3FC;\n"," --hover-bg-color: #434B5C;\n"," --hover-fill-color: #FFFFFF;\n"," --disabled-bg-color: #3B4455;\n"," --disabled-fill-color: #666;\n"," }\n","\n"," .colab-df-quickchart {\n"," background-color: var(--bg-color);\n"," border: none;\n"," border-radius: 50%;\n"," cursor: pointer;\n"," display: none;\n"," fill: var(--fill-color);\n"," height: 32px;\n"," padding: 0;\n"," width: 32px;\n"," }\n","\n"," .colab-df-quickchart:hover {\n"," background-color: var(--hover-bg-color);\n"," box-shadow: 0 1px 2px rgba(60, 64, 67, 0.3), 0 1px 3px 1px rgba(60, 64, 67, 0.15);\n"," fill: var(--button-hover-fill-color);\n"," }\n","\n"," .colab-df-quickchart-complete:disabled,\n"," .colab-df-quickchart-complete:disabled:hover {\n"," background-color: var(--disabled-bg-color);\n"," fill: var(--disabled-fill-color);\n"," box-shadow: none;\n"," }\n","\n"," .colab-df-spinner {\n"," border: 2px solid var(--fill-color);\n"," border-color: transparent;\n"," border-bottom-color: var(--fill-color);\n"," animation:\n"," spin 1s steps(1) infinite;\n"," }\n","\n"," @keyframes spin {\n"," 0% {\n"," border-color: transparent;\n"," border-bottom-color: var(--fill-color);\n"," border-left-color: var(--fill-color);\n"," }\n"," 20% {\n"," border-color: transparent;\n"," border-left-color: var(--fill-color);\n"," border-top-color: var(--fill-color);\n"," }\n"," 30% {\n"," border-color: transparent;\n"," border-left-color: var(--fill-color);\n"," border-top-color: var(--fill-color);\n"," border-right-color: var(--fill-color);\n"," }\n"," 40% {\n"," border-color: transparent;\n"," border-right-color: var(--fill-color);\n"," border-top-color: var(--fill-color);\n"," }\n"," 60% {\n"," border-color: transparent;\n"," border-right-color: var(--fill-color);\n"," }\n"," 80% {\n"," border-color: transparent;\n"," border-right-color: var(--fill-color);\n"," border-bottom-color: var(--fill-color);\n"," }\n"," 90% {\n"," border-color: transparent;\n"," border-bottom-color: var(--fill-color);\n"," }\n"," }\n","</style>\n","\n"," <script>\n"," async function quickchart(key) {\n"," const quickchartButtonEl =\n"," document.querySelector('#' + key + ' button');\n"," quickchartButtonEl.disabled = true; // To prevent multiple clicks.\n"," quickchartButtonEl.classList.add('colab-df-spinner');\n"," try {\n"," const charts = await google.colab.kernel.invokeFunction(\n"," 'suggestCharts', [key], {});\n"," } catch (error) {\n"," console.error('Error during call to suggestCharts:', error);\n"," }\n"," quickchartButtonEl.classList.remove('colab-df-spinner');\n"," quickchartButtonEl.classList.add('colab-df-quickchart-complete');\n"," }\n"," (() => {\n"," let quickchartButtonEl =\n"," document.querySelector('#df-1570c1d3-0cb6-48fa-9c9d-9aa90f30c4fd button');\n"," quickchartButtonEl.style.display =\n"," google.colab.kernel.accessAllowed ? 'block' : 'none';\n"," })();\n"," </script>\n","</div>\n","\n"," </div>\n"," </div>\n"],"application/vnd.google.colaboratory.intrinsic+json":{"type":"dataframe","summary":"{\n \"name\": \"pd\",\n \"rows\": 20640,\n \"fields\": [\n {\n \"column\": \"MedInc\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 1.8998217179452732,\n \"min\": 0.4999,\n \"max\": 15.0001,\n \"num_unique_values\": 12928,\n \"samples\": [\n 5.0286,\n 2.0433,\n 6.1228\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"HouseAge\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 12.585557612111637,\n \"min\": 1.0,\n \"max\": 52.0,\n \"num_unique_values\": 52,\n \"samples\": [\n 35.0,\n 25.0,\n 7.0\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"AveRooms\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 2.4741731394243205,\n \"min\": 0.8461538461538461,\n \"max\": 141.9090909090909,\n \"num_unique_values\": 19392,\n \"samples\": [\n 6.111269614835948,\n 5.912820512820513,\n 5.7924528301886795\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"AveBedrms\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 0.47391085679546435,\n \"min\": 0.3333333333333333,\n \"max\": 34.06666666666667,\n \"num_unique_values\": 14233,\n \"samples\": [\n 0.9906542056074766,\n 1.112099644128114,\n 1.0398230088495575\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"Population\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 1132.4621217653375,\n \"min\": 3.0,\n \"max\": 35682.0,\n \"num_unique_values\": 3888,\n \"samples\": [\n 4169.0,\n 636.0,\n 3367.0\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"AveOccup\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 10.386049562213591,\n \"min\": 0.6923076923076923,\n \"max\": 1243.3333333333333,\n \"num_unique_values\": 18841,\n \"samples\": [\n 2.6939799331103678,\n 3.559375,\n 3.297082228116711\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"Latitude\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 2.1359523974571117,\n \"min\": 32.54,\n \"max\": 41.95,\n \"num_unique_values\": 862,\n \"samples\": [\n 33.7,\n 34.41,\n 38.24\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n },\n {\n \"column\": \"Longitude\",\n \"properties\": {\n \"dtype\": \"number\",\n \"std\": 2.003531723502581,\n \"min\": -124.35,\n \"max\": -114.31,\n \"num_unique_values\": 844,\n \"samples\": [\n -118.63,\n -119.86,\n -121.26\n ],\n \"semantic_type\": \"\",\n \"description\": \"\"\n }\n }\n ]\n}"}},"metadata":{},"execution_count":7}]},{"cell_type":"code","source":[],"metadata":{"id":"EWgETLnHvOyX"},"execution_count":null,"outputs":[]}]}
readme.md ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Previsione Prezzi Case
2
+
3
+ Questa app utilizza un modello di machine learning addestrato con scikit-learn per prevedere i prezzi delle case.
4
+
5
+ ## Come utilizzare l'app
6
+
7
+ 1. Prepara un file CSV contenente le seguenti colonne:
8
+ - MedInc: reddito mediano del quartiere
9
+ - HouseAge: età media delle case nel quartiere
10
+ - AveRooms: numero medio di stanze per casa
11
+ - AveBedrms: numero medio di camere da letto per casa
12
+ - Population: popolazione nel quartiere
13
+ - AveOccup: numero medio di occupanti per casa
14
+ - Latitude: latitudine del quartiere
15
+ - Longitude: longitudine del quartiere
16
+
17
+ 2. Carica il file CSV nell'app
18
+ 3. Clicca su "Submit"
19
+ 4. Scarica il file CSV risultante con le previsioni
20
+
21
+ Nota: Il modello è stato addestrato sul dataset California Housing, quindi funziona meglio con dati simili.
requirements.txt ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ scikit-learn==1.0.2
2
+ pandas==1.4.2
3
+ numpy==1.22.3
4
+ gradio==3.7.0
5
+ joblib==1.1.0