韻を扱いたいpart4

##__内容__
これまでの流れで、入力のテキストデータを分割したものをノードに、分割したもの同士の母音の一致をエッジの重みにしてネットワーク分析を行ってみる。グラフの描写、中心性を見るところまでが目標。
##__データを分割し、辞書を作る__

```python
from pykakasi import kakasi
import re
from collections import defaultdict
from janome.tokenizer import Tokenizer

with open("./gennama.txt","r") as f:
    data = f.read()
    
tokenizer = Tokenizer()
tokens = tokenizer.tokenize(data)

surface_list = []
part_of_speech_list = []
for token in tokens:
    surface_list.append(token.surface)
    part_of_speech_list.append(token.part_of_speech.split(",")[0])
    
segment_text = []
for i in range(len(surface_list)):
    if part_of_speech_list[i] == "記号":
        continue
    elif part_of_speech_list[i] == "助詞" or part_of_speech_list[i] == "助動詞":
        row = segment_text.pop(-1) + surface_list[i]
    else:
        row = surface_list[i]
    segment_text.append(row)

kakasi = kakasi()

kakasi.setMode('H', 'a')
kakasi.setMode('K', 'a')
kakasi.setMode('J', 'a')

conv = kakasi.getConverter()
text_data = [conv.do(text) for text in segment_text]
vowel_data = [re.sub(r"[^aeiou]+","",text) for text in text_data]
#{0:"oea"}
dic_vo = {k:v for k,v in enumerate(vowel_data)}
#voel_dataのインデックスで母音変換前のdataが分かるように辞書作成。{0:"俺は"}
dic = {k:v for k,v in enumerate(segment_text)}
```

part3でやったことを活用。今回はN-gramは向いていないと判断。この、dic_voのキーの数だけノードがあり、ノード間は母音の一致があるかどうかで繋がりを見る。母音が一致する長さが長いほど重みを付けるようにしておく。part1で作っていたような方法を使用するが、自身への繋がりと２文字以上の一致からエッジが出来るようにする。
##__グラフを作る__

```python
#dic_voを渡し、インデックスがnode,値がedge,重みがscoreの(node,node,score)を作る。
def create_edge(dic_vo):
    node_len = len(dic_vo)
    
    edge_list = []
    for i in range(node_len):
        for j in range(node_len):
            score = create_weight(dic_vo[i],dic_vo[j])
            if score != 0:
                edge_list.append((i,j,score))
    return edge_list
            
def create_weight(word_a, word_b):
    weight = 0
    if len(word_a) > len(word_b):
        max_len = len(word_b)
        for i in range(max_len):
            for j in range(max_len + 1):
                if word_b[i:j] in word_a:
                    if word_b == word_a:
                        continue
                    elif len(word_b[i:j]) < 2:
                        continue
                    else:
                        weight += len(word_b[i:j])
    else:
        max_len = len(word_a)
        for i in range(max_len):
            for j in range(max_len + 1):
                if word_a[i:j] in word_b:
                    if word_a == word_b:
                        continue
                    elif len(word_b[i:j]) < 2:
                        continue
                    else:
                        weight += len(word_a[i:j])
    return weight

edge_list = create_edge(dic_vo)            
```

あとはこのedge_listをもとにグラフを描写する。ついでに、固有ベクトル中心性と媒介中心性が高いノードを取得し、元のデータを表示してみる。

```python
import networkx as nx
import matplotlib.pyplot as plt

G = nx.Graph()
G.add_weighted_edges_from(edge_list)
pos = nx.spring_layout(G)
nx.draw_networkx_edges(G, pos)

plt.show()

#固有ベクトル中心性
cent = nx.eigenvector_centrality_numpy(G)
max_cent_node = max(list(cent.keys()), key=lambda val: cent[val])
#媒介中心性
between_cent = nx.communicability_betweenness_centrality(G, weight="weight)
max_betw_node = max(list(between_cent.keys()), key=lambda val: between_cent[val])

print("固有ベクトル中心性が高いのは:" + dic[max_cent_node])
print("媒介中心性が高いのは:" + dic[max_betw_node])
```

結果は予想通り、part2で行った「target_wordを絞れるのでは」と同じだ。まあ同じことをしているので当たり前だが、`networkx`ではこのグラフを元にまだ出来ることがありそうなので追及してみる。
##__今後の方針__
スコアの付け方で、「い」と「う」に注目し、前の音が「e」と「o」ならば、つまり「eい」「oう」ならば「ee」「oo」と変換して母音の一致を見るというものを考えている。（外来語の発音を参考にした）日本語でもそれは聞き分けにくく、響きは同じだと言えるはずだ。ラップ界での押韻の扱いではNGだと思われるがやってみる。~~ちなみに皆さんは本場の「ABCの歌」を聞いたことがあるだろうか？「LMNOP」を「エレネノピー」と一気にいくあれだ。子供の頃から「韻」が身近にあるようだ。日本語ラップへのリスペクトは忘れないが、韻を少し拡張して捉えることを試みる~~