Character interaction temporal graph analysis
Project description
CIGA: Character Interaction Graph Analyzer
CIGA is a Python package designed for performing graph analysis on social interactions between individuals across time. It is a redesign of CharNet using igraph.
Simple example
import ciga as cg
import pandas as pd
import matplotlib.pyplot as plt
df = pd.DataFrame({
'Season': [1, 1, 1, 1],
'Episode': [1, 1, 1, 1],
'Scene': [1, 1, 2, 2],
'Line': [1, 2, 1, 2],
'Speaker': ['Sheldon', 'Leonard', 'Penny', 'Sheldon'],
'Listener': ['Leonard', 'Sheldon', 'Sheldon', 'Penny'],
'Words': ['Hello', 'Hi there', 'How are you?', 'Fine, thank you']
})
def weight_func(interaction):
return 1
position = ('Season', 'Episode', 'Scene', 'Line')
interactions = cg.prepare_data(data=df,
position=position,
source='Speaker',
target='Listener',
interaction='Words')
sub_interactions = cg.segment(interactions, start=(1, 1, 1, 1), end=(2, 1, 1, 1))
weights = cg.calculate_weights(sub_interactions, weight_func)
agg_weights = cg.agg_weights(data=weights,
position=position[:-1],
agg_func=lambda x: sum(x))
tg = cg.TGraph(data=agg_weights,
position=position[:-1],
directed=False)
graph = tg.get_graph((1, 1, 1))
fig, ax = plt.subplots()
cg.iplot(graph, target=ax)
plt.show()
res = cg.tgraph_degree(tg, weighted=True, w_normalized=False, normalized=True)
res.to_csv('results.csv')
More Examples
1. Basic Interaction Graph Creation and Visualization
import ciga as cg
import pandas as pd
import matplotlib.pyplot as plt
# Sample interaction data
data = pd.DataFrame({
'Time': [1, 1, 2, 2, 3],
'Source': ['Alice', 'Bob', 'Alice', 'Charlie', 'Bob'],
'Target': ['Bob', 'Alice', 'Charlie', 'Alice', 'Charlie'],
'Interaction': ['talk', 'talk', 'nod', 'talk', 'smile']
})
# Prepare the data
position = ('Time',)
interactions = cg.prepare_data(data, position, source='Source', target='Target', interaction='Interaction')
# Calculate weights (using the length of the interaction as weight)
weights = cg.calculate_weights(interactions, weight_func=lambda x: len(x))
# Aggregate weights
agg_weights = cg.agg_weights(weights, position)
# Create a temporal graph
tg = cg.TGraph(data=agg_weights, position=position, directed=True)
# Get the graph at time step 2
graph = tg.get_graph(time_point=(2,))
# Visualize the graph
fig, ax = plt.subplots()
cg.iplot(graph, target=ax)
plt.show()
2. Centrality Analysis
import ciga as cg
import pandas as pd
# ... (using the same 'data' and 'tg' from the previous example)
# Degree centrality
degree_centrality = cg.tgraph_degree(tg, weighted=True, normalized=True)
print("Degree Centrality:\n", degree_centrality)
# Betweenness centrality
betweenness_centrality = cg.tgraph_betweenness(tg, weighted=True, normalized=True)
print("Betweenness Centrality:\n", betweenness_centrality)
# Closeness centrality
closeness_centrality = cg.tgraph_closeness(tg, weighted=True, normalized=True)
print("Closeness Centrality:\n", closeness_centrality)
# Eigenvector centrality
eigenvector_centrality = cg.tgraph_eigenvector_centrality(tg, weighted=True)
print("Eigenvector Centrality:\n", eigenvector_centrality)
3. Community Detection
import ciga as cg
import pandas as pd
# ... (using the same 'data' and 'tg' from the previous example)
# Community detection using Leiden algorithm
communities = cg.tgraph_community_leiden(tg, weights='weight', resolution=1.0)
print("Communities:\n", communities)
4. Graph Properties
import ciga as cg
import pandas as pd
# ... (using the same 'data' and 'tg' from the previous example)
# Graph density over time
density = cg.tgraph_density(tg)
print("Density:\n", density)
# Graph transitivity over time
transitivity = cg.tgraph_transitivity_undirected(tg)
print("Transitivity:\n", transitivity)
5. Using a Custom Weight Function
import ciga as cg
import pandas as pd
# Sample interaction data with text
data = pd.DataFrame({
'Time': [1, 1, 2, 2, 3],
'Source': ['Alice', 'Bob', 'Alice', 'Charlie', 'Bob'],
'Target': ['Bob', 'Alice', 'Charlie', 'Alice', 'Charlie'],
'Interaction': ['I like you', 'Thanks!', 'This is great', 'Hello', 'Nice to see you']
})
# Custom weight function: assign higher weight to "positive" interactions
def custom_weight_func(interaction):
positive_words = ['like', 'great', 'nice', 'thanks']
text = str(interaction).lower()
score = 1
for word in positive_words:
if word in text:
score += 2
return score
# Prepare the data
position = ('Time',)
interactions = cg.prepare_data(data, position, source='Source', target='Target', interaction='Interaction')
# Calculate weights using the custom weight function
weights = cg.calculate_weights(interactions, weight_func=custom_weight_func)
# Aggregate weights
agg_weights = cg.agg_weights(weights, position)
# Create a temporal graph
tg = cg.TGraph(data=agg_weights, position=position, directed=True)
# Get the graph at time step 2
graph = tg.get_graph(time_point=(2,))
# Visualize the graph
fig, ax = plt.subplots()
cg.iplot(graph, target=ax)
plt.show()
6. Inferring Listeners with LLM
import ciga as cg
import pandas as pd
from openai import OpenAI
# Sample data with dialogue and scene descriptions
data = pd.DataFrame({
'Season': [1, 1, 1, 1, 1],
'Episode': [1, 1, 1, 2, 2],
'Scene': [1, 1, 2, 1, 1],
'Line': [1, 2, 3, 1, 2],
'Speaker': ['Alice', 'Bob', 'Charlie', 'Alice', 'Bob'],
'Dialogue': ['Hi Bob', 'Hello Alice', 'Hey everyone', 'Good morning', 'Morning Alice'],
'Action': ['Waive hand', 'Smile', '', 'Smile', 'Waive hand'],
'Scene_Description': ['In the room', 'In the room', 'In the room', 'In the room', 'In the room']
})
# Initialize OpenAI-compatible client
client = OpenAI(
base_url="https://api.openai.com/v1", # Or other providers like https://api.deepseek.com
api_key="YOUR_API_KEY"
)
# Infer listeners
inferred_listeners = cg.infer_listeners(data=data,
position=('Season', 'Episode', 'Scene', 'Line'),
speaker='Speaker',
dialogue='Dialogue',
action='Action',
scene_description='Scene_Description',
client=client,
model='gpt-4o-mini', # or any compatible model name
max_tokens=200,
gap=0.5)
print("Inferred Listeners:\n", inferred_listeners)
7. Visualizing with Pyvis
import ciga as cg
import pandas as pd
# ... (using the same 'data' and 'tg' from the previous example)
# Get the graph at time step 2
graph = tg.get_graph(time_point=(2,))
# Visualize the graph using Pyvis
cg.pyviz(graph, output_file='interactive_graph.html')
8. Topological Data Analysis (TDA)
Analyze the topological stability of the graph over time using Persistent Homology.
import ciga as cg
# ... (using the same 'tg' from the previous example)
# Compute Persistence Diagrams (H0 and H1)
diagrams = cg.tgraph_persistence_diagrams(tg, maxdim=1)
# Calculate Stability (Bottleneck distance) across time
stability = cg.tgraph_stability(tg, metric='bottleneck')
print(stability)
Install
Install the latest version of CIGA:
$ pip install ciga
Install with visualization dependencies (for interactive plotting with pyviz):
$ pip install ciga[visualization]
Install with TDA dependencies (for topological analysis):
$ pip install ciga[tda]
Install with all optional dependencies:
$ pip install ciga[all]
Note: The pyviz function requires pyvis as an optional dependency. If you try to use pyviz without installing the visualization dependencies, you'll see a helpful error message with installation instructions.
To Do
- Add non-directed graph support
- Add closeness centrality
- Add Eigenvector centrality
- Add Leiden community detection
- Add forgetting simulation
- Add temporal visualization
- Add Topological Data Analysis (Persistent Homology)
- Add centrality visualizer (with visualization)
License
Released under the GNU General Public License v3.0.
Copyright (c) 2024 Media Comprehension Lab
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ciga-0.1.2.tar.gz.
File metadata
- Download URL: ciga-0.1.2.tar.gz
- Upload date:
- Size: 60.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
51c00b83713344feb175ce05261afab28ba7d8f881d527258d343b39aab342d4
|
|
| MD5 |
9ce1e4e586f1ed3cca5b94610e569851
|
|
| BLAKE2b-256 |
3a4dc2bc6618fe2ccaf397032f594810c3dff968520056ba0c0f7ff6334b0609
|
File details
Details for the file ciga-0.1.2-py3-none-any.whl.
File metadata
- Download URL: ciga-0.1.2-py3-none-any.whl
- Upload date:
- Size: 66.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fe3b5e29bdd8432db2d83477ac16788b4f8f54cbf28a756b31dc9531ab9537c2
|
|
| MD5 |
edf165f18b3b5341c095ca5afbc0b77e
|
|
| BLAKE2b-256 |
c63ed648548b5f21f39f7b79323b7768cc6eea66f9438bd0515ea66e1b0f98ec
|