Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -10,6 +10,10 @@ warnings.filterwarnings("ignore", category=DeprecationWarning)
|
|
| 10 |
|
| 11 |
HTML_WRAPPER = """<div style="overflow-x: auto; border: 1px solid #e6e9ef; border-radius: 0.25rem; padding: 1rem; margin-bottom: 2.5rem">{}</div>"""
|
| 12 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 13 |
# Define your example prompts here for easy management
|
| 14 |
EXAMPLE_PROMPTS = {
|
| 15 |
"Example 1️⃣: Asset Allocation": "Cautious Asset Investment has a total of $150,000 to manage and decides to invest it in money market fund, which yields a 2% return as well as in foreign bonds, which gives and average rate of return of 10.2%. Internal policies require PAI to diversify the asset allocation so that the minimum investment in money market fund is 40% of the total investment. Due to the risk of default of foreign countries, no more than 40% of the total investment should be allocated to foreign bonds. How much should the Cautious Asset Investment allocate in each asset so as to maximize its average return?",
|
|
@@ -31,7 +35,6 @@ EXAMPLE_PROMPTS = {
|
|
| 31 |
"Example 9️⃣: Resource Allocation": "A project manager has 4 teams available to work on 3 different projects. Each team has different productivity rates for each project and different hourly costs. Project A requires 100 hours, Project B requires 150 hours, and Project C requires 200 hours. Each team can work a maximum of 160 hours this month. How should the manager assign teams to projects to minimize total cost while completing all projects on time?",
|
| 32 |
|
| 33 |
"Example 🔟: Diet Optimization": "A diet plan requires at least 3000 calories, 50 grams of protein, and 70 grams of fat. Food X provides 600 calories, 20g protein, and 10g fat per serving. Food Y provides 500 calories, 10g protein, and 20g fat per serving. How many servings of each food should be consumed to meet the requirements at minimum cost?",
|
| 34 |
-
|
| 35 |
}
|
| 36 |
|
| 37 |
@st.cache_resource
|
|
@@ -47,6 +50,22 @@ def set_example_text(example_key):
|
|
| 47 |
"""Callback to set the text area value based on the selected example."""
|
| 48 |
st.session_state.text_input = EXAMPLE_PROMPTS[example_key]
|
| 49 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 50 |
def main():
|
| 51 |
st.title("""Ner4Opt: Named Entity Recognition for Optimization""")
|
| 52 |
st.markdown("""Given an optimization problem in natural language, Ner4Opt extracts optimization related entities from free-form text. The source code for Ner4Opt is available at https://github.com/skadio/ner4opt""")
|
|
@@ -54,15 +73,32 @@ def main():
|
|
| 54 |
# Initialize session state for the text input if it doesn't exist
|
| 55 |
if "text_input" not in st.session_state:
|
| 56 |
st.session_state.text_input = EXAMPLE_PROMPTS["Example 1️⃣: Asset Allocation"]
|
|
|
|
|
|
|
|
|
|
|
|
|
| 57 |
|
| 58 |
# --- Add the example prompts section ---
|
| 59 |
-
st.subheader("Try with an example:")
|
| 60 |
-
|
| 61 |
-
|
| 62 |
-
|
| 63 |
-
|
| 64 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 65 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 66 |
# ----------------------------------------
|
| 67 |
|
| 68 |
option = st.sidebar.selectbox(
|
|
@@ -70,44 +106,59 @@ def main():
|
|
| 70 |
('Lexical', 'Lexical Plus', 'Semantic', 'Hybrid'), index=3)
|
| 71 |
|
| 72 |
text = st.text_area(
|
| 73 |
-
"Text",
|
| 74 |
value=st.session_state.text_input, # Use the session state value here
|
|
|
|
|
|
|
| 75 |
)
|
|
|
|
| 76 |
text = text.strip()
|
| 77 |
if text == "":
|
| 78 |
-
st.
|
| 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 |
if __name__ == '__main__':
|
| 113 |
main()
|
|
|
|
| 10 |
|
| 11 |
HTML_WRAPPER = """<div style="overflow-x: auto; border: 1px solid #e6e9ef; border-radius: 0.25rem; padding: 1rem; margin-bottom: 2.5rem">{}</div>"""
|
| 12 |
|
| 13 |
+
# Configuration: Change this number to control how many examples to show by default
|
| 14 |
+
DEFAULT_EXAMPLES_TO_SHOW = 3
|
| 15 |
+
EXAMPLES_PER_ROW = 3
|
| 16 |
+
|
| 17 |
# Define your example prompts here for easy management
|
| 18 |
EXAMPLE_PROMPTS = {
|
| 19 |
"Example 1️⃣: Asset Allocation": "Cautious Asset Investment has a total of $150,000 to manage and decides to invest it in money market fund, which yields a 2% return as well as in foreign bonds, which gives and average rate of return of 10.2%. Internal policies require PAI to diversify the asset allocation so that the minimum investment in money market fund is 40% of the total investment. Due to the risk of default of foreign countries, no more than 40% of the total investment should be allocated to foreign bonds. How much should the Cautious Asset Investment allocate in each asset so as to maximize its average return?",
|
|
|
|
| 35 |
"Example 9️⃣: Resource Allocation": "A project manager has 4 teams available to work on 3 different projects. Each team has different productivity rates for each project and different hourly costs. Project A requires 100 hours, Project B requires 150 hours, and Project C requires 200 hours. Each team can work a maximum of 160 hours this month. How should the manager assign teams to projects to minimize total cost while completing all projects on time?",
|
| 36 |
|
| 37 |
"Example 🔟: Diet Optimization": "A diet plan requires at least 3000 calories, 50 grams of protein, and 70 grams of fat. Food X provides 600 calories, 20g protein, and 10g fat per serving. Food Y provides 500 calories, 10g protein, and 20g fat per serving. How many servings of each food should be consumed to meet the requirements at minimum cost?",
|
|
|
|
| 38 |
}
|
| 39 |
|
| 40 |
@st.cache_resource
|
|
|
|
| 50 |
"""Callback to set the text area value based on the selected example."""
|
| 51 |
st.session_state.text_input = EXAMPLE_PROMPTS[example_key]
|
| 52 |
|
| 53 |
+
def display_example_buttons(show_all=False):
|
| 54 |
+
"""Display example buttons in organized rows."""
|
| 55 |
+
example_items = list(EXAMPLE_PROMPTS.items())
|
| 56 |
+
|
| 57 |
+
if not show_all:
|
| 58 |
+
example_items = example_items[:DEFAULT_EXAMPLES_TO_SHOW]
|
| 59 |
+
|
| 60 |
+
# Display examples in rows
|
| 61 |
+
for i in range(0, len(example_items), EXAMPLES_PER_ROW):
|
| 62 |
+
cols = st.columns(EXAMPLES_PER_ROW)
|
| 63 |
+
|
| 64 |
+
for j, (key, value) in enumerate(example_items[i:i+EXAMPLES_PER_ROW]):
|
| 65 |
+
with cols[j]:
|
| 66 |
+
if st.button(key, key=f"example_btn_{i+j}", use_container_width=True):
|
| 67 |
+
set_example_text(key)
|
| 68 |
+
|
| 69 |
def main():
|
| 70 |
st.title("""Ner4Opt: Named Entity Recognition for Optimization""")
|
| 71 |
st.markdown("""Given an optimization problem in natural language, Ner4Opt extracts optimization related entities from free-form text. The source code for Ner4Opt is available at https://github.com/skadio/ner4opt""")
|
|
|
|
| 73 |
# Initialize session state for the text input if it doesn't exist
|
| 74 |
if "text_input" not in st.session_state:
|
| 75 |
st.session_state.text_input = EXAMPLE_PROMPTS["Example 1️⃣: Asset Allocation"]
|
| 76 |
+
|
| 77 |
+
# Initialize session state for showing all examples
|
| 78 |
+
if "show_all_examples" not in st.session_state:
|
| 79 |
+
st.session_state.show_all_examples = False
|
| 80 |
|
| 81 |
# --- Add the example prompts section ---
|
| 82 |
+
st.subheader("📝 Try with an example:")
|
| 83 |
+
|
| 84 |
+
# Toggle button for showing more/fewer examples
|
| 85 |
+
total_examples = len(EXAMPLE_PROMPTS)
|
| 86 |
+
if total_examples > DEFAULT_EXAMPLES_TO_SHOW:
|
| 87 |
+
col1, col2 = st.columns([3, 1])
|
| 88 |
+
with col2:
|
| 89 |
+
if st.session_state.show_all_examples:
|
| 90 |
+
if st.button(f"Show fewer ({DEFAULT_EXAMPLES_TO_SHOW})", key="toggle_examples"):
|
| 91 |
+
st.session_state.show_all_examples = False
|
| 92 |
+
st.rerun()
|
| 93 |
+
else:
|
| 94 |
+
if st.button(f"Show all ({total_examples})", key="toggle_examples"):
|
| 95 |
+
st.session_state.show_all_examples = True
|
| 96 |
+
st.rerun()
|
| 97 |
|
| 98 |
+
# Display the example buttons
|
| 99 |
+
display_example_buttons(st.session_state.show_all_examples)
|
| 100 |
+
|
| 101 |
+
st.markdown("---")
|
| 102 |
# ----------------------------------------
|
| 103 |
|
| 104 |
option = st.sidebar.selectbox(
|
|
|
|
| 106 |
('Lexical', 'Lexical Plus', 'Semantic', 'Hybrid'), index=3)
|
| 107 |
|
| 108 |
text = st.text_area(
|
| 109 |
+
"Text (Tip: Use Ctrl+Enter to process)",
|
| 110 |
value=st.session_state.text_input, # Use the session state value here
|
| 111 |
+
height=120,
|
| 112 |
+
help="Enter your optimization problem description or select an example above."
|
| 113 |
)
|
| 114 |
+
|
| 115 |
text = text.strip()
|
| 116 |
if text == "":
|
| 117 |
+
st.warning("Please write a valid sentence or select an example above.")
|
| 118 |
+
return
|
| 119 |
+
|
| 120 |
+
try:
|
| 121 |
+
with st.spinner("Processing text..."):
|
| 122 |
+
lexical_ner_model, lexical_plus_ner_model, semantic_ner_model, hybrid_ner_model = load_models()
|
| 123 |
+
|
| 124 |
+
# get entities
|
| 125 |
+
if option == "Lexical":
|
| 126 |
+
predicted_entities = lexical_ner_model.get_entities(text)
|
| 127 |
+
elif option == "Lexical Plus":
|
| 128 |
+
predicted_entities = lexical_plus_ner_model.get_entities(text)
|
| 129 |
+
elif option == "Semantic":
|
| 130 |
+
predicted_entities = semantic_ner_model.get_entities(text)
|
| 131 |
+
elif option == "Hybrid":
|
| 132 |
+
predicted_entities = hybrid_ner_model.get_entities(text)
|
| 133 |
+
|
| 134 |
+
# re-format to match SpaCy, as it uses label instead of entity_group
|
| 135 |
+
# entity_group follows huggingface design and is compatible with most NER interfaces
|
| 136 |
+
entities_formatted = []
|
| 137 |
+
for tag in predicted_entities:
|
| 138 |
+
entities_formatted.append({
|
| 139 |
+
"start": tag['start'],
|
| 140 |
+
"end": tag['end'],
|
| 141 |
+
"label": tag['entity_group'],
|
| 142 |
+
"score": tag['score']
|
| 143 |
+
})
|
| 144 |
+
|
| 145 |
+
ner_for_display = [{
|
| 146 |
+
"text": spacy_tokenize_sentence(preprocess(text)),
|
| 147 |
+
"ents": entities_formatted,
|
| 148 |
+
"title": "Named Entities"
|
| 149 |
+
}]
|
| 150 |
+
html_ner = displacy.render(ner_for_display, style="ent", manual=True)
|
| 151 |
+
html_ner = html_ner.replace("\n", " ")
|
| 152 |
+
st.write(HTML_WRAPPER.format(html_ner), unsafe_allow_html=True)
|
| 153 |
+
|
| 154 |
+
# Show entity count if any entities found
|
| 155 |
+
if entities_formatted:
|
| 156 |
+
st.success(f"Found {len(entities_formatted)} entities using {option} model")
|
| 157 |
+
else:
|
| 158 |
+
st.info("No entities detected in the text.")
|
| 159 |
+
|
| 160 |
+
except Exception as e:
|
| 161 |
+
st.error(f"An error occurred: {str(e)}")
|
| 162 |
|
| 163 |
if __name__ == '__main__':
|
| 164 |
main()
|