Spaces:
Sleeping
Sleeping
Download app.py from farachella/EEMM_Machine_V05: direct link, hf CLI and curl.
- Browser
- Download file 8.37 kB
-
https://huggingface.co/spaces/farachella/EEMM_Machine_V05/resolve/main/app.py
- Command line
-
hf download hf://spaces/farachella/EEMM_Machine_V05/app.py
-
curl -L -o app.py https://huggingface.co/spaces/farachella/EEMM_Machine_V05/resolve/main/app.py
8.37 kB
| from transformers import pipeline | |
| import gradio as gr | |
| import os | |
| import pandas as pd | |
| import tempfile | |
| import os | |
| #Get api key to record changes. | |
| api_key = os.environ.get("HF_API_KEY_INFERENCE") | |
| ######################## | |
| ## Loading the model: ## | |
| ####################### | |
| #Changed API endpoint calls to pipeline usage. | |
| classifier1 = pipeline( | |
| "text-classification", | |
| model="chernandezc/EEMM_7_categories_WB", | |
| token=os.environ.get("HF_API_KEY_INFERENCE") | |
| ) | |
| classifier2 = pipeline( | |
| "text-classification", | |
| model="chernandezc/EEMM_3_dimensions_1201", | |
| token=os.environ.get("HF_API_KEY_INFERENCE") | |
| ) | |
| # ########################################################## | |
| # Function to process the output and print classifications # | |
| ############################################################ | |
| def classify_output(item): | |
| # Dictionary for dimensions. | |
| label_dict1 = { | |
| 'LABEL_0': 'Cognition', | |
| 'LABEL_1': 'Affect', | |
| 'LABEL_2': 'Self', | |
| 'LABEL_3': 'Motivation', | |
| 'LABEL_4': 'Attention', | |
| 'LABEL_5': 'Overt Behavior', | |
| 'LABEL_6': 'Context' | |
| } | |
| # Dictionary for levels. | |
| label_dict2 = { | |
| 'LABEL_0': 'Social', | |
| 'LABEL_1': 'Psychological', | |
| 'LABEL_2': 'Physical' | |
| } | |
| # Call the local pipelines to get the list of dictionaries | |
| output1 = classifier1(item, top_k=None) | |
| output2 = classifier2(item, top_k=None) | |
| # Store classifications in a list | |
| classifications1 = [] | |
| classifications2 = [] | |
| # Find the item with the highest score for fallback cases | |
| highest_score_item1 = max(output1, key=lambda x: x['score']) | |
| highest_score_item2 = max(output2, key=lambda x: x['score']) | |
| # Process results for dimensions | |
| for result_item in output1: | |
| if result_item['score'] >= 0.5: | |
| classifications1.append((label_dict1[result_item['label']], result_item['score'])) | |
| # Process results for levels | |
| for result_item in output2: | |
| if result_item['score'] >= 0.5: | |
| classifications2.append((label_dict2[result_item['label']], result_item['score'])) | |
| # Construct and return the final classification message | |
| if classifications1 and classifications2: | |
| classification_str1 = ', '.join([f"{label} ({score:.2f})" for label, score in classifications1]) | |
| classification_str2 = ', '.join([f"{label} ({score:.2f})" for label, score in classifications2]) | |
| return f"For dimensions: {classification_str1}\nFor levels: {classification_str2}" | |
| elif classifications1 and not classifications2: | |
| classification_str1 = ', '.join([f"{label} ({score:.2f})" for label, score in classifications1]) | |
| return f"For dimensions: {classification_str1}\nFor levels: No classifications with a score of 0.5 or higher were found.\nHowever, the highest probability was for: '{label_dict2[highest_score_item2['label']]}' ({highest_score_item2['score']:.2f})\n Use this classification with caution due to uncertainty" | |
| elif classifications2 and not classifications1: | |
| classification_str2 = ', '.join([f"{label} ({score:.2f})" for label, score in classifications2]) | |
| return f"For levels: {classification_str2}\nFor dimensions: No classifications with a score of 0.5 or higher were found.\nHowever, the highest probability was for: '{label_dict1[highest_score_item1['label']]}' ({highest_score_item1['score']:.2f}) \n Use this classification with caution due to uncertainty" | |
| else: | |
| return (f"No classification with a score of 0.5 or higher were found for both levels and dimensions.\n" | |
| f"The highest probability for dimensions was: '{label_dict1[highest_score_item1['label']]}' ({highest_score_item1['score']:.2f}).\n" | |
| f"The highest probability for level was: '{label_dict2[highest_score_item2['label']]}' ({highest_score_item2['score']:.2f}). \n" | |
| f" Use this classification with caution due to uncertainty") | |
| ######################################### | |
| ######## RUN GRADIO APP ################# | |
| ######################################### | |
| #Article text. | |
| article_text = "### Have fun!" | |
| def extract_eemm_binary_columns(classification_text): | |
| labels = [ | |
| "Cognition", | |
| "Affect", | |
| "Self", | |
| "Motivation", | |
| "Attention", | |
| "Overt Behavior", | |
| "Context", | |
| "Social", | |
| "Physical", | |
| "Psychological" | |
| ] | |
| result = {label: 0 for label in labels} | |
| if classification_text is None: | |
| return result | |
| text = str(classification_text) | |
| # Only use the actual "For dimensions" and "For levels" classification lines. | |
| # This avoids accidentally coding the "highest probability was..." caution text as 1. | |
| valid_lines = [] | |
| for line in text.splitlines(): | |
| line = line.strip() | |
| if line.startswith("For dimensions:") or line.startswith("For levels:"): | |
| if "No classifications with a score" not in line: | |
| valid_lines.append(line) | |
| valid_text = " ".join(valid_lines) | |
| for label in labels: | |
| # Looks for labels followed by a probability, e.g. Context (1.00) | |
| if f"{label} (" in valid_text: | |
| result[label] = 1 | |
| return result | |
| def classify_bulk_csv(file): | |
| if file is None: | |
| raise ValueError("Please upload a CSV file.") | |
| file_path = file if isinstance(file, str) else file.name | |
| df = pd.read_csv(file_path) | |
| if "item" not in df.columns: | |
| raise ValueError("Your CSV must contain a column named exactly 'item'.") | |
| raw_outputs = [] | |
| binary_rows = [] | |
| for item in df["item"]: | |
| if pd.isna(item) or str(item).strip() == "": | |
| raw_output = "" | |
| else: | |
| raw_output = classify_output(str(item)) | |
| raw_outputs.append(raw_output) | |
| binary_rows.append(extract_eemm_binary_columns(raw_output)) | |
| binary_df = pd.DataFrame(binary_rows) | |
| # Keep original item, raw model output, and then binary EEMM columns | |
| df["raw_eemm_classification"] = raw_outputs | |
| ordered_columns = [ | |
| "Cognition", | |
| "Affect", | |
| "Self", | |
| "Motivation", | |
| "Attention", | |
| "Overt Behavior", | |
| "Context", | |
| "Social", | |
| "Physical", | |
| "Psychological" | |
| ] | |
| for col in ordered_columns: | |
| df[col] = binary_df[col] | |
| output_path = os.path.join( | |
| tempfile.gettempdir(), | |
| "eemm_bulk_classification_results_binary.csv" | |
| ) | |
| df.to_csv(output_path, index=False) | |
| return output_path | |
| # The app. | |
| with gr.Blocks(theme=gr.themes.Soft(primary_hue="orange")) as demo: | |
| gr.Markdown("# EEMM Item Classification Machine V 0.5") | |
| gr.Markdown(""" | |
| This app showcases two machine learning models to classify items and phrases into the EEMM grid. | |
| It will output a classification for dimensions such as Cognition, Self, Affect, Motivation, Attention, Overt Behavior, or Context. | |
| It will also output levels such as Social, Psychological, or Physical. | |
| Please note that the machine goes idle after a period of inactivity. If this occurs, waking it up may take a short while. | |
| """) | |
| with gr.Tab("Single item"): | |
| txtbx = gr.Textbox( | |
| value="I would like to feel better", | |
| label="Please enter your item:", | |
| container=True | |
| ) | |
| txtbxopt = gr.Textbox( | |
| label="The item you provided was classified as:", | |
| container=True | |
| ) | |
| single_button = gr.Button("Classify item") | |
| single_button.click( | |
| fn=classify_output, | |
| inputs=txtbx, | |
| outputs=txtbxopt | |
| ) | |
| with gr.Tab("Bulk CSV"): | |
| gr.Markdown(""" | |
| Upload a CSV file with one item per row. | |
| The CSV must contain a column named exactly: `item`. | |
| For large batches, such as 200 items, the app will return a downloadable CSV file only. | |
| """) | |
| csv_input = gr.File( | |
| label="Upload CSV file", | |
| file_types=[".csv"] | |
| ) | |
| bulk_button = gr.Button("Classify CSV") | |
| bulk_output_file = gr.File( | |
| label="Download classified CSV" | |
| ) | |
| bulk_button.click( | |
| fn=classify_bulk_csv, | |
| inputs=csv_input, | |
| outputs=bulk_output_file | |
| ) | |
| gr.Markdown(article_text) | |
| demo.launch() | |