bertrend 0.3.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- bertrend/BERTopicModel.py +320 -0
- bertrend/BERTrend.py +1211 -0
- bertrend/__init__.py +59 -0
- bertrend/config/bertopic_default_config.toml +48 -0
- bertrend/config/bertrend_default_config.toml +16 -0
- bertrend/config/parameters.py +92 -0
- bertrend/config/services_default_config.toml +32 -0
- bertrend/demos/__init__.py +4 -0
- bertrend/demos/demos_utils/__init__.py +13 -0
- bertrend/demos/demos_utils/data_loading_component.py +267 -0
- bertrend/demos/demos_utils/embed_documents_component.py +52 -0
- bertrend/demos/demos_utils/icons.py +41 -0
- bertrend/demos/demos_utils/messages.py +11 -0
- bertrend/demos/demos_utils/parameters_component.py +162 -0
- bertrend/demos/demos_utils/state_utils.py +99 -0
- bertrend/demos/start_summarizer_app.sh +9 -0
- bertrend/demos/start_topic_analysis_app.sh +9 -0
- bertrend/demos/start_weak_signals_app.sh +9 -0
- bertrend/demos/summarization/__init__.py +4 -0
- bertrend/demos/summarization/summarizer_app.py +98 -0
- bertrend/demos/topic_analysis/__init__.py +4 -0
- bertrend/demos/topic_analysis/app.py +87 -0
- bertrend/demos/topic_analysis/app_utils.py +69 -0
- bertrend/demos/topic_analysis/demo_pages/__init__.py +4 -0
- bertrend/demos/topic_analysis/demo_pages/explore_topics.py +455 -0
- bertrend/demos/topic_analysis/demo_pages/newsletters_generation.py +178 -0
- bertrend/demos/topic_analysis/demo_pages/temporal_visualizations.py +573 -0
- bertrend/demos/topic_analysis/demo_pages/topic_visualizations.py +280 -0
- bertrend/demos/topic_analysis/demo_pages/training_page.py +219 -0
- bertrend/demos/topic_analysis/messages.py +13 -0
- bertrend/demos/weak_signals/__init__.py +4 -0
- bertrend/demos/weak_signals/app.py +510 -0
- bertrend/demos/weak_signals/messages.py +32 -0
- bertrend/demos/weak_signals/visualizations_utils.py +403 -0
- bertrend/llm_utils/__init__.py +4 -0
- bertrend/llm_utils/newsletter.css +131 -0
- bertrend/llm_utils/newsletter_features.py +272 -0
- bertrend/llm_utils/openai_client.py +235 -0
- bertrend/llm_utils/prompts.py +94 -0
- bertrend/metrics/__init__.py +4 -0
- bertrend/metrics/temporal_metrics_embedding.py +861 -0
- bertrend/metrics/topic_metrics.py +199 -0
- bertrend/resources/common_ngrams.json +23 -0
- bertrend/resources/stopwords-en.json +3 -0
- bertrend/resources/stopwords-fr.json +1 -0
- bertrend/resources/stopwords-rte.json +15 -0
- bertrend/services/__init__.py +4 -0
- bertrend/services/authentication.py +66 -0
- bertrend/services/embedding_client.py +154 -0
- bertrend/services/embedding_service.py +380 -0
- bertrend/services/summarizer.py +45 -0
- bertrend/services/summary/__init__.py +4 -0
- bertrend/services/summary/abstractive_summarizer.py +74 -0
- bertrend/services/summary/chatgpt_summarizer.py +67 -0
- bertrend/services/summary/extractive_summarizer.py +368 -0
- bertrend/services/summary/lexrank.py +126 -0
- bertrend/services/summary/prompts.py +43 -0
- bertrend/tests/__init__.py +4 -0
- bertrend/tests/test_abstractive_summarizer.py +140 -0
- bertrend/tests/test_bertrend.py +1091 -0
- bertrend/tests/test_cache_utils.py +111 -0
- bertrend/tests/test_chatgpt_summarizer.py +150 -0
- bertrend/tests/test_config_utils.py +54 -0
- bertrend/tests/test_data_loading.py +326 -0
- bertrend/tests/test_data_structure.py +53 -0
- bertrend/tests/test_embedding_client.py +546 -0
- bertrend/tests/test_extractive_summarizer.py +250 -0
- bertrend/tests/test_installation.py +183 -0
- bertrend/tests/test_newsletter_features.py +354 -0
- bertrend/tests/test_openai_client.py +210 -0
- bertrend/tests/test_representative_docs.py +125 -0
- bertrend/tests/test_summarizer.py +115 -0
- bertrend/tests/test_temporal_metrics_embedding.py +349 -0
- bertrend/tests/test_topic_description.py +159 -0
- bertrend/tests/test_topic_metrics.py +233 -0
- bertrend/tests/test_topic_model.py +285 -0
- bertrend/tests/test_trend_analysis_data_structure.py +174 -0
- bertrend/tests/test_trend_analysis_prompts.py +225 -0
- bertrend/tests/test_trend_analysis_visualizations.py +307 -0
- bertrend/tests/test_trend_analysis_weak_signals.py +598 -0
- bertrend/tests/test_utils_init.py +70 -0
- bertrend/tests/test_visualizations.py +306 -0
- bertrend/topic_analysis/__init__.py +4 -0
- bertrend/topic_analysis/data_structure.py +13 -0
- bertrend/topic_analysis/prompts.py +42 -0
- bertrend/topic_analysis/representative_docs.py +57 -0
- bertrend/topic_analysis/topic_description.py +66 -0
- bertrend/topic_analysis/visualizations.py +315 -0
- bertrend/trend_analysis/__init__.py +4 -0
- bertrend/trend_analysis/data_structure.py +78 -0
- bertrend/trend_analysis/prompts.py +229 -0
- bertrend/trend_analysis/signal_llm_template_en.html +181 -0
- bertrend/trend_analysis/signal_llm_template_fr.html +181 -0
- bertrend/trend_analysis/visualizations.py +605 -0
- bertrend/trend_analysis/weak_signals.py +425 -0
- bertrend/utils/__init__.py +31 -0
- bertrend/utils/cache_utils.py +31 -0
- bertrend/utils/config_utils.py +41 -0
- bertrend/utils/data_loading.py +329 -0
- bertrend-0.3.1.dist-info/AUTHORS.txt +15 -0
- bertrend-0.3.1.dist-info/LICENSE.md +373 -0
- bertrend-0.3.1.dist-info/METADATA +400 -0
- bertrend-0.3.1.dist-info/RECORD +181 -0
- bertrend-0.3.1.dist-info/WHEEL +4 -0
- bertrend_apps/__init__.py +4 -0
- bertrend_apps/common/__init__.py +4 -0
- bertrend_apps/common/crontab_utils.py +113 -0
- bertrend_apps/common/mail_utils.py +91 -0
- bertrend_apps/config/feeds/arxiv_feed.toml +15 -0
- bertrend_apps/config/feeds/decarbonation_feed.toml +15 -0
- bertrend_apps/config/feeds/llm_en_feed.toml +15 -0
- bertrend_apps/config/feeds/llm_feed.toml +16 -0
- bertrend_apps/config/feeds/nlp_feed.toml +15 -0
- bertrend_apps/config/feeds/rte_feed.toml +15 -0
- bertrend_apps/config/gmail_credentials.json +1 -0
- bertrend_apps/config/newsletters/arxiv_newsletter_from_last.toml +39 -0
- bertrend_apps/config/newsletters/arxiv_newsletter_from_scratch.toml +39 -0
- bertrend_apps/config/newsletters/decarbonation_newsletter_from_last.toml +38 -0
- bertrend_apps/config/newsletters/decarbonation_newsletter_from_scratch.toml +38 -0
- bertrend_apps/config/newsletters/llm_en_newsletter_from_last.toml +38 -0
- bertrend_apps/config/newsletters/llm_newsletter_from_last.toml +39 -0
- bertrend_apps/config/newsletters/nlp_newsletter_from_last.toml +38 -0
- bertrend_apps/config/newsletters/rte_newsletter_from_last.toml +38 -0
- bertrend_apps/config/newsletters/rte_newsletter_from_scratch.toml +38 -0
- bertrend_apps/data_provider/__init__.py +9 -0
- bertrend_apps/data_provider/__main__.py +237 -0
- bertrend_apps/data_provider/arxiv_provider.py +161 -0
- bertrend_apps/data_provider/bing_news_provider.py +82 -0
- bertrend_apps/data_provider/curebot_provider.py +105 -0
- bertrend_apps/data_provider/data_provider.py +194 -0
- bertrend_apps/data_provider/google_news_provider.py +94 -0
- bertrend_apps/data_provider/newscatcher_provider.py +74 -0
- bertrend_apps/data_provider/utils.py +165 -0
- bertrend_apps/exploration/__init__.py +4 -0
- bertrend_apps/exploration/curebot/__init__.py +4 -0
- bertrend_apps/exploration/curebot/app.py +45 -0
- bertrend_apps/exploration/curebot/app_utils.py +317 -0
- bertrend_apps/exploration/curebot/config.toml +33 -0
- bertrend_apps/exploration/curebot/import_extraction_article.ipynb +108 -0
- bertrend_apps/exploration/curebot/old_veille_analyse.py +298 -0
- bertrend_apps/exploration/curebot/prompts.py +24 -0
- bertrend_apps/exploration/curebot/start_newsletter_generator.sh +8 -0
- bertrend_apps/exploration/curebot/tabs/tab1.py +150 -0
- bertrend_apps/exploration/curebot/tabs/tab2.py +95 -0
- bertrend_apps/exploration/curebot/tabs/tab3.py +125 -0
- bertrend_apps/exploration/dataviz/Main_page.py +10 -0
- bertrend_apps/exploration/dataviz/__init__.py +4 -0
- bertrend_apps/exploration/dataviz/pages/1_Data_feeds.py +105 -0
- bertrend_apps/exploration/geolocalization/__init__.py +4 -0
- bertrend_apps/exploration/geolocalization/entity_utils.py +118 -0
- bertrend_apps/exploration/geolocalization/spacy/__init__.py +4 -0
- bertrend_apps/exploration/geolocalization/spacy/common_factory.py +142 -0
- bertrend_apps/exploration/geolocalization/spacy/dbpedia.py +206 -0
- bertrend_apps/exploration/geolocalization/spacy/nlp.config +37 -0
- bertrend_apps/exploration/geolocalization/spacy/utils.py +39 -0
- bertrend_apps/install_feeds_and_newsletters.py +29 -0
- bertrend_apps/newsletters/__init__.py +4 -0
- bertrend_apps/newsletters/__main__.py +277 -0
- bertrend_apps/prospective_demo/.streamlit/config.toml +3 -0
- bertrend_apps/prospective_demo/.streamlit/secrets.toml +9 -0
- bertrend_apps/prospective_demo/__init__.py +70 -0
- bertrend_apps/prospective_demo/app.py +111 -0
- bertrend_apps/prospective_demo/authentication.py +44 -0
- bertrend_apps/prospective_demo/dashboard_analysis.py +132 -0
- bertrend_apps/prospective_demo/dashboard_common.py +79 -0
- bertrend_apps/prospective_demo/dashboard_signals.py +226 -0
- bertrend_apps/prospective_demo/feeds_common.py +38 -0
- bertrend_apps/prospective_demo/feeds_config.py +261 -0
- bertrend_apps/prospective_demo/feeds_data.py +95 -0
- bertrend_apps/prospective_demo/i18n.py +136 -0
- bertrend_apps/prospective_demo/llm_utils.py +34 -0
- bertrend_apps/prospective_demo/models_info.py +361 -0
- bertrend_apps/prospective_demo/perf_utils.py +23 -0
- bertrend_apps/prospective_demo/process_new_data.py +348 -0
- bertrend_apps/prospective_demo/report_generation.py +214 -0
- bertrend_apps/prospective_demo/report_template.html +148 -0
- bertrend_apps/prospective_demo/report_utils.py +132 -0
- bertrend_apps/prospective_demo/start_demo.sh +9 -0
- bertrend_apps/prospective_demo/streamlit_utils.py +37 -0
- bertrend_apps/start_apps.sh +15 -0
- bertrend_apps/stop_apps.sh +11 -0
bertrend/__init__.py
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# Copyright (c) 2024, RTE (https://www.rte-france.com)
|
|
2
|
+
# See AUTHORS.txt
|
|
3
|
+
# SPDX-License-Identifier: MPL-2.0
|
|
4
|
+
# This file is part of BERTrend.
|
|
5
|
+
import os
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
|
|
8
|
+
from bertrend.utils.config_utils import load_toml_config
|
|
9
|
+
|
|
10
|
+
# Default config files path
|
|
11
|
+
BERTOPIC_DEFAULT_CONFIG_PATH = (
|
|
12
|
+
Path(__file__).parent / "config" / "bertopic_default_config.toml"
|
|
13
|
+
)
|
|
14
|
+
BERTREND_DEFAULT_CONFIG_PATH = (
|
|
15
|
+
Path(__file__).parent / "config" / "bertrend_default_config.toml"
|
|
16
|
+
)
|
|
17
|
+
SERVICES_DEFAULT_CONFIG_PATH = (
|
|
18
|
+
Path(__file__).parent / "config" / "services_default_config.toml"
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
# Read config
|
|
22
|
+
BERTOPIC_CONFIG = load_toml_config(BERTOPIC_DEFAULT_CONFIG_PATH)
|
|
23
|
+
BERTREND_CONFIG = load_toml_config(BERTREND_DEFAULT_CONFIG_PATH)
|
|
24
|
+
SERVICES_CONFIG = load_toml_config(SERVICES_DEFAULT_CONFIG_PATH)
|
|
25
|
+
|
|
26
|
+
EMBEDDING_CONFIG = SERVICES_CONFIG["embedding_service"]
|
|
27
|
+
LLM_CONFIG = SERVICES_CONFIG["llm_service"]
|
|
28
|
+
|
|
29
|
+
# Linux command to find the index of the GPU device currently less used than the others
|
|
30
|
+
BEST_CUDA_DEVICE = r"\`nvidia-smi --query-gpu=index,memory.used --format=csv,nounits | tail -n +2 | sort -t',' -k2 -n | head -n 1 | cut -d',' -f1\`"
|
|
31
|
+
|
|
32
|
+
BERTREND_BASE_DIR = os.getenv("BERTREND_BASE_DIR", None)
|
|
33
|
+
BASE_PATH = (
|
|
34
|
+
Path(BERTREND_BASE_DIR)
|
|
35
|
+
if BERTREND_BASE_DIR
|
|
36
|
+
else Path(__file__).parent.parent.parent
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
# Base dirs
|
|
40
|
+
DATA_PATH = BASE_PATH / "data"
|
|
41
|
+
CACHE_PATH = BASE_PATH / "cache"
|
|
42
|
+
OUTPUT_PATH = BASE_PATH / "output"
|
|
43
|
+
CONFIG_PATH = BASE_PATH / "config"
|
|
44
|
+
|
|
45
|
+
FEED_BASE_PATH = DATA_PATH / "feeds"
|
|
46
|
+
BERTREND_LOG_PATH = BASE_PATH / "logs"
|
|
47
|
+
|
|
48
|
+
# Weak signals
|
|
49
|
+
MODELS_DIR = CACHE_PATH / "models"
|
|
50
|
+
ZEROSHOT_TOPICS_DATA_DIR = CACHE_PATH / "zeroshot_topics_data"
|
|
51
|
+
SIGNAL_EVOLUTION_DATA_DIR = CACHE_PATH / "signal_evolution_data"
|
|
52
|
+
|
|
53
|
+
# Create directories if they do not exist
|
|
54
|
+
DATA_PATH.mkdir(parents=True, exist_ok=True)
|
|
55
|
+
OUTPUT_PATH.mkdir(parents=True, exist_ok=True)
|
|
56
|
+
CACHE_PATH.mkdir(parents=True, exist_ok=True)
|
|
57
|
+
CONFIG_PATH.mkdir(parents=True, exist_ok=True)
|
|
58
|
+
BERTREND_LOG_PATH.mkdir(parents=True, exist_ok=True)
|
|
59
|
+
MODELS_DIR.mkdir(parents=True, exist_ok=True)
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Default configuration file to be used for topic model
|
|
2
|
+
|
|
3
|
+
# Global parameters
|
|
4
|
+
[global]
|
|
5
|
+
language = "French"
|
|
6
|
+
|
|
7
|
+
# BERTopic parameters: https://maartengr.github.io/BERTopic/api/bertopic.html#bertopic._bertopic.BERTopic.__init__
|
|
8
|
+
[bertopic_model]
|
|
9
|
+
top_n_words = 10
|
|
10
|
+
verbose = true
|
|
11
|
+
representation_model = ["MaximalMarginalRelevance"] # KeyBERTInspired, OpenAI
|
|
12
|
+
zeroshot_topic_list = []
|
|
13
|
+
zeroshot_min_similarity = 0
|
|
14
|
+
|
|
15
|
+
# UMAP parameters: https://umap-learn.readthedocs.io/en/latest/api.html
|
|
16
|
+
[umap_model]
|
|
17
|
+
n_neighbors = 5
|
|
18
|
+
n_components = 5
|
|
19
|
+
min_dist = 0.0
|
|
20
|
+
metric = "cosine"
|
|
21
|
+
random_state = 42
|
|
22
|
+
|
|
23
|
+
# HDBSCAN parameters: https://hdbscan.readthedocs.io/en/latest/api.html
|
|
24
|
+
[hdbscan_model]
|
|
25
|
+
min_cluster_size = 5
|
|
26
|
+
min_samples = 5
|
|
27
|
+
metric = "euclidean"
|
|
28
|
+
cluster_selection_method = "eom"
|
|
29
|
+
prediction_data = true
|
|
30
|
+
|
|
31
|
+
# CountVectorizer: https://scikit-learn.org/1.5/modules/generated/sklearn.feature_extraction.text.CountVectorizer.html
|
|
32
|
+
[vectorizer_model]
|
|
33
|
+
ngram_range = [1, 1]
|
|
34
|
+
stop_words = true # If true, will check `language` parameter and load associated stopwords file
|
|
35
|
+
min_df = 2
|
|
36
|
+
|
|
37
|
+
# ClassTfidfTransformer: https://maartengr.github.io/BERTopic/api/ctfidf.html
|
|
38
|
+
[ctfidf_model]
|
|
39
|
+
bm25_weighting = false
|
|
40
|
+
reduce_frequent_words = true
|
|
41
|
+
|
|
42
|
+
# MaximalMarginalRelevance: https://maartengr.github.io/BERTopic/api/representation/mmr.html
|
|
43
|
+
[mmr_model]
|
|
44
|
+
diversity = 0.3
|
|
45
|
+
|
|
46
|
+
# Reduce outliers: https://maartengr.github.io/BERTopic/api/bertopic.html#bertopic._bertopic.BERTopic.reduce_outliers
|
|
47
|
+
[reduce_outliers]
|
|
48
|
+
strategy = "c-tf-idf"
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Copyright (c) 2024, RTE (https://www.rte-france.com)
|
|
2
|
+
# See AUTHORS.txt
|
|
3
|
+
# SPDX-License-Identifier: MPL-2.0
|
|
4
|
+
# This file is part of BERTrend.
|
|
5
|
+
|
|
6
|
+
# BERTrend Hyperparameters
|
|
7
|
+
|
|
8
|
+
# Data split settings
|
|
9
|
+
granularity = 2
|
|
10
|
+
# Merge model settings
|
|
11
|
+
min_similarity = 0.7
|
|
12
|
+
# Signal popularity settings
|
|
13
|
+
decay_factor = 0.01
|
|
14
|
+
decay_power = 2
|
|
15
|
+
signal_classif_lower_bound = 10
|
|
16
|
+
signal_classif_upper_bound = 75
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# Copyright (c) 2024, RTE (https://www.rte-france.com)
|
|
2
|
+
# See AUTHORS.txt
|
|
3
|
+
# SPDX-License-Identifier: MPL-2.0
|
|
4
|
+
# This file is part of BERTrend.
|
|
5
|
+
|
|
6
|
+
import json
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
|
|
9
|
+
import torch
|
|
10
|
+
|
|
11
|
+
from bertrend import BERTREND_CONFIG, EMBEDDING_CONFIG
|
|
12
|
+
|
|
13
|
+
stopwords_en_file = Path(__file__).parent.parent / "resources" / "stopwords-en.json"
|
|
14
|
+
stopwords_fr_file = Path(__file__).parent.parent / "resources" / "stopwords-fr.json"
|
|
15
|
+
stopwords_rte_file = Path(__file__).parent.parent / "resources" / "stopwords-rte.json"
|
|
16
|
+
common_ngrams_file = Path(__file__).parent.parent / "resources" / "common_ngrams.json"
|
|
17
|
+
with open(stopwords_en_file, "r", encoding="utf-8") as file:
|
|
18
|
+
ENGLISH_STOPWORDS = json.load(file)
|
|
19
|
+
with open(stopwords_fr_file, "r", encoding="utf-8") as file:
|
|
20
|
+
FRENCH_STOPWORDS = json.load(file)
|
|
21
|
+
with open(stopwords_rte_file, "r", encoding="utf-8") as file:
|
|
22
|
+
STOP_WORDS_RTE = json.load(file)
|
|
23
|
+
with open(common_ngrams_file, "r", encoding="utf-8") as file:
|
|
24
|
+
COMMON_NGRAMS = json.load(file)
|
|
25
|
+
|
|
26
|
+
STOPWORDS = STOP_WORDS_RTE + COMMON_NGRAMS + FRENCH_STOPWORDS
|
|
27
|
+
|
|
28
|
+
# File names
|
|
29
|
+
STATE_FILE = "app_state.pkl"
|
|
30
|
+
EMBEDDINGS_FILE = "embeddings.npy"
|
|
31
|
+
BERTREND_FILE = "bertrend.dill"
|
|
32
|
+
DOC_INFO_DF_FILE = "doc_info_df.pkl"
|
|
33
|
+
TOPIC_INFO_DF_FILE = "topic_info_df.pkl"
|
|
34
|
+
|
|
35
|
+
# Model file names
|
|
36
|
+
ZEROSHOT_TOPICS_DATA_FILE = "zeroshot_topics_data.json"
|
|
37
|
+
INDIVIDUAL_MODEL_TOPIC_COUNTS_FILE = "individual_topic_counts.json"
|
|
38
|
+
CUMULATIVE_MERGED_TOPIC_COUNTS_FILE = "cumulative_topic_counts.json"
|
|
39
|
+
|
|
40
|
+
# Embedding models
|
|
41
|
+
ENGLISH_EMBEDDING_MODELS = [
|
|
42
|
+
"all-mpnet-base-v2",
|
|
43
|
+
"Alibaba-NLP/gte-base-en-v1.5",
|
|
44
|
+
"all-MiniLM-L12-v2",
|
|
45
|
+
]
|
|
46
|
+
FRENCH_EMBEDDING_MODELS = [
|
|
47
|
+
"OrdalieTech/Solon-embeddings-base-0.1",
|
|
48
|
+
"OrdalieTech/Solon-embeddings-large-0.1",
|
|
49
|
+
"dangvantuan/sentence-camembert-large",
|
|
50
|
+
"antoinelouis/biencoder-distilcamembert-mmarcoFR",
|
|
51
|
+
]
|
|
52
|
+
|
|
53
|
+
# MODEL REPRESENTATIONS
|
|
54
|
+
MMR_REPRESENTATION_MODEL = "MaximalMarginalRelevance"
|
|
55
|
+
KEYBERTINSPIRED_REPRESENTATION_MODEL = "KeyBERTInspired"
|
|
56
|
+
OPENAI_REPRESENTATION_MODEL = "OpenAI"
|
|
57
|
+
|
|
58
|
+
# BERTopic Hyperparameters
|
|
59
|
+
BERTOPIC_SERIALIZATION = "safetensors" # or pickle
|
|
60
|
+
LANGUAGES = ["French", "English"]
|
|
61
|
+
REPRESENTATION_MODELS = [
|
|
62
|
+
MMR_REPRESENTATION_MODEL,
|
|
63
|
+
KEYBERTINSPIRED_REPRESENTATION_MODEL,
|
|
64
|
+
OPENAI_REPRESENTATION_MODEL,
|
|
65
|
+
]
|
|
66
|
+
|
|
67
|
+
# BERTrend parameters
|
|
68
|
+
SIGNAL_CLASSIF_LOWER_BOUND = BERTREND_CONFIG["signal_classif_lower_bound"]
|
|
69
|
+
SIGNAL_CLASSIF_UPPER_BOUND = BERTREND_CONFIG["signal_classif_upper_bound"]
|
|
70
|
+
|
|
71
|
+
# Embedding Settings
|
|
72
|
+
EMBEDDING_DTYPES = EMBEDDING_CONFIG["embedding_dtypes"]
|
|
73
|
+
EMBEDDING_BATCH_SIZE = EMBEDDING_CONFIG["embedding_batch_size"]
|
|
74
|
+
EMBEDDING_MAX_SEQ_LENGTH = EMBEDDING_CONFIG["embedding_max_seq_length"]
|
|
75
|
+
EMBEDDING_DEVICE = "cuda" if torch.cuda.is_available() else "cpu"
|
|
76
|
+
|
|
77
|
+
# Representation models parameters
|
|
78
|
+
KEYBERT_NR_REPR_DOCS = (5,)
|
|
79
|
+
KEYBERT_NR_CANDIDATE_WORDS = (40,)
|
|
80
|
+
KEYBERT_TOP_N_WORDS = 20
|
|
81
|
+
OPENAI_NR_DOCS = 5
|
|
82
|
+
|
|
83
|
+
# Data Processing
|
|
84
|
+
MIN_CHARS_DEFAULT = 1
|
|
85
|
+
SAMPLE_SIZE_DEFAULT = 1.0 # Or whatever default you want, None means all documents
|
|
86
|
+
|
|
87
|
+
# Time Settings
|
|
88
|
+
DEFAULT_WINDOW_SIZE = 7 # days
|
|
89
|
+
MAX_WINDOW_SIZE = 365 # days
|
|
90
|
+
|
|
91
|
+
# Data Analysis Settings
|
|
92
|
+
POPULARITY_THRESHOLD = 0.1 # for weak signal detection, if applicable
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Copyright (c) 2024, RTE (https://www.rte-france.com)
|
|
2
|
+
# See AUTHORS.txt
|
|
3
|
+
# SPDX-License-Identifier: MPL-2.0
|
|
4
|
+
# This file is part of BERTrend.
|
|
5
|
+
|
|
6
|
+
# Embedding service parameters
|
|
7
|
+
[embedding_service]
|
|
8
|
+
# Indicates if BERTrend shall use a local embedding service (run by BERTrend) or if the embedding service
|
|
9
|
+
# is delegated to an external service. If set to false, the other properties shall be set properly.
|
|
10
|
+
# It is generally more efficient to use a dedicated service for embeddings.
|
|
11
|
+
use_local = true
|
|
12
|
+
model_name = "OrdalieTech/Solon-embeddings-large-0.1"
|
|
13
|
+
url = "https://10.132.5.44:6464"
|
|
14
|
+
embedding_dtypes = ["float32", "float16", "bfloat16"]
|
|
15
|
+
embedding_batch_size = 2048
|
|
16
|
+
embedding_max_seq_length = 512
|
|
17
|
+
|
|
18
|
+
# LLM service parameters
|
|
19
|
+
[llm_service]
|
|
20
|
+
# Specifies here the information about the LLM to be used to benefit from some LLM features such as
|
|
21
|
+
# improved topic description and topic analysis over time
|
|
22
|
+
# If empty, these features will not be available
|
|
23
|
+
# BERTrend can use any kind of openai-compatible deployment such as
|
|
24
|
+
# - local LLM deployed with VLLM or similar libraries
|
|
25
|
+
# - the official OpenAI endpoint
|
|
26
|
+
# - models deployed on Azure cloud
|
|
27
|
+
api_key = "$AZURE_SE_WATTELSE_OPENAI_API_KEY_DEV"
|
|
28
|
+
endpoint = "$AZURE_SE_WATTELSE_OPENAI_ENDPOINT_DEV"
|
|
29
|
+
model = "$AZURE_SE_WATTELSE_OPENAI_DEFAULT_MODEL_NAME_DEV"
|
|
30
|
+
temperature = 0.1
|
|
31
|
+
max_output_tokens = 2048
|
|
32
|
+
system_prompt = "You are a helpful assistant, skilled in detailing topic evolution over time for the detection of emerging trends and signals."
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Copyright (c) 2024, RTE (https://www.rte-france.com)
|
|
2
|
+
# See AUTHORS.txt
|
|
3
|
+
# SPDX-License-Identifier: MPL-2.0
|
|
4
|
+
# This file is part of BERTrend.
|
|
5
|
+
import streamlit as st
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def is_admin_mode() -> bool:
|
|
9
|
+
"""Indicates whether the application is in an admin mode."""
|
|
10
|
+
admin_param = st.query_params.get("admin")
|
|
11
|
+
if not admin_param:
|
|
12
|
+
return False
|
|
13
|
+
return admin_param.lower() == "true"
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
# Copyright (c) 2024, RTE (https://www.rte-france.com)
|
|
2
|
+
# See AUTHORS.txt
|
|
3
|
+
# SPDX-License-Identifier: MPL-2.0
|
|
4
|
+
# This file is part of BERTrend.
|
|
5
|
+
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
from tempfile import TemporaryDirectory
|
|
8
|
+
|
|
9
|
+
import pandas as pd
|
|
10
|
+
import streamlit as st
|
|
11
|
+
from streamlit.runtime.uploaded_file_manager import UploadedFile
|
|
12
|
+
|
|
13
|
+
from bertrend import DATA_PATH
|
|
14
|
+
from bertrend.demos.demos_utils.icons import (
|
|
15
|
+
WARNING_ICON,
|
|
16
|
+
JSON_ICON,
|
|
17
|
+
CSV_ICON,
|
|
18
|
+
PARQUET_ICON,
|
|
19
|
+
XLSX_ICON,
|
|
20
|
+
CLIENT_STORAGE_ICON,
|
|
21
|
+
SERVER_STORAGE_ICON,
|
|
22
|
+
)
|
|
23
|
+
from bertrend.demos.demos_utils.messages import NO_DATA_AFTER_PREPROCESSING_MESSAGE
|
|
24
|
+
from bertrend.demos.demos_utils.state_utils import (
|
|
25
|
+
save_widget_state,
|
|
26
|
+
register_widget,
|
|
27
|
+
SessionStateManager,
|
|
28
|
+
)
|
|
29
|
+
from bertrend.config.parameters import MIN_CHARS_DEFAULT, SAMPLE_SIZE_DEFAULT
|
|
30
|
+
from bertrend.utils.data_loading import (
|
|
31
|
+
find_compatible_files,
|
|
32
|
+
TEXT_COLUMN,
|
|
33
|
+
load_data,
|
|
34
|
+
split_data,
|
|
35
|
+
TIMESTAMP_COLUMN,
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
NO_DATASET_WARNING = "Please select at least one dataset to proceed."
|
|
39
|
+
FORMAT_ICONS = {
|
|
40
|
+
"xlsx": XLSX_ICON,
|
|
41
|
+
"csv": CSV_ICON,
|
|
42
|
+
"parquet": PARQUET_ICON,
|
|
43
|
+
"json": JSON_ICON,
|
|
44
|
+
"jsonl": JSON_ICON,
|
|
45
|
+
"jsonlines": JSON_ICON,
|
|
46
|
+
"jsonl.gz": JSON_ICON,
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def _process_uploaded_files(
|
|
51
|
+
files: list[UploadedFile],
|
|
52
|
+
) -> list[pd.DataFrame]:
|
|
53
|
+
"""Read a list of uploaded files and return a list of dataframes containing the associated data"""
|
|
54
|
+
dataframes = []
|
|
55
|
+
with TemporaryDirectory() as tmpdir:
|
|
56
|
+
for f in files:
|
|
57
|
+
with open(tmpdir + "/" + f.name, "wb") as tmp_file:
|
|
58
|
+
tmp_file.write(f.getvalue())
|
|
59
|
+
if tmp_file is not None:
|
|
60
|
+
df = load_data(
|
|
61
|
+
Path(tmp_file.name),
|
|
62
|
+
SessionStateManager.get("language", "French"),
|
|
63
|
+
)
|
|
64
|
+
if df is not None:
|
|
65
|
+
dataframes.append(df)
|
|
66
|
+
return dataframes
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def _load_files(
|
|
70
|
+
files: list[Path],
|
|
71
|
+
) -> list[pd.DataFrame]:
|
|
72
|
+
"""Read a list of files from storage and return a list of dataframes containing the associated data"""
|
|
73
|
+
dfs = []
|
|
74
|
+
for selected_file in files:
|
|
75
|
+
file_path = DATA_PATH / selected_file
|
|
76
|
+
df = load_data(
|
|
77
|
+
file_path,
|
|
78
|
+
SessionStateManager.get("language", "French"),
|
|
79
|
+
)
|
|
80
|
+
if df is not None:
|
|
81
|
+
dfs.append(df)
|
|
82
|
+
return dfs
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
# TODO: if loaded data column names do not match our default values, show a popup for column data mapping
|
|
86
|
+
def display_data_loading_component():
|
|
87
|
+
"""
|
|
88
|
+
Component for a streamlit app about topic modelling. It allows to choose data to load and preprocess data.
|
|
89
|
+
Preprocessing of data includes:
|
|
90
|
+
- concatenation of data from different files
|
|
91
|
+
- adding potentially missing columns to make all datasets homogeneous
|
|
92
|
+
- removal of duplicates
|
|
93
|
+
- splitting the dataset by paragraphs to avoid too long textes
|
|
94
|
+
- filtering based on timestamp range
|
|
95
|
+
- filtering based on a minimum number of characters
|
|
96
|
+
|
|
97
|
+
The initial dataframe (one line per document) is stored after filtering of bad data inside a Streamlit state
|
|
98
|
+
variable "initial_df". After split by paragraph, it is stored in "df_split". The final dataframe (possibly
|
|
99
|
+
split by paragraph from initial documents and in all cases filtered by dates) is stored inside the Streamlit
|
|
100
|
+
state variable "time_filtered_df".
|
|
101
|
+
"""
|
|
102
|
+
# Data loading section
|
|
103
|
+
st.header("Data loading")
|
|
104
|
+
|
|
105
|
+
# Find files in the current directory and subdirectories
|
|
106
|
+
tab1, tab2 = st.tabs(
|
|
107
|
+
[
|
|
108
|
+
CLIENT_STORAGE_ICON + " Data from local storage",
|
|
109
|
+
SERVER_STORAGE_ICON + " Data from server data",
|
|
110
|
+
]
|
|
111
|
+
)
|
|
112
|
+
compatible_extensions = FORMAT_ICONS.keys()
|
|
113
|
+
|
|
114
|
+
with tab1:
|
|
115
|
+
st.file_uploader(
|
|
116
|
+
label="Select dataset from local storage (.xlsx, .csv, .json, .jsonl, .parquet)",
|
|
117
|
+
type=compatible_extensions,
|
|
118
|
+
accept_multiple_files=True,
|
|
119
|
+
help="Drag and drop files to be used as dataset in this area",
|
|
120
|
+
on_change=save_widget_state,
|
|
121
|
+
key="uploaded_files",
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
with tab2:
|
|
125
|
+
register_widget("selected_files")
|
|
126
|
+
st.multiselect(
|
|
127
|
+
label="Select one or more datasets from the server data",
|
|
128
|
+
options=find_compatible_files(DATA_PATH, compatible_extensions),
|
|
129
|
+
default=SessionStateManager.get("selected_files", []),
|
|
130
|
+
key="selected_files",
|
|
131
|
+
format_func=lambda x: FORMAT_ICONS[x.suffix.lstrip(".")] + " " + str(x),
|
|
132
|
+
on_change=save_widget_state,
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
if (
|
|
136
|
+
not SessionStateManager.get("uploaded_files", [])
|
|
137
|
+
and not SessionStateManager.get("selected_files")
|
|
138
|
+
and "initial_df" not in st.session_state
|
|
139
|
+
):
|
|
140
|
+
st.warning(NO_DATASET_WARNING, icon=WARNING_ICON)
|
|
141
|
+
st.stop()
|
|
142
|
+
|
|
143
|
+
# Load each selected file, then concatenate them
|
|
144
|
+
# Priority to local data if both are set
|
|
145
|
+
dfs = None
|
|
146
|
+
if SessionStateManager.get("uploaded_files"):
|
|
147
|
+
dfs = _process_uploaded_files(
|
|
148
|
+
SessionStateManager.get("uploaded_files"),
|
|
149
|
+
)
|
|
150
|
+
elif SessionStateManager.get("selected_files"):
|
|
151
|
+
dfs = _load_files(
|
|
152
|
+
SessionStateManager.get("selected_files"),
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
# If DataFrames found, concatenate them
|
|
156
|
+
if dfs:
|
|
157
|
+
# Concatenate DataFrames
|
|
158
|
+
df = pd.concat(dfs, ignore_index=True)
|
|
159
|
+
|
|
160
|
+
# Save state of initial DF (before split and data selection)
|
|
161
|
+
st.session_state["initial_df"] = df.copy()
|
|
162
|
+
# If dfs is None and there is no 'initial_df' in session_state, show warining
|
|
163
|
+
elif "initial_df" not in st.session_state:
|
|
164
|
+
st.warning(
|
|
165
|
+
NO_DATA_AFTER_PREPROCESSING_MESSAGE,
|
|
166
|
+
icon=WARNING_ICON,
|
|
167
|
+
)
|
|
168
|
+
st.stop()
|
|
169
|
+
# If dfs is None but there is initial_df, set it
|
|
170
|
+
else:
|
|
171
|
+
df = st.session_state["initial_df"]
|
|
172
|
+
|
|
173
|
+
# Show raw data info
|
|
174
|
+
st.write(
|
|
175
|
+
f"Number of documents in raw data: **{len(st.session_state['initial_df'])}**"
|
|
176
|
+
)
|
|
177
|
+
|
|
178
|
+
# Data filtering section
|
|
179
|
+
st.header("Data filtering")
|
|
180
|
+
|
|
181
|
+
# Display number input and checkbox for preprocessing options
|
|
182
|
+
col1, col2, col3 = st.columns(3)
|
|
183
|
+
with col1:
|
|
184
|
+
register_widget("min_chars")
|
|
185
|
+
st.number_input(
|
|
186
|
+
"Minimum Characters",
|
|
187
|
+
value=MIN_CHARS_DEFAULT,
|
|
188
|
+
min_value=0,
|
|
189
|
+
max_value=1000,
|
|
190
|
+
key="min_chars",
|
|
191
|
+
on_change=save_widget_state,
|
|
192
|
+
help="Minimum number of characters each document must contain.",
|
|
193
|
+
)
|
|
194
|
+
with col2:
|
|
195
|
+
register_widget("sample_size")
|
|
196
|
+
sample_size = st.number_input(
|
|
197
|
+
"Sample ratio",
|
|
198
|
+
value=SAMPLE_SIZE_DEFAULT,
|
|
199
|
+
min_value=0.0,
|
|
200
|
+
max_value=1.0,
|
|
201
|
+
key="sample_size",
|
|
202
|
+
on_change=save_widget_state,
|
|
203
|
+
help="Fraction of raw data to use for computing topics. Randomly samples documents from raw data.",
|
|
204
|
+
)
|
|
205
|
+
with col3:
|
|
206
|
+
register_widget("split_by_paragraph")
|
|
207
|
+
SessionStateManager.get_or_set("split_by_paragraph", "no")
|
|
208
|
+
st.segmented_control(
|
|
209
|
+
"Split text by paragraphs",
|
|
210
|
+
key="split_by_paragraph",
|
|
211
|
+
options=["no", "yes", "enhanced"],
|
|
212
|
+
selection_mode="single",
|
|
213
|
+
help="'No split': No splitting on the documents ; 'Split by paragraphs': Split documents into paragraphs ; "
|
|
214
|
+
"'Enhanced split': uses a more advanced but slower method for splitting that considers the embedding "
|
|
215
|
+
"model's maximum input length.",
|
|
216
|
+
on_change=save_widget_state,
|
|
217
|
+
)
|
|
218
|
+
|
|
219
|
+
df = split_data(
|
|
220
|
+
df,
|
|
221
|
+
SessionStateManager.get("min_chars"),
|
|
222
|
+
SessionStateManager.get("split_by_paragraph"),
|
|
223
|
+
embedding_model_name=SessionStateManager.get("embedding_model_name"),
|
|
224
|
+
)
|
|
225
|
+
|
|
226
|
+
# Deduplicate using all columns
|
|
227
|
+
df = df.drop_duplicates()
|
|
228
|
+
|
|
229
|
+
# Save state of split dataframe (before time-based filtering)
|
|
230
|
+
st.session_state["split_df"] = df.copy()
|
|
231
|
+
|
|
232
|
+
# Select timeframe
|
|
233
|
+
min_date, max_date = st.session_state["initial_df"][TIMESTAMP_COLUMN].dt.date.agg(
|
|
234
|
+
["min", "max"]
|
|
235
|
+
)
|
|
236
|
+
register_widget("timeframe_slider")
|
|
237
|
+
start_date, end_date = st.slider(
|
|
238
|
+
"Select Timeframe",
|
|
239
|
+
min_value=min_date,
|
|
240
|
+
max_value=max_date,
|
|
241
|
+
value=(min_date, max_date),
|
|
242
|
+
key="timeframe_slider",
|
|
243
|
+
on_change=save_widget_state,
|
|
244
|
+
)
|
|
245
|
+
|
|
246
|
+
# Filter and sample the DataFrame
|
|
247
|
+
df_filtered = df[
|
|
248
|
+
(df[TIMESTAMP_COLUMN].dt.date >= start_date)
|
|
249
|
+
& (df[TIMESTAMP_COLUMN].dt.date <= end_date)
|
|
250
|
+
]
|
|
251
|
+
df_filtered = df_filtered.sort_values(by=TIMESTAMP_COLUMN).reset_index(drop=True)
|
|
252
|
+
|
|
253
|
+
if sample_size < 1:
|
|
254
|
+
df_filtered = df_filtered.sample(frac=sample_size, random_state=42)
|
|
255
|
+
|
|
256
|
+
df_filtered = df_filtered.sort_values(by=TIMESTAMP_COLUMN).reset_index(drop=True)
|
|
257
|
+
|
|
258
|
+
SessionStateManager.set("time_filtered_df", df_filtered)
|
|
259
|
+
st.write(
|
|
260
|
+
f"Number of documents in filtered data: **{len(SessionStateManager.get_dataframe('time_filtered_df'))}**"
|
|
261
|
+
)
|
|
262
|
+
st.dataframe(
|
|
263
|
+
SessionStateManager.get_dataframe("time_filtered_df")[
|
|
264
|
+
[TEXT_COLUMN, "timestamp"]
|
|
265
|
+
],
|
|
266
|
+
use_container_width=True,
|
|
267
|
+
)
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Copyright (c) 2024, RTE (https://www.rte-france.com)
|
|
2
|
+
# See AUTHORS.txt
|
|
3
|
+
# SPDX-License-Identifier: MPL-2.0
|
|
4
|
+
# This file is part of BERTrend.
|
|
5
|
+
import streamlit as st
|
|
6
|
+
|
|
7
|
+
from bertrend.demos.demos_utils.icons import SUCCESS_ICON
|
|
8
|
+
from bertrend.demos.demos_utils.messages import EMBEDDINGS_CALCULATED_MESSAGE
|
|
9
|
+
from bertrend.demos.demos_utils.state_utils import SessionStateManager
|
|
10
|
+
from bertrend.services.embedding_service import EmbeddingService
|
|
11
|
+
from bertrend.utils.data_loading import TEXT_COLUMN
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def display_embed_documents_component():
|
|
15
|
+
"""
|
|
16
|
+
Common Streamlit UI component for embedding documents.
|
|
17
|
+
"""
|
|
18
|
+
# Embed documents
|
|
19
|
+
if st.button("Embed Documents"):
|
|
20
|
+
with st.spinner("Embedding documents..."):
|
|
21
|
+
embedding_dtype = SessionStateManager.get("embedding_dtype")
|
|
22
|
+
embedding_model_name = SessionStateManager.get("embedding_model_name")
|
|
23
|
+
if SessionStateManager.get("embedding_service_type", "remote") == "local":
|
|
24
|
+
embedding_service = EmbeddingService(
|
|
25
|
+
local=True,
|
|
26
|
+
model_name=embedding_model_name,
|
|
27
|
+
embedding_dtype=embedding_dtype,
|
|
28
|
+
)
|
|
29
|
+
else:
|
|
30
|
+
embedding_service = EmbeddingService(
|
|
31
|
+
local=False,
|
|
32
|
+
url=SessionStateManager.get("embedding_service_url"),
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
texts = SessionStateManager.get_dataframe("time_filtered_df")[
|
|
36
|
+
TEXT_COLUMN
|
|
37
|
+
].tolist()
|
|
38
|
+
|
|
39
|
+
embeddings, token_strings, token_embeddings = embedding_service.embed(
|
|
40
|
+
texts=texts,
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
SessionStateManager.set(
|
|
44
|
+
"embedding_model", embedding_service.embedding_model
|
|
45
|
+
)
|
|
46
|
+
SessionStateManager.set("embeddings", embeddings)
|
|
47
|
+
SessionStateManager.set("token_strings", token_strings)
|
|
48
|
+
SessionStateManager.set("token_embeddings", token_embeddings)
|
|
49
|
+
|
|
50
|
+
SessionStateManager.set("data_embedded", True)
|
|
51
|
+
|
|
52
|
+
st.success(EMBEDDINGS_CALCULATED_MESSAGE, icon=SUCCESS_ICON)
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Copyright (c) 2024, RTE (https://www.rte-france.com)
|
|
2
|
+
# See AUTHORS.txt
|
|
3
|
+
# SPDX-License-Identifier: MPL-2.0
|
|
4
|
+
# This file is part of BERTrend.
|
|
5
|
+
|
|
6
|
+
WARNING_ICON = ":material/warning:"
|
|
7
|
+
ERROR_ICON = ":material/error:"
|
|
8
|
+
INFO_ICON = ":material/info:"
|
|
9
|
+
EDIT_ICON = ":material/edit:"
|
|
10
|
+
ADD_ICON = ":material/add_circle:"
|
|
11
|
+
DELETE_ICON = ":material/delete:"
|
|
12
|
+
SUCCESS_ICON = ":material/check:"
|
|
13
|
+
SETTINGS_ICON = ":material/settings:"
|
|
14
|
+
TOPIC_ICON = ":material/speaker_notes:"
|
|
15
|
+
TREND_ICON = ":material/trending_up:"
|
|
16
|
+
MODELS_ICON = ":material/network_intelligence:"
|
|
17
|
+
EMBEDDING_ICON = ":material/memory:"
|
|
18
|
+
SAVE_ICON = ":material/save:"
|
|
19
|
+
TOPIC_EXPLORATION_ICON = ":material/explore:"
|
|
20
|
+
TOPIC_VISUALIZATION_ICON = ":material/monitoring:"
|
|
21
|
+
TEMPORAL_VISUALIZATION_ICON = ":material/timelapse:"
|
|
22
|
+
NEWSLETTER_ICON = ":material/newspaper:"
|
|
23
|
+
ANALYSIS_ICON = ":material/query_stats:"
|
|
24
|
+
DATA_LOADING_ICON = ":material/drive_folder_upload:"
|
|
25
|
+
MODEL_TRAINING_ICON = ":material/cognition:"
|
|
26
|
+
SERVER_STORAGE_ICON = ":material/database:"
|
|
27
|
+
CLIENT_STORAGE_ICON = ":material/upload:"
|
|
28
|
+
UNHAPPY_ICON = ":material/sentiment_extremely_dissatisfied:"
|
|
29
|
+
TOGGLE_ON_ICON = ":material/toggle_on:"
|
|
30
|
+
TOGGLE_OFF_ICON = ":material/toggle_off:"
|
|
31
|
+
NOISE_ICON = ":material/signal_cellular_off:"
|
|
32
|
+
WEAK_SIGNAL_ICON = ":material/signal_cellular_1_bar:"
|
|
33
|
+
STRONG_SIGNAL_ICON = ":material/signal_cellular_3_bar:"
|
|
34
|
+
DOWNLOAD_ICON = ":material/download:"
|
|
35
|
+
EMAIL_ICON = ":material/mail:"
|
|
36
|
+
RESTART_ICON = ":material/restart_alt:"
|
|
37
|
+
|
|
38
|
+
JSON_ICON = "๐งพ"
|
|
39
|
+
PARQUET_ICON = "๐ฆ๏ธ"
|
|
40
|
+
CSV_ICON = "๐"
|
|
41
|
+
XLSX_ICON = "๐"
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Copyright (c) 2024, RTE (https://www.rte-france.com)
|
|
2
|
+
# See AUTHORS.txt
|
|
3
|
+
# SPDX-License-Identifier: MPL-2.0
|
|
4
|
+
# This file is part of BERTrend.
|
|
5
|
+
|
|
6
|
+
EMBEDDINGS_CALCULATED_MESSAGE = "Embeddings calculated successfully!"
|
|
7
|
+
NO_EMBEDDINGS_WARNING_MESSAGE = (
|
|
8
|
+
"Please embed data and train models before proceeding to analysis."
|
|
9
|
+
)
|
|
10
|
+
MODEL_TRAINING_COMPLETE_MESSAGE = "Model training complete!"
|
|
11
|
+
NO_DATA_AFTER_PREPROCESSING_MESSAGE = "No data available after preprocessing. Please check the selected files and preprocessing options."
|