nlpblogs commited on
Commit
dad6db7
·
verified ·
1 Parent(s): c2463ad

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +121 -117
app.py CHANGED
@@ -1,50 +1,41 @@
1
  import streamlit as st
2
- import time
3
  import pandas as pd
4
  import io
5
- from transformers import pipeline
6
  from streamlit_extras.stylable_container import stylable_container
7
  import plotly.express as px
8
  import zipfile
9
- from gliner import GLiNER
10
-
11
  import os
12
  from comet_ml import Experiment
13
 
14
-
15
-
16
- st.subheader("8-Named Entity Recognition Web App", divider = "red")
17
- st.link_button("DEMO APP by nlpblogs", "https://nlpblogs.com", type = "tertiary")
18
 
19
  expander = st.expander("**Important notes on the 8-Named Entity Recognition Web App**")
20
  expander.write('''
21
-
22
- **Named Entities:**
23
- This 8-Named Entity Recognition Web App predicts eight (8) labels (“person”, “country”, “city”, “organization”, “date”, “money”, “percent value”, “position”). Results are presented in an easy-to-read table, visualized in an interactive tree map, pie chart, and bar chart, and are available for download along with a Glossary of tags.
24
-
25
- **How to Use:**
26
- Type or paste your text and press Ctrl + Enter. Then, click the 'Results' button to extract and tag entities in your text data.
27
-
28
- **Usage Limits:**
29
- Unlimited number of Result requests.
30
-
31
- **Customization:**
32
- To change the app's background color to white or black, click the three-dot menu on the right-hand side of your app, go to Settings and then Choose app theme, colors and fonts.
33
-
34
- **Technical issues:**
35
- If your connection times out, please refresh the page or reopen the app's URL.
36
- For any errors or inquiries, please contact us at info@nlpblogs.com
37
-
38
- ''')
39
-
40
-
41
  with st.sidebar:
42
  container = st.container(border=True)
43
  container.write("**Named Entity Recognition (NER)** is the task of extracting and tagging entities in text data. Entities can be persons, organizations, locations, countries, products, events etc.")
44
- st.subheader("Related NLP Web Apps", divider = "red")
45
- st.link_button("14-Named Entity Recognition Web App", "https://nlpblogs.com/shop/named-entity-recognition-ner/14-named-entity-recognition-web-app/", type = "primary")
46
-
47
 
 
48
  COMET_API_KEY = os.environ.get("COMET_API_KEY")
49
  COMET_WORKSPACE = os.environ.get("COMET_WORKSPACE")
50
  COMET_PROJECT_NAME = os.environ.get("COMET_PROJECT_NAME")
@@ -55,8 +46,17 @@ else:
55
  comet_initialized = False
56
  st.warning("Comet ML not initialized. Check environment variables.")
57
 
 
 
 
58
 
 
 
 
 
 
59
 
 
60
  text = st.text_area("Type or paste your text below, and then press Ctrl + Enter", key='my_text_area')
61
  st.write("**Input text**: ", text)
62
 
@@ -64,96 +64,100 @@ def clear_text():
64
  st.session_state['my_text_area'] = ""
65
 
66
  st.button("Clear text", on_click=clear_text)
67
-
68
  st.divider()
69
 
 
70
  if st.button("Results"):
