

### 前提

環境[python3.9,networkxも最新です,anaconda]  
上記の環境でグラフの類似率を求めるプログラミングを実行しています。  
<https://networkx.org/documentation/stable/reference/algorithms/similarity.html#>

↑NetworkXの公式サイトの類似グラフのgraph_edit_distanceの詳細サイトを参考にプログラミングを組みました。  
GEDという手法を用いるのですが、その内容を理解しないといけないので参考URLを置いておきます。  
<https://nw.tsuda.ac.jp/lec/EditDistance/>

そこで削除、置換、作成が行われる際の重みづけができるのですが、そのコード通りに実行してもエラーが出てしまいます。

![イメージ説明](https://ddjkaamml8q8x.cloudfront.net/questions/2022-11-11/e60a646b-005f-4f34-931f-de8047c6405b.png)

### 実現したいこと

削除、置換、作成が行われる際の重みづけをできるようにする。  
（普段は削除は１、置換は1、作成は１だと思いますが、costを増やしたいです。）

### 発生している問題・エラーメッセージ

[code]

    nx.graph_edit_distance(G1, G2,node_subst_cost=(G1.nodes[G1], G2.nodes[G2]), node_del_cost=1, node_ins_cost=1)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "/Users/tokut/opt/anaconda3/envs/py39/lib/python3.9/site-packages/networkx/classes/reportviews.py", line 194, in __getitem__
        return self._nodes[n]
    KeyError: <networkx.classes.graph.Graph object at 0x7fb1f01f2340>
    
[/code]

### 該当のソースコード

[code]

    import numpy as np
    import networkx as nx
    import scipy as sp
    import matplotlib.pyplot as plt
    
    G1 = nx.Graph()
    G1.add_nodes_from([("Owner1", {"attribute":"Owner1"},{"label":"Owner1"}),
    ("M1", {"attribute":"M1"},{"label":"M1"}),
    ("M2", {"attribute":"M2"},{"label":"M2"}),
    ("R0", {"attribute":"R0"},{"label":"R0"})])
    G1.add_edges_from([("Owner1","R0"), ("Owner1", "M1"),
    ("M1", "M2")])
    print(G1.nodes())
    print(G1.edges())
    nx.nx_agraph.view_pygraphviz(G1, prog='fdp')
    
    G2 = nx.Graph()
    G2.add_nodes_from([("C1", {"attribute":"C1"},{"label":"C1"}),
    ("S1", {"attribute":"S1"},{"label":"S1"}),
    ("S2", {"attribute":"S2"},{"label":"S2"}),
    ("R0R", {"attribute":"R0R"},{"label":"R0R"}),
    ("M3", {"attribute":"M3"},{"label":"M3"})])
    G2.add_edges_from([("C1", "R0R"),
    ("S1", "S2"), ("C1", "S1"),
    ("M3", "S2")])
    print(G2.nodes())
    print(G2.edges())
    
    nx.nx_agraph.view_pygraphviz(G2, prog='fdp')
    
    nx.graph_edit_distance(G1, G2,node_subst_cost=(G1.nodes[G1], G2.nodes[G2]), node_del_cost=1, node_ins_cost=1)
    
[/code]

こちらの2つのグラフのGEDは２です。（作成✖️２[nodeとedges]）  
![イメージ説明](https://ddjkaamml8q8x.cloudfront.net/questions/2022-11-11/b4daf1ba-2466-447c-9968-82086d2b7298.png)  
こちらにdeleteとinsertの重み付けをしたいのですが、公式サイトでは  
![イメージ説明](https://ddjkaamml8q8x.cloudfront.net/questions/2022-11-11/96c6c8c2-23ba-4479-8ad4-53d16ff09f28.png)  
上記の通り、costの大きさ、値をどこに書いていればいいのかが書いてません。公式サイトの例題ではrootの例題になっており、説明がありません。  
そこで自分で作ってみたのですが、うまくいきません。

### 試したこと

様々な記載方法を試しましたが、実行する際にエラーが出てしまいます。

<https://data-analysis-
stats.jp/%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92/networkx%E3%81%AE%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E9%A1%9E%E4%BC%BC%E5%BA%A6/>  
上記のサイトを利用してラベル付きのGED測定はできたのですが、重み付けの記事がなく、どうやってうまくcostを自分のやりたいように増やせるかがわかりません。

### 補足情報（FW/ツールのバージョンなど）

環境[python3.9,networkxも最新です,anaconda]


CC BY-SA 4.0
2022-11-11T07:26:28.327
92150
2022-12-23T06:30:45.997
55332
question
python python3 networkx
NetworkXのGEDを実行する際の重み付け（cost）を増やしたい。


最初に `graph_edit_distance` のリファレンスのとおりに全ての引数を指定（`node_match=None, ....,
timeout=None`）して `2.0` が得られることを確認しました。次にリファレンスによれば3番目から10番目の引数は callable
と指定されているので，適当な関数 `func1` を定義（下記）して `node_subst_cost=func1`
としてみたところ反映（`2.04`，頂点の置換が4回）されました。

[code]

    def func1(x, y):
        return 0.01
    
[/code]

一律に値を変えたいのであれば無名関数（`lambda`）を使う方が簡明なので，その記述例を下記に示します。  
なお，リファレンスによると「置換，削除，挿入」のコストのデフォルト値は「0, 1, 1」のようです。また，私の環境「macOS13(M1), Python
3.10.8, networkx 2.8.8」では提示された書き方で `add_nodes_from()` がエラーになったので書き方を変更しています。

[code]

    import networkx as nx
    
    G1 = nx.Graph()
    G1.add_nodes_from([("Owner1", {"attribute": "Owner1", "label": "Owner1"}),
                       ("M1", {"attribute": "M1", "label": "M1"}),
                       ("M2", {"attribute": "M2", "label": "M2"}),
                       ("R0", {"attribute": "R0", "label": "R0"})])
    G1.add_edges_from([("Owner1", "R0"), ("Owner1", "M1"),
                       ("M1", "M2")])
    print(G1.nodes())
    print(G1.edges())
    nx.nx_agraph.view_pygraphviz(G1, prog='fdp')
    
    G2 = nx.Graph()
    G2.add_nodes_from([("C1", {"attribute": "C1", "label": "C1"}),
                       ("S1", {"attribute": "S1", "label": "S1"}),
                       ("S2", {"attribute": "S2", "label": "S2"}),
                       ("R0R", {"attribute": "R0R", "label": "R0R"}),
                       ("M3", {"attribute": "M3", "label": "M3"})])
    G2.add_edges_from([("C1", "R0R"),
                       ("S1", "S2"), ("C1", "S1"),
                       ("M3", "S2")])
    print(G2.nodes())
    print(G2.edges())
    nx.nx_agraph.view_pygraphviz(G2, prog='fdp')
    
    ged = nx.graph_edit_distance(G1, G2,
                                 node_match=None,
                                 edge_match=None,
                                 node_subst_cost=lambda x, y: 0.01,
                                 node_del_cost=lambda x: 1.001,
                                 node_ins_cost=lambda x: 1.0001,
                                 edge_subst_cost=lambda x, y: 0.00001,
                                 edge_del_cost=lambda x: 1.000001,
                                 edge_ins_cost=lambda x: 1.0000001,
                                 roots=None,
                                 upper_bound=None,
                                 timeout=None)
    print(ged)
    
[/code]

[code]

    ['Owner1', 'M1', 'M2', 'R0']
    [('Owner1', 'R0'), ('Owner1', 'M1'), ('M1', 'M2')]
    ['C1', 'S1', 'S2', 'R0R', 'M3']
    [('C1', 'R0R'), ('C1', 'S1'), ('S1', 'S2'), ('S2', 'M3')]
    2.0401301
    
[/code]


CC BY-SA 4.0
2022-12-23T06:06:49.520
92975
2022-12-23T06:30:45.997
2022-12-23T06:30:45.997
54588
54588
92150
answer