Spaces:
Sleeping
Sleeping
File size: 5,727 Bytes
0726909 d295dd6 cf55b6e d295dd6 0726909 976e600 722d02c 0726909 d295dd6 0726909 d295dd6 0726909 722d02c 0726909 d295dd6 0726909 d295dd6 0726909 d295dd6 0726909 722d02c 0726909 976e600 b393db3 976e600 0726909 722d02c 0726909 722d02c 0726909 722d02c d295dd6 0726909 1311c26 e8145aa 1311c26 0726909 1311c26 0726909 976e600 0726909 1311c26 0726909 1311c26 0726909 e8145aa 976e600 0726909 976e600 0726909 d295dd6 0726909 d295dd6 0726909 d295dd6 0726909 d295dd6 0726909 d295dd6 0726909 d295dd6 0726909 976e600 d295dd6 0726909 1311c26 0726909 1311c26 0726909 1311c26 0726909 db377e7 fd36190 1311c26 0726909 1311c26 0726909 1311c26 0726909 1311c26 d295dd6 0726909 d295dd6 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 | ## Batch Evaluation Code
##Import Libraries
import pandas as pd
import json
from joblib import load
import gradio as gr
from sklearn.metrics import accuracy_score, classification_report
## Load Model
model = load("rf_activity_model.pkl") # ensure uploaded to HF Space
# Load from code(A–S) to int mapping
with open("label_map.json", "r") as f:
label_to_int = json.load(f)
## Reverse mapping from integer to code(A-S)
int_to_label = {v: k for k, v in label_to_int.items()}
# Load json containing activity name mapping (A–S) to the layman activity
with open("activity_names.json", "r") as f:
activity_names = json.load(f)
# Risk map of A-S to risk tier for alerting logic
risk_map = {
"A": "Medium", "B": "High", "C": "High", "D": "Low", "E": "Medium",
"F": "Low", "G": "Low", "H": "Medium", "I": "Medium", "J": "Medium",
"K": "Medium", "L": "Medium", "M": "High", "O": "High", "P": "High",
"Q": "Low", "R": "Low", "S": "Low"
}
# Threshold for triggering alert in samples
HIGH_THRESHOLD = 30
MEDIUM_THRESHOLD = 180
LOW_THRESHOLD = 90
def analyze_csv(file):
## Read CSV
df = pd.read_csv(file)
## Drop activity column, only taking the columns which are the features for inference
X = df.drop(columns=["ACTIVITY"])
preds_int = model.predict(X)
## Convert integers to code(A-S)
preds_code = [int_to_label[i] for i in preds_int]
## Convert code to human readable activity names
preds_activity = [activity_names[c] for c in preds_code]
## Convert codes to risk tiers(Low, Medium, High)
preds_risk = [risk_map[c] for c in preds_code]
## Build the result table for the user interface, showing the predicted activity, risk and the actual activity
results_df = pd.DataFrame({
#"pred_code": preds_code,
"Predicted_Activity": preds_activity,
"Risk Level": preds_risk
})
## Default message if the CSV lacks ground-truth label("ACTIVITY")
metrics_text = "⚠️ Ground truth labels not found in CSV"
## If CSV contain the ground-truth label("ACTIVITY")
if "ACTIVITY" in df.columns:
## Convert Ground Truth integer to code (A-S)
actual_codes = df["ACTIVITY"].map(int_to_label)
## Convert codes to human friendly readable activity names
actual_names = actual_codes.map(activity_names)
## Add ground-truth activity for side-by-side viewing
results_df["Actual_Activity"] = actual_names
# Checks the model's accuracy and generates a detailed report for each activity class
acc = accuracy_score(actual_codes, preds_code)
report = classification_report(actual_codes, preds_code, zero_division=0)
metrics_text = f"✅ Accuracy: {acc:.3f}\n\nClassification Report:\n{report}"
## Tracks consecutive counts per risk
high_count = medium_count = low_count = 0
## Collect alert messages for display
alerts = []
##Iterate through risk predictions in order to simulate timeline
for i, risk in enumerate(preds_risk):
if risk == "High":
## If high count exceeds the high threshold, print alert
high_count += 1; medium_count = 0; low_count = 0
if high_count >= HIGH_THRESHOLD:
alerts.append(f"⚠️ ALERT: Prolonged HIGH-RISK activity at index {i}")
high_count = 0
elif risk == "Medium":
## If medium count exceeds the medium threshold, print alert
medium_count += 1; high_count = 0; low_count = 0
if medium_count >= MEDIUM_THRESHOLD:
alerts.append(f"⚠️ ALERT: Prolonged MEDIUM-RISK activity at index {i}")
medium_count = 0
elif risk == "Low":
## If low count exceeds the low threshold, print alert
low_count += 1; high_count = 0; medium_count = 0
if low_count >= LOW_THRESHOLD:
alerts.append(f"⚠️ ALERT: Prolonged LOW-RISK activity at index {i}")
low_count = 0
# Return table, metrics summary, and alerts, or no alert message
return results_df, metrics_text, "\n".join(alerts) if alerts else "✅ No alerts triggered."
## Gradio User Interface
with gr.Blocks() as demo:
gr.Markdown("## Healthcare Activity Recognition")
gr.Markdown("Upload a CSV of sensor features. The model predicts activities, assigns risk levels, "
"and compares them to actuals if provided. Metrics (accuracy + classification report) are also displayed.")
with gr.Row():
##Row to input the file
file_input = gr.File(type="filepath", file_types=[".csv"], label="Upload CSV")
with gr.Row():
with gr.Column(scale=2):
results_df = gr.Dataframe(
headers=["Predicted_Activity", "Risk Level", "Actual_Activity"],
label="Predictions vs Actuals",
wrap=True,
##This is for fixing only 3 columns for consistency
datatype=["str", "str", "str"],
col_count=(3, "fixed"),
interactive=False
)
with gr.Column(scale=1):
##Show accuracy and classification report
metrics_box = gr.Textbox(label="Metrics", lines=8)
##Shows alert list or “No alerts”
alerts_box = gr.Textbox(label="Alerts", lines=6)
# When a file is uploaded, run analyze_csv() and show results in the table, metrics, and alerts
file_input.change(
fn=analyze_csv,
inputs=file_input,
outputs=[results_df, metrics_box, alerts_box]
)
##Start the Gradio app if this script is the main entry point
if __name__ == "__main__":
demo.launch()
|