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.
Files changed (181) hide show
  1. bertrend/BERTopicModel.py +320 -0
  2. bertrend/BERTrend.py +1211 -0
  3. bertrend/__init__.py +59 -0
  4. bertrend/config/bertopic_default_config.toml +48 -0
  5. bertrend/config/bertrend_default_config.toml +16 -0
  6. bertrend/config/parameters.py +92 -0
  7. bertrend/config/services_default_config.toml +32 -0
  8. bertrend/demos/__init__.py +4 -0
  9. bertrend/demos/demos_utils/__init__.py +13 -0
  10. bertrend/demos/demos_utils/data_loading_component.py +267 -0
  11. bertrend/demos/demos_utils/embed_documents_component.py +52 -0
  12. bertrend/demos/demos_utils/icons.py +41 -0
  13. bertrend/demos/demos_utils/messages.py +11 -0
  14. bertrend/demos/demos_utils/parameters_component.py +162 -0
  15. bertrend/demos/demos_utils/state_utils.py +99 -0
  16. bertrend/demos/start_summarizer_app.sh +9 -0
  17. bertrend/demos/start_topic_analysis_app.sh +9 -0
  18. bertrend/demos/start_weak_signals_app.sh +9 -0
  19. bertrend/demos/summarization/__init__.py +4 -0
  20. bertrend/demos/summarization/summarizer_app.py +98 -0
  21. bertrend/demos/topic_analysis/__init__.py +4 -0
  22. bertrend/demos/topic_analysis/app.py +87 -0
  23. bertrend/demos/topic_analysis/app_utils.py +69 -0
  24. bertrend/demos/topic_analysis/demo_pages/__init__.py +4 -0
  25. bertrend/demos/topic_analysis/demo_pages/explore_topics.py +455 -0
  26. bertrend/demos/topic_analysis/demo_pages/newsletters_generation.py +178 -0
  27. bertrend/demos/topic_analysis/demo_pages/temporal_visualizations.py +573 -0
  28. bertrend/demos/topic_analysis/demo_pages/topic_visualizations.py +280 -0
  29. bertrend/demos/topic_analysis/demo_pages/training_page.py +219 -0
  30. bertrend/demos/topic_analysis/messages.py +13 -0
  31. bertrend/demos/weak_signals/__init__.py +4 -0
  32. bertrend/demos/weak_signals/app.py +510 -0
  33. bertrend/demos/weak_signals/messages.py +32 -0
  34. bertrend/demos/weak_signals/visualizations_utils.py +403 -0
  35. bertrend/llm_utils/__init__.py +4 -0
  36. bertrend/llm_utils/newsletter.css +131 -0
  37. bertrend/llm_utils/newsletter_features.py +272 -0
  38. bertrend/llm_utils/openai_client.py +235 -0
  39. bertrend/llm_utils/prompts.py +94 -0
  40. bertrend/metrics/__init__.py +4 -0
  41. bertrend/metrics/temporal_metrics_embedding.py +861 -0
  42. bertrend/metrics/topic_metrics.py +199 -0
  43. bertrend/resources/common_ngrams.json +23 -0
  44. bertrend/resources/stopwords-en.json +3 -0
  45. bertrend/resources/stopwords-fr.json +1 -0
  46. bertrend/resources/stopwords-rte.json +15 -0
  47. bertrend/services/__init__.py +4 -0
  48. bertrend/services/authentication.py +66 -0
  49. bertrend/services/embedding_client.py +154 -0
  50. bertrend/services/embedding_service.py +380 -0
  51. bertrend/services/summarizer.py +45 -0
  52. bertrend/services/summary/__init__.py +4 -0
  53. bertrend/services/summary/abstractive_summarizer.py +74 -0
  54. bertrend/services/summary/chatgpt_summarizer.py +67 -0
  55. bertrend/services/summary/extractive_summarizer.py +368 -0
  56. bertrend/services/summary/lexrank.py +126 -0
  57. bertrend/services/summary/prompts.py +43 -0
  58. bertrend/tests/__init__.py +4 -0
  59. bertrend/tests/test_abstractive_summarizer.py +140 -0
  60. bertrend/tests/test_bertrend.py +1091 -0
  61. bertrend/tests/test_cache_utils.py +111 -0
  62. bertrend/tests/test_chatgpt_summarizer.py +150 -0
  63. bertrend/tests/test_config_utils.py +54 -0
  64. bertrend/tests/test_data_loading.py +326 -0
  65. bertrend/tests/test_data_structure.py +53 -0
  66. bertrend/tests/test_embedding_client.py +546 -0
  67. bertrend/tests/test_extractive_summarizer.py +250 -0
  68. bertrend/tests/test_installation.py +183 -0
  69. bertrend/tests/test_newsletter_features.py +354 -0
  70. bertrend/tests/test_openai_client.py +210 -0
  71. bertrend/tests/test_representative_docs.py +125 -0
  72. bertrend/tests/test_summarizer.py +115 -0
  73. bertrend/tests/test_temporal_metrics_embedding.py +349 -0
  74. bertrend/tests/test_topic_description.py +159 -0
  75. bertrend/tests/test_topic_metrics.py +233 -0
  76. bertrend/tests/test_topic_model.py +285 -0
  77. bertrend/tests/test_trend_analysis_data_structure.py +174 -0
  78. bertrend/tests/test_trend_analysis_prompts.py +225 -0
  79. bertrend/tests/test_trend_analysis_visualizations.py +307 -0
  80. bertrend/tests/test_trend_analysis_weak_signals.py +598 -0
  81. bertrend/tests/test_utils_init.py +70 -0
  82. bertrend/tests/test_visualizations.py +306 -0
  83. bertrend/topic_analysis/__init__.py +4 -0
  84. bertrend/topic_analysis/data_structure.py +13 -0
  85. bertrend/topic_analysis/prompts.py +42 -0
  86. bertrend/topic_analysis/representative_docs.py +57 -0
  87. bertrend/topic_analysis/topic_description.py +66 -0
  88. bertrend/topic_analysis/visualizations.py +315 -0
  89. bertrend/trend_analysis/__init__.py +4 -0
  90. bertrend/trend_analysis/data_structure.py +78 -0
  91. bertrend/trend_analysis/prompts.py +229 -0
  92. bertrend/trend_analysis/signal_llm_template_en.html +181 -0
  93. bertrend/trend_analysis/signal_llm_template_fr.html +181 -0
  94. bertrend/trend_analysis/visualizations.py +605 -0
  95. bertrend/trend_analysis/weak_signals.py +425 -0
  96. bertrend/utils/__init__.py +31 -0
  97. bertrend/utils/cache_utils.py +31 -0
  98. bertrend/utils/config_utils.py +41 -0
  99. bertrend/utils/data_loading.py +329 -0
  100. bertrend-0.3.1.dist-info/AUTHORS.txt +15 -0
  101. bertrend-0.3.1.dist-info/LICENSE.md +373 -0
  102. bertrend-0.3.1.dist-info/METADATA +400 -0
  103. bertrend-0.3.1.dist-info/RECORD +181 -0
  104. bertrend-0.3.1.dist-info/WHEEL +4 -0
  105. bertrend_apps/__init__.py +4 -0
  106. bertrend_apps/common/__init__.py +4 -0
  107. bertrend_apps/common/crontab_utils.py +113 -0
  108. bertrend_apps/common/mail_utils.py +91 -0
  109. bertrend_apps/config/feeds/arxiv_feed.toml +15 -0
  110. bertrend_apps/config/feeds/decarbonation_feed.toml +15 -0
  111. bertrend_apps/config/feeds/llm_en_feed.toml +15 -0
  112. bertrend_apps/config/feeds/llm_feed.toml +16 -0
  113. bertrend_apps/config/feeds/nlp_feed.toml +15 -0
  114. bertrend_apps/config/feeds/rte_feed.toml +15 -0
  115. bertrend_apps/config/gmail_credentials.json +1 -0
  116. bertrend_apps/config/newsletters/arxiv_newsletter_from_last.toml +39 -0
  117. bertrend_apps/config/newsletters/arxiv_newsletter_from_scratch.toml +39 -0
  118. bertrend_apps/config/newsletters/decarbonation_newsletter_from_last.toml +38 -0
  119. bertrend_apps/config/newsletters/decarbonation_newsletter_from_scratch.toml +38 -0
  120. bertrend_apps/config/newsletters/llm_en_newsletter_from_last.toml +38 -0
  121. bertrend_apps/config/newsletters/llm_newsletter_from_last.toml +39 -0
  122. bertrend_apps/config/newsletters/nlp_newsletter_from_last.toml +38 -0
  123. bertrend_apps/config/newsletters/rte_newsletter_from_last.toml +38 -0
  124. bertrend_apps/config/newsletters/rte_newsletter_from_scratch.toml +38 -0
  125. bertrend_apps/data_provider/__init__.py +9 -0
  126. bertrend_apps/data_provider/__main__.py +237 -0
  127. bertrend_apps/data_provider/arxiv_provider.py +161 -0
  128. bertrend_apps/data_provider/bing_news_provider.py +82 -0
  129. bertrend_apps/data_provider/curebot_provider.py +105 -0
  130. bertrend_apps/data_provider/data_provider.py +194 -0
  131. bertrend_apps/data_provider/google_news_provider.py +94 -0
  132. bertrend_apps/data_provider/newscatcher_provider.py +74 -0
  133. bertrend_apps/data_provider/utils.py +165 -0
  134. bertrend_apps/exploration/__init__.py +4 -0
  135. bertrend_apps/exploration/curebot/__init__.py +4 -0
  136. bertrend_apps/exploration/curebot/app.py +45 -0
  137. bertrend_apps/exploration/curebot/app_utils.py +317 -0
  138. bertrend_apps/exploration/curebot/config.toml +33 -0
  139. bertrend_apps/exploration/curebot/import_extraction_article.ipynb +108 -0
  140. bertrend_apps/exploration/curebot/old_veille_analyse.py +298 -0
  141. bertrend_apps/exploration/curebot/prompts.py +24 -0
  142. bertrend_apps/exploration/curebot/start_newsletter_generator.sh +8 -0
  143. bertrend_apps/exploration/curebot/tabs/tab1.py +150 -0
  144. bertrend_apps/exploration/curebot/tabs/tab2.py +95 -0
  145. bertrend_apps/exploration/curebot/tabs/tab3.py +125 -0
  146. bertrend_apps/exploration/dataviz/Main_page.py +10 -0
  147. bertrend_apps/exploration/dataviz/__init__.py +4 -0
  148. bertrend_apps/exploration/dataviz/pages/1_Data_feeds.py +105 -0
  149. bertrend_apps/exploration/geolocalization/__init__.py +4 -0
  150. bertrend_apps/exploration/geolocalization/entity_utils.py +118 -0
  151. bertrend_apps/exploration/geolocalization/spacy/__init__.py +4 -0
  152. bertrend_apps/exploration/geolocalization/spacy/common_factory.py +142 -0
  153. bertrend_apps/exploration/geolocalization/spacy/dbpedia.py +206 -0
  154. bertrend_apps/exploration/geolocalization/spacy/nlp.config +37 -0
  155. bertrend_apps/exploration/geolocalization/spacy/utils.py +39 -0
  156. bertrend_apps/install_feeds_and_newsletters.py +29 -0
  157. bertrend_apps/newsletters/__init__.py +4 -0
  158. bertrend_apps/newsletters/__main__.py +277 -0
  159. bertrend_apps/prospective_demo/.streamlit/config.toml +3 -0
  160. bertrend_apps/prospective_demo/.streamlit/secrets.toml +9 -0
  161. bertrend_apps/prospective_demo/__init__.py +70 -0
  162. bertrend_apps/prospective_demo/app.py +111 -0
  163. bertrend_apps/prospective_demo/authentication.py +44 -0
  164. bertrend_apps/prospective_demo/dashboard_analysis.py +132 -0
  165. bertrend_apps/prospective_demo/dashboard_common.py +79 -0
  166. bertrend_apps/prospective_demo/dashboard_signals.py +226 -0
  167. bertrend_apps/prospective_demo/feeds_common.py +38 -0
  168. bertrend_apps/prospective_demo/feeds_config.py +261 -0
  169. bertrend_apps/prospective_demo/feeds_data.py +95 -0
  170. bertrend_apps/prospective_demo/i18n.py +136 -0
  171. bertrend_apps/prospective_demo/llm_utils.py +34 -0
  172. bertrend_apps/prospective_demo/models_info.py +361 -0
  173. bertrend_apps/prospective_demo/perf_utils.py +23 -0
  174. bertrend_apps/prospective_demo/process_new_data.py +348 -0
  175. bertrend_apps/prospective_demo/report_generation.py +214 -0
  176. bertrend_apps/prospective_demo/report_template.html +148 -0
  177. bertrend_apps/prospective_demo/report_utils.py +132 -0
  178. bertrend_apps/prospective_demo/start_demo.sh +9 -0
  179. bertrend_apps/prospective_demo/streamlit_utils.py +37 -0
  180. bertrend_apps/start_apps.sh +15 -0
  181. bertrend_apps/stop_apps.sh +11 -0
