liveBook · Manning

Edge

As explained in Financial AI in Practice

A connection between vertices in a graph, representing a relationship or interaction.

In a fraud investigation, separate transaction rows may conceal that several customers use the same device. A graph makes that relationship visible: entities such as customers, accounts, devices, and IP addresses become nodes; an edge records a connection or interaction between two nodes. Investigators can then ask who is connected to whom, rather than assessing each event alone. section 9.2.1 section 9.1

Define what an edge means before building the graph:

  • A transaction can connect a user to a merchant; ownership can connect a user to an account; a transfer can connect two accounts. section 9.2.1
  • A shared identifier can link users who used the same device or IP address. An edge can also carry properties, such as transaction amount, timestamp, or a count of shared-IP use. section 9.2.1
  • For a graph built from transaction records, connect entities that appear in the same transaction. An edge weight can count how many transactions linked a pair. section 9.3.2
Listing 9.2 Building the graph from transaction data with parallel edge preparation
if transactions_df is not None:
    G = nx.Graph()            #1

    node_types_and_columns = {
        'user': 'user_id', 'ip': 'ip', 'device': 'device_id',
        'phone': 'phone_number', 'card': 'credit_card_number'
    }

    print("Preparing nodes for the graph...")
    for node_type, col_name in node_types_and_columns.items():
        for entity_id in transactions_df[col_name].unique():
            G.add_node(f"{node_type}_{entity_id}", type=node_type) 
    print(f"Initial nodes added. Total nodes: {G.number_of_nodes()}")

    edges_to_add_with_attributes = defaultdict(lambda: {'weight': 0, 'transactions': []})

    def process_transaction_row(index_row_tuple):
        index, row = index_row_tuple
        transaction_entities_in_row = []
        for node_type_key, col_name_val in node_types_and_columns.items():
            transaction_entities_in_row.append(f"{node_type_key}_{row[col_name_val]}")
        row_edges = []
        for node1, node2 in combinations(sorted(transaction_entities_in_row), 2):
            row_edges.append(((node1, node2), row['transaction_id']))
        return row_edges

    print("\nProcessing transactions in parallel to prepare edge data...")

    prepared_edges_nested_list = []
    with ThreadPoolExecutor(max_workers=8) as executor: # Using 8 worker threads
        futures = [executor.submit(process_transaction_row, item) for item in transactions_df.iterrows()]
        count = 0
        for future in as_completed(futures):
            prepared_edges_nested_list.extend(future.result())
            count += 1
            if count % 1000 == 0 and count > 0: # Print progress every 1000 transactions
                print(f"Processed {count} transactions for edge preparation...")

    print(f"All {len(transactions_df)} transactions processed for edge preparation.")

    print("\nAggregating edge data and adding edges to the graph...")
    for (node1, node2), transaction_id in prepared_edges_nested_list:
        edges_to_add_with_attributes[(node1, node2)]['weight'] += 1
        edges_to_add_with_attributes[(node1, node2)]['transactions'].append(transaction_id)

    for (node1, node2), attributes in edges_to_add_with_attributes.items():
        G.add_edge(node1, node2, weight=attributes['weight'], transactions=attributes['transactions'])

    print("\nGraph construction completed.")
    print(f"Number of nodes in the graph: {G.number_of_nodes()}")
    print(f"Number of edges in the graph: {G.number_of_edges()}")
else:
    print("transactions_df not loaded. Skipping graph construction.")
    G = None

The NetworkX listing starts with typed nodes for users, IPs, devices, phones, and cards, then prepares edges from transaction co-occurrences in parallel. Check the resulting node and edge counts before applying community detection. section 9.3.2

Figure 7.5 A conceptual visualization of transactions involving users who filed chargebacks. This simplified graph highlights the ability to quickly identify commonly shared merchants among users. The numbers on the edges represent the transaction dates (YY.MM.DD format). The solid lines indicate normal transactions, while the dashed lines represent transactions that were later disputed as chargebacks. While this example remains intentionally minimal, such graph-based relationships become even more valuable in complex real-world scenarios where detecting shared connections can reveal fraud rings or coordinated behavior.
figure

The chargeback diagram distinguishes ordinary transactions from later-disputed ones with line styles and marks transaction dates on the edges. Shared merchants become easier to spot. section 7.4.1

Edge design affects what an investigation can find. Multi-hop links can expose apparently unrelated applicants connected through a device, while densely connected groups can point analysts toward coordinated activity. Choose directed, undirected, weighted, or heterogeneous relationships according to the fraud pattern; treat a suspicious connection as an investigative signal, not a verdict on its own. section 9.1 section 9.6

How Financial AI in Practice covers it

How deep it goes
Defines edges and their properties, then shows transaction co-occurrence, weighted edge construction, and graph-count checks in NetworkX.
Examples
Uses user–merchant transactions, shared devices or IPs, account transfers, and dated chargeback connections.
What it assumes
Starts with nodes and edges as basic graph components, then assumes transaction records with identifiable users and other entities.
What you can do after
Build it from scratch with NetworkX by connecting transaction entities, counting repeated links, and checking graph statistics before community detection.
How it connects
Links nodes, edge properties, multi-hop analysis, community detection, and graph representation choices.

Also explained in

Compare how 18 books explain edge →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Financial AI in Practice. The section links point to the parts of the book it draws on.