ovos-solver-bm25-plugin 0.0.0__tar.gz

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.
@@ -0,0 +1,344 @@
1
+ Metadata-Version: 2.1
2
+ Name: ovos-solver-bm25-plugin
3
+ Version: 0.0.0
4
+ Summary: A question solver plugin for OVOS
5
+ Home-page: https://github.com/TigreGotico/ovos-solver-BM25-plugin
6
+ Author: jarbasai
7
+ Author-email: jarbasai@mailfence.com
8
+ License: MIT
9
+ Description: # BM25CorpusSolver Plugin
10
+
11
+ BM25CorpusSolver is an OVOS (OpenVoiceOS) plugin designed to retrieve answers from a corpus of documents using the [BM25](https://en.wikipedia.org/wiki/Okapi_BM25)
12
+ algorithm. This solver is ideal for question-answering systems that require efficient and accurate retrieval of
13
+ information from a predefined set of documents.
14
+
15
+ - [Features](#features)
16
+ - [Retrieval Chatbots](#retrieval-chatbots)
17
+ - [Example Solvers](#example-solvers)
18
+ - [SquadQASolver](#squadqasolver)
19
+ - [FreebaseQASolver](#freebaseqasolver)
20
+ - [Implementing a Retrieval Chatbot](#implementing-a-retrieval-chatbot)
21
+ - [BM25CorpusSolver](#bm25corpussolver)
22
+ - [BM25QACorpusSolver](#bm25qacorpussolver)
23
+ - [Limitations of Retrieval Chatbots](#limitations-of-retrieval-chatbots)
24
+ - [ReRanking](#reranking)
25
+ - [BM25MultipleChoiceSolver](#bm25multiplechoicesolver)
26
+ - [BM25EvidenceSolverPlugin](#bm25evidencesolverplugin)
27
+ - [Embeddings Store](#embeddings-store)
28
+ - [Integrating with Persona Framework](#integrating-with-persona-framework)
29
+
30
+
31
+ ## Features
32
+
33
+ - **BM25 Algorithm**: Utilizes the BM25 ranking function for information retrieval, providing relevance-based document scoring.
34
+ - **Configurable**: Allows customization of language, minimum confidence score, and the number of answers to retrieve.
35
+ - **Logging**: Integrates with OVOS logging system for debugging and monitoring.
36
+ - **BM25QACorpusSolver**: Extends `BM25CorpusSolver` to handle question-answer pairs, optimizing the retrieval process for QA datasets.
37
+ - **BM25MultipleChoiceSolver**: Reranks multiple-choice options based on relevance to the query.
38
+ - **BM25EvidenceSolverPlugin**: Extracts the best sentence from a text that answers a question using the BM25 algorithm.
39
+
40
+ ## Retrieval Chatbots
41
+
42
+ Retrieval chatbots use BM25CorpusSolver to provide answers to user queries by searching through a preloaded corpus of documents or QA pairs.
43
+
44
+ These chatbots excel in environments where the information is structured and the queries are straightforward.
45
+
46
+ ### Example solvers
47
+
48
+ #### SquadQASolver
49
+
50
+ The SquadQASolver is a subclass of BM25QACorpusSolver that automatically loads and indexes the [SQuAD dataset](https://rajpurkar.github.io/SQuAD-explorer/) upon initialization.
51
+
52
+ This solver is suitable for usage with the ovos-persona framework.
53
+
54
+ ```python
55
+ from ovos_bm25_solver import SquadQASolver
56
+
57
+ s = SquadQASolver()
58
+ query = "is there life on mars"
59
+ print("Query:", query)
60
+ print("Answer:", s.spoken_answer(query))
61
+ # 2024-07-19 22:31:12.625 - OVOS - __main__:load_corpus:60 - DEBUG - indexed 86769 documents
62
+ # 2024-07-19 22:31:12.625 - OVOS - __main__:load_squad_corpus:119 - INFO - Loaded and indexed 86769 question-answer pairs from SQuAD dataset
63
+ # Query: is there life on mars
64
+ # 2024-07-19 22:31:12.628 - OVOS - __main__:retrieve_from_corpus:69 - DEBUG - Rank 1 (score: 6.334013938903809): How is it postulated that Mars life might have evolved?
65
+ # 2024-07-19 22:31:12.628 - OVOS - __main__:retrieve_from_corpus:93 - DEBUG - closest question in corpus: How is it postulated that Mars life might have evolved?
66
+ # Answer: similar to Antarctic
67
+ ```
68
+
69
+ #### FreebaseQASolver
70
+
71
+ The FreebaseQASolver is a subclass of BM25QACorpusSolver that automatically loads and indexes the [FreebaseQA dataset](https://github.com/kelvin-jiang/FreebaseQA) upon initialization.
72
+
73
+ This solver is suitable for usage with the ovos-persona framework.
74
+
75
+ ```python
76
+ from ovos_bm25_solver import FreebaseQASolver
77
+
78
+ s = FreebaseQASolver()
79
+ query = "What is the capital of France"
80
+ print("Query:", query)
81
+ print("Answer:", s.spoken_answer(query))
82
+ # 2024-07-19 22:31:09.468 - OVOS - __main__:load_corpus:60 - DEBUG - indexed 20357 documents
83
+ # Query: What is the capital of France
84
+ # 2024-07-19 22:31:09.468 - OVOS - __main__:retrieve_from_corpus:69 - DEBUG - Rank 1 (score: 5.996074199676514): what is the capital of france
85
+ # 2024-07-19 22:31:09.469 - OVOS - __main__:retrieve_from_corpus:93 - DEBUG - closest question in corpus: what is the capital of france
86
+ # Answer: paris
87
+ ```
88
+
89
+ ### Implementing a Retrieval Chatbot
90
+
91
+ To use the BM25CorpusSolver, you need to create an instance of the solver, load your corpus, and then query it.
92
+
93
+ #### BM25CorpusSolver
94
+
95
+ This class is meant to be used to create your own solvers with a dedicated corpus.
96
+
97
+ ```python
98
+ from ovos_bm25_solver import BM25CorpusSolver
99
+
100
+ config = {
101
+ "lang": "en-us",
102
+ "min_conf": 0.4,
103
+ "n_answer": 2
104
+ }
105
+ solver = BM25CorpusSolver(config)
106
+
107
+ corpus = [
108
+ "a cat is a feline and likes to purr",
109
+ "a dog is the human's best friend and loves to play",
110
+ "a bird is a beautiful animal that can fly",
111
+ "a fish is a creature that lives in water and swims",
112
+ ]
113
+ solver.load_corpus(corpus)
114
+
115
+ query = "does the fish purr like a cat?"
116
+ answer = solver.get_spoken_answer(query)
117
+ print(answer)
118
+
119
+ # Expected Output:
120
+ # 2024-07-19 20:03:29.979 - OVOS - ovos_plugin_manager.utils.config:get_plugin_config:40 - DEBUG - Loaded configuration: {'module': 'ovos-translate-plugin-server', 'lang': 'en-us'}
121
+ # 2024-07-19 20:03:30.024 - OVOS - __main__:load_corpus:28 - DEBUG - indexed 4 documents
122
+ # 2024-07-19 20:03:30.025 - OVOS - __main__:retrieve_from_corpus:37 - DEBUG - Rank 1 (score: 1.0584375858306885): a cat is a feline and likes to purr
123
+ # 2024-07-19 20:03:30.025 - OVOS - __main__:retrieve_from_corpus:37 - DEBUG - Rank 2 (score: 0.481589138507843): a fish is a creature that lives in water and swims
124
+ # a cat is a feline and likes to purr. a fish is a creature that lives in water and swims
125
+ ```
126
+
127
+ #### BM25QACorpusSolver
128
+
129
+ This class is meant to be used to create your own solvers with a dedicated corpus
130
+
131
+ BM25QACorpusSolver is an extension of BM25CorpusSolver, designed to work with question-answer pairs. It is particularly
132
+ useful when working with datasets like SQuAD, FreebaseQA, or similar QA datasets.
133
+
134
+ ```python
135
+ import requests
136
+ from ovos_bm25_solver import BM25QACorpusSolver
137
+
138
+ # Load SQuAD dataset
139
+ corpus = {}
140
+ data = requests.get("https://github.com/chrischute/squad/raw/master/data/train-v2.0.json").json()
141
+ for s in data["data"]:
142
+ for p in s["paragraphs"]:
143
+ for qa in p["qas"]:
144
+ if "question" in qa and qa["answers"]:
145
+ corpus[qa["question"]] = qa["answers"][0]["text"]
146
+
147
+ # Load FreebaseQA dataset
148
+ data = requests.get("https://github.com/kelvin-jiang/FreebaseQA/raw/master/FreebaseQA-train.json").json()
149
+ for qa in data["Questions"]:
150
+ q = qa["ProcessedQuestion"]
151
+ a = qa["Parses"][0]["Answers"][0]["AnswersName"][0]
152
+ corpus[q] = a
153
+
154
+ # Initialize BM25QACorpusSolver with config
155
+ config = {
156
+ "lang": "en-us",
157
+ "min_conf": 0.4,
158
+ "n_answer": 1
159
+ }
160
+ solver = BM25QACorpusSolver(config)
161
+ solver.load_corpus(corpus)
162
+
163
+ query = "is there life on mars?"
164
+ answer = solver.get_spoken_answer(query)
165
+ print("Query:", query)
166
+ print("Answer:", answer)
167
+
168
+ # Expected Output:
169
+ # 86769 qa pairs imports from squad dataset
170
+ # 20357 qa pairs imports from freebaseQA dataset
171
+ # 2024-07-19 21:49:31.360 - OVOS - ovos_plugin_manager.language:create:233 - INFO - Loaded the Language Translation plugin ovos-translate-plugin-server
172
+ # 2024-07-19 21:49:31.360 - OVOS - ovos_plugin_manager.utils.config:get_plugin_config:40 - DEBUG - Loaded configuration: {'module': 'ovos-translate-plugin-server', 'lang': 'en-us'}
173
+ # 2024-07-19 21:49:32.759 - OVOS - __main__:load_corpus:61 - DEBUG - indexed 107126 documents
174
+ # Query: is there life on mars
175
+ # 2024-07-19 21:49:32.760 - OVOS - __main__:retrieve_from_corpus:70 - DEBUG - Rank 1 (score: 6.037893295288086): How is it postulated that Mars life might have evolved?
176
+ # 2024-07-19 21:49:32.760 - OVOS - __main__:retrieve_from_corpus:94 - DEBUG - closest question in corpus: How is it postulated that Mars life might have evolved?
177
+ # Answer: similar to Antarctic
178
+ ```
179
+
180
+ In this example, BM25QACorpusSolver is used to load a large corpus of question-answer pairs from the SQuAD and
181
+ FreebaseQA datasets. The solver retrieves the best matching answer for the given query.
182
+
183
+ ### Limitations of Retrieval Chatbots
184
+
185
+ Retrieval chatbots, while powerful, have certain limitations. These include:
186
+
187
+ 1. **Dependence on Corpus Quality and Size**: The accuracy of a retrieval chatbot heavily relies on the quality and comprehensiveness of the underlying corpus. A limited or biased corpus can lead to inaccurate or irrelevant responses.
188
+ 2. **Static Knowledge Base**: Unlike generative models, retrieval chatbots can't generate new information or answers. They can only retrieve and rephrase content from the pre-existing corpus.
189
+ 3. **Contextual Understanding**: While advanced algorithms like BM25 can rank documents based on relevance, they may still struggle with understanding nuanced or complex queries, especially those requiring deep contextual understanding.
190
+ 4. **Scalability**: As the size of the corpus increases, the computational resources required for indexing and retrieving relevant documents also increase, potentially impacting performance.
191
+ 5. **Dynamic Updates**: Keeping the corpus updated with the latest information can be challenging, especially in fast-evolving domains.
192
+
193
+ Despite these limitations, retrieval chatbots are effective for domains where the corpus is well-defined and relatively static, such as FAQs, documentation, and knowledge bases.
194
+
195
+ ### ReRanking
196
+
197
+ ReRanking is a technique used to refine a list of potential answers by evaluating their relevance to a given query.
198
+ This process is crucial in scenarios where multiple options or responses need to be assessed to determine the most appropriate one.
199
+
200
+ In retrieval chatbots, ReRanking helps in selecting the best answer from a set of retrieved documents or options, enhancing the accuracy of the response provided to the user.
201
+
202
+ `MultipleChoiceSolver` are integrated into the OVOS Common Query framework, where they are used to select the most relevant answer from a set of multiple skill responses.
203
+
204
+ #### BM25MultipleChoiceSolver
205
+
206
+ BM25MultipleChoiceSolver is designed to select the best answer to a question from a list of options.
207
+
208
+ In the context of retrieval chatbots, BM25MultipleChoiceSolver is useful for scenarios where a user query results in a list of predefined answers or options.
209
+ The solver ranks these options based on their relevance to the query and selects the most suitable one.
210
+
211
+
212
+ ```python
213
+ from ovos_bm25_solver import BM25MultipleChoiceSolver
214
+
215
+ solver = BM25MultipleChoiceSolver()
216
+ a = solver.rerank("what is the speed of light", [
217
+ "very fast", "10m/s", "the speed of light is C"
218
+ ])
219
+ print(a)
220
+ # 2024-07-22 15:03:10.295 - OVOS - __main__:load_corpus:61 - DEBUG - indexed 3 documents
221
+ # 2024-07-22 15:03:10.297 - OVOS - __main__:retrieve_from_corpus:70 - DEBUG - Rank 1 (score: 0.7198746800422668): the speed of light is C
222
+ # 2024-07-22 15:03:10.297 - OVOS - __main__:retrieve_from_corpus:70 - DEBUG - Rank 2 (score: 0.0): 10m/s
223
+ # 2024-07-22 15:03:10.297 - OVOS - __main__:retrieve_from_corpus:70 - DEBUG - Rank 3 (score: 0.0): very fast
224
+ # [(0.7198747, 'the speed of light is C'), (0.0, '10m/s'), (0.0, 'very fast')]
225
+
226
+ # NOTE: select_answer is part of the MultipleChoiceSolver base class and uses rerank internally
227
+ a = solver.select_answer("what is the speed of light", [
228
+ "very fast", "10m/s", "the speed of light is C"
229
+ ])
230
+ print(a) # the speed of light is C
231
+ ```
232
+
233
+ #### BM25EvidenceSolverPlugin
234
+
235
+ BM25EvidenceSolverPlugin is designed to extract the most relevant sentence from a text passage that answers a given question. This plugin uses the BM25 algorithm to evaluate and rank sentences based on their relevance to the query.
236
+
237
+ In text extraction and machine comprehension tasks, BM25EvidenceSolverPlugin enables the identification of specific sentences within a larger body of text that directly address a user's query.
238
+
239
+ For example, in a scenario where a user queries about the number of rovers exploring Mars, BM25EvidenceSolverPlugin scans the provided text passage, ranks sentences based on their relevance, and extracts the most informative sentence.
240
+
241
+ ```python
242
+ from ovos_bm25_solver import BM25EvidenceSolverPlugin
243
+
244
+ config = {
245
+ "lang": "en-us",
246
+ "min_conf": 0.4,
247
+ "n_answer": 1
248
+ }
249
+ solver = BM25EvidenceSolverPlugin(config)
250
+
251
+ text = """Mars is the fourth planet from the Sun. It is a dusty, cold, desert world with a very thin atmosphere.
252
+ Mars is also a dynamic planet with seasons, polar ice caps, canyons, extinct volcanoes, and evidence that it was even more active in the past.
253
+ Mars is one of the most explored bodies in our solar system, and it's the only planet where we've sent rovers to roam the alien landscape.
254
+ NASA currently has two rovers (Curiosity and Perseverance), one lander (InSight), and one helicopter (Ingenuity) exploring the surface of Mars.
255
+ """
256
+ query = "how many rovers are currently exploring Mars"
257
+ answer = solver.get_best_passage(evidence=text, question=query)
258
+ print("Query:", query)
259
+ print("Answer:", answer)
260
+ # 2024-07-22 15:05:14.209 - OVOS - __main__:load_corpus:61 - DEBUG - indexed 5 documents
261
+ # 2024-07-22 15:05:14.209 - OVOS - __main__:retrieve_from_corpus:70 - DEBUG - Rank 1 (score: 1.39238703250885): NASA currently has two rovers (Curiosity and Perseverance), one lander (InSight), and one helicopter (Ingenuity) exploring the surface of Mars.
262
+ # 2024-07-22 15:05:14.210 - OVOS - __main__:retrieve_from_corpus:70 - DEBUG - Rank 2 (score: 0.38667747378349304): Mars is one of the most explored bodies in our solar system, and it's the only planet where we've sent rovers to roam the alien landscape.
263
+ # 2024-07-22 15:05:14.210 - OVOS - __main__:retrieve_from_corpus:70 - DEBUG - Rank 3 (score: 0.15732118487358093): Mars is the fourth planet from the Sun.
264
+ # 2024-07-22 15:05:14.210 - OVOS - __main__:retrieve_from_corpus:70 - DEBUG - Rank 4 (score: 0.10177625715732574): Mars is also a dynamic planet with seasons, polar ice caps, canyons, extinct volcanoes, and evidence that it was even more active in the past.
265
+ # 2024-07-22 15:05:14.210 - OVOS - __main__:retrieve_from_corpus:70 - DEBUG - Rank 5 (score: 0.0): It is a dusty, cold, desert world with a very thin atmosphere.
266
+ # Query: how many rovers are currently exploring Mars
267
+ # Answer: NASA currently has two rovers (Curiosity and Perseverance), one lander (InSight), and one helicopter (Ingenuity) exploring the surface of Mars.
268
+
269
+ ```
270
+
271
+ In this example, `BM25EvidenceSolverPlugin` effectively identifies and retrieves the most relevant sentence from the provided text that answers the query about the number of rovers exploring Mars.
272
+ This capability is essential for applications requiring information extraction from extensive textual content, such as automated research assistants or content summarizers.
273
+
274
+ ## Embeddings Store
275
+
276
+ A fake embeddings store is provided using only text search
277
+
278
+ > NOTE: this does not scale to large datasets
279
+
280
+ ```python
281
+ from ovos_bm25_solver.embed import JsonEmbeddingsDB, BM25TextEmbeddingsStore
282
+ db = JsonEmbeddingsDB("bm25_index")
283
+ # Initialize the BM25 text embeddings store
284
+ index = BM25TextEmbeddingsStore(db=db)
285
+
286
+ # Add documents to the database
287
+ text = "hello world"
288
+ text2 = "goodbye cruel world"
289
+ index.add_document(text)
290
+ index.add_document(text2)
291
+
292
+ # Querying with fuzzy match
293
+ results = db.query("the world", top_k=2)
294
+ print("Fuzzy Match Results:", results)
295
+
296
+ # Querying with BM25
297
+ results = index.query("the world", top_k=2)
298
+ print("BM25 Query Results:", results)
299
+
300
+ # Comparing strings using fuzzy match
301
+ distance = index.distance(text, text2)
302
+ print("Distance between strings:", distance)
303
+ ```
304
+
305
+ ## Integrating with Persona Framework
306
+
307
+ To use the `SquadQASolver` and `FreebaseQASolver` in the persona framework, you can define a persona configuration file and specify the solvers to be used.
308
+
309
+ Here's an example of how to define a persona that uses the `SquadQASolver` and `FreebaseQASolver`:
310
+
311
+ 1. Create a persona configuration file, e.g., `qa_persona.json`:
312
+
313
+ ```json
314
+ {
315
+ "name": "QAPersona",
316
+ "solvers": [
317
+ "ovos-solver-squadqa-plugin",
318
+ "ovos-solver-freebaseqa-plugin",
319
+ "ovos-solver-failure-plugin"
320
+ ]
321
+ }
322
+ ```
323
+
324
+ 2. Run [ovos-persona-server](https://github.com/OpenVoiceOS/ovos-persona-server) with the defined persona:
325
+
326
+ ```bash
327
+ $ ovos-persona-server --persona qa_persona.json
328
+ ```
329
+
330
+ In this example, the persona named "QAPersona" will first use the `SquadQASolver` to answer questions. If it cannot find an answer, it will fall back to the `FreebaseQASolver`. Finally, it will use the `ovos-solver-failure-plugin` to ensure it always responds with something, even if the previous solvers fail.
331
+
332
+
333
+ Check setup.py for reference in how to package your own corpus backed solvers
334
+
335
+ ```python
336
+ PLUGIN_ENTRY_POINTS = [
337
+ 'ovos-solver-bm25-squad-plugin=ovos_bm25_solver:SquadQASolver',
338
+ 'ovos-solver-bm25-freebase-plugin=ovos_bm25_solver:FreebaseQASolver'
339
+ ]
340
+ ```
341
+
342
+ Keywords: OVOS openvoiceos plugin utterance fallback query
343
+ Platform: UNKNOWN
344
+ Description-Content-Type: text/markdown
@@ -0,0 +1,332 @@
1
+ # BM25CorpusSolver Plugin
2
+
3
+ BM25CorpusSolver is an OVOS (OpenVoiceOS) plugin designed to retrieve answers from a corpus of documents using the [BM25](https://en.wikipedia.org/wiki/Okapi_BM25)
4
+ algorithm. This solver is ideal for question-answering systems that require efficient and accurate retrieval of
5
+ information from a predefined set of documents.
6
+
7
+ - [Features](#features)
8
+ - [Retrieval Chatbots](#retrieval-chatbots)
9
+ - [Example Solvers](#example-solvers)
10
+ - [SquadQASolver](#squadqasolver)
11
+ - [FreebaseQASolver](#freebaseqasolver)
12
+ - [Implementing a Retrieval Chatbot](#implementing-a-retrieval-chatbot)
13
+ - [BM25CorpusSolver](#bm25corpussolver)
14
+ - [BM25QACorpusSolver](#bm25qacorpussolver)
15
+ - [Limitations of Retrieval Chatbots](#limitations-of-retrieval-chatbots)
16
+ - [ReRanking](#reranking)
17
+ - [BM25MultipleChoiceSolver](#bm25multiplechoicesolver)
18
+ - [BM25EvidenceSolverPlugin](#bm25evidencesolverplugin)
19
+ - [Embeddings Store](#embeddings-store)
20
+ - [Integrating with Persona Framework](#integrating-with-persona-framework)
21
+
22
+
23
+ ## Features
24
+
25
+ - **BM25 Algorithm**: Utilizes the BM25 ranking function for information retrieval, providing relevance-based document scoring.
26
+ - **Configurable**: Allows customization of language, minimum confidence score, and the number of answers to retrieve.
27
+ - **Logging**: Integrates with OVOS logging system for debugging and monitoring.
28
+ - **BM25QACorpusSolver**: Extends `BM25CorpusSolver` to handle question-answer pairs, optimizing the retrieval process for QA datasets.
29
+ - **BM25MultipleChoiceSolver**: Reranks multiple-choice options based on relevance to the query.
30
+ - **BM25EvidenceSolverPlugin**: Extracts the best sentence from a text that answers a question using the BM25 algorithm.
31
+
32
+ ## Retrieval Chatbots
33
+
34
+ Retrieval chatbots use BM25CorpusSolver to provide answers to user queries by searching through a preloaded corpus of documents or QA pairs.
35
+
36
+ These chatbots excel in environments where the information is structured and the queries are straightforward.
37
+
38
+ ### Example solvers
39
+
40
+ #### SquadQASolver
41
+
42
+ The SquadQASolver is a subclass of BM25QACorpusSolver that automatically loads and indexes the [SQuAD dataset](https://rajpurkar.github.io/SQuAD-explorer/) upon initialization.
43
+
44
+ This solver is suitable for usage with the ovos-persona framework.
45
+
46
+ ```python
47
+ from ovos_bm25_solver import SquadQASolver
48
+
49
+ s = SquadQASolver()
50
+ query = "is there life on mars"
51
+ print("Query:", query)
52
+ print("Answer:", s.spoken_answer(query))
53
+ # 2024-07-19 22:31:12.625 - OVOS - __main__:load_corpus:60 - DEBUG - indexed 86769 documents
54
+ # 2024-07-19 22:31:12.625 - OVOS - __main__:load_squad_corpus:119 - INFO - Loaded and indexed 86769 question-answer pairs from SQuAD dataset
55
+ # Query: is there life on mars
56
+ # 2024-07-19 22:31:12.628 - OVOS - __main__:retrieve_from_corpus:69 - DEBUG - Rank 1 (score: 6.334013938903809): How is it postulated that Mars life might have evolved?
57
+ # 2024-07-19 22:31:12.628 - OVOS - __main__:retrieve_from_corpus:93 - DEBUG - closest question in corpus: How is it postulated that Mars life might have evolved?
58
+ # Answer: similar to Antarctic
59
+ ```
60
+
61
+ #### FreebaseQASolver
62
+
63
+ The FreebaseQASolver is a subclass of BM25QACorpusSolver that automatically loads and indexes the [FreebaseQA dataset](https://github.com/kelvin-jiang/FreebaseQA) upon initialization.
64
+
65
+ This solver is suitable for usage with the ovos-persona framework.
66
+
67
+ ```python
68
+ from ovos_bm25_solver import FreebaseQASolver
69
+
70
+ s = FreebaseQASolver()
71
+ query = "What is the capital of France"
72
+ print("Query:", query)
73
+ print("Answer:", s.spoken_answer(query))
74
+ # 2024-07-19 22:31:09.468 - OVOS - __main__:load_corpus:60 - DEBUG - indexed 20357 documents
75
+ # Query: What is the capital of France
76
+ # 2024-07-19 22:31:09.468 - OVOS - __main__:retrieve_from_corpus:69 - DEBUG - Rank 1 (score: 5.996074199676514): what is the capital of france
77
+ # 2024-07-19 22:31:09.469 - OVOS - __main__:retrieve_from_corpus:93 - DEBUG - closest question in corpus: what is the capital of france
78
+ # Answer: paris
79
+ ```
80
+
81
+ ### Implementing a Retrieval Chatbot
82
+
83
+ To use the BM25CorpusSolver, you need to create an instance of the solver, load your corpus, and then query it.
84
+
85
+ #### BM25CorpusSolver
86
+
87
+ This class is meant to be used to create your own solvers with a dedicated corpus.
88
+
89
+ ```python
90
+ from ovos_bm25_solver import BM25CorpusSolver
91
+
92
+ config = {
93
+ "lang": "en-us",
94
+ "min_conf": 0.4,
95
+ "n_answer": 2
96
+ }
97
+ solver = BM25CorpusSolver(config)
98
+
99
+ corpus = [
100
+ "a cat is a feline and likes to purr",
101
+ "a dog is the human's best friend and loves to play",
102
+ "a bird is a beautiful animal that can fly",
103
+ "a fish is a creature that lives in water and swims",
104
+ ]
105
+ solver.load_corpus(corpus)
106
+
107
+ query = "does the fish purr like a cat?"
108
+ answer = solver.get_spoken_answer(query)
109
+ print(answer)
110
+
111
+ # Expected Output:
112
+ # 2024-07-19 20:03:29.979 - OVOS - ovos_plugin_manager.utils.config:get_plugin_config:40 - DEBUG - Loaded configuration: {'module': 'ovos-translate-plugin-server', 'lang': 'en-us'}
113
+ # 2024-07-19 20:03:30.024 - OVOS - __main__:load_corpus:28 - DEBUG - indexed 4 documents
114
+ # 2024-07-19 20:03:30.025 - OVOS - __main__:retrieve_from_corpus:37 - DEBUG - Rank 1 (score: 1.0584375858306885): a cat is a feline and likes to purr
115
+ # 2024-07-19 20:03:30.025 - OVOS - __main__:retrieve_from_corpus:37 - DEBUG - Rank 2 (score: 0.481589138507843): a fish is a creature that lives in water and swims
116
+ # a cat is a feline and likes to purr. a fish is a creature that lives in water and swims
117
+ ```
118
+
119
+ #### BM25QACorpusSolver
120
+
121
+ This class is meant to be used to create your own solvers with a dedicated corpus
122
+
123
+ BM25QACorpusSolver is an extension of BM25CorpusSolver, designed to work with question-answer pairs. It is particularly
124
+ useful when working with datasets like SQuAD, FreebaseQA, or similar QA datasets.
125
+
126
+ ```python
127
+ import requests
128
+ from ovos_bm25_solver import BM25QACorpusSolver
129
+
130
+ # Load SQuAD dataset
131
+ corpus = {}
132
+ data = requests.get("https://github.com/chrischute/squad/raw/master/data/train-v2.0.json").json()
133
+ for s in data["data"]:
134
+ for p in s["paragraphs"]:
135
+ for qa in p["qas"]:
136
+ if "question" in qa and qa["answers"]:
137
+ corpus[qa["question"]] = qa["answers"][0]["text"]
138
+
139
+ # Load FreebaseQA dataset
140
+ data = requests.get("https://github.com/kelvin-jiang/FreebaseQA/raw/master/FreebaseQA-train.json").json()
141
+ for qa in data["Questions"]:
142
+ q = qa["ProcessedQuestion"]
143
+ a = qa["Parses"][0]["Answers"][0]["AnswersName"][0]
144
+ corpus[q] = a
145
+
146
+ # Initialize BM25QACorpusSolver with config
147
+ config = {
148
+ "lang": "en-us",
149
+ "min_conf": 0.4,
150
+ "n_answer": 1
151
+ }
152
+ solver = BM25QACorpusSolver(config)
153
+ solver.load_corpus(corpus)
154
+
155
+ query = "is there life on mars?"
156
+ answer = solver.get_spoken_answer(query)
157
+ print("Query:", query)
158
+ print("Answer:", answer)
159
+
160
+ # Expected Output:
161
+ # 86769 qa pairs imports from squad dataset
162
+ # 20357 qa pairs imports from freebaseQA dataset
163
+ # 2024-07-19 21:49:31.360 - OVOS - ovos_plugin_manager.language:create:233 - INFO - Loaded the Language Translation plugin ovos-translate-plugin-server
164
+ # 2024-07-19 21:49:31.360 - OVOS - ovos_plugin_manager.utils.config:get_plugin_config:40 - DEBUG - Loaded configuration: {'module': 'ovos-translate-plugin-server', 'lang': 'en-us'}
165
+ # 2024-07-19 21:49:32.759 - OVOS - __main__:load_corpus:61 - DEBUG - indexed 107126 documents
166
+ # Query: is there life on mars
167
+ # 2024-07-19 21:49:32.760 - OVOS - __main__:retrieve_from_corpus:70 - DEBUG - Rank 1 (score: 6.037893295288086): How is it postulated that Mars life might have evolved?
168
+ # 2024-07-19 21:49:32.760 - OVOS - __main__:retrieve_from_corpus:94 - DEBUG - closest question in corpus: How is it postulated that Mars life might have evolved?
169
+ # Answer: similar to Antarctic
170
+ ```
171
+
172
+ In this example, BM25QACorpusSolver is used to load a large corpus of question-answer pairs from the SQuAD and
173
+ FreebaseQA datasets. The solver retrieves the best matching answer for the given query.
174
+
175
+ ### Limitations of Retrieval Chatbots
176
+
177
+ Retrieval chatbots, while powerful, have certain limitations. These include:
178
+
179
+ 1. **Dependence on Corpus Quality and Size**: The accuracy of a retrieval chatbot heavily relies on the quality and comprehensiveness of the underlying corpus. A limited or biased corpus can lead to inaccurate or irrelevant responses.
180
+ 2. **Static Knowledge Base**: Unlike generative models, retrieval chatbots can't generate new information or answers. They can only retrieve and rephrase content from the pre-existing corpus.
181
+ 3. **Contextual Understanding**: While advanced algorithms like BM25 can rank documents based on relevance, they may still struggle with understanding nuanced or complex queries, especially those requiring deep contextual understanding.
182
+ 4. **Scalability**: As the size of the corpus increases, the computational resources required for indexing and retrieving relevant documents also increase, potentially impacting performance.
183
+ 5. **Dynamic Updates**: Keeping the corpus updated with the latest information can be challenging, especially in fast-evolving domains.
184
+
185
+ Despite these limitations, retrieval chatbots are effective for domains where the corpus is well-defined and relatively static, such as FAQs, documentation, and knowledge bases.
186
+
187
+ ### ReRanking
188
+
189
+ ReRanking is a technique used to refine a list of potential answers by evaluating their relevance to a given query.
190
+ This process is crucial in scenarios where multiple options or responses need to be assessed to determine the most appropriate one.
191
+
192
+ In retrieval chatbots, ReRanking helps in selecting the best answer from a set of retrieved documents or options, enhancing the accuracy of the response provided to the user.
193
+
194
+ `MultipleChoiceSolver` are integrated into the OVOS Common Query framework, where they are used to select the most relevant answer from a set of multiple skill responses.
195
+
196
+ #### BM25MultipleChoiceSolver
197
+
198
+ BM25MultipleChoiceSolver is designed to select the best answer to a question from a list of options.
199
+
200
+ In the context of retrieval chatbots, BM25MultipleChoiceSolver is useful for scenarios where a user query results in a list of predefined answers or options.
201
+ The solver ranks these options based on their relevance to the query and selects the most suitable one.
202
+
203
+
204
+ ```python
205
+ from ovos_bm25_solver import BM25MultipleChoiceSolver
206
+
207
+ solver = BM25MultipleChoiceSolver()
208
+ a = solver.rerank("what is the speed of light", [
209
+ "very fast", "10m/s", "the speed of light is C"
210
+ ])
211
+ print(a)
212
+ # 2024-07-22 15:03:10.295 - OVOS - __main__:load_corpus:61 - DEBUG - indexed 3 documents
213
+ # 2024-07-22 15:03:10.297 - OVOS - __main__:retrieve_from_corpus:70 - DEBUG - Rank 1 (score: 0.7198746800422668): the speed of light is C
214
+ # 2024-07-22 15:03:10.297 - OVOS - __main__:retrieve_from_corpus:70 - DEBUG - Rank 2 (score: 0.0): 10m/s
215
+ # 2024-07-22 15:03:10.297 - OVOS - __main__:retrieve_from_corpus:70 - DEBUG - Rank 3 (score: 0.0): very fast
216
+ # [(0.7198747, 'the speed of light is C'), (0.0, '10m/s'), (0.0, 'very fast')]
217
+
218
+ # NOTE: select_answer is part of the MultipleChoiceSolver base class and uses rerank internally
219
+ a = solver.select_answer("what is the speed of light", [
220
+ "very fast", "10m/s", "the speed of light is C"
221
+ ])
222
+ print(a) # the speed of light is C
223
+ ```
224
+
225
+ #### BM25EvidenceSolverPlugin
226
+
227
+ BM25EvidenceSolverPlugin is designed to extract the most relevant sentence from a text passage that answers a given question. This plugin uses the BM25 algorithm to evaluate and rank sentences based on their relevance to the query.
228
+
229
+ In text extraction and machine comprehension tasks, BM25EvidenceSolverPlugin enables the identification of specific sentences within a larger body of text that directly address a user's query.
230
+
231
+ For example, in a scenario where a user queries about the number of rovers exploring Mars, BM25EvidenceSolverPlugin scans the provided text passage, ranks sentences based on their relevance, and extracts the most informative sentence.
232
+
233
+ ```python
234
+ from ovos_bm25_solver import BM25EvidenceSolverPlugin
235
+
236
+ config = {
237
+ "lang": "en-us",
238
+ "min_conf": 0.4,
239
+ "n_answer": 1
240
+ }
241
+ solver = BM25EvidenceSolverPlugin(config)
242
+
243
+ text = """Mars is the fourth planet from the Sun. It is a dusty, cold, desert world with a very thin atmosphere.
244
+ Mars is also a dynamic planet with seasons, polar ice caps, canyons, extinct volcanoes, and evidence that it was even more active in the past.
245
+ Mars is one of the most explored bodies in our solar system, and it's the only planet where we've sent rovers to roam the alien landscape.
246
+ NASA currently has two rovers (Curiosity and Perseverance), one lander (InSight), and one helicopter (Ingenuity) exploring the surface of Mars.
247
+ """
248
+ query = "how many rovers are currently exploring Mars"
249
+ answer = solver.get_best_passage(evidence=text, question=query)
250
+ print("Query:", query)
251
+ print("Answer:", answer)
252
+ # 2024-07-22 15:05:14.209 - OVOS - __main__:load_corpus:61 - DEBUG - indexed 5 documents
253
+ # 2024-07-22 15:05:14.209 - OVOS - __main__:retrieve_from_corpus:70 - DEBUG - Rank 1 (score: 1.39238703250885): NASA currently has two rovers (Curiosity and Perseverance), one lander (InSight), and one helicopter (Ingenuity) exploring the surface of Mars.
254
+ # 2024-07-22 15:05:14.210 - OVOS - __main__:retrieve_from_corpus:70 - DEBUG - Rank 2 (score: 0.38667747378349304): Mars is one of the most explored bodies in our solar system, and it's the only planet where we've sent rovers to roam the alien landscape.
255
+ # 2024-07-22 15:05:14.210 - OVOS - __main__:retrieve_from_corpus:70 - DEBUG - Rank 3 (score: 0.15732118487358093): Mars is the fourth planet from the Sun.
256
+ # 2024-07-22 15:05:14.210 - OVOS - __main__:retrieve_from_corpus:70 - DEBUG - Rank 4 (score: 0.10177625715732574): Mars is also a dynamic planet with seasons, polar ice caps, canyons, extinct volcanoes, and evidence that it was even more active in the past.
257
+ # 2024-07-22 15:05:14.210 - OVOS - __main__:retrieve_from_corpus:70 - DEBUG - Rank 5 (score: 0.0): It is a dusty, cold, desert world with a very thin atmosphere.
258
+ # Query: how many rovers are currently exploring Mars
259
+ # Answer: NASA currently has two rovers (Curiosity and Perseverance), one lander (InSight), and one helicopter (Ingenuity) exploring the surface of Mars.
260
+
261
+ ```
262
+
263
+ In this example, `BM25EvidenceSolverPlugin` effectively identifies and retrieves the most relevant sentence from the provided text that answers the query about the number of rovers exploring Mars.
264
+ This capability is essential for applications requiring information extraction from extensive textual content, such as automated research assistants or content summarizers.
265
+
266
+ ## Embeddings Store
267
+
268
+ A fake embeddings store is provided using only text search
269
+
270
+ > NOTE: this does not scale to large datasets
271
+
272
+ ```python
273
+ from ovos_bm25_solver.embed import JsonEmbeddingsDB, BM25TextEmbeddingsStore
274
+ db = JsonEmbeddingsDB("bm25_index")
275
+ # Initialize the BM25 text embeddings store
276
+ index = BM25TextEmbeddingsStore(db=db)
277
+
278
+ # Add documents to the database
279
+ text = "hello world"
280
+ text2 = "goodbye cruel world"
281
+ index.add_document(text)
282
+ index.add_document(text2)
283
+
284
+ # Querying with fuzzy match
285
+ results = db.query("the world", top_k=2)
286
+ print("Fuzzy Match Results:", results)
287
+
288
+ # Querying with BM25
289
+ results = index.query("the world", top_k=2)
290
+ print("BM25 Query Results:", results)
291
+
292
+ # Comparing strings using fuzzy match
293
+ distance = index.distance(text, text2)
294
+ print("Distance between strings:", distance)
295
+ ```
296
+
297
+ ## Integrating with Persona Framework
298
+
299
+ To use the `SquadQASolver` and `FreebaseQASolver` in the persona framework, you can define a persona configuration file and specify the solvers to be used.
300
+
301
+ Here's an example of how to define a persona that uses the `SquadQASolver` and `FreebaseQASolver`:
302
+
303
+ 1. Create a persona configuration file, e.g., `qa_persona.json`:
304
+
305
+ ```json
306
+ {
307
+ "name": "QAPersona",
308
+ "solvers": [
309
+ "ovos-solver-squadqa-plugin",
310
+ "ovos-solver-freebaseqa-plugin",
311
+ "ovos-solver-failure-plugin"
312
+ ]
313
+ }
314
+ ```
315
+
316
+ 2. Run [ovos-persona-server](https://github.com/OpenVoiceOS/ovos-persona-server) with the defined persona:
317
+
318
+ ```bash
319
+ $ ovos-persona-server --persona qa_persona.json
320
+ ```
321
+
322
+ In this example, the persona named "QAPersona" will first use the `SquadQASolver` to answer questions. If it cannot find an answer, it will fall back to the `FreebaseQASolver`. Finally, it will use the `ovos-solver-failure-plugin` to ensure it always responds with something, even if the previous solvers fail.
323
+
324
+
325
+ Check setup.py for reference in how to package your own corpus backed solvers
326
+
327
+ ```python
328
+ PLUGIN_ENTRY_POINTS = [
329
+ 'ovos-solver-bm25-squad-plugin=ovos_bm25_solver:SquadQASolver',
330
+ 'ovos-solver-bm25-freebase-plugin=ovos_bm25_solver:FreebaseQASolver'
331
+ ]
332
+ ```