SenseiAlgo commited on
Commit
d8a434c
·
verified ·
1 Parent(s): 5db0e2a

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +92 -41
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
- cols = st.columns(len(EXAMPLE_PROMPTS))
61
- for i, (key, value) in enumerate(EXAMPLE_PROMPTS.items()):
62
- with cols[i]:
63
- if st.button(key):
64
- set_example_text(key)
 
 
 
 
 
 
 
 
 
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.write("Please write a valid sentence.")
79
-
80
- lexical_ner_model, lexical_plus_ner_model, semantic_ner_model, hybrid_ner_model = load_models()
81
-
82
- # get entities
83
- if option == "Lexical":
84
- predicted_entities = lexical_ner_model.get_entities(text)
85
- elif option == "Lexical Plus":
86
- predicted_entities = lexical_plus_ner_model.get_entities(text)
87
- elif option == "Semantic":
88
- predicted_entities = semantic_ner_model.get_entities(text)
89
- elif option == "Hybrid":
90
- predicted_entities = hybrid_ner_model.get_entities(text)
91
-
92
- # re-format to match SpaCy, as it uses label instead of entity_group
93
- # entity_group follows huggingface design and is compatible with most NER interfaces
94
- entities_formatted = []
95
- for tag in predicted_entities:
96
- entities_formatted.append({
97
- "start": tag['start'],
98
- "end": tag['end'],
99
- "label": tag['entity_group'],
100
- "score": tag['score']
101
- })
102
-
103
- ner_for_display = [{
104
- "text": spacy_tokenize_sentence(preprocess(text)),
105
- "ents": entities_formatted,
106
- "title": "Named Entities"
107
- }]
108
- html_ner = displacy.render(ner_for_display, style="ent", manual=True)
109
- html_ner = html_ner.replace("\n", " ")
110
- st.write(HTML_WRAPPER.format(html_ner), unsafe_allow_html=True)
 
 
 
 
 
 
 
 
 
 
 
 
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()