71
- with st.spinner("Wait for it...", show_time=True):
72
- time.sleep(5)
73
- model = GLiNER.from_pretrained("xomad/gliner-model-merge-large-v1.0")
74
- labels = ["person", "country", "city", "organization", "date", "money", "percent value", "position"]
75
- entities = model.predict_entities(text, labels)
76
- df = pd.DataFrame(entities)
77
-
78
- if comet_initialized:
79
- experiment = Experiment(
80
- api_key=COMET_API_KEY,
81
- workspace=COMET_WORKSPACE,
82
- project_name=COMET_PROJECT_NAME,
83
- )
84
- experiment.log_parameter("input_text", text)
85
- experiment.log_table("predicted_entities", df)
86
-
87
- properties = {"border": "2px solid gray", "color": "blue", "font-size": "16px"}
88
- df_styled = df.style.set_properties(**properties)
89
- st.dataframe(df_styled)
90
-
91
- with st.expander("See Glossary of tags"):
92
- st.write('''
93
- '**text**': ['entity extracted from your text data']
94
-
95
- '**score**': ['accuracy score; how accurately a tag has been assigned to a given entity']
96
-
97
- '**label**': ['label (tag) assigned to a given extracted entity']
98
-
99
- '**start**': ['index of the start of the corresponding entity']
100
-
101
- '**end**': ['index of the end of the corresponding entity']
102
- ''')
103
-
104
- if df is not None:
105
- fig = px.treemap(df, path=[px.Constant("all"), 'text', 'label'],
106
- values='score', color='label')
107
- fig.update_layout(margin = dict(t=50, l=25, r=25, b=25))
108
- st.subheader("Tree map", divider = "red")
109
- st.plotly_chart(fig)
110
  if comet_initialized:
111
- experiment.log_figure(figure=fig, figure_name="entity_treemap")
112
-
113
- if df is not None:
114
- value_counts1 = df['label'].value_counts()
115
- df1 = pd.DataFrame(value_counts1)
116
- final_df = df1.reset_index().rename(columns={"index": "label"})
117
- col1, col2 = st.columns(2)
118
- with col1:
119
- fig1 = px.pie(final_df, values='count', names='label', hover_data=['count'], labels={'count': 'count'}, title='Percentage of predicted labels')
120
- fig1.update_traces(textposition='inside', textinfo='percent+label')
121
- st.subheader("Pie Chart", divider = "red")
122
- st.plotly_chart(fig1)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
123
  if comet_initialized:
124
- experiment.log_figure(figure=fig1, figure_name="label_pie_chart")
125
- with col2:
126
- fig2 = px.bar(final_df, x="count", y="label", color="label", text_auto=True, title='Occurrences of predicted labels')
127
- st.subheader("Bar Chart", divider = "red")
128
- st.plotly_chart(fig2)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
129
  if comet_initialized:
130
- experiment.log_figure(figure=fig2, figure_name="label_bar_chart")
131
-
132
- dfa = pd.DataFrame(
133
- data={
134
- 'text': ['entity extracted from your text data'], 'score': ['accuracy score; how accurately a tag has been assigned to a given entity'], 'label': ['label (tag) assigned to a given extracted entity'],
135
- 'start': ['index of the start of the corresponding entity'],
136
- 'end': ['index of the end of the corresponding entity'],
137
- })
138
- buf = io.BytesIO()
139
- with zipfile.ZipFile(buf, "w") as myzip:
140
- myzip.writestr("Summary of the results.csv", df.to_csv(index=False))
141
- myzip.writestr("Glossary of tags.csv", dfa.to_csv(index=False))
142
-
143
-
144
- with stylable_container(
145
- key="download_button",
146
- css_styles="""button { background-color: yellow; border: 1px solid black; padding: 5px; color: black; }""",
147
- ):
148
- st.download_button(
149
- label="Download zip file",
150
- data=buf.getvalue(),
151
- file_name="zip file.zip",
152
- mime="application/zip",
153
- )
154
- if comet_initialized:
155
- experiment.log_asset(buf.getvalue(), file_name="downloadable_results.zip")
156
 
157
- st.divider()
158
- if comet_initialized:
159
- experiment.end()
 
1
  import streamlit as st
2
+ import time # Still imported, but time.sleep(5) will be removed from the main logic
3
  import pandas as pd
4
  import io
 
5
  from streamlit_extras.stylable_container import stylable_container
6
  import plotly.express as px
7
  import zipfile
8
+ from gliner import GLiNER # Import GLiNER
 
9
  import os
10
  from comet_ml import Experiment
