Spaces:
Runtime error
Runtime error
Cascade Bot
commited on
Commit
·
bb6f0d3
1
Parent(s):
c7d9c30
Renamed BayesianReasoning to BayesianStrategy and fixed imports
Browse files- reasoning/__init__.py +2 -2
- reasoning/bayesian.py +157 -194
reasoning/__init__.py
CHANGED
@@ -39,7 +39,7 @@ from .local_llm import LocalLLMStrategy
|
|
39 |
|
40 |
# Advanced reasoning strategies
|
41 |
from .multimodal import MultiModalReasoning
|
42 |
-
from .bayesian import
|
43 |
from .quantum import QuantumReasoning
|
44 |
from .neurosymbolic import NeurosymbolicReasoning
|
45 |
from .emergent import EmergentReasoning
|
@@ -72,7 +72,7 @@ __all__ = [
|
|
72 |
|
73 |
# Advanced reasoning
|
74 |
'MultiModalReasoning',
|
75 |
-
'
|
76 |
'QuantumReasoning',
|
77 |
'NeurosymbolicReasoning',
|
78 |
'EmergentReasoning',
|
|
|
39 |
|
40 |
# Advanced reasoning strategies
|
41 |
from .multimodal import MultiModalReasoning
|
42 |
+
from .bayesian import BayesianStrategy
|
43 |
from .quantum import QuantumReasoning
|
44 |
from .neurosymbolic import NeurosymbolicReasoning
|
45 |
from .emergent import EmergentReasoning
|
|
|
72 |
|
73 |
# Advanced reasoning
|
74 |
'MultiModalReasoning',
|
75 |
+
'BayesianStrategy',
|
76 |
'QuantumReasoning',
|
77 |
'NeurosymbolicReasoning',
|
78 |
'EmergentReasoning',
|
reasoning/bayesian.py
CHANGED
@@ -9,7 +9,7 @@ from datetime import datetime
|
|
9 |
import numpy as np
|
10 |
from collections import defaultdict
|
11 |
|
12 |
-
from .base import ReasoningStrategy
|
13 |
|
14 |
@dataclass
|
15 |
class BayesianHypothesis:
|
@@ -20,9 +20,8 @@ class BayesianHypothesis:
|
|
20 |
posterior: float = 0.0
|
21 |
evidence: List[Dict[str, Any]] = field(default_factory=list)
|
22 |
|
23 |
-
class
|
24 |
-
"""
|
25 |
-
Advanced Bayesian reasoning that:
|
26 |
1. Generates hypotheses
|
27 |
2. Calculates prior probabilities
|
28 |
3. Updates with evidence
|
@@ -39,8 +38,15 @@ class BayesianReasoning(ReasoningStrategy):
|
|
39 |
self.prior_weight = self.config.get('prior_weight', 0.3)
|
40 |
self.evidence_threshold = self.config.get('evidence_threshold', 0.1)
|
41 |
self.min_likelihood = self.config.get('min_likelihood', 0.01)
|
|
|
|
|
|
|
42 |
|
43 |
-
async def reason(
|
|
|
|
|
|
|
|
|
44 |
"""
|
45 |
Apply Bayesian reasoning to analyze probabilities and update beliefs.
|
46 |
|
@@ -49,119 +55,113 @@ class BayesianReasoning(ReasoningStrategy):
|
|
49 |
context: Additional context and parameters
|
50 |
|
51 |
Returns:
|
52 |
-
|
53 |
"""
|
54 |
try:
|
55 |
-
# Generate hypotheses
|
56 |
-
hypotheses = await self._generate_hypotheses(query, context)
|
57 |
|
58 |
-
# Calculate
|
59 |
-
priors = await self._calculate_priors(hypotheses, context)
|
60 |
|
61 |
# Update with evidence
|
62 |
-
posteriors = await self._update_with_evidence(
|
63 |
-
hypotheses,
|
64 |
-
priors,
|
65 |
-
context
|
66 |
-
)
|
67 |
|
68 |
# Generate analysis
|
69 |
analysis = await self._generate_analysis(posteriors, context)
|
70 |
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
79 |
|
80 |
except Exception as e:
|
81 |
-
logging.error(f"Bayesian reasoning
|
82 |
-
return
|
83 |
-
|
84 |
-
|
85 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
86 |
|
87 |
async def _generate_hypotheses(
|
88 |
self,
|
89 |
query: str,
|
90 |
context: Dict[str, Any]
|
91 |
-
) -> List[
|
92 |
"""Generate plausible hypotheses."""
|
93 |
-
hypotheses = []
|
94 |
-
|
95 |
# Extract key terms for hypothesis generation
|
96 |
-
terms =
|
97 |
|
98 |
-
# Generate hypotheses
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
hypotheses.extend([
|
110 |
-
{
|
111 |
-
'name': 'primary',
|
112 |
-
'description': "Primary hypothesis based on direct interpretation",
|
113 |
-
'factors': self._extract_factors(query, terms)
|
114 |
-
},
|
115 |
-
{
|
116 |
-
'name': 'alternative',
|
117 |
-
'description': "Alternative hypothesis considering other factors",
|
118 |
-
'factors': self._generate_alternative_factors(terms)
|
119 |
-
}
|
120 |
-
])
|
121 |
|
122 |
return hypotheses
|
123 |
|
124 |
async def _calculate_priors(
|
125 |
self,
|
126 |
-
hypotheses: List[
|
127 |
context: Dict[str, Any]
|
128 |
) -> Dict[str, float]:
|
129 |
"""Calculate prior probabilities."""
|
130 |
priors = {}
|
|
|
131 |
|
132 |
-
# Get historical data if available
|
133 |
-
history = context.get('history', {})
|
134 |
-
total_cases = sum(history.values()) if history else len(hypotheses)
|
135 |
-
|
136 |
-
for hypothesis in hypotheses:
|
137 |
-
name = hypothesis['name']
|
138 |
-
|
139 |
-
# Calculate prior from history or use uniform prior
|
140 |
-
if name in history:
|
141 |
-
priors[name] = history[name] / total_cases
|
142 |
-
else:
|
143 |
-
priors[name] = 1.0 / len(hypotheses)
|
144 |
-
|
145 |
-
# Adjust prior based on factors
|
146 |
-
factor_weight = len(hypothesis['factors']) / 10 # Normalize factor count
|
147 |
-
priors[name] = (
|
148 |
-
priors[name] * (1 - self.prior_weight) +
|
149 |
-
factor_weight * self.prior_weight
|
150 |
-
)
|
151 |
-
|
152 |
-
# Normalize priors
|
153 |
-
total_prior = sum(priors.values())
|
154 |
if total_prior > 0:
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
|
|
|
|
|
|
|
|
159 |
|
160 |
return priors
|
161 |
|
162 |
async def _update_with_evidence(
|
163 |
self,
|
164 |
-
hypotheses: List[
|
165 |
priors: Dict[str, float],
|
166 |
context: Dict[str, Any]
|
167 |
) -> Dict[str, float]:
|
@@ -170,51 +170,41 @@ class BayesianReasoning(ReasoningStrategy):
|
|
170 |
|
171 |
# Get evidence from context
|
172 |
evidence = context.get('evidence', [])
|
173 |
-
if not evidence:
|
174 |
-
return posteriors
|
175 |
|
176 |
for e in evidence:
|
177 |
-
# Calculate
|
178 |
likelihoods = {}
|
179 |
-
|
180 |
-
name = hypothesis['name']
|
181 |
-
likelihood = self._calculate_likelihood(hypothesis, e)
|
182 |
-
likelihoods[name] = max(likelihood, self.min_likelihood)
|
183 |
|
184 |
-
|
185 |
-
|
186 |
-
likelihoods[name]
|
187 |
-
|
188 |
-
)
|
189 |
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
|
|
|
195 |
|
196 |
return posteriors
|
197 |
|
198 |
-
def _calculate_likelihood(
|
199 |
self,
|
200 |
-
hypothesis:
|
201 |
evidence: Dict[str, Any]
|
202 |
) -> float:
|
203 |
"""Calculate likelihood of evidence given hypothesis."""
|
204 |
-
#
|
205 |
-
|
206 |
-
|
207 |
-
for v in evidence.values()
|
208 |
-
if isinstance(v, (str, int, float))
|
209 |
-
)
|
210 |
-
|
211 |
-
# Compare with hypothesis factors
|
212 |
-
common_factors = evidence_factors.intersection(hypothesis['factors'])
|
213 |
|
214 |
-
|
215 |
-
|
|
|
216 |
|
217 |
-
return
|
218 |
|
219 |
async def _generate_analysis(
|
220 |
self,
|
@@ -222,104 +212,77 @@ class BayesianReasoning(ReasoningStrategy):
|
|
222 |
context: Dict[str, Any]
|
223 |
) -> Dict[str, Any]:
|
224 |
"""Generate probabilistic analysis."""
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
|
232 |
-
#
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
|
240 |
-
return
|
241 |
-
'top_hypothesis': ranked_hypotheses[0][0],
|
242 |
-
'probability': ranked_hypotheses[0][1],
|
243 |
-
'alternatives': [
|
244 |
-
{'name': name, 'probability': prob}
|
245 |
-
for name, prob in ranked_hypotheses[1:]
|
246 |
-
],
|
247 |
-
'statistics': {
|
248 |
-
'mean': mean,
|
249 |
-
'std': std,
|
250 |
-
'entropy': entropy
|
251 |
-
}
|
252 |
-
}
|
253 |
|
254 |
def _format_analysis(self, analysis: Dict[str, Any]) -> str:
|
255 |
"""Format analysis into readable text."""
|
256 |
-
|
257 |
|
258 |
-
|
259 |
-
|
260 |
-
f"Most likely hypothesis: {
|
261 |
-
|
262 |
-
|
263 |
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
|
269 |
-
f"- {alt['name']}: {alt['probability']:.2%}"
|
270 |
-
)
|
271 |
-
|
272 |
-
# Statistics
|
273 |
-
stats = analysis['statistics']
|
274 |
-
sections.append("\nDistribution statistics:")
|
275 |
-
sections.append(f"- Mean probability: {stats['mean']:.2%}")
|
276 |
-
sections.append(f"- Standard deviation: {stats['std']:.2%}")
|
277 |
-
sections.append(f"- Entropy: {stats['entropy']:.2f} bits")
|
278 |
|
279 |
-
return "\n".join(
|
280 |
|
281 |
def _calculate_confidence(self, posteriors: Dict[str, float]) -> float:
|
282 |
"""Calculate overall confidence score."""
|
283 |
if not posteriors:
|
284 |
return 0.0
|
285 |
|
286 |
-
#
|
287 |
-
|
288 |
-
|
289 |
-
# Adjust based on probability distribution
|
290 |
-
probs = list(posteriors.values())
|
291 |
-
|
292 |
-
# Strong leading hypothesis increases confidence
|
293 |
-
max_prob = max(probs)
|
294 |
-
if max_prob > 0.8:
|
295 |
-
confidence += 0.3
|
296 |
-
elif max_prob > 0.6:
|
297 |
-
confidence += 0.2
|
298 |
-
elif max_prob > 0.4:
|
299 |
-
confidence += 0.1
|
300 |
-
|
301 |
-
# Low entropy (clear distinction) increases confidence
|
302 |
-
entropy = -sum(p * np.log2(p) if p > 0 else 0 for p in probs)
|
303 |
-
max_entropy = -np.log2(1/len(probs)) # Maximum possible entropy
|
304 |
|
305 |
-
if
|
306 |
-
|
307 |
-
|
308 |
-
|
|
|
|
|
|
|
|
|
|
|
309 |
|
310 |
-
return min(
|
311 |
|
312 |
def _extract_factors(self, text: str, terms: Set[str]) -> Set[str]:
|
313 |
"""Extract relevant factors from text."""
|
314 |
-
|
|
|
|
|
|
|
315 |
|
316 |
-
def _generate_alternative_factors(self, terms: Set[str]) ->
|
317 |
"""Generate factors for alternative hypothesis."""
|
318 |
-
# Simple
|
319 |
-
|
320 |
-
|
321 |
-
|
322 |
-
|
323 |
-
|
324 |
-
|
325 |
-
|
|
|
|
9 |
import numpy as np
|
10 |
from collections import defaultdict
|
11 |
|
12 |
+
from .base import ReasoningStrategy, StrategyResult
|
13 |
|
14 |
@dataclass
|
15 |
class BayesianHypothesis:
|
|
|
20 |
posterior: float = 0.0
|
21 |
evidence: List[Dict[str, Any]] = field(default_factory=list)
|
22 |
|
23 |
+
class BayesianStrategy(ReasoningStrategy):
|
24 |
+
"""Advanced Bayesian reasoning that:
|
|
|
25 |
1. Generates hypotheses
|
26 |
2. Calculates prior probabilities
|
27 |
3. Updates with evidence
|
|
|
38 |
self.prior_weight = self.config.get('prior_weight', 0.3)
|
39 |
self.evidence_threshold = self.config.get('evidence_threshold', 0.1)
|
40 |
self.min_likelihood = self.config.get('min_likelihood', 0.01)
|
41 |
+
|
42 |
+
# Initialize hypothesis storage
|
43 |
+
self.hypotheses: List[BayesianHypothesis] = []
|
44 |
|
45 |
+
async def reason(
|
46 |
+
self,
|
47 |
+
query: str,
|
48 |
+
context: Dict[str, Any]
|
49 |
+
) -> StrategyResult:
|
50 |
"""
|
51 |
Apply Bayesian reasoning to analyze probabilities and update beliefs.
|
52 |
|
|
|
55 |
context: Additional context and parameters
|
56 |
|
57 |
Returns:
|
58 |
+
StrategyResult containing reasoning results and confidence scores
|
59 |
"""
|
60 |
try:
|
61 |
+
# Generate initial hypotheses
|
62 |
+
self.hypotheses = await self._generate_hypotheses(query, context)
|
63 |
|
64 |
+
# Calculate prior probabilities
|
65 |
+
priors = await self._calculate_priors(self.hypotheses, context)
|
66 |
|
67 |
# Update with evidence
|
68 |
+
posteriors = await self._update_with_evidence(self.hypotheses, priors, context)
|
|
|
|
|
|
|
|
|
69 |
|
70 |
# Generate analysis
|
71 |
analysis = await self._generate_analysis(posteriors, context)
|
72 |
|
73 |
+
# Format results
|
74 |
+
answer = self._format_analysis(analysis)
|
75 |
+
confidence = self._calculate_confidence(posteriors)
|
76 |
+
|
77 |
+
return StrategyResult(
|
78 |
+
strategy_type="bayesian",
|
79 |
+
success=True,
|
80 |
+
answer=answer,
|
81 |
+
confidence=confidence,
|
82 |
+
reasoning_trace=[{
|
83 |
+
"step": "bayesian_analysis",
|
84 |
+
"hypotheses": [h.__dict__ for h in self.hypotheses],
|
85 |
+
"priors": priors,
|
86 |
+
"posteriors": posteriors,
|
87 |
+
"analysis": analysis,
|
88 |
+
"timestamp": datetime.now().isoformat()
|
89 |
+
}],
|
90 |
+
metadata={
|
91 |
+
"num_hypotheses": len(self.hypotheses),
|
92 |
+
"max_posterior": max(posteriors.values()) if posteriors else 0.0,
|
93 |
+
"config": self.config
|
94 |
+
},
|
95 |
+
performance_metrics={
|
96 |
+
"prior_weight": self.prior_weight,
|
97 |
+
"evidence_threshold": self.evidence_threshold,
|
98 |
+
"min_likelihood": self.min_likelihood
|
99 |
+
}
|
100 |
+
)
|
101 |
|
102 |
except Exception as e:
|
103 |
+
logging.error(f"Bayesian reasoning error: {str(e)}")
|
104 |
+
return StrategyResult(
|
105 |
+
strategy_type="bayesian",
|
106 |
+
success=False,
|
107 |
+
answer=None,
|
108 |
+
confidence=0.0,
|
109 |
+
reasoning_trace=[{
|
110 |
+
"step": "error",
|
111 |
+
"error": str(e),
|
112 |
+
"timestamp": datetime.now().isoformat()
|
113 |
+
}],
|
114 |
+
metadata={"error": str(e)},
|
115 |
+
performance_metrics={}
|
116 |
+
)
|
117 |
|
118 |
async def _generate_hypotheses(
|
119 |
self,
|
120 |
query: str,
|
121 |
context: Dict[str, Any]
|
122 |
+
) -> List[BayesianHypothesis]:
|
123 |
"""Generate plausible hypotheses."""
|
|
|
|
|
124 |
# Extract key terms for hypothesis generation
|
125 |
+
terms = self._extract_factors(query, set())
|
126 |
|
127 |
+
# Generate alternative hypotheses
|
128 |
+
alternatives = self._generate_alternative_factors(terms)
|
129 |
+
|
130 |
+
# Create hypothesis objects
|
131 |
+
hypotheses = []
|
132 |
+
for name, prior in alternatives.items():
|
133 |
+
hypotheses.append(BayesianHypothesis(
|
134 |
+
name=name,
|
135 |
+
prior=prior,
|
136 |
+
likelihood=1.0 # Initial likelihood
|
137 |
+
))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
138 |
|
139 |
return hypotheses
|
140 |
|
141 |
async def _calculate_priors(
|
142 |
self,
|
143 |
+
hypotheses: List[BayesianHypothesis],
|
144 |
context: Dict[str, Any]
|
145 |
) -> Dict[str, float]:
|
146 |
"""Calculate prior probabilities."""
|
147 |
priors = {}
|
148 |
+
total_prior = sum(h.prior for h in hypotheses)
|
149 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
150 |
if total_prior > 0:
|
151 |
+
# Normalize priors
|
152 |
+
for h in hypotheses:
|
153 |
+
priors[h.name] = h.prior / total_prior
|
154 |
+
else:
|
155 |
+
# Equal priors if no information
|
156 |
+
prior = 1.0 / len(hypotheses)
|
157 |
+
for h in hypotheses:
|
158 |
+
priors[h.name] = prior
|
159 |
|
160 |
return priors
|
161 |
|
162 |
async def _update_with_evidence(
|
163 |
self,
|
164 |
+
hypotheses: List[BayesianHypothesis],
|
165 |
priors: Dict[str, float],
|
166 |
context: Dict[str, Any]
|
167 |
) -> Dict[str, float]:
|
|
|
170 |
|
171 |
# Get evidence from context
|
172 |
evidence = context.get('evidence', [])
|
|
|
|
|
173 |
|
174 |
for e in evidence:
|
175 |
+
# Calculate likelihoods
|
176 |
likelihoods = {}
|
177 |
+
total_likelihood = 0.0
|
|
|
|
|
|
|
178 |
|
179 |
+
for h in hypotheses:
|
180 |
+
likelihood = await self._calculate_likelihood(h, e)
|
181 |
+
likelihoods[h.name] = max(likelihood, self.min_likelihood)
|
182 |
+
total_likelihood += likelihood * posteriors[h.name]
|
|
|
183 |
|
184 |
+
# Update posteriors using Bayes' rule
|
185 |
+
if total_likelihood > 0:
|
186 |
+
for h in hypotheses:
|
187 |
+
posteriors[h.name] = (
|
188 |
+
likelihoods[h.name] * posteriors[h.name] / total_likelihood
|
189 |
+
)
|
190 |
|
191 |
return posteriors
|
192 |
|
193 |
+
async def _calculate_likelihood(
|
194 |
self,
|
195 |
+
hypothesis: BayesianHypothesis,
|
196 |
evidence: Dict[str, Any]
|
197 |
) -> float:
|
198 |
"""Calculate likelihood of evidence given hypothesis."""
|
199 |
+
# Simple likelihood calculation
|
200 |
+
# Could be enhanced with more sophisticated methods
|
201 |
+
base_likelihood = 0.5
|
|
|
|
|
|
|
|
|
|
|
|
|
202 |
|
203 |
+
# Adjust based on evidence strength
|
204 |
+
strength = evidence.get('strength', 0.0)
|
205 |
+
likelihood = base_likelihood * (1 + strength)
|
206 |
|
207 |
+
return min(1.0, max(self.min_likelihood, likelihood))
|
208 |
|
209 |
async def _generate_analysis(
|
210 |
self,
|
|
|
212 |
context: Dict[str, Any]
|
213 |
) -> Dict[str, Any]:
|
214 |
"""Generate probabilistic analysis."""
|
215 |
+
analysis = {
|
216 |
+
'top_hypothesis': max(posteriors.items(), key=lambda x: x[1]),
|
217 |
+
'confidence': self._calculate_confidence(posteriors),
|
218 |
+
'distribution': posteriors,
|
219 |
+
'summary': []
|
220 |
+
}
|
221 |
|
222 |
+
# Generate summary points
|
223 |
+
for name, prob in sorted(posteriors.items(), key=lambda x: x[1], reverse=True):
|
224 |
+
analysis['summary'].append({
|
225 |
+
'hypothesis': name,
|
226 |
+
'probability': prob,
|
227 |
+
'strength': 'strong' if prob > 0.7 else 'moderate' if prob > 0.3 else 'weak'
|
228 |
+
})
|
229 |
|
230 |
+
return analysis
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
231 |
|
232 |
def _format_analysis(self, analysis: Dict[str, Any]) -> str:
|
233 |
"""Format analysis into readable text."""
|
234 |
+
top_hyp, top_prob = analysis['top_hypothesis']
|
235 |
|
236 |
+
text = [
|
237 |
+
f"Based on Bayesian analysis:",
|
238 |
+
f"- Most likely hypothesis: {top_hyp} (probability: {top_prob:.2f})",
|
239 |
+
"\nProbability distribution:"
|
240 |
+
]
|
241 |
|
242 |
+
for item in analysis['summary']:
|
243 |
+
text.append(
|
244 |
+
f"- {item['hypothesis']}: {item['probability']:.2f} "
|
245 |
+
f"({item['strength']} evidence)"
|
246 |
+
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
247 |
|
248 |
+
return "\n".join(text)
|
249 |
|
250 |
def _calculate_confidence(self, posteriors: Dict[str, float]) -> float:
|
251 |
"""Calculate overall confidence score."""
|
252 |
if not posteriors:
|
253 |
return 0.0
|
254 |
|
255 |
+
# Get top two probabilities
|
256 |
+
probs = sorted(posteriors.values(), reverse=True)
|
257 |
+
top_prob = probs[0]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
258 |
|
259 |
+
if len(probs) > 1:
|
260 |
+
# Consider the gap between top hypotheses
|
261 |
+
second_prob = probs[1]
|
262 |
+
margin = top_prob - second_prob
|
263 |
+
|
264 |
+
# Confidence increases with both probability and margin
|
265 |
+
confidence = (top_prob + margin) / 2
|
266 |
+
else:
|
267 |
+
confidence = top_prob
|
268 |
|
269 |
+
return min(1.0, max(0.0, confidence))
|
270 |
|
271 |
def _extract_factors(self, text: str, terms: Set[str]) -> Set[str]:
|
272 |
"""Extract relevant factors from text."""
|
273 |
+
# Simple word-based extraction
|
274 |
+
# Could be enhanced with NLP techniques
|
275 |
+
words = text.lower().split()
|
276 |
+
return set(words).union(terms)
|
277 |
|
278 |
+
def _generate_alternative_factors(self, terms: Set[str]) -> Dict[str, float]:
|
279 |
"""Generate factors for alternative hypothesis."""
|
280 |
+
# Simple alternative generation
|
281 |
+
# Could be enhanced with domain knowledge
|
282 |
+
alternatives = {
|
283 |
+
'primary': 0.6,
|
284 |
+
'alternative': 0.3,
|
285 |
+
'null': 0.1
|
286 |
+
}
|
287 |
+
|
288 |
+
return alternatives
|