def centrality_analysis(G, isDriected=False):
    '''
    :param g: Digraph()/ Graph()
    :return: several types of centrality of each nodes
    '''
    nodes = G.nodes()
    if isDriected:
        in_dc = centrality.in_degree_centrality(G)
        out_dc = centrality.out_degree_centrality(G)
        bc = centrality.betweenness_centrality(G)
        ec = centrality.eigenvector_centrality(G)

        cent = {}
        for node in nodes:
            cent[node] = [in_dc[node], out_dc[node], bc[node], ec[node]]
        print(
            "Four types of centrality are calculated \n" +
            "\n\tin_degree_centrality\n\tout_degree_centrality\n\tbetweenness_centrality\n\teigenvector_centrality"
        )
        return cent
    else:
        dc = centrality.degree_centrality(G)
        bc = centrality.betweenness_centrality(G)
        ec = centrality.eigenvector_centrality(G)

        cent = {}
        for node in nodes:
            cent[node] = [dc[node], bc[node], ec[node]]
        print(
            "Three types of centrality are calculated \n" +
            "\n\tdegree_centrality\n\tbetweenness_centrality\n\teigenvector_centrality"
        )
        return cent
Example #2
0
def centrality_in_degree(dg):
    """
    dmargo's paper has edges in reverse of the data flow
    hello has inputs bar.txt and has outputs foo.txt
    then we have edges:

    bar.txt <--- hello <----foo.txt

    whereas our graph has edges in the other direction
    hence we actually want out degree
    """
    return in_degree_centrality(dg)
def graph_2():
    G = nx.nx.DiGraph()
    # G.add_nodes_from([2, 3, 5, 6, 7])
    G.add_edges_from([[2, 3], [5, 3], [6, 7], [7, 2], [5, 7]])
    # G.add_path([2,3,6,7])
    # G.add_path([2,4,5])
    # print(list(G.nodes()))
    print(list(G.edges()))
    print(list(G.out_degree()))
    print(list(G.in_degree()))
    print(centrality.in_degree_centrality(G))
    print(link_analysis.pagerank(G, personalization={2: -4}))
    print(link_analysis.pagerank(G, dangling={5: 0, 7: 1}))
Example #4
0
    def centrality(self,
                   h_i_shock=None,
                   alpha=0.0,
                   rank=False,
                   seed=123,
                   max_iter=100,
                   **kwargs):
        #       include: degree centrality,...
        cdntrality_index = [
            'in-degree centrality', 'out-degree centrality',
            'degree centrality', 'betweenness centrality',
            'in-closeness centrality', 'out-closeness centrality',
            'in-eigenvector centrality', 'out-eigenvector centrality',
            'debtrank', 'non-linear debtrank'
        ]

        # the greater the value, the more important
        self._in_degree_centrality = ct.in_degree_centrality(self._FN)
        # reflect the enthusiasm of banks
        self._out_degree_centrality = ct.out_degree_centrality(self._FN)
        # the greater the value, the more important
        self._degree_centrality = ct.degree_centrality(self._FN)
        # the greater the value, the more important
        self._betweenness_centrality = ct.betweenness_centrality(
            self._FN, weight='weight', seed=seed)
        # integration
        self._in_closeness_centrality = ct.closeness_centrality(
            self._FN, distance='weight')
        # radiality
        self._out_closeness_centrality = ct.closeness_centrality(
            self._FN.reverse(), distance='weight')
        # # the greater the value, the more important, Similar to PageRank
        self._in_eigenvector_centrality = ct.eigenvector_centrality(
            self._FN, max_iter=max_iter, weight='weight')
        self._out_eigenvector_centrality = ct.eigenvector_centrality(
            self._FN.reverse(), max_iter=max_iter, weight='weight')
        # self._katz_centrality = ct.katz_centrality(self._FN, weight='weight') # bug

        # debtrank
        if h_i_shock is None:
            h_i_shock = self._data.h_i_shock

        assert isinstance(
            h_i_shock, (list, np.ndarray)
        ), "ERROR: the 'h_i_shock' you provided should be a list or np.ndarray."
        assert len(
            h_i_shock
        ) == self._data._N, "ERROR: the length of 'h_i_shock' you provided is not equal to data."

        self._debtrank = self._run_centrality(method='dr',
                                              h_i_shock=h_i_shock,
                                              t_max=max_iter)['centrality']
        self._debtrank = dict(zip(self._nodes, self._debtrank))
        self._nonlinear_debtrank = self._run_centrality(
            method='nldr', h_i_shock=h_i_shock, alpha=alpha,
            t_max=max_iter)['centrality']
        self._nonlinear_debtrank = dict(
            zip(self._nodes, self._nonlinear_debtrank))

        network_centrality = [
            self._in_degree_centrality, self._out_degree_centrality,
            self._degree_centrality, self._betweenness_centrality,
            self._in_closeness_centrality, self._out_closeness_centrality,
            self._in_eigenvector_centrality, self._in_eigenvector_centrality,
            self._debtrank, self._nonlinear_debtrank
        ]
        df = pd.DataFrame(network_centrality).T
        df.columns = cdntrality_index

        if rank:
            df = df.rank(method='min', ascending=False)

        return df
Example #5
0
    def draw(self,
             method='',
             h_i_shock=None,
             alpha=None,
             max_iter=100,
             is_savefig=False,
             font_size=5,
             node_color='b',
             seed=None,
             **kwargs):
        """draw financial network.

        Parameters:
        ---
        `method`: <str>.
            the optional, the color of nodes map to the important level of bank. i.e. {'dr','nldr','dc',...}. Default = 'dr'.
        
        `h_i_shock`: <np.ndarray>. 
            the initial shock. see `tt.creating_initial_shock()`.

        `alpha`: <float>.
            optional, the parameter of Non-Linear DebtRank. Default = 0.

        `t_max`: <int>. 
            the max number of iteration. Default = 100.

        `is_savefig`: <False>. 
            optional, if True, it will be saved to the current work environment. otherwise, plt.show().

        `font_size`: <int>. 
            the size of the labels of nodes. Default = 5.  

        `node_color`: <str or RGB>.
            the color of nodes. if method is not empty, the colors reflect the importance level.  

        `**kwargs`: 
            customize your figure, see detail in networkx.draw.
        """
        # initial setting
        title = 'The interbank network' + '(%s)' % self._data._label_year
        method = str(method)
        debtrank_alias = {'dr': 'debtrank', 'nldr': 'nonlinear debtrank'}
        importance_alias = {'lp': 'loss_percentile'}
        centrality_alias = {
            'idc': 'in-degree centrality',
            'odc': 'out-degree centrality',
            'dc': 'degree centrality',
            'bc': 'betweenness centrality',
            'cc': 'closeness(in) centrality',
            'occ': 'out-closeness centrality',
            'ec': 'eigenvector(in) centrality',
            'oec': 'out-eigenvector centrality',
            'kc': 'katz centrality',
        }
        # method
        if method in debtrank_alias:
            if h_i_shock is None:
                try:
                    self._h_i_shock = self._data.h_i_shock
                except:
                    raise Exception(
                        "ERROR: the parameter 'h_i_shock' cannot be empty.",
                        h_i_shock)
            else:
                self._h_i_shock = h_i_shock

            assert isinstance(
                self._h_i_shock, (list, np.ndarray)
            ), "ERROR: the 'h_i_shock' you provided should be a list or np.ndarray."
            assert len(
                self._h_i_shock
            ) == self._data._N, "ERROR: the length of 'h_i_shock' you provided is not equal to data."

            # the node labels
            self._node_labels = {}
            for i, j in zip(self._nodes, self._h_i_shock):
                assert j >= 0, "ERROR: the value of h_i_shock should in [0,1]"
                if j == 0.0:
                    self._node_labels[i] = i
                else:
                    self._node_labels[i] = i + r"$\bigstar$"
            # the method of debtrant
            if method == 'dr':
                # the legend labels
                self._legend_labels = [
                    'debtrank < 25%', 'debtrank > 25%', 'debtrank > 50%',
                    'debtrank > 75%'
                ]
                # the color of nodes
                self._nodes_color = self._run_centrality(
                    method='dr', h_i_shock=self._h_i_shock,
                    t_max=max_iter)['node color']
            elif method == 'nldr':
                if alpha is None:
                    alpha = 0
                    print(
                        "Warning: the paramater of 'alpha' is essential! Default = %.2f"
                        % alpha)
                # rename figure title
                title = 'The interbank network, ' + r'$\alpha = %.2f$' % alpha + ' (%s)' % self._data._label_year
                # the legend labels
                self._legend_labels = [
                    'nonlinear debtrank < 25%', 'nonlinear debtrank > 25%',
                    'nonlinear debtrank > 50%', 'nonlinear debtrank > 75%'
                ]
                # the color of nodes
                self._nodes_color = self._run_centrality(
                    method='nldr',
                    h_i_shock=self._h_i_shock,
                    alpha=alpha,
                    t_max=max_iter)['node color']
            else:
                pass  # TODO

            _legend_elements = [
                Line2D([0], [0],
                       marker='o',
                       color="#6495ED",
                       markersize=3.5,
                       label=self._legend_labels[0]),
                Line2D([0], [0],
                       marker='o',
                       color="#EEEE00",
                       markersize=3.5,
                       label=self._legend_labels[1]),
                Line2D([0], [0],
                       marker='o',
                       color="#EE9A00",
                       markersize=3.5,
                       label=self._legend_labels[2]),
                Line2D([0], [0],
                       marker='o',
                       color="#EE0000",
                       markersize=3.5,
                       label=self._legend_labels[3]),
                Line2D([0], [0],
                       marker='*',
                       markerfacecolor="#000000",
                       color='w',
                       markersize=6.5,
                       label='the initial shock')
            ]
            _ncol = 5
        elif method in importance_alias:
            # title
            title = r'$x_{shock} = %.2f$' % kwargs[
                'x_shock'] + ', t = %d' % kwargs[
                    't'] + ' (%s)' % self._data._label_year
            # the node labels
            self._node_labels = dict(zip(self._nodes, self._nodes))
            # 'lp'
            self._legend_labels = [
                'importantance level < 25%', 'importantance level > 25 %',
                'importantance level > 50%', 'importantance level > 75%'
            ]
            # the color of nodes
            self._nodes_color = self._run_centrality(
                method='lp', t=kwargs['t'],
                x_shock=kwargs['x_shock'])['node color']

            _legend_elements = [
                Line2D([0], [0],
                       marker='o',
                       color="#6495ED",
                       markersize=3.5,
                       label=self._legend_labels[0]),
                Line2D([0], [0],
                       marker='o',
                       color="#EEEE00",
                       markersize=3.5,
                       label=self._legend_labels[1]),
                Line2D([0], [0],
                       marker='o',
                       color="#EE9A00",
                       markersize=3.5,
                       label=self._legend_labels[2]),
                Line2D([0], [0],
                       marker='o',
                       color="#EE0000",
                       markersize=3.5,
                       label=self._legend_labels[3])
            ]
            _ncol = 4

        elif method in centrality_alias:
            # the node labels
            self._node_labels = dict(zip(self._nodes, self._nodes))
            # 'dc'
            if method == 'idc':
                # dict: dictionary. see detail in centrality.
                # the legend labels
                self._legend_labels = [
                    'in-degree centrality < 25%', 'in-degree centrality > 25%',
                    'in-degree centrality > 50%', 'in-degree centrality > 75%'
                ]
                # the color of nodes
                self._in_degree_centrality = ct.in_degree_centrality(self._FN)
                self._nodes_color = self._run_centrality(
                    method='idc',
                    centrality=self._in_degree_centrality)['node color']
            elif method == 'odc':
                # dict: dictionary. see detail in centrality.
                # the legend labels
                self._legend_labels = [
                    'out-degree centrality < 25%',
                    'out-degree centrality > 25%',
                    'out-degree centrality > 50%',
                    'out-degree centrality > 75%'
                ]
                # the color of nodes
                self._out_degree_centrality = ct.out_degree_centrality(
                    self._FN)
                self._nodes_color = self._run_centrality(
                    method='odc',
                    centrality=self._out_degree_centrality)['node color']
            elif method == 'dc':
                # dict: dictionary. see detail in centrality.
                # the legend labels
                self._legend_labels = [
                    'degree centrality < 25%', 'degree centrality > 25%',
                    'degree centrality > 50%', 'degree centrality > 75%'
                ]
                # the color of nodes
                self._degree_centrality = ct.degree_centrality(self._FN)
                self._nodes_color = self._run_centrality(
                    method='dc',
                    centrality=self._degree_centrality)['node color']
            elif method == 'bc':
                # dict: dictionary. see detail in centrality.
                # the legend labels
                self._legend_labels = [
                    'betweenness centrality < 25%',
                    'betweenness centrality > 25%',
                    'betweenness centrality > 50%',
                    'betweenness centrality > 75%'
                ]
                # the color of nodes
                self._betweenness_centrality = ct.betweenness_centrality(
                    self._FN, weight='weight', seed=seed)
                self._nodes_color = self._run_centrality(
                    method='bc',
                    centrality=self._betweenness_centrality)['node color']
            elif method == 'cc' or method == 'icc':
                # dict: dictionary. see detail in centrality.
                # the legend labels
                self._legend_labels = [
                    'in-closeness centrality < 25%',
                    'in-closeness centrality > 25%',
                    'in-closeness centrality > 50%',
                    'in-closeness centrality > 75%'
                ]
                # the color of nodes
                self._in_closeness_centrality = ct.closeness_centrality(
                    self._FN, distance='weight')
                self._nodes_color = self._run_centrality(
                    method='cc',
                    centrality=self._in_closeness_centrality)['node color']
            elif method == 'occ':
                # dict: dictionary. see detail in centrality.
                # the legend labels
                self._legend_labels = [
                    'out-closeness centrality < 25%',
                    'out-closeness centrality > 25%',
                    'out-closeness centrality > 50%',
                    'out-closeness centrality > 75%'
                ]
                # the color of nodes
                self._out_closeness_centrality = ct.closeness_centrality(
                    self._FN.reverse(), distance='weight')
                self._nodes_color = self._run_centrality(
                    method='occ',
                    centrality=self._out_closeness_centrality)['node color']
            elif method == 'ec' or method == 'iec':
                # dict: dictionary. see detail in centrality.
                # the legend labels
                self._legend_labels = [
                    'in-eigenvector centrality < 25%',
                    'in-eigenvector centrality > 25%',
                    'in-eigenvector centrality > 50%',
                    'in-eigenvector centrality > 75%'
                ]
                # the color of nodes
                self._in_eigenvector_centrality = ct.eigenvector_centrality(
                    self._FN, max_iter=max_iter, weight='weight')
                self._nodes_color = self._run_centrality(
                    method='ec',
                    centrality=self._in_eigenvector_centrality)['node color']
            elif method == 'oec':
                # dict: dictionary. see detail in centrality.
                # the legend labels
                self._legend_labels = [
                    'out-eigenvector centrality < 25%',
                    'out-eigenvector centrality > 25%',
                    'out-eigenvector centrality > 50%',
                    'out-eigenvector centrality > 75%'
                ]
                # the color of nodes
                self._out_eigenvector_centrality = ct.eigenvector_centrality(
                    self._FN.reverse(), max_iter=max_iter, weight='weight')
                self._nodes_color = self._run_centrality(
                    method='oec',
                    centrality=self._out_eigenvector_centrality)['node color']
            elif method == 'kc':  # bug
                # dict: dictionary. see detail in centrality.
                # the legend labels
                self._legend_labels = [
                    'katz centrality < 25%', 'katz centrality > 25%',
                    'katz centrality > 50%', 'katz centrality > 75%'
                ]
                # the color of nodes
                phi, _ = np.linalg.eig(self._Ad_ij)
                self._katz_centrality = ct.katz_centrality(
                    self._FN, alpha=1 / np.max(phi) - 0.01, weight='weight')
                self._nodes_color = self._run_centrality(
                    method='kc',
                    centrality=self._katz_centrality)['node color']
            else:
                pass  # TODO

            _legend_elements = [
                Line2D([0], [0],
                       marker='o',
                       color="#6495ED",
                       markersize=3.5,
                       label=self._legend_labels[0]),
                Line2D([0], [0],
                       marker='o',
                       color="#EEEE00",
                       markersize=3.5,
                       label=self._legend_labels[1]),
                Line2D([0], [0],
                       marker='o',
                       color="#EE9A00",
                       markersize=3.5,
                       label=self._legend_labels[2]),
                Line2D([0], [0],
                       marker='o',
                       color="#EE0000",
                       markersize=3.5,
                       label=self._legend_labels[3])
            ]
            _ncol = 4

        else:
            # the node labels
            self._node_labels = dict(zip(self._nodes, self._nodes))
            self._nodes_color = node_color  # "#00BFFF"
            print("Warning: the color of nodes have no special meaning.")

        # draw
        draw_default = {
            'node_size': self._node_assets,
            'node_color': self._nodes_color,
            'edge_color': self._edge_color,
            'edge_cmap': plt.cm.binary,
            'labels': self._node_labels,
            'width': 0.8,
            'style': 'solid',
            'with_labels': True
        }

        # customize your nx.draw
        if 'node_size' in kwargs:
            draw_default['node_size'] = kwargs['node_size']
        if 'node_color' in kwargs:
            draw_default['node_color'] = kwargs['node_color']
        if 'edge_cmap' in kwargs:
            draw_default['edge_cmap'] = kwargs['edge_cmap']
        if 'labels' in kwargs:
            draw_default['labels'] = kwargs['labels']
        if 'style' in kwargs:
            draw_default['style'] = kwargs['style']
        if 'with_labels' in kwargs:
            draw_default['with_labels'] = kwargs['with_labels']

        draw_kwargs = draw_default

        plt.rcParams['figure.dpi'] = 160
        plt.rcParams['savefig.dpi'] = 400
        plt.title(title, fontsize=font_size + 2)
        nx.draw(self._FN,
                pos=nx.circular_layout(self._FN),
                font_size=font_size,
                **draw_kwargs)
        if method:
            plt.legend(handles=_legend_elements,
                       ncol=_ncol,
                       fontsize=font_size - 1,
                       loc='lower center',
                       frameon=False)

        if is_savefig:
            net = "interbanknetwork"
            date = parse(self._data._label_year).strftime("%Y%m%d")
            plt.savefig(net + date + '.png', format='png', dpi=400)
            print("save to '%s'" % os.getcwd() + ' and named as %s' %
                  (net + date) + '.png')
        else:
            plt.show()