Spaces:
Running
Running
Modernize: latest bertopic/streamlit, py3.12, cache_resource with full settings key, drop altair<5 pin
Browse files- README.md +1 -0
- app.py +26 -19
- requirements.txt +6 -3
README.md
CHANGED
|
@@ -4,6 +4,7 @@ emoji: 🅱️ 🇪 🇷 🇹
|
|
| 4 |
colorFrom: gray
|
| 5 |
colorTo: gray
|
| 6 |
sdk: streamlit
|
|
|
|
| 7 |
app_file: app.py
|
| 8 |
pinned: false
|
| 9 |
license: mit
|
|
|
|
| 4 |
colorFrom: gray
|
| 5 |
colorTo: gray
|
| 6 |
sdk: streamlit
|
| 7 |
+
python_version: "3.12"
|
| 8 |
app_file: app.py
|
| 9 |
pinned: false
|
| 10 |
license: mit
|
app.py
CHANGED
|
@@ -1,6 +1,5 @@
|
|
| 1 |
from bertopic import BERTopic
|
| 2 |
import streamlit as st
|
| 3 |
-
import streamlit.components.v1 as components
|
| 4 |
from datasets import load_dataset
|
| 5 |
import pandas as pd
|
| 6 |
from sentence_transformers import SentenceTransformer
|
|
@@ -93,27 +92,29 @@ form.form_submit_button("Submit")
|
|
| 93 |
|
| 94 |
|
| 95 |
|
| 96 |
-
@st.
|
| 97 |
def load_and_process_data(path, name, streaming, split_name, number_of_records):
|
| 98 |
-
dataset = load_dataset(path = path, name = name, streaming=streaming)
|
| 99 |
#return list(dataset)
|
| 100 |
dataset_head = dataset[split_name].take(number_of_records)
|
| 101 |
df = pd.DataFrame.from_dict(dataset_head)
|
| 102 |
return df
|
| 103 |
|
| 104 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 105 |
|
| 106 |
-
hdbscan_model = HDBSCAN(min_cluster_size=hdbscan_min_cluster_size, min_samples = hdbscan_min_samples, metric=hdbscan_metric, prediction_data=True)
|
| 107 |
-
if use_random_seed:
|
| 108 |
-
umap_model = UMAP(n_neighbors=umap_n_neighbors, n_components=umap_n_components, min_dist=umap_min_dist, metric=umap_metric, random_state = 42)
|
| 109 |
-
else:
|
| 110 |
-
umap_model = UMAP(n_neighbors=umap_n_neighbors, n_components=umap_n_components, min_dist=umap_min_dist, metric=umap_metric)
|
| 111 |
-
vectorizer_model = CountVectorizer(lowercase = cv_lowercase, ngram_range=(cv_ngram_min, cv_ngram_max), analyzer=cv_analyzer, max_df=cv_max_df, min_df=cv_min_df, stop_words="english")
|
| 112 |
-
|
| 113 |
-
|
| 114 |
-
|
| 115 |
-
@st.cache(allow_output_mutation=True)
|
| 116 |
-
def load_model(model_name, hdbscan_model=hdbscan_model, umap_model=umap_model, vectorizer_model=vectorizer_model, use_topic_reduction = use_topic_reduction, number_of_topics = number_of_topics):
|
| 117 |
sentence_model = SentenceTransformer(model_name)
|
| 118 |
if use_topic_reduction == "Auto":
|
| 119 |
kw_model = BERTopic(embedding_model=sentence_model, umap_model = umap_model, hdbscan_model = hdbscan_model, vectorizer_model = vectorizer_model, nr_topics = "auto", calculate_probabilities = True)
|
|
@@ -123,13 +124,19 @@ def load_model(model_name, hdbscan_model=hdbscan_model, umap_model=umap_model, v
|
|
| 123 |
kw_model = BERTopic(embedding_model=sentence_model, umap_model = umap_model, hdbscan_model = hdbscan_model, vectorizer_model = vectorizer_model, calculate_probabilities = True)
|
| 124 |
return kw_model
|
| 125 |
|
| 126 |
-
|
| 127 |
-
|
| 128 |
-
|
|
|
|
| 129 |
return topics, probs
|
| 130 |
|
| 131 |
|
| 132 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 133 |
|
| 134 |
df = load_and_process_data(dataset_name, dataset_name_2, True, split_name, number_of_records)
|
| 135 |
|
|
@@ -139,7 +146,7 @@ st.header("Original Dataset")
|
|
| 139 |
st.write(df)
|
| 140 |
|
| 141 |
|
| 142 |
-
topics, probs = fit_transform(model, X)
|
| 143 |
|
| 144 |
st.header("Topic assignment for each example")
|
| 145 |
st.write(topics)
|
|
|
|
| 1 |
from bertopic import BERTopic
|
| 2 |
import streamlit as st
|
|
|
|
| 3 |
from datasets import load_dataset
|
| 4 |
import pandas as pd
|
| 5 |
from sentence_transformers import SentenceTransformer
|
|
|
|
| 92 |
|
| 93 |
|
| 94 |
|
| 95 |
+
@st.cache_data
|
| 96 |
def load_and_process_data(path, name, streaming, split_name, number_of_records):
|
| 97 |
+
dataset = load_dataset(path = path, name = name or None, streaming=streaming)
|
| 98 |
#return list(dataset)
|
| 99 |
dataset_head = dataset[split_name].take(number_of_records)
|
| 100 |
df = pd.DataFrame.from_dict(dataset_head)
|
| 101 |
return df
|
| 102 |
|
| 103 |
|
| 104 |
+
## The sub-models are built inside the cached function so that every setting forms part
|
| 105 |
+
## of the cache key - st.cache_resource hashes arguments only, unlike legacy st.cache
|
| 106 |
+
@st.cache_resource
|
| 107 |
+
def load_model(model_name, use_topic_reduction, number_of_topics, use_random_seed,
|
| 108 |
+
hdbscan_min_cluster_size, hdbscan_min_samples, hdbscan_metric,
|
| 109 |
+
umap_n_neighbors, umap_n_components, umap_min_dist, umap_metric,
|
| 110 |
+
cv_lowercase, cv_ngram_min, cv_ngram_max, cv_analyzer, cv_max_df, cv_min_df):
|
| 111 |
+
hdbscan_model = HDBSCAN(min_cluster_size=hdbscan_min_cluster_size, min_samples = hdbscan_min_samples, metric=hdbscan_metric, prediction_data=True)
|
| 112 |
+
if use_random_seed:
|
| 113 |
+
umap_model = UMAP(n_neighbors=umap_n_neighbors, n_components=umap_n_components, min_dist=umap_min_dist, metric=umap_metric, random_state = 42)
|
| 114 |
+
else:
|
| 115 |
+
umap_model = UMAP(n_neighbors=umap_n_neighbors, n_components=umap_n_components, min_dist=umap_min_dist, metric=umap_metric)
|
| 116 |
+
vectorizer_model = CountVectorizer(lowercase = cv_lowercase, ngram_range=(cv_ngram_min, cv_ngram_max), analyzer=cv_analyzer, max_df=cv_max_df, min_df=cv_min_df, stop_words="english")
|
| 117 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 118 |
sentence_model = SentenceTransformer(model_name)
|
| 119 |
if use_topic_reduction == "Auto":
|
| 120 |
kw_model = BERTopic(embedding_model=sentence_model, umap_model = umap_model, hdbscan_model = hdbscan_model, vectorizer_model = vectorizer_model, nr_topics = "auto", calculate_probabilities = True)
|
|
|
|
| 124 |
kw_model = BERTopic(embedding_model=sentence_model, umap_model = umap_model, hdbscan_model = hdbscan_model, vectorizer_model = vectorizer_model, calculate_probabilities = True)
|
| 125 |
return kw_model
|
| 126 |
|
| 127 |
+
## _model is excluded from the cache key by the underscore; cache_key carries the settings
|
| 128 |
+
@st.cache_data(show_spinner="Fitting BERTopic...")
|
| 129 |
+
def fit_transform(_model, docs, cache_key):
|
| 130 |
+
topics, probs = _model.fit_transform(docs)
|
| 131 |
return topics, probs
|
| 132 |
|
| 133 |
|
| 134 |
+
model_settings = (model_name, use_topic_reduction, number_of_topics, use_random_seed,
|
| 135 |
+
hdbscan_min_cluster_size, hdbscan_min_samples, hdbscan_metric,
|
| 136 |
+
umap_n_neighbors, umap_n_components, umap_min_dist, umap_metric,
|
| 137 |
+
cv_lowercase, cv_ngram_min, cv_ngram_max, cv_analyzer, cv_max_df, cv_min_df)
|
| 138 |
+
|
| 139 |
+
model = load_model(*model_settings)
|
| 140 |
|
| 141 |
df = load_and_process_data(dataset_name, dataset_name_2, True, split_name, number_of_records)
|
| 142 |
|
|
|
|
| 146 |
st.write(df)
|
| 147 |
|
| 148 |
|
| 149 |
+
topics, probs = fit_transform(model, X, model_settings)
|
| 150 |
|
| 151 |
st.header("Topic assignment for each example")
|
| 152 |
st.write(topics)
|
requirements.txt
CHANGED
|
@@ -1,7 +1,10 @@
|
|
| 1 |
streamlit
|
| 2 |
-
pandas
|
| 3 |
bertopic
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4 |
datasets
|
|
|
|
| 5 |
numpy
|
| 6 |
-
|
| 7 |
-
altair<5
|
|
|
|
| 1 |
streamlit
|
|
|
|
| 2 |
bertopic
|
| 3 |
+
sentence-transformers
|
| 4 |
+
scikit-learn
|
| 5 |
+
umap-learn
|
| 6 |
+
hdbscan
|
| 7 |
datasets
|
| 8 |
+
pandas
|
| 9 |
numpy
|
| 10 |
+
plotly
|
|
|