11
 
12
+ # --- App Header and Info ---
13
+ st.subheader("8-Named Entity Recognition Web App", divider="red")
14
+ st.link_button("DEMO APP by nlpblogs", "https://nlpblogs.com", type="tertiary")
 
15
 
16
  expander = st.expander("**Important notes on the 8-Named Entity Recognition Web App**")
17
  expander.write('''
18
+ **Named Entities:** This 8-Named Entity Recognition Web App predicts eight (8) labels (“person”, “country”, “city”, “organization”, “date”, “money”, “percent value”, “position”). Results are presented in an easy-to-read table, visualized in an interactive tree map, pie chart, and bar chart, and are available for download along with a Glossary of tags.
19
+
20
+ **How to Use:** Type or paste your text and press Ctrl + Enter. Then, click the 'Results' button to extract and tag entities in your text data.
21
+
22
+ **Usage Limits:** Unlimited number of Result requests.
23
+
24
+ **Customization:** To change the app's background color to white or black, click the three-dot menu on the right-hand side of your app, go to Settings and then Choose app theme, colors and fonts.
25
+
26
+ **Technical issues:** If your connection times out, please refresh the page or reopen the app's URL.
27
+
28
+ For any errors or inquiries, please contact us at info@nlpblogs.com
29
+ ''')
30
+
31
+ # --- Sidebar ---
 
 
 
 
 
 
32
  with st.sidebar:
33
  container = st.container(border=True)
34
  container.write("**Named Entity Recognition (NER)** is the task of extracting and tagging entities in text data. Entities can be persons, organizations, locations, countries, products, events etc.")
35
+ st.subheader("Related NLP Web Apps", divider="red")
36
+ st.link_button("14-Named Entity Recognition Web App", "https://nlpblogs.com/shop/named-entity-recognition-ner/14-named-entity-recognition-web-app/", type="primary")
 
37
 
38
+ # --- Comet ML Setup ---
39
  COMET_API_KEY = os.environ.get("COMET_API_KEY")
40
  COMET_WORKSPACE = os.environ.get("COMET_WORKSPACE")
41
  COMET_PROJECT_NAME = os.environ.get("COMET_PROJECT_NAME")
 
46
  comet_initialized = False
47
  st.warning("Comet ML not initialized. Check environment variables.")
48
 
49
+ # --- Cache the GLiNER model ---
50
+ @st.cache_resource
51
+ def load_gliner_model():
52
 
53
+ return GLiNER.from_pretrained("xomad/gliner-model-merge-large-v1.0")
54
+
55
+ # Load the model using the cached function
56
+ model = load_gliner_model()
57
+ # --- End Caching ---
58
 
59
+ # --- Text Input and Clear Button ---
60
  text = st.text_area("Type or paste your text below, and then press Ctrl + Enter", key='my_text_area')
61
  st.write("**Input text**: ", text)
62
 
 
64
  st.session_state['my_text_area'] = ""
65
 
66
  st.button("Clear text", on_click=clear_text)
 
67
  st.divider()
68
 
69
+ # --- Results Section ---
70
  if st.button("Results"):
71
+ if not text.strip(): # Check if the input text is empty
72
+ st.warning("Please enter some text to extract entities.")
73
+ else:
74
+ with st.spinner("Extracting entities..."): # Spinner while processing
75
+ # No need for time.sleep(5) here, as the model is already loaded
76
+ labels = ["person", "country", "city", "organization", "date", "money", "percent value", "position"]
77
+ entities = model.predict_entities(text, labels)
78
+
79
+ # Ensure entities is a list of dictionaries for DataFrame creation
80
+ # If no entities are found, 'entities' might be an empty list, which is fine for pd.DataFrame
81
+ df = pd.DataFrame(entities)
82
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
83
  if comet_initialized:
84
+ experiment = Experiment(
85
+ api_key=COMET_API_KEY,
86
+ workspace=COMET_WORKSPACE,
87
+ project_name=COMET_PROJECT_NAME,
88
+ )
89
+ experiment.log_parameter("input_text", text)
90
+ experiment.log_table("predicted_entities", df)
91
+
92
+ properties = {"border": "2px solid gray", "color": "blue", "font-size": "16px"}
93
+ df_styled = df.style.set_properties(**properties)
94
+ st.dataframe(df_styled)
95
+
96
+ with st.expander("See Glossary of tags"):
97
+ st.write('''
98
+ '**text**': ['entity extracted from your text data']
99
+ '**score**': ['accuracy score; how accurately a tag has been assigned to a given entity']
100
+ '**label**': ['label (tag) assigned to a given extracted entity']
101
+ '**start**': ['index of the start of the corresponding entity']
102
+ '**end**': ['index of the end of the corresponding entity']
103
+ ''')
104
+
105
+ # --- Visualizations ---
106
+ if not df.empty: # Only plot if DataFrame is not empty
107
+ st.subheader("Tree map", divider="red")
108
+ fig = px.treemap(df, path=[px.Constant("all"), 'text', 'label'],
109
+ values='score', color='label')
110
+ fig.update_layout(margin=dict(t=50, l=25, r=25, b=25))
111
+ st.plotly_chart(fig)
112
  if comet_initialized:
113
+ experiment.log_figure(figure=fig, figure_name="entity_treemap")
114
+
115
+ col1, col2 = st.columns(2)
116
+ with col1:
117
+ st.subheader("Pie Chart", divider="red")
118
+ value_counts1 = df['label'].value_counts()
119
+ df1 = pd.DataFrame(value_counts1)
120
+ final_df = df1.reset_index().rename(columns={"index": "label"})
121
+ fig1 = px.pie(final_df, values='count', names='label', hover_data=['count'], labels={'count': 'count'}, title='Percentage of predicted labels')
122
+ fig1.update_traces(textposition='inside', textinfo='percent+label')
123
+ st.plotly_chart(fig1)
124
+ if comet_initialized:
125
+ experiment.log_figure(figure=fig1, figure_name="label_pie_chart")
126
+
127
+ with col2:
128
+ st.subheader("Bar Chart", divider="red")
129
+ fig2 = px.bar(final_df, x="count", y="label", color="label", text_auto=True, title='Occurrences of predicted labels')
130
+ st.plotly_chart(fig2)
131
+ if comet_initialized:
132
+ experiment.log_figure(figure=fig2, figure_name="label_bar_chart")
133
+ else:
134
+ st.info("No entities found in the provided text.")
135
+
136
+ # --- Download Buttons ---
137
+ dfa = pd.DataFrame(
138
+ data={
139
+ 'text': ['entity extracted from your text data'], 'score': ['accuracy score; how accurately a tag has been assigned to a given entity'], 'label': ['label (tag) assigned to a given extracted entity'],
140
+ 'start': ['index of the start of the corresponding entity'],
141
+ 'end': ['index of the end of the corresponding entity'],
142
+ })
143
+ buf = io.BytesIO()
144
+ with zipfile.ZipFile(buf, "w") as myzip:
145
+ myzip.writestr("Summary of the results.csv", df.to_csv(index=False))
146
+ myzip.writestr("Glossary of tags.csv", dfa.to_csv(index=False))
147
+
148
+ with stylable_container(
149
+ key="download_button",
150
+ css_styles="""button { background-color: yellow; border: 1px solid black; padding: 5px; color: black; }""",
151
+ ):
152
+ st.download_button(
153
+ label="Download zip file",
154
+ data=buf.getvalue(),
155
+ file_name="zip file.zip",
156
+ mime="application/zip",
157
+ )
158
  if comet_initialized:
159
+ experiment.log_asset(buf.getvalue(), file_name="downloadable_results.zip")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
160
 
161
+ st.divider()
162
+ if comet_initialized:
163
+ experiment.end()