@@ -0,0 +1,162 @@
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 code_editor import code_editor
8
+
9
+ from bertrend import (
10
+ BERTOPIC_DEFAULT_CONFIG_PATH,
11
+ BERTREND_DEFAULT_CONFIG_PATH,
12
+ EMBEDDING_CONFIG,
13
+ load_toml_config,
14
+ )
15
+ from bertrend.demos.demos_utils.state_utils import (
16
+ register_widget,
17
+ save_widget_state,
18
+ SessionStateManager,
19
+ register_multiple_widget,
20
+ reset_widget_state,
21
+ )
22
+ from bertrend.config.parameters import (
23
+ EMBEDDING_DTYPES,
24
+ LANGUAGES,
25
+ ENGLISH_EMBEDDING_MODELS,
26
+ FRENCH_EMBEDDING_MODELS,
27
+ REPRESENTATION_MODELS,
28
+ MMR_REPRESENTATION_MODEL,
29
+ )
30
+
31
+ from bertrend.demos.demos_utils.icons import INFO_ICON
32
+
33
+
34
+ def display_local_embeddings():
35
+ """UI settings for local embedding service"""
36
+ register_multiple_widget("language", "embedding_dtype", "embedding_model_name")
37
+
38
+ language = st.selectbox(
39
+ "Select Language",
40
+ LANGUAGES,
41
+ key="language",
42
+ on_change=_on_language_change,
43
+ )
44
+ st.selectbox(
45
+ "Embedding Dtype",
46
+ EMBEDDING_DTYPES,
47
+ key="embedding_dtype",
48
+ on_change=save_widget_state,
49
+ )
50
+ embedding_models = (
51
+ ENGLISH_EMBEDDING_MODELS if language == "English" else FRENCH_EMBEDDING_MODELS
52
+ )
53
+ st.selectbox(
54
+ "Embedding Model",
55
+ options=embedding_models,
56
+ key="embedding_model_name",
57
+ on_change=save_widget_state,
58
+ )
59
+
60
+
61
+ def _on_language_change():
62
+ save_widget_state()
63
+ # required to handle multi-page app and restore_state call:
64
+ reset_widget_state("embedding_model_name")
65
+ st.session_state.pop("embedding_model_name")
66
+
67
+
68
+ def display_remote_embeddings():
69
+ """UI settings for remote embedding service"""
70
+ register_widget("embedding_service_url")
71
+ if "embedding_service_url" not in st.session_state:
72
+ st.session_state["embedding_service_url"] = EMBEDDING_CONFIG["url"]
73
+ st.text_input(
74
+ "Embedding service URL",
75
+ key="embedding_service_url",
76
+ on_change=save_widget_state,
77
+ )
78
+
79
+
80
+ def display_embedding_hyperparameters():
81
+ """UI settings for embedding hyperparameters"""
82
+ # Embedding model parameters
83
+ with st.expander("Embedding Model Settings", expanded=False):
84
+ register_widget("embedding_service_type")
85
+ if "embedding_service_type" not in st.session_state:
86
+ st.session_state["embedding_service_type"] = "remote"
87
+ st.segmented_control(
88
+ "Embedding service",
89
+ selection_mode="single",
90
+ key="embedding_service_type",
91
+ options=["local", "remote"],
92
+ on_change=save_widget_state,
93
+ )
94
+ if st.session_state["embedding_service_type"] == "local":
95
+ display_local_embeddings()
96
+ else:
97
+ display_remote_embeddings()
98
+
99
+
100
+ def display_bertopic_hyperparameters():
101
+ # BERTopic model parameters
102
+ with st.expander("BERTopic Model Settings", expanded=False):
103
+ # If BERTopic config is already in session state, use it
104
+ if "bertopic_config" in st.session_state:
105
+ toml_txt = st.session_state["bertopic_config"]
106
+ # Else get BERTopic default configuration
107
+ else:
108
+ with open(BERTOPIC_DEFAULT_CONFIG_PATH, "r") as f:
109
+ # Load default parameter the first time
110
+ toml_txt = f.read()
111
+
112
+ # Add code editor to edit the config file
113
+ st.write(INFO_ICON + " CTRL + Enter to update")
114
+ config_editor = code_editor(
115
+ toml_txt,
116
+ lang="toml",
117
+ )
118
+
119
+ # If code is edited, update config
120
+ if config_editor["text"] != "":
121
+ st.session_state["bertopic_config"] = config_editor["text"]
122
+ # Else use default config
123
+ else:
124
+ st.session_state["bertopic_config"] = toml_txt
125
+
126
+
127
+ def display_bertrend_hyperparameters():
128
+ """UI settings for Bertrend hyperparameters"""
129
+ with st.expander("BERTrend Model Settings", expanded=False):
130
+ # Get BERTrend default configuration
131
+ with open(BERTREND_DEFAULT_CONFIG_PATH, "r") as f:
132
+ # Load default parameter the first time
133
+ toml_txt = f.read()
134
+
135
+ # Add code editor to edit the config file
136
+ st.write(INFO_ICON + " CTRL + Enter to update")
137
+ config_editor = code_editor(toml_txt, lang="toml")
138
+
139
+ # If code is edited, update config
140
+ if config_editor["text"] != "":
141
+ st.session_state["bertrend_config"] = config_editor["text"]
142
+ # Else use default config
143
+ else:
144
+ st.session_state["bertrend_config"] = toml_txt
145
+
146
+ # Save granularity in session state as it is re-used in other components
147
+ st.session_state["granularity"] = load_toml_config(
148
+ st.session_state["bertrend_config"]
149
+ )["granularity"]
150
+
151
+
152
+ def display_representation_model_options():
153
+ """UI settings for representation model options"""
154
+ with st.expander("Representation model selection", expanded=False):
155
+ register_widget("representation_models")
156
+ selected_models = st.multiselect(
157
+ label="Select representation models",
158
+ options=REPRESENTATION_MODELS,
159
+ default=MMR_REPRESENTATION_MODEL,
160
+ key="representation_models",
161
+ on_change=save_widget_state,
162
+ )
@@ -0,0 +1,99 @@
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
+ from typing import Any
6
+
7
+ import numpy as np
8
+ import pandas as pd
9
+
10
+ import streamlit as st
11
+
12
+ STATE_KEYS = "state_keys"
13
+ WIDGET_STATE = "widget_state"
14
+
15
+ # Set of util functions to manage the state of widgets in streamlit
16
+ # - at the beginning of each page: add restore_widget_state() to restore the last selected values
17
+ # - each time a widget is used, call *before* register_widget with the *key* of the widget as argument
18
+ # and use the call_back of the widget (for example on_change) to call save_widget_state
19
+
20
+
21
+ def register_widget(key: str):
22
+ """Keeps track of widget state in case of multi-pages Streamlit app. It shall be called with the key of
23
+ the widget before the widget creation."""
24
+ if STATE_KEYS not in st.session_state.keys():
25
+ st.session_state[STATE_KEYS] = []
26
+ if key not in st.session_state[STATE_KEYS]:
27
+ st.session_state[STATE_KEYS].append(key)
28
+
29
+
30
+ def reset_widget_state(key: str):
31
+ """Removes the widget state from session state."""
32
+ if WIDGET_STATE in st.session_state.keys():
33
+ st.session_state[WIDGET_STATE].pop(key)
34
+
35
+
36
+ def register_multiple_widget(*keys: str):
37
+ """Keeps track of widget state in case of multi-pages Streamlit app. It shall be called with the key of
38
+ the widget before the widget creation."""
39
+ for key in keys:
40
+ register_widget(key)
41
+
42
+
43
+ def save_widget_state():
44
+ """(Callback) Function to save the widget state in case of multi-pages Streamlit app.
45
+ It shall be used as the call_back of the widget (for example on_change)."""
46
+ if STATE_KEYS in st.session_state.keys():
47
+ st.session_state[WIDGET_STATE] = {
48
+ key: st.session_state[key]
49
+ for key in st.session_state[STATE_KEYS]
50
+ if key in st.session_state
51
+ }
52
+
53
+
54
+ def restore_widget_state():
55
+ """Function to restore widget states in case of multi-pages Streamlit app.
56
+ It shall be called at the start of each page."""
57
+ if WIDGET_STATE in st.session_state.keys():
58
+ for k, v in st.session_state[WIDGET_STATE].items():
59
+ st.session_state[k] = v
60
+
61
+
62
+ class SessionStateManager:
63
+ """Class to ease the management of Streamlit session state"""
64
+
65
+ @staticmethod
66
+ def get(key: str, default: Any = None) -> Any:
67
+ return st.session_state.get(key, default)
68
+
69
+ @staticmethod
70
+ def set(key: str, value: Any) -> None:
71
+ st.session_state[key] = value
72
+
73
+ @staticmethod
74
+ def get_or_set(key: str, default: Any) -> Any:
75
+ if key not in st.session_state:
76
+ st.session_state[key] = default
77
+ return st.session_state[key]
78
+
79
+ @staticmethod
80
+ def get_multiple(*keys: str) -> dict[str, Any]:
81
+ return {key: st.session_state.get(key) for key in keys}
82
+
83
+ @staticmethod
84
+ def set_multiple(**kwargs: Any) -> None:
85
+ for key, value in kwargs.items():
86
+ st.session_state[key] = value
87
+
88
+ @staticmethod
89
+ def clear() -> None:
90
+ st.session_state.clear()
91
+
92
+ @staticmethod
93
+ def get_dataframe(key: str) -> pd.DataFrame | None:
94
+ df = st.session_state.get(key)
95
+ return df if isinstance(df, pd.DataFrame) else None
96
+
97
+ @staticmethod
98
+ def get_embeddings(key: str = "embeddings") -> np.ndarray | None:
99
+ return st.session_state.get(key)
@@ -0,0 +1,9 @@
1
+ #
2
+ # Copyright (c) 2024, RTE (https://www.rte-france.com)
3
+ # See AUTHORS.txt
4
+ # SPDX-License-Identifier: MPL-2.0
5
+ # This file is part of BERTrend.
6
+ #
7
+
8
+ # Starts the Summarizer app (a comparison of various method of text summarization)
9
+ CUDA_VISIBLE_DEVICES=0 OPENAI_API_KEY=$AZURE_WATTELSE_OPENAI_API_KEY OPENAI_ENDPOINT=$AZURE_WATTELSE_OPENAI_ENDPOINT OPENAI_DEFAULT_MODEL_NAME=$AZURE_WATTELSE_OPENAI_DEFAULT_MODEL_NAME streamlit run --theme.primaryColor royalblue summarization/summarizer_app.py
@@ -0,0 +1,9 @@
1
+ #
2
+ # Copyright (c) 2024, RTE (https://www.rte-france.com)
3
+ # See AUTHORS.txt
4
+ # SPDX-License-Identifier: MPL-2.0
5
+ # This file is part of BERTrend.
6
+ #
7
+
8
+ # Starts the Topic Analysis application
9
+ CUDA_VISIBLE_DEVICES=0 streamlit run --theme.primaryColor royalblue topic_analysis/app.py
@@ -0,0 +1,9 @@
1
+ #
2
+ # Copyright (c) 2024, RTE (https://www.rte-france.com)
3
+ # See AUTHORS.txt
4
+ # SPDX-License-Identifier: MPL-2.0
5
+ # This file is part of BERTrend.
6
+ #
7
+
8
+ # Starts the Trend Analysis application
9
+ CUDA_VISIBLE_DEVICES=0 streamlit run --theme.primaryColor royalblue weak_signals/app.py
@@ -0,0 +1,4 @@
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.
@@ -0,0 +1,98 @@
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
+
7
+ import streamlit as st
8
+ from loguru import logger
9
+
10
+ from bertrend.demos.demos_utils.icons import WARNING_ICON
11
+ from bertrend.services.summary.abstractive_summarizer import AbstractiveSummarizer
12
+ from bertrend.services.summary.chatgpt_summarizer import GPTSummarizer
13
+ from bertrend.services.summary.extractive_summarizer import (
14
+ EnhancedExtractiveSummarizer,
15
+ ExtractiveSummarizer,
16
+ )
17
+
18
+ SUMMARIZER_OPTIONS_MAPPER = {
19
+ "GPTSummarizer": GPTSummarizer,
20
+ "EnhancedExtractiveSummarizer": EnhancedExtractiveSummarizer,
21
+ "ExtractiveSummarizer": ExtractiveSummarizer,
22
+ "AbstractiveSummarizer": AbstractiveSummarizer,
23
+ }
24
+
25
+ DEFAULT_TEXT = """RTE, sigle du Réseau de transport d'électricité, est le gestionnaire de réseau de transport français responsable du réseau public de transport d'électricité haute tension en France métropolitaine (la Corse n'est pas gérée par RTE). Sa mission fondamentale est d’assurer à tous ses clients l’accès à une alimentation électrique économique, sûre et propre. RTE connecte ses clients par une infrastructure adaptée et leur fournit tous les outils et services qui leur permettent d’en tirer parti pour répondre à leurs besoins. À cet effet, RTE exploite, maintient et développe le réseau à haute et très haute tension. Il est le garant du bon fonctionnement et de la sûreté du système électrique. RTE achemine l’électricité entre les fournisseurs d’électricité (français et européens) et les consommateurs, qu’ils soient distributeurs d’électricité ou industriels directement raccordés au réseau de transport. Plus de 105 000 km de lignes comprises entre 45 000 et 400 000 volts et 50 lignes transfrontalières connectent le réseau français à 33 pays européens, offrant ainsi des opportunités d’échanges d’électricité essentiels pour l’optimisation économique du système électrique.
26
+
27
+ RTE fait partie du Réseau européen des gestionnaires de réseau de transport d’électricité (ENTSO-E), organisation qui regroupe les gestionnaires de réseaux de transport à haute et très haute tension de 35 pays3. Elle découle de la fusion le 1er juillet 2009 de l'UCTE, de BALTSO, de NORDEL, d'ATSOI et d'UKTSOA.
28
+
29
+ Les réseaux de ces sociétés desservent, via les réseaux de distribution, une population d'environ 500 millions de personnes. Ils se décomposent en cinq grands systèmes synchrones : l'Europe continentale (à laquelle est rattachée la Turquie), les pays baltes, les pays nordiques, l'Irlande et la Grande-Bretagne.
30
+
31
+ Les lignes à basse et moyenne tension françaises ne sont pas du ressort de RTE. Elles sont essentiellement exploitées par Enedis (anciennement ERDF, filiale de distribution électrique d'EDF), mais aussi par d'autres entreprises locales de distribution (ELD) comme Électricité de Strasbourg, l'Usine d'électricité de Metz, ou encore Gascogne Énergies Services à Aire-sur-l’Adour dans les Landes."""
32
+
33
+ models = {}
34
+
35
+
36
+ @st.cache_resource
37
+ def get_summarizer(summary_model):
38
+ """Instantiates models once, keep them in memory"""
39
+ kwargs = {}
40
+ if summary_model == "GPTSummarizer":
41
+ kwargs["api_key"] = st.session_state.openai_api_key
42
+ kwargs["endpoint"] = st.session_state.openai_endpoint
43
+
44
+ summarizer_class = SUMMARIZER_OPTIONS_MAPPER[summary_model]
45
+ return summarizer_class(**kwargs)
46
+
47
+
48
+ def app():
49
+ st.title("Comparison of summarizers")
50
+
51
+ st.warning(
52
+ "Warning: be sure that when using a GPT summarizer, the server is on Azure or local. "
53
+ "Otherwise, use it EXCLUSIVELY on public data.",
54
+ icon=WARNING_ICON,
55
+ )
56
+
57
+ summary_model = st.selectbox(
58
+ "summary model", SUMMARIZER_OPTIONS_MAPPER.keys(), key="summary_model"
59
+ )
60
+ summary_ratio = (
61
+ st.number_input(
62
+ "summary ratio", min_value=1, max_value=100, value=20, key="summary_ratio"
63
+ )
64
+ / 100
65
+ )
66
+ st.text_input(
67
+ "Openai API key",
68
+ key="openai_api_key",
69
+ value=os.getenv("OPENAI_API_KEY"),
70
+ type="password",
71
+ )
72
+ st.text_input(
73
+ "Openai endpoint", key="openai_endpoint", value=os.getenv("OPENAI_ENDPOINT")
74
+ )
75
+ st.text_input(
76
+ "Openai model name",
77
+ key="openai_model_name",
78
+ value=os.getenv("OPENAI_DEFAULT_MODEL_NAME"),
79
+ )
80
+
81
+ col1, col2 = st.columns(2)
82
+ with col1:
83
+ st.text_area("Input text", DEFAULT_TEXT, height=250, key="text")
84
+ with col2:
85
+ st.text_area("Summary", "", height=250, key="summary")
86
+
87
+ def on_click():
88
+ summarizer = get_summarizer(summary_model)
89
+ st.session_state.summary = summarizer.generate_summary(
90
+ st.session_state.text, max_length_ratio=summary_ratio
91
+ )
92
+ logger.debug(st.session_state.summary)
93
+
94
+ st.button("Summarize", on_click=on_click)
95
+
96
+
97
+ if __name__ == "__main__":
98
+ app()
@@ -0,0 +1,4 @@
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.
@@ -0,0 +1,87 @@
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 torch
7
+
8
+ # workaround with streamlit to avoid errors Examining the path of torch.classes raised: Tried to instantiate class 'path.path’, but it does not exist! Ensure that it is registered via torch::class
9
+ torch.classes.__path__ = []
10
+
11
+ import locale
12
+
13
+ import streamlit as st
14
+
15
+ from bertrend.demos.demos_utils.icons import (
16
+ SAVE_ICON,
17
+ TOPIC_EXPLORATION_ICON,
18
+ TOPIC_VISUALIZATION_ICON,
19
+ TEMPORAL_VISUALIZATION_ICON,
20
+ NEWSLETTER_ICON,
21
+ )
22
+ from bertrend.demos.demos_utils.state_utils import restore_widget_state
23
+
24
+ TITLE = "BERTrend - Topic Analysis demo"
25
+ LAYOUT = "wide"
26
+
27
+
28
+ # Set locale for French date names
29
+ locale.setlocale(locale.LC_TIME, "fr_FR.UTF-8")
30
+
31
+
32
+ def define_pages():
33
+ data_page = st.Page(
34
+ page="demo_pages/training_page.py",
35
+ title="Data loading & model training",
36
+ icon=SAVE_ICON,
37
+ )
38
+ topic_exploration_page = st.Page(
39
+ page="demo_pages/explore_topics.py",
40
+ title="Topic exploration",
41
+ icon=TOPIC_EXPLORATION_ICON,
42
+ )
43
+ topic_visualization_page = st.Page(
44
+ page="demo_pages/topic_visualizations.py",
45
+ title="Topic visualization",
46
+ icon=TOPIC_VISUALIZATION_ICON,
47
+ )
48
+ temporal_visualization_page = st.Page(
49
+ page="demo_pages/temporal_visualizations.py",
50
+ title="Temporal visualization",
51
+ icon=TEMPORAL_VISUALIZATION_ICON,
52
+ )
53
+ newsletter_page = st.Page(
54
+ page="demo_pages/newsletters_generation.py",
55
+ title="Newsletter generation",
56
+ icon=NEWSLETTER_ICON,
57
+ )
58
+
59
+ pg = st.navigation(
60
+ {
61
+ "Topic Analysis": [
62
+ data_page,
63
+ topic_exploration_page,
64
+ topic_visualization_page,
65
+ temporal_visualization_page,
66
+ ],
67
+ "Application example": [newsletter_page],
68
+ }
69
+ )
70
+ return pg
71
+
72
+
73
+ def main():
74
+ pg = define_pages()
75
+ st.set_page_config(
76
+ page_title=TITLE,
77
+ layout=LAYOUT,
78
+ initial_sidebar_state="expanded",
79
+ page_icon=":part_alternation_mark:",
80
+ )
81
+ # Restore widget state
82
+ restore_widget_state()
83
+ pg.run()
84
+
85
+
86
+ if __name__ == "__main__":
87
+ main()
@@ -0,0 +1,69 @@
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 numpy as np
6
+ import pandas as pd
7
+ import streamlit as st
8
+ from bertopic import BERTopic
9
+
10
+ from bertrend.utils.data_loading import (
11
+ TIMESTAMP_COLUMN,
12
+ GROUPED_TIMESTAMP_COLUMN,
13
+ TEXT_COLUMN,
14
+ TITLE_COLUMN,
15
+ URL_COLUMN,
16
+ CITATION_COUNT_COL,
17
+ )
18
+
19
+
20
+ def _make_dynamic_topics_split(df: pd.DataFrame, nr_bins: int):
21
+ """
22
+ Split docs into nr_bins and generate a llm_utils timestamp label into a new column
23
+ """
24
+ df = df.sort_values(TIMESTAMP_COLUMN, ascending=False)
25
+ split_df = np.array_split(df, nr_bins)
26
+ for split in split_df:
27
+ split[GROUPED_TIMESTAMP_COLUMN] = split[TIMESTAMP_COLUMN].max()
28
+ return pd.concat(split_df)
29
+
30
+
31
+ @st.cache_data
32
+ def compute_topics_over_time(
33
+ _topic_model: BERTopic,
34
+ df: pd.DataFrame,
35
+ nr_bins: int,
36
+ ):
37
+ """Computes topics over time."""
38
+ df = _make_dynamic_topics_split(df, nr_bins)
39
+ res = _topic_model.topics_over_time(
40
+ df[TEXT_COLUMN],
41
+ df[GROUPED_TIMESTAMP_COLUMN],
42
+ global_tuning=False,
43
+ )
44
+ return res
45
+
46
+
47
+ def print_docs_for_specific_topic(
48
+ df: pd.DataFrame, topics: list[int], topic_number: int
49
+ ):
50
+ """
51
+ Print documents for a specific topic
52
+ """
53
+ columns_list = [
54
+ col
55
+ for col in [
56
+ TITLE_COLUMN,
57
+ TEXT_COLUMN,
58
+ URL_COLUMN,
59
+ TIMESTAMP_COLUMN,
60
+ CITATION_COUNT_COL,
61
+ ]
62
+ if col in df.keys()
63
+ ]
64
+ df = df.loc[pd.Series(topics) == topic_number][columns_list]
65
+ for _, doc in df.iterrows():
66
+ st.write(f"[{doc.title}]({doc.url})")
67
+
68
+
69
+ # TODO: Remove "put embeddings in cache" option since it's unadvised due to the large size of embeddings returned by embedding model (sentence and token embeddings)
@@ -0,0 +1,4 @@
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.