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 edges
  • resolution=1.0 — Standard modularity optimization
  • random_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 CommunityAnalyzer class in src/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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →