normalized weights
removed diagonal
N = 10 # number of sectors lmax = 10 # max labor intensity l2 = np.random.randint(lmax, size=N)+1 # labor vector l1 = 1/l2 L1 = np.diag(l1/LA.norm(l1),0) # weight against sector labor L2 = np.diag(l2/LA.norm(l2),0) # weight by downstream labor A = np.random.randint(2, size=(N, N)) # I/O adjacency matrix np.fill_diagonal(A,0) #remove diagonal B = np.matmul(np.matmul(L1,A),L2) # weighted matrix eigval, eigvec = LA.eig(B) # eigenvalues and eigenvectors C = abs(eigvec[1,:]/eigval[1]) # eigencentrality print(C) print(A) print(B)
Are there some prototypical I/O tables and labor values i.e something like a 3X3 or 5x5 I/O matrix one would see in a textbook?
@madredalchemist You can use the IO tables from your country's national accounts. Here are the tables for Sweden. The supply-use tables are also useful.
@madredalchemist You can use the IO tables from your country's national accounts. Here are the tables for Sweden. The supply-use tables are also useful.
Here's the IO Tables for all OECD Countries as well
which goods are the most common inputs, and identify bottlenecks
The purpose of the centrality analysis is to identify which industries are furthest up the supply chain; these industries are the most critical and are therefore the bottleneck industries. The weighting is to identify which sectors will result in the largest losses with respect to the ease of interrupting its production. My goal is to create a theoretical model which I can then constrain to specific conditions.
For 'furthest up' it might be worth looking into algorithms for trophic level and trophic coherence in addition to centrality. This paper got me thinking along these lines right before the pandemic. I was discouraged by how much domain knowledge a network model would omit, but I'm sure there has been a ton of relevant research in networks since then.
@j-alt I like this a lot because applied to I/O analysis this could give insight into industrial metabolism if one where able to incorporate natural resources/natural resource limitations into account. If I understand correctly trophic level is a measure of 'hierarchalness' and I presume in the ecological example a food web that is more trophically coherent is less stable.
It looks like the concept comes from this paper, where they mention
We must caution that these findings do not imply that trophic coherence was somehow selected for by the forces of nature to improve food-web function. It seems unlikely that there should be any selective pressure on the individuals making up a species to do what is best for their ecosystem. Rather, many biological features of a species are associated with its trophic level. Therefore, adaptations which allow a given predator to prey on species A are likely to be useful also in preying on species B if A and B have similar trophic levels. This leads to trophic coherence, which results in high stability.
I can imagine arguments that firms at the top of coherent networks would be similarly adapted, or that they would be more vulnerable. Trophic incoherence on the other hand means there are more cycles and feedbacks, so I would expect those sectors to be less stable.
I also found this paper which makes a model for stability out of a ton of different centralities, and this one which has a more in-depth model of firms adapting to supply shocks on networks.
So I finally got around to entering the 1973/74 Italian I/O table (16X16) adjacency matrix in and the results seem plausible. I take the magnitude for the eigencentrality as I get complex valued eigenvectors and eigenvalues (the imaginary components are relatively small).
Just to recap:
- eigencentrality of the I/O adjacency matrix should rank the industries by upstreamedness
- adjacency matrix is weighted against sectoral labor (Li) and weighted for downstream labor (Lj) i.e interdependency ij is weighted by Lj/Li
If my analysis is correct: #1 is real estate and related services #2 is hotels, retail and wholesale trade + miscellaneous trade #3 is public administration non-profit private services and other services.
#16 is agriculture and forestry #15 is financial services and #14 is tied between (wood, paper, rubber and related industries)and (textiles, leather, footwear)
The higher rank industries should be the ones that will have the most 'labor gain' that is the industries with the smallest amount of labor that supply to industries with the largest amount of labor.
Here is the code:
import numpy as np import matplotlib.pyplot as plt from numpy import linalg as LA Aex = np.array([[0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1], [1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1], [1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1], [1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1], [1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1], [1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1], [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]) #adjacency matrix of italian economy 1973/1974 l2ex = np.array([12117, 1689, 2532, 3692, 2854, 11732, 3653, 3810, 11441, 8190, 15366, 13647, 8079, 2267, 6803, 29338]) #labor vector 1973 N = 16 # number of sectors lmax = 16 # max labor intensity l2 = l2ex#np.random.randint(lmax, size=N)+1 # labor vector l1 = 1/l2 L1 = np.diag(l1,0) # weight against sector labor L2 = np.diag(l2,0) # weight by downstream labor A = Aex #np.random.randint(2, size=(N, N)) # I/O adjacency matrix np.fill_diagonal(A,0) #remove diagonal B = np.matmul(np.matmul(L1,A),L2) # weighted matrix eigval, eigvec = LA.eig(B) # eigenvalues and eigenvectors C = abs(eigvec[0,:]/eigval[0]) # eigencentrality print(C*1000) #print(A) #print(B)
All being said I am not an expert in graph theory or I/O analysis and I have no other context for the Italian economy at this time other than the I/O table from Luca Perrone's paper.
UPDATE: So it's seems like I will have to change to Katz centrality as eigenvector centrality fails with directed graphs apparently. Unless anyone has any clever symmetrization schemes, I'm probably going to change to Katz centrality and start using this network analysis python API called networkx.
Additionally I think I can also use the centrality measure from google's PageRank algorithm.
SMALL UPDATE:
Going to be reading up on this ---> https://arxiv.org/pdf/2104.02764.pdf
@madredalchemist I wonder what a useful weighting would be. Number of workers? That the eigenvalue is known to be 1 is useful for fast computation.
@thardin I was planning on using the Technology matrix itself and then choosing the out-strength to be the labor in that industry i.e wji/sj = tji/lj
@madredalchemist Sounds reasonable. By technology matrix do you mean the IO table? We'd want to be more disaggregated than that. System should still be square since we're tracking from/to which workplaces stuff is sent
@thardin Yes and I thought the I/O table is square, it's # of industries X # of industries where unconnected industries have coupling of 0.