-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement bias detection system with detailed analysis and reporting #49
Conversation
…ation - Add BiasDetector class for analyzing various cognitive biases in text - Implement async document analysis with chunking support - Add confidence scoring using embedding similarity - Support multiple bias types: confirmation, stereotypical, ingroup-outgroup, anchoring, and availability - Include comprehensive error handling and logging - Remove example narrative stories file Technical details: - Uses Ollama for LLM integration and embeddings - Implements cosine similarity for confidence scoring - Supports async processing of large documents - Preserves semantic boundaries in text chunking
Reviewer's Guide by SourceryThis pull request introduces a bias detection system and analysis of political speech, focusing on identifying and analyzing different types of cognitive biases (confirmation, stereotypical, ingroup-outgroup, anchoring, and availability bias). The implementation includes a Python-based bias detector class that uses language models for analysis, along with documentation and example analysis reports. Class diagram for Bias Detection SystemclassDiagram
class BiasType {
<<enumeration>>
CONFIRMATION
STEREOTYPICAL
INGROUP_OUTGROUP
ANCHORING
AVAILABILITY
}
class BiasDetectionResult {
BiasType bias_type
float confidence
string explanation
List~string~ affected_segments
}
class BiasDetector {
-string model_name
-string embeddings
-Dict~BiasType, string~ prompts
+BiasDetector(string model_name, string embeddings_model_name)
+Dict~BiasType, string~ _load_bias_prompts()
+List~float~ get_embedding(string text)
+List~BiasDetectionResult~ detect_bias(string text, List~BiasType~ bias_types)
+float _calculate_confidence(List~float~ text_embedding, string explanation)
+Dict~BiasType, List~BiasDetectionResult~~ analyze_document(Path file_path)
+List~string~ _split_text(string text, int chunk_size)
+void save_analysis_report(Dict~BiasType, List~BiasDetectionResult~ results, Path output_path)
}
BiasDetectionResult --> BiasType
BiasDetector --> BiasDetectionResult
BiasDetector --> BiasType
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @leonvanbokhorst - I've reviewed your changes - here's some feedback:
Overall Comments:
- Consider adding more robust error handling and validation around the model calls and JSON parsing to handle potential API failures gracefully.
- The text chunking could be improved by using a proper NLP tokenizer instead of basic string splitting to better handle complex sentence structures.
- The confidence calculation using cosine similarity is quite basic - consider implementing more sophisticated metrics or ensemble methods for bias detection confidence scoring.
Here's what I looked at during the review
- 🟡 General issues: 3 issues found
- 🟢 Security: all looks good
- 🟢 Testing: all looks good
- 🟡 Complexity: 1 issue found
- 🟡 Documentation: 1 issue found
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
response = ollama.embeddings(model=self.model_name, prompt=text) | ||
return response["embedding"] | ||
|
||
async def detect_bias( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
issue (performance): The method is marked async but makes blocking calls to ollama.generate and ollama.embeddings
Consider using async versions of these calls to prevent blocking the event loop. This is especially important when processing multiple chunks of text.
|
||
return results | ||
|
||
def _calculate_confidence( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion (performance): Multiple separate embedding calls could be optimized by batching or caching
Consider caching the embeddings or batching the calls to reduce API usage and improve performance, especially when processing multiple chunks of text.
@lru_cache(maxsize=1024)
def _calculate_confidence(
self, text_embedding: Tuple[float, ...], explanation: str
) -> float:
|
||
for paragraph in paragraphs: | ||
# Split paragraph into sentences (basic splitting) | ||
sentences = [ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
issue: Basic sentence splitting might miss common abbreviations
Consider using a proper sentence tokenizer (like nltk.sent_tokenize) to handle cases with abbreviations like 'Mr.', 'Dr.', etc.
- Schoof's response directly contradicts this assumption by stating that antisemitism is an issue for all of Netherlands and needs to be discussed across various sectors, including conversations with Jewish organizations. | ||
- The author does not seem to acknowledge or address Schoof's answer which goes against their preconceived notion. | ||
|
||
### Instance (Confidence: 0.70) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion (documentation): Consider adding explanation of confidence scores
The document uses confidence scores throughout but never explains what they mean or how they're calculated. This context would be valuable for readers.
### Instance (Confidence: 0.70) | |
### Instance (Confidence: 0.70 - scores range from 0.0 to 1.0, indicating analysis certainty) |
|
||
return [chunk for chunk in chunks if chunk.strip()] # Remove empty chunks | ||
|
||
def save_analysis_report( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
issue (complexity): Consider extracting report generation functionality into a separate class with dedicated responsibilities.
The report generation logic should be extracted to a separate class to improve maintainability and reusability. This would also make the BiasDetector class more focused on its core responsibility. Here's a suggested refactor:
@dataclass
class BiasAnalysisReport:
results: Dict[BiasType, List[BiasDetectionResult]]
class BiasReportGenerator:
def generate_markdown(self, analysis: BiasAnalysisReport, output_path: Path) -> None:
total_instances = sum(len(bias_results) for bias_results in analysis.results.values())
avg_confidences = {
bias_type: np.mean([r.confidence for r in bias_results])
for bias_type, bias_results in analysis.results.items()
}
# Generate report content (existing logic)
report = self._generate_report_content(total_instances, avg_confidences, analysis.results)
# Save report
output_path.parent.mkdir(parents=True, exist_ok=True)
output_path.write_text("\n".join(report))
class BiasDetector:
def save_analysis_report(self, results: Dict[BiasType, List[BiasDetectionResult]], output_path: Path) -> None:
report = BiasAnalysisReport(results=results)
generator = BiasReportGenerator()
generator.generate_markdown(report, output_path)
This change:
- Encapsulates report generation in a dedicated class
- Makes it easier to add new report formats
- Simplifies testing of report generation
- Reduces the responsibilities of BiasDetector
|
||
try: | ||
# Get embedding for the explanation | ||
explanation_embedding = self.get_embedding(explanation) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
issue (code-quality): Extract code out into method (extract-method
)
Summary by Sourcery
Implement a bias detection system to analyze text for cognitive biases and generate detailed reports. Document the findings in comprehensive and mini-analysis reports, and provide educational material on bias types and their impacts.
New Features:
Documentation: