hina.dyad
+++++++++
Tutorial
========
The `dyad` module provides functions for the statistical analysis of interactions in heterogeneous networks at the dyad level. This module focuses on identifying statistically significant edges by comparing observed edge weights against a binomial-based null model. The null model may be configured to fix the weighted degrees for nodes in a specified set. This module provides dyad-level analyses for heterogeneous networks.
Currently, the module contains the `significant_edges.py` file, which includes:
- `prune_edges(B, fix_deg='None', alpha=0.05)`: Prunes edges in a bipartite graph by retaining only those that are statistically significant under a specified null model.
.. list-table:: Functions
:header-rows: 1
* - Function
- Description
* - `prune_edges(B, fix_deg='None', alpha=0.05) <#prune-edges>`_
- Computes statistically significant edges using a binomial null model with optional fixed degrees.
Reference
---------
.. _prune-edges:
.. raw:: html
**Description**:
Prunes edges in a bipartite graph to retain only those that are statistically significant under a null model. The function uses a binomial significance test to compare each edge's weight against a threshold derived from the overall edge weight distribution or, when specified, the degree-constrained distribution for nodes whose degrees are fixed. This allows for flexible analysis of dyad-level interaction patterns.
**Parameters**:
.. raw:: html
(B, fix_deg='None', alpha=0.05)
-
B: A NetworkX graph representing a bipartite network with weighted edges.
- Nodes must have a
bipartite attribute indicating their partition.
-
alpha: The significance level for retaining edges.
Default:
0.05.
-
fix_deg: Specifies the node set for which the weighted degrees are fixed in the null model.
'None': No degree constraints are applied.
- Any student or object column string (e.g.,
'student' or 'object1') will fix the weighted degrees for nodes whose bipartite attribute matches that string.
Default: 'None'.
**Returns**:
- **dict**: A dictionary containing:
- ``pruned network``: A NetworkX graph representing the pruned network with only statistically significant edges.
- ``significant edges``: A set of tuples ``(i, j, w)``, where ``i`` and ``j`` are node labels and ``w`` is the weight of the edge.
Demo
====
Example Code
------------
This example demonstrates how to use the `prune_edges` function to filter significant edges in a bipartite network.
**Step 1: Import necessary libraries**
.. code-block:: python
import pandas as pd
from hina.construction import get_bipartite
from hina.dyad import prune_edges
**Step 2: Define the dataset**
A dataset containing student-task interactions:
.. code-block:: python
df = pd.DataFrame({
'student': ['Alice', 'Bob', 'Alice', 'Charlie', 'Bob', 'Alice', 'Charlie', 'Alice', 'Bob', 'Charlie',
'Alice', 'Bob', 'Charlie', 'Bob', 'Alice', 'Alice', 'Bob', 'Charlie'],
'object1': ['ask questions', 'answer questions', 'evaluating', 'monitoring', 'ask questions', 'evaluating',
'monitoring', 'ask questions', 'answer questions', 'evaluating', 'ask questions', 'answer questions',
'evaluating', 'monitoring', 'ask questions', 'ask questions', 'answer questions', 'evaluating'],
'object2': ['tilt head', 'shake head', 'nod head', 'nod head', 'tilt head', 'shake head', 'nod head',
'tilt head', 'shake head', 'nod head', 'shake head', 'nod head', 'tilt head', 'shake head',
'tilt head', 'tilt head', 'shake head', 'nod head'],
'group': ['A', 'B', 'A', 'B', 'B', 'A', 'B', 'A', 'B', 'A', 'B', 'A', 'B', 'A', 'A', 'A', 'B', 'B'],
'attr': ['cognitive', 'cognitive', 'metacognitive', 'cognitive', 'metacognitive',
'cognitive', 'cognitive', 'metacognitive', 'cognitive', 'cognitive', 'metacognitive',
'metacognitive', 'cognitive', 'cognitive', 'cognitive', 'cognitive', 'metacognitive', 'metacognitive']
})
**Step 3: Construct the bipartite network representation**
We create a bipartite network representation of the interactions between students and objects in the 'object1' category, adding the additional attribute 'attr' storing object codes.
.. code-block:: python
B = get_bipartite(df,student_col='student', object_col='object1', attr_col='attr', group_col='group')
**Step 4: Compute significant edges without fixing degrees**
.. code-block:: python
alpha = 0.05 # Significance level
result_none = prune_edges(B, fix_deg='None', alpha=alpha)
print("Significant Edges (No Degree Fixing):", result_none['significant edges'])
**Step 5: Compute significant edges with fixed degrees for Student nodes**
.. code-block:: python
result_student= prune_edges(B, alpha=alpha, fix_deg='student')
print("Significant Edges (Fixing Degree for Student):", result_student['significant edges'])
**Step 6: Compute significant edges with fixed degrees for Object1 nodes**
.. code-block:: python
result_object = prune_edges(B, alpha=alpha, fix_deg='object1')
print("Significant Edges (Fixing Degree for Object1):", result_object['significant edges'])
Example Output
--------------
.. code-block:: console
Significant Edges (No Degree Fixing):
{('Bob', 'answer questions', 4), ('Alice', 'ask questions', 5)}
Significant Edges (Fixing Degree for Student):
{('Bob', 'answer questions', 4), ('Charlie', 'evaluating', 3), ('Alice', 'ask questions', 5)}
Significant Edges (Fixing Degree for Object1):
{('Bob', 'answer questions', 4), ('Charlie', 'monitoring', 2), ('Charlie', 'evaluating', 3), ('Alice', 'ask questions', 5)}
Paper Source
============
If you use this function in your work, please cite:
Feng, S., Gibson, D., & Gasevic, D. (2025). Analyzing students' emerging roles based on quantity and heterogeneity of individual contributions in small group online collaborative learning using bipartite network analysis. Journal of Learning Analytics, 12(1), 253–270.