Spaces:
Sleeping
Sleeping
Upload 5 files
Browse files- .streamlit/config.toml +3 -0
- Demo.py +163 -0
- Dockerfile +70 -0
- pages/Workflow & Model Overview.py +242 -0
- requirements.txt +6 -0
.streamlit/config.toml
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
[theme]
|
2 |
+
base="light"
|
3 |
+
primaryColor="#29B4E8"
|
Demo.py
ADDED
@@ -0,0 +1,163 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
import sparknlp
|
3 |
+
import os
|
4 |
+
import pandas as pd
|
5 |
+
|
6 |
+
from sparknlp.base import *
|
7 |
+
from sparknlp.annotator import *
|
8 |
+
from pyspark.ml import Pipeline
|
9 |
+
from sparknlp.pretrained import PretrainedPipeline
|
10 |
+
from annotated_text import annotated_text
|
11 |
+
from pyspark.sql import SparkSession
|
12 |
+
from pyspark.sql.functions import col, concat, lit, round
|
13 |
+
|
14 |
+
# Page configuration
|
15 |
+
st.set_page_config(
|
16 |
+
layout="wide",
|
17 |
+
page_title="Spark NLP Demos App",
|
18 |
+
initial_sidebar_state="auto"
|
19 |
+
)
|
20 |
+
|
21 |
+
# CSS for styling
|
22 |
+
st.markdown("""
|
23 |
+
<style>
|
24 |
+
.main-title {
|
25 |
+
font-size: 36px;
|
26 |
+
color: #4A90E2;
|
27 |
+
font-weight: bold;
|
28 |
+
text-align: center;
|
29 |
+
}
|
30 |
+
.section p, .section ul {
|
31 |
+
color: #666666;
|
32 |
+
}
|
33 |
+
</style>
|
34 |
+
""", unsafe_allow_html=True)
|
35 |
+
|
36 |
+
@st.cache_resource
|
37 |
+
def init_spark():
|
38 |
+
return sparknlp.start()
|
39 |
+
|
40 |
+
@st.cache_resource
|
41 |
+
def create_pipeline(model):
|
42 |
+
document_assembler = DocumentAssembler() \
|
43 |
+
.setInputCol("text") \
|
44 |
+
.setOutputCol("document")
|
45 |
+
|
46 |
+
tokenizer = Tokenizer() \
|
47 |
+
.setInputCols(["document"]) \
|
48 |
+
.setOutputCol("token")
|
49 |
+
|
50 |
+
embeddings = WordEmbeddingsModel.pretrained('glove_840B_300', lang='xx') \
|
51 |
+
.setInputCols(["document", "token"]) \
|
52 |
+
.setOutputCol("embeddings")
|
53 |
+
|
54 |
+
ner_model = NerDLModel.pretrained(model, 'xx') \
|
55 |
+
.setInputCols(["document", "token", "embeddings"]) \
|
56 |
+
.setOutputCol("ner")
|
57 |
+
|
58 |
+
ner_converter = NerConverter() \
|
59 |
+
.setInputCols(["document", "token", "ner"]) \
|
60 |
+
.setOutputCol("ner_chunk")
|
61 |
+
|
62 |
+
pipeline = Pipeline(stages=[
|
63 |
+
document_assembler,
|
64 |
+
tokenizer,
|
65 |
+
embeddings,
|
66 |
+
ner_model,
|
67 |
+
ner_converter
|
68 |
+
])
|
69 |
+
|
70 |
+
return pipeline
|
71 |
+
|
72 |
+
def fit_data(pipeline, data):
|
73 |
+
empty_df = spark.createDataFrame([['']]).toDF('text')
|
74 |
+
pipeline_model = pipeline.fit(empty_df)
|
75 |
+
model = LightPipeline(pipeline_model)
|
76 |
+
result = model.fullAnnotate(data)
|
77 |
+
return result
|
78 |
+
|
79 |
+
def annotate(data):
|
80 |
+
document, chunks, labels = data["Document"], data["NER Chunk"], data["NER Label"]
|
81 |
+
annotated_words = []
|
82 |
+
for chunk, label in zip(chunks, labels):
|
83 |
+
parts = document.split(chunk, 1)
|
84 |
+
if parts[0]:
|
85 |
+
annotated_words.append(parts[0])
|
86 |
+
annotated_words.append((chunk, label))
|
87 |
+
document = parts[1]
|
88 |
+
if document:
|
89 |
+
annotated_words.append(document)
|
90 |
+
annotated_text(*annotated_words)
|
91 |
+
|
92 |
+
# Set up the page layout
|
93 |
+
st.markdown('<div class="main-title">Identificare entitΓ generali nel testo italiano with Spark NLP</div>', unsafe_allow_html=True)
|
94 |
+
|
95 |
+
# Sidebar content
|
96 |
+
model = st.sidebar.selectbox(
|
97 |
+
"Choose the pretrained model",
|
98 |
+
["ner_wikiner_glove_840B_300"],
|
99 |
+
help="For more info about the models visit: https://sparknlp.org/models"
|
100 |
+
)
|
101 |
+
|
102 |
+
# Reference notebook link in sidebar
|
103 |
+
link = """
|
104 |
+
<a href="https://colab.research.google.com/github/JohnSnowLabs/spark-nlp-workshop/blob/master/tutorials/streamlit_notebooks/NER_FR.ipynb">
|
105 |
+
<img src="https://colab.research.google.com/assets/colab-badge.svg" style="zoom: 1.3" alt="Open In Colab"/>
|
106 |
+
</a>
|
107 |
+
"""
|
108 |
+
st.sidebar.markdown('Reference notebook:')
|
109 |
+
st.sidebar.markdown(link, unsafe_allow_html=True)
|
110 |
+
|
111 |
+
# Load examples
|
112 |
+
examples = [
|
113 |
+
"""William Henry Gates III (nato il 28 ottobre 1955) è un magnate d'affari americano, sviluppatore di software, investitore e filantropo. à noto soprattutto come co-fondatore di Microsoft Corporation. Durante la sua carriera in Microsoft, Gates ha ricoperto le posizioni di presidente, amministratore delegato (CEO), presidente e capo architetto del software, pur essendo il principale azionista individuale fino a maggio 2014. à uno dei più noti imprenditori e pionieri del rivoluzione dei microcomputer degli anni '70 e '80. Nato e cresciuto a Seattle, Washington, Gates ha co-fondato Microsoft con l'amico d'infanzia Paul Allen nel 1975, ad Albuquerque, nel New Mexico; divenne la più grande azienda di software per personal computer al mondo. Gates ha guidato l'azienda come presidente e CEO fino a quando non si è dimesso da CEO nel gennaio 2000, ma è rimasto presidente e divenne capo architetto del software. Alla fine degli anni '90, Gates era stato criticato per le sue tattiche commerciali, che erano state considerate anticoncorrenziali. Questa opinione è stata confermata da numerose sentenze giudiziarie. Nel giugno 2006, Gates ha annunciato che sarebbe passato a un ruolo part-time presso Microsoft e un lavoro a tempo pieno presso la Bill & Melinda Gates Foundation, la fondazione di beneficenza privata che lui e sua moglie, Melinda Gates, hanno fondato nel 2000. [ 9] A poco a poco trasferì i suoi doveri a Ray Ozzie e Craig Mundie. Si è dimesso da presidente di Microsoft nel febbraio 2014 e ha assunto un nuovo incarico come consulente tecnologico per supportare il neo nominato CEO Satya Nadella.""",
|
114 |
+
"""La Gioconda Γ¨ un dipinto ad olio del XVI secolo creato da Leonardo. Si tiene al Louvre di Parigi.""",
|
115 |
+
"""Quando Sebastian Thrun ha iniziato a lavorare su auto a guida autonoma presso Google nel 2007, poche persone al di fuori dell'azienda lo hanno preso sul serio. "Posso dirti che amministratori delegati molto importanti delle principali case automobilistiche americane mi stringerebbero la mano e si allontanerebbero perchΓ© non valeva la pena parlarne", ha dichiarato Thrun, ora co-fondatore e CEO della startup di istruzione superiore online Udacity, in un'intervista con Recode all'inizio di questa settimana.""",
|
116 |
+
"""Facebook Γ¨ un servizio di social network lanciato come TheFacebook il 4 febbraio 2004. Γ stato fondato da Mark Zuckerberg con i suoi compagni di stanza del college e gli altri studenti dell'UniversitΓ di Harvard Eduardo Saverin, Andrew McCollum, Dustin Moskovitz e Chris Hughes. L'adesione al sito web Γ¨ stata inizialmente limitata dai fondatori agli studenti di Harvard, ma Γ¨ stata estesa ad altri college nell'area di Boston, la Ivy League e gradualmente la maggior parte delle universitΓ negli Stati Uniti e in Canada.""",
|
117 |
+
"""La storia dell'elaborazione del linguaggio naturale iniziΓ² generalmente negli anni '50, sebbene si possano trovare lavori di epoche precedenti. Nel 1950, Alan Turing pubblicΓ² un articolo intitolato "Computing Machinery and Intelligence" che proponeva quello che ora viene chiamato il test di Turing come criterio di intelligenza""",
|
118 |
+
"""Geoffrey Everest Hinton Γ¨ uno psicologo cognitivo e uno scienziato informatico canadese inglese, noto soprattutto per il suo lavoro sulle reti neurali artificiali. Dal 2013 divide il suo tempo lavorando per Google e l'UniversitΓ di Toronto. Nel 2017 Γ¨ stato cofondatore ed Γ¨ diventato Chief Scientific Advisor del Vector Institute di Toronto.""",
|
119 |
+
"""Quando ho detto a John che volevo trasferirmi in Alaska, mi ha avvertito che avrei avuto difficoltà a trovare uno Starbucks lì.""",
|
120 |
+
"""Steven Paul Jobs era un magnate degli affari americano, designer industriale, investitore e proprietario dei media. Γ stato presidente, amministratore delegato (CEO) e co-fondatore di Apple Inc., presidente e azionista di maggioranza di Pixar, membro del consiglio di amministrazione di The Walt Disney Company a seguito dell'acquisizione di Pixar, e fondatore, presidente e CEO di NeXT. Jobs Γ¨ ampiamente riconosciuto come un pioniere della rivoluzione del personal computer degli anni '70 e '80, insieme al co-fondatore di Apple Steve Wozniak. Jobs Γ¨ nato a San Francisco, in California, e Γ¨ stato adottato. Γ cresciuto nella Bay Area di San Francisco. Ha frequentato il Reed College nel 1972 prima di abbandonare quello stesso anno, e ha viaggiato attraverso l'India nel 1974 in cerca di illuminazione e studiando il buddismo Zen.""",
|
121 |
+
"""Titanic Γ¨ un romanzo epico americano del 1997 e film catastrofico diretto, scritto, coprodotto e coprodotto da James Cameron. Incorporando aspetti sia storici che di fantasia, si basa sui racconti dell'affondamento del Titanic RMS e vede protagonisti Leonardo DiCaprio e Kate Winslet come membri di diverse classi sociali che si innamorano a bordo della nave durante il suo viaggio inaugurale sfortunato.""",
|
122 |
+
"""Oltre ad essere il re del nord, John Snow Γ¨ un medico inglese e un leader nello sviluppo dell'anestesia e dell'igiene medica. Γ considerato il primo a utilizzare i dati per curare l'epidemia di colera nel 1834."""
|
123 |
+
]
|
124 |
+
|
125 |
+
# st.subheader("Riconoscere persone, luoghi, organizzazioni e varie entitΓ utilizzando un modello di apprendimento profondo preconfigurato predefinito e incorporamenti di parole GloVe (glove_300d).")
|
126 |
+
selected_text = st.selectbox("Select an example", examples)
|
127 |
+
custom_input = st.text_input("Try it with your own Sentence!")
|
128 |
+
|
129 |
+
text_to_analyze = custom_input if custom_input else selected_text
|
130 |
+
|
131 |
+
st.subheader('Full example text')
|
132 |
+
HTML_WRAPPER = """<div class="scroll entities" style="overflow-x: auto; border: 1px solid #e6e9ef; border-radius: 0.25rem; padding: 1rem; margin-bottom: 2.5rem; white-space:pre-wrap">{}</div>"""
|
133 |
+
st.markdown(HTML_WRAPPER.format(text_to_analyze), unsafe_allow_html=True)
|
134 |
+
|
135 |
+
# Initialize Spark and create pipeline
|
136 |
+
spark = init_spark()
|
137 |
+
pipeline = create_pipeline(model)
|
138 |
+
output = fit_data(pipeline, text_to_analyze)
|
139 |
+
|
140 |
+
# Display matched sentence
|
141 |
+
st.subheader("Processed output:")
|
142 |
+
|
143 |
+
results = {
|
144 |
+
'Document': output[0]['document'][0].result,
|
145 |
+
'NER Chunk': [n.result for n in output[0]['ner_chunk']],
|
146 |
+
'NER Label': [n.metadata['entity'] for n in output[0]['ner_chunk']],
|
147 |
+
'Confidence': [n.metadata['confidence'] for n in output[0]['ner_chunk']]
|
148 |
+
}
|
149 |
+
|
150 |
+
spark_df = spark.createDataFrame(
|
151 |
+
zip(results['NER Chunk'], results['NER Label'], results['Confidence']),
|
152 |
+
schema=['NER Chunk', 'NER Label', 'Confidence']
|
153 |
+
)
|
154 |
+
|
155 |
+
processed_df = spark_df.select(
|
156 |
+
col('NER Chunk').alias('result'),
|
157 |
+
col('NER Label').alias('entity'),
|
158 |
+
concat(round(col('Confidence').cast('float') * 100, 2), lit('%')).alias('confidence')
|
159 |
+
)
|
160 |
+
|
161 |
+
annotate(results)
|
162 |
+
with st.expander("View DataFrame"):
|
163 |
+
st.dataframe(processed_df)
|
Dockerfile
ADDED
@@ -0,0 +1,70 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Download base image ubuntu 18.04
|
2 |
+
FROM ubuntu:18.04
|
3 |
+
|
4 |
+
# Set environment variables
|
5 |
+
ENV NB_USER jovyan
|
6 |
+
ENV NB_UID 1000
|
7 |
+
ENV HOME /home/${NB_USER}
|
8 |
+
|
9 |
+
# Install required packages
|
10 |
+
RUN apt-get update && apt-get install -y \
|
11 |
+
tar \
|
12 |
+
wget \
|
13 |
+
bash \
|
14 |
+
rsync \
|
15 |
+
gcc \
|
16 |
+
libfreetype6-dev \
|
17 |
+
libhdf5-serial-dev \
|
18 |
+
libpng-dev \
|
19 |
+
libzmq3-dev \
|
20 |
+
python3 \
|
21 |
+
python3-dev \
|
22 |
+
python3-pip \
|
23 |
+
unzip \
|
24 |
+
pkg-config \
|
25 |
+
software-properties-common \
|
26 |
+
graphviz \
|
27 |
+
openjdk-8-jdk \
|
28 |
+
ant \
|
29 |
+
ca-certificates-java \
|
30 |
+
&& apt-get clean \
|
31 |
+
&& update-ca-certificates -f;
|
32 |
+
|
33 |
+
# Install Python 3.8 and pip
|
34 |
+
RUN add-apt-repository ppa:deadsnakes/ppa \
|
35 |
+
&& apt-get update \
|
36 |
+
&& apt-get install -y python3.8 python3-pip \
|
37 |
+
&& apt-get clean;
|
38 |
+
|
39 |
+
# Set up JAVA_HOME
|
40 |
+
ENV JAVA_HOME /usr/lib/jvm/java-8-openjdk-amd64/
|
41 |
+
RUN mkdir -p ${HOME} \
|
42 |
+
&& echo "export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64/" >> ${HOME}/.bashrc \
|
43 |
+
&& chown -R ${NB_UID}:${NB_UID} ${HOME}
|
44 |
+
|
45 |
+
# Create a new user named "jovyan" with user ID 1000
|
46 |
+
RUN useradd -m -u ${NB_UID} ${NB_USER}
|
47 |
+
|
48 |
+
# Switch to the "jovyan" user
|
49 |
+
USER ${NB_USER}
|
50 |
+
|
51 |
+
# Set home and path variables for the user
|
52 |
+
ENV HOME=/home/${NB_USER} \
|
53 |
+
PATH=/home/${NB_USER}/.local/bin:$PATH
|
54 |
+
|
55 |
+
# Set the working directory to the user's home directory
|
56 |
+
WORKDIR ${HOME}
|
57 |
+
|
58 |
+
# Upgrade pip and install Python dependencies
|
59 |
+
RUN python3.8 -m pip install --upgrade pip
|
60 |
+
COPY requirements.txt /tmp/requirements.txt
|
61 |
+
RUN python3.8 -m pip install -r /tmp/requirements.txt
|
62 |
+
|
63 |
+
# Copy the application code into the container at /home/jovyan
|
64 |
+
COPY --chown=${NB_USER}:${NB_USER} . ${HOME}
|
65 |
+
|
66 |
+
# Expose port for Streamlit
|
67 |
+
EXPOSE 7860
|
68 |
+
|
69 |
+
# Define the entry point for the container
|
70 |
+
ENTRYPOINT ["streamlit", "run", "Demo.py", "--server.port=7860", "--server.address=0.0.0.0"]
|
pages/Workflow & Model Overview.py
ADDED
@@ -0,0 +1,242 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
|
3 |
+
# Custom CSS for better styling
|
4 |
+
st.markdown("""
|
5 |
+
<style>
|
6 |
+
.main-title {
|
7 |
+
font-size: 36px;
|
8 |
+
color: #4A90E2;
|
9 |
+
font-weight: bold;
|
10 |
+
text-align: center;
|
11 |
+
}
|
12 |
+
.sub-title {
|
13 |
+
font-size: 24px;
|
14 |
+
color: #4A90E2;
|
15 |
+
margin-top: 20px;
|
16 |
+
}
|
17 |
+
.section {
|
18 |
+
background-color: #f9f9f9;
|
19 |
+
padding: 15px;
|
20 |
+
border-radius: 10px;
|
21 |
+
margin-top: 20px;
|
22 |
+
}
|
23 |
+
.section h2 {
|
24 |
+
font-size: 22px;
|
25 |
+
color: #4A90E2;
|
26 |
+
}
|
27 |
+
.section p, .section ul {
|
28 |
+
color: #666666;
|
29 |
+
}
|
30 |
+
.link {
|
31 |
+
color: #4A90E2;
|
32 |
+
text-decoration: none;
|
33 |
+
}
|
34 |
+
</style>
|
35 |
+
""", unsafe_allow_html=True)
|
36 |
+
|
37 |
+
# Main Title
|
38 |
+
st.markdown('<div class="main-title">State-of-the-Art Named Entity Recognition with Spark NLP (Italian)</div>', unsafe_allow_html=True)
|
39 |
+
|
40 |
+
# Introduction
|
41 |
+
st.markdown("""
|
42 |
+
<div class="section">
|
43 |
+
<p>Named Entity Recognition (NER) is the task of identifying important words in a text and associating them with a category. For example, we may be interested in finding all the personal names in documents, or company names in news articles. Other examples include domain-specific uses such as identifying all disease names in a clinical text, or company trading codes in financial ones.</p>
|
44 |
+
<p>NER can be implemented with many approaches. In this post, we introduce a deep learning-based method using the NerDL model. This approach leverages the scalability of Spark NLP with Python.</p>
|
45 |
+
</div>
|
46 |
+
""", unsafe_allow_html=True)
|
47 |
+
|
48 |
+
# Introduction to Spark NLP
|
49 |
+
st.markdown('<div class="sub-title">Introduction to Spark NLP</div>', unsafe_allow_html=True)
|
50 |
+
st.markdown("""
|
51 |
+
<div class="section">
|
52 |
+
<p>Spark NLP is an open-source library maintained by John Snow Labs. It is built on top of Apache Spark and Spark ML and provides simple, performant & accurate NLP annotations for machine learning pipelines that can scale easily in a distributed environment.</p>
|
53 |
+
<p>To install Spark NLP, you can simply use any package manager like conda or pip. For example, using pip you can simply run <code>pip install spark-nlp</code>. For different installation options, check the official <a href="https://nlp.johnsnowlabs.com/docs/en/install" target="_blank" class="link">documentation</a>.</p>
|
54 |
+
</div>
|
55 |
+
""", unsafe_allow_html=True)
|
56 |
+
|
57 |
+
# Using NerDL Model
|
58 |
+
st.markdown('<div class="sub-title">Using NerDL Model</div>', unsafe_allow_html=True)
|
59 |
+
st.markdown("""
|
60 |
+
<div class="section">
|
61 |
+
<p>The NerDL model in Spark NLP is a deep learning-based approach for NER tasks. It uses a Char CNNs - BiLSTM - CRF architecture that achieves state-of-the-art results in most datasets. The training data should be a labeled Spark DataFrame in the format of CoNLL 2003 IOB with annotation type columns.</p>
|
62 |
+
</div>
|
63 |
+
""", unsafe_allow_html=True)
|
64 |
+
|
65 |
+
# Setup Instructions
|
66 |
+
st.markdown('<div class="sub-title">Setup</div>', unsafe_allow_html=True)
|
67 |
+
st.markdown('<p>To install Spark NLP in Python, use your favorite package manager (conda, pip, etc.). For example:</p>', unsafe_allow_html=True)
|
68 |
+
st.code("""
|
69 |
+
pip install spark-nlp
|
70 |
+
pip install pyspark
|
71 |
+
""", language="bash")
|
72 |
+
|
73 |
+
st.markdown("<p>Then, import Spark NLP and start a Spark session:</p>", unsafe_allow_html=True)
|
74 |
+
st.code("""
|
75 |
+
import sparknlp
|
76 |
+
|
77 |
+
# Start Spark Session
|
78 |
+
spark = sparknlp.start()
|
79 |
+
""", language='python')
|
80 |
+
|
81 |
+
# Example Usage with NerDL Model in Italian
|
82 |
+
st.markdown('<div class="sub-title">Example Usage with NerDL Model in Italian</div>', unsafe_allow_html=True)
|
83 |
+
st.markdown("""
|
84 |
+
<div class="section">
|
85 |
+
<p>Below is an example of how to set up and use the NerDL model for named entity recognition in Italian:</p>
|
86 |
+
</div>
|
87 |
+
""", unsafe_allow_html=True)
|
88 |
+
st.code('''
|
89 |
+
from sparknlp.base import *
|
90 |
+
from sparknlp.annotator import *
|
91 |
+
from pyspark.ml import Pipeline
|
92 |
+
from pyspark.sql.functions import col, expr, round, concat, lit
|
93 |
+
|
94 |
+
# Document Assembler
|
95 |
+
document_assembler = DocumentAssembler() \\
|
96 |
+
.setInputCol("text") \\
|
97 |
+
.setOutputCol("document")
|
98 |
+
|
99 |
+
# Tokenizer
|
100 |
+
tokenizer = Tokenizer() \\
|
101 |
+
.setInputCols(["document"]) \\
|
102 |
+
.setOutputCol("token")
|
103 |
+
|
104 |
+
# Word Embeddings
|
105 |
+
embeddings = WordEmbeddingsModel.pretrained('glove_840B_300', lang='xx') \\
|
106 |
+
.setInputCols(["document", "token"]) \\
|
107 |
+
.setOutputCol("embeddings")
|
108 |
+
|
109 |
+
# NerDL Model
|
110 |
+
ner_model = NerDLModel.pretrained('ner_wikiner_glove_840B_300', 'xx') \\
|
111 |
+
.setInputCols(["document", "token", "embeddings"]) \\
|
112 |
+
.setOutputCol("ner")
|
113 |
+
|
114 |
+
# NER Converter
|
115 |
+
ner_converter = NerConverter() \\
|
116 |
+
.setInputCols(["document", "token", "ner"]) \\
|
117 |
+
.setOutputCol("ner_chunk")
|
118 |
+
|
119 |
+
# Pipeline
|
120 |
+
pipeline = Pipeline(stages=[
|
121 |
+
document_assembler,
|
122 |
+
tokenizer,
|
123 |
+
embeddings,
|
124 |
+
ner_model,
|
125 |
+
ner_converter
|
126 |
+
])
|
127 |
+
|
128 |
+
# Example sentence
|
129 |
+
example = """
|
130 |
+
Giuseppe Verdi nacque a Le Roncole, una frazione di Busseto, il 10 ottobre 1813.
|
131 |
+
Era un compositore italiano, noto per le sue opere come La Traviata e Rigoletto.
|
132 |
+
"""
|
133 |
+
|
134 |
+
data = spark.createDataFrame([[example]]).toDF("text")
|
135 |
+
|
136 |
+
# Transforming data
|
137 |
+
result = pipeline.fit(data).transform(data)
|
138 |
+
|
139 |
+
# Select the result, entity, and confidence columns
|
140 |
+
result.select(
|
141 |
+
expr("explode(ner_chunk) as ner_chunk")
|
142 |
+
).select(
|
143 |
+
col("ner_chunk.result").alias("result"),
|
144 |
+
col("ner_chunk.metadata").getItem("entity").alias("entity"),
|
145 |
+
concat(
|
146 |
+
round((col("ner_chunk.metadata").getItem("confidence").cast("float") * 100), 2),
|
147 |
+
lit("%")
|
148 |
+
).alias("confidence")
|
149 |
+
).show(truncate=False)
|
150 |
+
''', language="python")
|
151 |
+
|
152 |
+
st.text("""
|
153 |
+
+--------------+------+----------+
|
154 |
+
|result |entity|confidence|
|
155 |
+
+--------------+------+----------+
|
156 |
+
|Giuseppe Verdi|PER |66.19% |
|
157 |
+
|Le Roncole |LOC |51.45% |
|
158 |
+
|Busseto |LOC |85.39% |
|
159 |
+
|La Traviata |MISC |69.35% |
|
160 |
+
|Rigoletto |MISC |93.34% |
|
161 |
+
+--------------+------+----------+
|
162 |
+
""")
|
163 |
+
|
164 |
+
# Benchmark Section
|
165 |
+
st.markdown('<div class="sub-title">Benchmark</div>', unsafe_allow_html=True)
|
166 |
+
st.markdown("""
|
167 |
+
<div class="section">
|
168 |
+
<p>Evaluating the performance of NER models is crucial to understanding their effectiveness in real-world applications. Below are the benchmark results for the "ner_wikiner_glove_840B_300" model on Italian text, focusing on various named entity categories. The metrics used include precision, recall, and F1-score, which are standard for evaluating classification models.</p>
|
169 |
+
</div>
|
170 |
+
""", unsafe_allow_html=True)
|
171 |
+
|
172 |
+
st.markdown("""
|
173 |
+
<div class="sub-title">Detailed Results</div>
|
174 |
+
|
175 |
+
| Entity Type | Precision | Recall | F1-Score | Support |
|
176 |
+
|-------------|:---------:|:------:|:--------:|--------:|
|
177 |
+
| **B-LOC** | 0.88 | 0.92 | 0.90 | 13,050 |
|
178 |
+
| **I-ORG** | 0.78 | 0.71 | 0.74 | 1,211 |
|
179 |
+
| **I-LOC** | 0.89 | 0.85 | 0.87 | 7,454 |
|
180 |
+
| **I-PER** | 0.93 | 0.94 | 0.94 | 4,539 |
|
181 |
+
| **B-ORG** | 0.88 | 0.72 | 0.79 | 2,222 |
|
182 |
+
| **B-PER** | 0.90 | 0.93 | 0.92 | 7,206 |
|
183 |
+
|
184 |
+
<div class="sub-title">Averages</div>
|
185 |
+
|
186 |
+
| Average Type | Precision | Recall | F1-Score | Support |
|
187 |
+
|--------------|:---------:|:------:|:--------:|--------:|
|
188 |
+
| **Micro** | 0.89 | 0.89 | 0.89 | 35,682 |
|
189 |
+
| **Macro** | 0.88 | 0.85 | 0.86 | 35,682 |
|
190 |
+
| **Weighted** | 0.89 | 0.89 | 0.89 | 35,682 |
|
191 |
+
|
192 |
+
<div class="sub-title">Category-Specific Performance</div>
|
193 |
+
|
194 |
+
| Category | Precision | Recall | F1-Score | Support |
|
195 |
+
|----------|:---------:|:------:|:--------:|--------:|
|
196 |
+
| **LOC** | 86.33% | 90.53% | 88.38 | 13,685 |
|
197 |
+
| **MISC** | 81.88% | 67.03% | 73.72 | 3,069 |
|
198 |
+
| **ORG** | 85.91% | 70.52% | 77.46 | 1,824 |
|
199 |
+
| **PER** | 89.54% | 92.08% | 90.79 | 7,410 |
|
200 |
+
|
201 |
+
<div class="sub-title">Additional Metrics</div>
|
202 |
+
|
203 |
+
- **Processed Tokens:** 349,242
|
204 |
+
- **Total Phrases:** 26,227
|
205 |
+
- **Found Phrases:** 25,988
|
206 |
+
- **Correct Phrases:** 22,529
|
207 |
+
- **Accuracy (non-O):** 85.99%
|
208 |
+
- **Overall Accuracy:** 98.06%
|
209 |
+
""", unsafe_allow_html=True)
|
210 |
+
|
211 |
+
# Summary
|
212 |
+
st.markdown('<div class="sub-title">Summary</div>', unsafe_allow_html=True)
|
213 |
+
st.markdown("""
|
214 |
+
<div class="section">
|
215 |
+
<p>In this article, we discussed named entity recognition using a deep learning-based method with the "wikiner_840B_300" model for Italian. We introduced how to perform the task using the open-source Spark NLP library with Python, which can be used at scale in the Spark ecosystem. These methods can be used for natural language processing applications in various fields, including finance and healthcare.</p>
|
216 |
+
</div>
|
217 |
+
""", unsafe_allow_html=True)
|
218 |
+
|
219 |
+
# References
|
220 |
+
st.markdown('<div class="sub-title">References</div>', unsafe_allow_html=True)
|
221 |
+
st.markdown("""
|
222 |
+
<div class="section">
|
223 |
+
<ul>
|
224 |
+
<li><a class="link" href="https://sparknlp.org/api/python/reference/autosummary/sparknlp/annotator/ner/ner_dl/index.html" target="_blank" rel="noopener">NerDLModel</a> annotator documentation</li>
|
225 |
+
<li>Model Used: <a class="link" href="https://sparknlp.org/2021/07/19/ner_wikiner_glove_840B_300_xx.html" target="_blank" rel="noopener">ner_wikiner_glove_840B_300</a></li>
|
226 |
+
<li><a class="link" href="https://nlp.johnsnowlabs.com/recognize_entitie" target="_blank" rel="noopener">Visualization demos for NER in Spark NLP</a></li>
|
227 |
+
<li><a class="link" href="https://www.johnsnowlabs.com/named-entity-recognition-ner-with-bert-in-spark-nlp/">Named Entity Recognition (NER) with BERT in Spark NLP</a></li>
|
228 |
+
</ul>
|
229 |
+
</div>
|
230 |
+
""", unsafe_allow_html=True)
|
231 |
+
|
232 |
+
# Community & Support
|
233 |
+
st.markdown('<div class="sub-title">Community & Support</div>', unsafe_allow_html=True)
|
234 |
+
st.markdown("""
|
235 |
+
<div class="section">
|
236 |
+
<ul>
|
237 |
+
<li><a class="link" href="https://sparknlp.org/" target="_blank">Official Website</a>: Documentation and examples</li>
|
238 |
+
<li><a class="link" href="https://join.slack.com/t/spark-nlp/shared_invite/zt-198dipu77-L3UWNe_AJf4Rqb3DaMb-7A" target="_blank">Slack Community</a>: Connect with other Spark NLP users</li>
|
239 |
+
<li><a class="link" href="https://github.com/JohnSnowLabs/spark-nlp" target="_blank">GitHub Repository</a>: Source code and issue tracker</li>
|
240 |
+
</ul>
|
241 |
+
</div>
|
242 |
+
""", unsafe_allow_html=True)
|
requirements.txt
ADDED
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
streamlit
|
2 |
+
st-annotated-text
|
3 |
+
pandas
|
4 |
+
numpy
|
5 |
+
spark-nlp
|
6 |
+
pyspark
|