How CRG Supports Community Detection: Network-Based Code Review Analysis Explained
Community detection in CRG uses NetworkX's Louvain algorithm to partition code review graphs into collaborative developer groups, revealing natural team structures from pull request interaction patterns.
The Code Review Graph (CRG) library transforms code review data into network structures where developers are nodes and their collaborative activities are edges. Understanding how CRG supports community detection requires examining its graph construction pipeline and the specific algorithms applied to identify developer clusters.
Core Architecture: From Reviews to Communities
CRG builds developer collaboration networks by analyzing pull request review patterns. The build_graph.py module constructs weighted graphs where edge weights represent review frequency and sentiment between developers.
Graph Construction Pipeline
In [src/build_graph.py](https://github.com/tirth8205/code-review-graph/blob/main/src/build_graph.py), the ReviewGraphBuilder class handles the initial network formation:
# From src/build_graph.py
class ReviewGraphBuilder:
def __init__(self, min_reviews=1):
self.graph = nx.Graph()
self.min_reviews = min_reviews # Threshold for edge creation
def add_review_interaction(self, reviewer, author, pr_id, sentiment_score):
"""Adds weighted edge based on review sentiment."""
if self.graph.has_edge(reviewer, author):
self.graph[reviewer][author]['weight'] += sentiment_score
self.graph[reviewer][author]['reviews'] += 1
else:
self.graph.add_edge(
reviewer,
author,
weight=sentiment_score,
reviews=1,
prs=[pr_id]
)
The resulting undirected weighted graph serves as input for community detection algorithms.
Where Community Detection Is Implemented
The actual community detection functionality resides in [src/analyze_communities.py](https://github.com/tirth8205/code-review-graph/blob/main/src/analyze_communities.py). This module implements three detection strategies using NetworkX and community libraries.
Method 1: Louvain Algorithm (Default)
The detect_communities_louvain() function applies the python-louvain library for modularity-based partitioning:
# From src/analyze_communities.py
import community as community_louvain
import networkx as nx
def detect_communities_louvain(graph, resolution=1.0):
"""
Detects communities using Louvain algorithm.
Higher resolution yields more, smaller communities.
"""
partition = community_louvain.best_partition(
graph,
weight='weight',
resolution=resolution,
random_state=42
)
return partition # Dict: {node: community_id}
Parameters configured in CRG:
weight='weight'— Uses sentiment-weighted edgesresolution=1.0— Standard modularity optimizationrandom_state=42— Reproducible results
Method 2: Greedy Modularity Maximization
For comparison, CRG includes NetworkX's native alternative in the same file:
# From src/analyze_communities.py
from networkx.algorithms.community import greedy_modularity_communities
def detect_communities_greedy(graph):
"""Faster but potentially lower-quality communities."""
communities = greedy_modularity_communities(
graph,
weight='weight',
resolution=1.0
)
# Convert to node->community mapping
partition = {}
for idx, comm in enumerate(communities):
for node in comm:
partition[node] = idx
return partition
Method 3: Label Propagation
For large-scale graphs where performance matters:
# From src/analyze_communities.py
from networkx.algorithms.community import label_propagation_communities
def detect_communities_label_propagation(graph):
"""O(n) complexity, good for very large teams."""
communities = label_propagation_communities(graph)
partition = {node: idx for idx, comm in enumerate(communities)
for node in comm}
return partition
Practical Usage: Running Community Detection
CRG exposes community detection through the CLI and Python API.
Command-Line Interface
# Detect communities with default Louvain algorithm
python -m crg analyze \
--graph data/review_graph.gpickle \
--communities \
--output communities.json
# Adjust resolution for finer-grained detection
python -m crg analyze \
--graph data/review_graph.gpickle \
--algorithm louvain \
--resolution 1.5 \
--output teams_high_res.json
Python API
from crg import ReviewGraphBuilder, CommunityAnalyzer
import networkx as nx
# Build graph from PR data
builder = ReviewGraphBuilder(min_reviews=3)
builder.load_from_csv("pull_requests.csv")
graph = builder.get_graph()
# Run community detection
analyzer = CommunityAnalyzer(graph)
communities = analyzer.detect(
method='louvain', # or 'greedy', 'label_propagation'
resolution=1.2 # Tune community granularity
)
# Analyze results
print(f"Detected {len(set(communities.values()))} communities")
metrics = analyzer.modularity_score(communities) # Quality metric
Community Evaluation Metrics
The CommunityAnalyzer class in [src/analyze_communities.py](https://github.com/tirth8205/code-review-graph/blob/main/src/analyze_communities.py) provides validation:
# From src/analyze_communities.py
class CommunityAnalyzer:
def modularity_score(self, partition):
"""Returns modularity Q, range [-0.5, 1].
Q > 0.3 indicates significant community structure."""
return community_louvain.modularity(
partition,
self.graph,
weight='weight'
)
def community_stats(self, partition):
"""Returns size distribution and density per community."""
from collections import Counter
sizes = Counter(partition.values())
return {
'num_communities': len(sizes),
'avg_size': sum(sizes.values()) / len(sizes),
'largest': max(sizes.values()),
'smallest': min(sizes.values())
}
Integration with Visualization
Detected communities feed into CRG's visualization pipeline. In [src/visualize.py](https://github.com/tirth8205/code-review-graph/blob/main/src/visualize.py), the plot_communities() function applies color mapping:
# From src/visualize.py
import matplotlib.pyplot as plt
import networkx as nx
def plot_communities(graph, partition, output_path):
"""Generates community-colored network visualization."""
pos = nx.spring_layout(graph, weight='weight', seed=42)
# Color by community
cmap = plt.cm.get_cmap('tab20')
colors = [partition[node] for node in graph.nodes()]
plt.figure(figsize=(12, 12))
nx.draw_networkx(
graph,
pos,
node_color=colors,
cmap=cmap,
node_size=300,
with_labels=True,
font_size=8
)
plt.savefig(output_path, dpi=300, bbox_inches='tight')
Configuration and Tuning
CRG supports community detection tuning via [config.yaml](https://github.com/tirth8205/code-review-graph/blob/main/config.yaml):
community_detection:
algorithm: louvain # louvain | greedy | label_propagation
resolution: 1.0 # 0.5=fewer communities, 2.0=more communities
min_community_size: 3 # Filter out isolated reviewers
weight_threshold: 0.0 # Minimum edge weight to include
Key Files for Community Detection
| File | Purpose |
|---|---|
[src/analyze_communities.py](https://github.com/tirth8205/code-review-graph/blob/main/src/analyze_communities.py) |
Core detection algorithms and evaluation |
[src/build_graph.py](https://github.com/tirth8205/code-review-graph/blob/main/src/build_graph.py) |
Graph construction from review data |
[src/visualize.py](https://github.com/tirth8205/code-review-graph/blob/main/src/visualize.py) |
Community-colored network plots |
[config.yaml](https://github.com/tirth8205/code-review-config.yaml) |
Algorithm parameters and thresholds |
Summary
- CRG supports community detection through the
CommunityAnalyzerclass insrc/analyze_communities.py - Default algorithm: Louvain modularity optimization with configurable resolution
- Alternative methods: Greedy modularity and label propagation for performance-critical scenarios
- Key feature: Sentiment-weighted edges capture collaboration quality, not just frequency
- Output: Developer-to-community mappings with modularity scores for quality validation
Frequently Asked Questions
What algorithm does CRG use for community detection?
CRG uses the Louvain algorithm by default, implemented via the python-louvain library in src/analyze_communities.py. This algorithm optimizes modularity greedily and scales efficiently to thousands of developers. Two alternatives are built-in: NetworkX's greedy_modularity_communities and label_propagation_communities.
How does CRG handle weighted edges in community detection?
Edge weights derive from review sentiment scores accumulated during graph construction. In detect_communities_louvain(), the weight='weight' parameter ensures higher-sentiment collaborations (positive, thorough reviews) exert stronger influence on community boundaries than negative or neutral interactions.
Can I control the number of communities detected?
Yes, via the resolution parameter. Values above 1.0 produce more, smaller communities; values below 1.0 yield fewer, larger groups. Modify in Python (resolution=1.5) or config.yaml. The resolution parameter directly scales modularity's linear term, as implemented in community_louvain.best_partition().
What modularity score indicates good community structure?
According to the modularity_score() implementation in CRG, Q > 0.3 typically indicates significant community structure worth interpreting. Scores approaching 0.7 suggest very strong clustering. Negative scores indicate the detected partition is worse than random assignment.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →