Python 3.x - リンク攻撃を視覚化する最良の方法は何ですか

okwaves2024-01-24  5

次の画像のような Networkx グラフがあります (画像ソース)

エッジ攻撃を実行し、結果のサブグラフのノードでの値の変化を観察します。

例: エッジ (a,2) を攻撃すると、エッジ (a, 2) と (2, 1) が削除されます。少し説明すると、エッジ (a, 2) が攻撃されると、ノード 2 の次数は < になります。 2. したがって、ノード 2 に接続されているエッジも削除されます。

上記の攻撃によりサブグラフが生成されます

エッジが攻撃されるたびに、時間の経過とともに観察される e というラベルが付いた終端ノードの値が変化します。 5 回 (攻撃 = 5) の攻撃を実行するとします。ノード e の時系列データを格納する時間 x 攻撃行列 (時間 = 25、攻撃 = 5) があります。

効果を視覚化する方法について提案を求めたいです。ノードの価値に対するこれらの攻撃は時間の経過とともに変化します。 編集:

どのような情報をユーザーから確認または識別できるようにしたいですか。 ビジュアライゼーション?

e で観測される時間経過値にどのエッジの攻撃が最大の影響を与えるかを確認したいと考えています。これは輸送ネットワークであると想像でき、ノードの値はその場所/ノードに到着した製品の量を反映します。商品はソースノード b からターゲットノード e に輸送されます。観察されたのは、エッジが攻撃された後のノード値の変化であり、エッジ値の観察は利用できません。

エッジの攻撃に使用されているコードを見つけてください

import networkx as nx
import matplotlib.pyplot as plt


def attack(G):
    print(G.edges())

    for i, edge in enumerate(G.edges()):
        no_attack = [(6, 9), (3, 16)]
        if edge not in no_attack:
            data = {}
            print(f'attacking edge {edge}')

            H = G.copy()

            # attack an edge
            H.remove_edges_from(ebunch=[edge])

            n = len(G.nodes)
            retain_node_ids = [9, 3]
            H.add_edges_from([(u, v) for u in retain_node_ids for v in (n+1, n+2)])

            # remove nodes with degree < 2
            H = nx.k_core(H, k=2)
            H.remove_nodes_from([n + 1, n + 2])
            # graph_utils_py.draw_graph3d(H, fig=2, show=True)

            # H = nx.convert_node_labels_to_integers(H, first_label=1, ordering='default', label_attribute=None)

            # delete connected nodes and edges
            diff_nodes = set(G.nodes()).difference(H.nodes())
            diff_edges = {e for e in G.edges() for n in diff_nodes if n in e}

            print(f"deleting connected nodes {diff_nodes} ...")
            print(f"deleting connected edges {diff_edges} ...")

            data['diff_nodes'] = list(diff_nodes)
            data['diff_edges'] = list(diff_edges)
            data['edge'] = edge


if __name__ == '__main__':
    n = 20
    G = nx.gnm_random_graph(n=20, m=30, seed=1)
    # nx.draw(G, with_labels=True)
    # plt.show()

    retain_node_ids = [11, 4]
    G.add_edges_from([(u, v) for u in retain_node_ids for v in (n, n + 1)])

    G = nx.k_core(G, k=2)
    G.remove_nodes_from([n, n + 1])
    # nx.draw(G, with_labels=True)
    # plt.show()

    G = nx.convert_node_labels_to_integers(G, first_label=1, ordering='default', label_attribute=None)
    nx.draw(G, with_labels=True)
    plt.show()

    attack(G)

編集2: 以下に投稿された回答は、不透明度を変更し、異なる色を設定することでエッジ攻撃を視覚化することを提案しています。化学物質。残念ながら、これは役に立ちません。攻撃ごとに異なるイメージを作成する必要があります。私はまだ他の提案を探しています。

編集 3: 物事をシンプルにするために、正確に何を視覚化したいのかをもう少し明確にします。

次のようなインタラクティブなグラフを探しています。

攻撃されているエッジをクリックすると、LHS プロットにターゲット ノードで行われた観測結果が表示されます。破線は、特定のエッジ (変数edge に格納されている) に対する攻撃の結果、影響を受けるエッジ (コード内の変数 diff_edges に格納されている) です。

リンクを攻撃した後に影響を受けるエッジに重複がある場合は、対応するカラー マッピングを使用して複数の行として表示できます。インタラクティブなグラフはユーザーの選択に役立ちますノード e での観察を比較するためにエッジ攻撃を設定します。攻撃されたエッジは、不透明度/線種/色を変えることで表示できます。

編集4: 以下に投稿された回答が役に立ちます。ただし、影響を受けるエッジが重なっている場合に問題が発生します。

例: 攻撃(H, (6, 4), color='red') 攻撃(H, (5, 4), color=' yellow')

与えます

色が重なっているため、視覚化するのが困難です。 edit3 で上に投稿した画像に示されているように、影響を受けるエッジを重ならずに隣り合って描画できれば、問題はありません。

何か提案がありましたらイオン?

– ナターシャ

2020 年 9 月 4 日 2:27

ビジュアライゼーションからどの情報を確認または識別できるようにしたいですか?エッジ値がどのように変化するかについて詳しく教えていただけますか?

– templatetypedef

2020 年 9 月 5 日 5:14

@templatetypedef 編集内容を見ていただけますか?

– ナターシャ

2020 年 9 月 5 日 5:21

@templatetypedef 元の投稿でエッジを攻撃するために更新されたコードを見つけてください

– ナターシャ

2020 年 9 月 5 日 6:36

@templatetypedef 何か提案はありますか?

– ナターシャ

2020 年 9 月 6 日 1:49



------------------------

次のことを行うことができますまず攻撃されたエッジを削除し、別の隣接ノードが廃止されるかどうかを確認します (影響を受けたエッジ)。次に、適切なエッジを見つけた後、その攻撃に固有の色でエッジを描画します。ここでは、メインの攻撃を実線スタイルで描き、衝撃を受けた攻撃を破線スタイルで描きました。

import matplotlib.pyplot as plt
import networkx as nx


H = nx.gnm_random_graph(n=8, m=9, seed=5)  # generate a random graph
H.add_edges_from([('In', 1), (5, 'Out')])  # adding input/output nodes
pos = nx.spring_layout(H, iterations=400)  # find good positions for nodes

edges = []
impacted_edges = []


def attack(G, edge, color):
    G.remove_edge(*edge)  # first remove the edge

    # check if another could be also impacted
    if G.degree[edge[0]] == 1:
        neighbor = [n for n in G.neighbors(edge[0])][0]
        impacted_edge = (edge[0], neighbor, color)

    elif G.degree[edge[1]] == 1:
        neighbor = [n for n in G.neighbors(edge[1])][0]
        impacted_edge = (edge[1], neighbor, color)

    else:
        impacted_edge = None

    if impacted_edge:
        impacted_edges.append(impacted_edge)

    edges.append((edge[0], edge[1], color))
    nx.draw_networkx_edges(
        H,
        edgelist=[edge],
        pos=pos,
        edge_color=color,
        style='solid',
        label=f'Attack {edge[0]}-{edge[1]}',
        width=4
    )
    G.add_edge(*edge)

# attack some edges
attack(H, (6, 4), color='red')
attack(H, (3, 6), color='blue')
attack(H, (1, 2), color='green')
attack(H, (5, 4), color='purple')

ax = plt.gca()
for edge in impacted_edges:
    ax.annotate('',
                xy=pos[edge[0]],
                xytext=pos[edge[1]],
                zorder=1,
                arrowprops=dict(
                    color=edge[2],
                    arrowstyle='-',
                    connectionstyle='arc3,rad=0.2',
                    lw=4,
                    linestyle='--'
                )
                )

H.remove_edges_from([(e[0], e[1]) for e in impacted_edges])
H.remove_edges_from([(e[0], e[1]) for e in edges])

nx.draw(H, pos, node_size=700, with_labels=True, node_color='gray', edge_color='gray')

plt.legend()
plt.show()

この回答であなたが望むものが見つかることを願っています。

4

ありがとうございます。次のステップは、nx グラフとデータ ポイントを組み合わせて視覚化することです。私の編集をご覧ください。

– ナターシャ

2020 年 9 月 13 日 2:47

1

どういたしまして。修正箇所を確認してください。これを使用して、データ ポイントの隣にプロットできます。

– アジム・マジナニ

2020 年 9 月 13 日 14:20

更新していただきありがとうございます。正直に言うと、この質問を投稿したときは明確なイメージがありませんでした質問。皆さんのコメントのおかげで、とても助かりました。現在の実装には問題が 1 つあります。影響を受ける 2 つのエッジをプロットする必要がある場合 (たとえば、4 ~ 5 の場合、1 つは赤で色付けされており、別の破線を黄色で追加する必要がある場合)、破線が表示されます。重複する可能性があります

– ナターシャ

2020 年 9 月 13 日 14:48

1

もちろん。その場合は、connectionstyle='arc3,rad=0.2' を変更できます。パラメータを大きいまたは小さい rad に設定します (次のようにします)y 0.3) は、重なった線の 1 つに対して適用されます。

– アジム・マジナニ

2020 年 9 月 13 日 15:02



------------------------

解決

ノードを削除する前に、ノード e を指すエッジに矢印を追加し、削除するノードとエッジを緑、次に赤で繰り返します。アルファを組み込んで、最小-最大距離と、グラフの変更に応じて距離がどのように変化するかを表すこともできます。

参考文献

NetworkX 有向グラフの例: https://networkx.github.io/documentation/stable/auto_examples/drawing/plot_directed.html

NetworkX のdraw_networkx_edges 引数 (矢印、色、アルファを含む): https://networkx.github.io/documentation/stable/reference/generated/networkx.drawing.nx_pylab.draw_networkx_edges.html

3

残念ながら、これは簡単な選択肢ではありません。グラフに 50 個のエッジがある場合、攻撃されるエッジに対して異なるアルファまたは異なるカラーコーディングを持つ 50 個の画像を作成する必要があります。

– ナターシャ

2020 年 9 月 9 日 2:33

@natasha どの媒体に公開する予定ですか?

– pygeek

2020 年 9 月 9 日 4:15

執筆中の原稿にこれらを追加したいと思います。

– ナターシャ

2020 年 9 月 9 日 5:12



------------------------

サンキーチャートは役に立ちますか?

サンキー ダイアグラムは、ある値のセットから別の値のセットへの流れを表すために使用される視覚化です。えーっと。以下のスニペットは Google チャートからのもので、グラフ フローの視覚化がどのように見えるかを示す一例です。

<html>
<body>
 <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>

<div id="sankey_multiple" style="width: 900px; height: 300px;"></div>

<script type="text/javascript">
  google.charts.load("current", {packages:["sankey"]});
  google.charts.setOnLoadCallback(drawChart);
   function drawChart() {
    var data = new google.visualization.DataTable();
    data.addColumn('string', 'From');
    data.addColumn('string', 'To');
    data.addColumn('number', 'Weight');
    data.addRows([
       [ 'Brazil', 'Portugal', 5 ],
       [ 'Brazil', 'France', 1 ],
       [ 'Brazil', 'Spain', 1 ],
       [ 'Brazil', 'England', 1 ],
       [ 'Canada', 'Portugal', 1 ],
       [ 'Canada', 'France', 5 ],
       [ 'Canada', 'England', 1 ],
       [ 'Mexico', 'Portugal', 1 ],
       [ 'Mexico', 'France', 1 ],
       [ 'Mexico', 'Spain', 5 ],
       [ 'Mexico', 'England', 1 ],
       [ 'USA', 'Portugal', 1 ],
       [ 'USA', 'France', 1 ],
       [ 'USA', 'Spain', 1 ],
       [ 'USA', 'England', 5 ],
       [ 'Portugal', 'Angola', 2 ],
       [ 'Portugal', 'Senegal', 1 ],
       [ 'Portugal', 'Morocco', 1 ],
       [ 'Portugal', 'South Africa', 3 ],
       [ 'France', 'Angola', 1 ],
       [ 'France', 'Senegal', 3 ],
       [ 'France', 'Mali', 3 ],
       [ 'France', 'Morocco', 3 ],
       [ 'France', 'South Africa', 1 ],
       [ 'Spain', 'Senegal', 1 ],
       [ 'Spain', 'Morocco', 3 ],
       [ 'Spain', 'South Africa', 1 ],
       [ 'England', 'Angola', 1 ],
       [ 'England', 'Senegal', 1 ],
       [ 'England', 'Morocco', 2 ],
       [ 'England', 'South Africa', 7 ],
       [ 'South Africa', 'China', 5 ],
       [ 'South Africa', 'India', 1 ],
       [ 'South Africa', 'Japan', 3 ],
       [ 'Angola', 'China', 5 ],
       [ 'Angola', 'India', 1 ],
       [ 'Angola', 'Japan', 3 ],
       [ 'Senegal', 'China', 5 ],
       [ 'Senegal', 'India', 1 ],
       [ 'Senegal', 'Japan', 3 ],
       [ 'Mali', 'China', 5 ],
       [ 'Mali', 'India', 1 ],
       [ 'Mali', 'Japan', 3 ],
       [ 'Morocco', 'China', 5 ],
       [ 'Morocco', 'India', 1 ],
       [ 'Morocco', 'Japan', 3 ]
    ]);

    // Set chart options
    var options = {
      width: 600,
    };

    // Instantiate and draw our chart, passing in some options.
    var chart = new google.visualization.Sankey(document.getElementById('sankey_multiple'));
    chart.draw(data, options);
   }
</script>
</body>
</html>

Python ライブラリを探している場合は、Plotly のサンキー図をチェックしてください。

1

ありがとうございます。しかし、これは攻撃を視覚化するのには役に立たないと思います

– ナターシャ

2020 年 9 月 11 日 17:00

総合生活情報サイト - OKWAVES
総合生活情報サイト - OKWAVES
生活総合情報サイトokwaves(オールアバウト)。その道のプロ(専門家)が、日常生活をより豊かに快適にするノウハウから業界の最新動向、読み物コラムまで、多彩なコンテンツを発信。