[PYTHON] C'est Noël, donc je vais essayer de dessiner la généalogie de Jésus-Christ avec Cabocha

Puisque c'est Noël, je vais le dessiner dans la généalogie de Jésus-Christ dans l'Évangile de Matai.

Le fils d'Abraham est Isaku,
Le fils d'Isaku est Jacob,
Le fils de Jacob est Juda et ses frères,
Le fils de Juda est Perez par Tamar et Zera,
Le fils de Perez est Hezlon,
Le fils de Hezlon est Ram,
Le fils d'Agneau est Aminadab,
L'enfant d'Aminadab est Nachon,
L'enfant de Nachon est Salmon,
Le fils de Salmon est Boaz de Lahab,
Le fils de Boaz est Obede de Ruth,
Le fils d'Obede est Essai,
Le fils d'Essai est David.

Le fils de David est Salomon de la femme d'Urie,
Le fils de Salomon est Rehabaam,
Le fils de Rehabaam est Abiya,
Le fils d'Abiya est Asa,
L'enfant d'Asa est Yoshapate,
Le fils de Yoshapate est Yoram,
Le fils de Yoram est Ujiya,
Le fils d'Ujiya est Yotam,
L'enfant de Yotam est Ahaz,
L'enfant d'Ahaz est Hizekiya,
L'enfant de Hizekiya est Manase,
Le fils de Manase est Amon,
Le fils d'Amon est Yoshiya,
Les fils de Josias étaient Econia et ses frères au moment de l'expulsion de Babylone.

Après l'expulsion de Babylone:
L'enfant d'Econia est Charter,
Le fils de Charter est Zelbabel,
Le fils de Zelbabel est Abiude,
Le fils d'Abiude est Eliya Kim,
Le fils d'Eliya Kim est Azor,
L'enfant d'Azor est Sadoku,
L'enfant de Sadoku est Akim,
Le fils d'Akim est Eriude,
Le fils d'Eliude est Eleazar,
Le fils d'Eléazar est Matane,
Le fils de Matane est Jacob,
Le fils de Jacob est le mari de Marie, Joseph.

Préparation

Installation de Cabocha 0.68 http://qiita.com/mima_ita/items/161cd869648edb30627b

Installation de GraphViz et pydot http://needtec.exblog.jp/20608517/

Créer un dictionnaire utilisateur

Puisqu'il existe un nom unique, créez un dictionnaire utilisateur afin que l'analyse morphologique puisse être effectuée. Créez le CSV suivant.

bible.csv


Abraham,0,0,500,nom,Général,*,*,*,*,Abraham,Abraham,Abraham
Isaku,0,0,500,nom,Général,*,*,*,*,Isaku,Isaku,Isaku
Jacob,0,0,500,nom,Général,*,*,*,*,Jacob,Jacob,Jacob
Juda,0,0,500,nom,Général,*,*,*,*,Juda,Juda,Juda
Zera,0,0,500,nom,Général,*,*,*,*,Zera,Zera,Zera
Perez,0,0,500,nom,Général,*,*,*,*,Perez,Perez,Perez
Hezlon,0,0,500,nom,Général,*,*,*,*,Hezlon,Hezlon,Hezlon
agneau,0,0,500,nom,Général,*,*,*,*,agneau,agneau,agneau
Amina Dub,0,0,500,nom,Général,*,*,*,*,Amina Dub,Amina Dub,Amina Dub
Nation,0,0,500,nom,Général,*,*,*,*,Nation,Nation,Nation
Saumon,0,0,500,nom,Général,*,*,*,*,Saumon,Saumon,Saumon
Boaz,0,0,500,nom,Général,*,*,*,*,Boaz,Boaz,Boaz
Obede,0,0,500,nom,Général,*,*,*,*,Obede,Obede,Obede
Essai,0,0,500,nom,Général,*,*,*,*,Essai,Essai,Essai
David,0,0,500,nom,Général,*,*,*,*,David,David,David
Salomon,0,0,500,nom,Général,*,*,*,*,Salomon,Salomon,Salomon
Reha Baam,0,0,500,nom,Général,*,*,*,*,Reha Baam,Reha Baam,Reha Baam
Abiya,0,0,500,nom,Général,*,*,*,*,Abiya,Abiya,Abiya
Comme un,0,0,500,nom,Général,*,*,*,*,Comme un,Comme un,Comme un
Mastic Yosha,0,0,500,nom,Général,*,*,*,*,Mastic Yosha,Mastic Yosha,Mastic Yosha
Yoram,0,0,500,nom,Général,*,*,*,*,Yoram,Yoram,Yoram
Ujiya,0,0,500,nom,Général,*,*,*,*,Ujiya,Ujiya,Ujiya
Yotam,0,0,500,nom,Général,*,*,*,*,Yotam,Yotam,Yotam
Ahaz,0,0,500,nom,Général,*,*,*,*,Ahaz,Ahaz,Ahaz
Hizekiya,0,0,500,nom,Général,*,*,*,*,Hizekiya,Hizekiya,Hizekiya
Manase,0,0,500,nom,Général,*,*,*,*,Manase,Manase,Manase
Amon,0,0,500,nom,Général,*,*,*,*,Amon,Amon,Amon
Yoshiya,0,0,500,nom,Général,*,*,*,*,Yoshiya,Yoshiya,Yoshiya
Babylone,0,0,500,nom,Général,*,*,*,*,Babylone,Babylone,Babylone
Econia,0,0,500,nom,Général,*,*,*,*,Econia,Econia,Econia
Charte,0,0,500,nom,Général,*,*,*,*,Charte,Charte,Charte
Zelbabel,0,0,500,nom,Général,*,*,*,*,Zelbabel,Zelbabel,Zelbabel
Abiude,0,0,500,nom,Général,*,*,*,*,Abiude,Abiude,Abiude
Eliya Kim,0,0,500,nom,Général,*,*,*,*,Eliya Kim,Eliya Kim,Eliya Kim
Azor,0,0,500,nom,Général,*,*,*,*,Azor,Azor,Azor
Sadoku,0,0,500,nom,Général,*,*,*,*,Sadoku,Sadoku,Sadoku
Akim,0,0,500,nom,Général,*,*,*,*,Akim,Akim,Akim
Eriude,0,0,500,nom,Général,*,*,*,*,Eriude,Eriude,Eriude
Singe Elea,0,0,500,nom,Général,*,*,*,*,Singe Elea,Singe Elea,Singe Elea
Matane,0,0,500,nom,Général,*,*,*,*,Matane,Matane,Matane
Jacob,0,0,500,nom,Général,*,*,*,*,Jacob,Jacob,Jacob

Sous Windows, vous pouvez créer un dictionnaire utilisateur appelé bible.dic en exécutant la commande suivante à l'invite de commandes.

"C:\Program Files (x86)\MeCab\bin\mecab-dict-index" -d"C:\Program Files (x86)\MeCab\dic\ipadic" -u bible.dic -f shift-jis -t utf-8 bible.csv

Dans Cabocha, vous pouvez effectuer une analyse des dépendances à l'aide du dictionnaire utilisateur en spécifiant le chemin du dictionnaire utilisateur avec l'option -u.

Code de création d'un organigramme de famille

bible.py


#!/usr/bin/python
# -*- coding: utf-8 -*-
import CaboCha
import pydot
import uuid
import sys


class node:
    """
Enregistrer les nœuds de pedigree
    """
    def __init__(self):
        self.name = None
        self.children_node = {}
        self.pairs_node = {}
        self.id = str(uuid.uuid4())

font_name = "ms ui gothic"

sentence = """
Le fils d'Abraham est Isaku,\n
Le fils d'Isaku est Jacob,\n
Le fils de Jacob est Juda et ses frères,\n
Le fils de Juda est Perez par Tamar et Zera,\n
Le fils de Perez est Hezlon,\n
Le fils de Hezlon est Ram,\n
Le fils d'Agneau est Aminadab,\n
L'enfant d'Aminadab est Nachon,\n
L'enfant de Nachon est Salmon,\n
Le fils de Salmon est Boaz de Lahab,\n
Le fils de Boaz est Obede de Ruth,\n
Le fils d'Obede est Essai,\n
Le fils d'Essai est David.\n

Le fils de David est Salomon de la femme d'Urie,\n
Le fils de Salomon est Rehabaam,\n
Le fils de Rehabaam est Abiya,\n
Le fils d'Abiya est Asa,\n
L'enfant d'Asa est Yoshapate,\n
Le fils de Yoshapate est Yoram,\n
Le fils de Yoram est Ujiya,\n
Le fils d'Ujiya est Yotam,\n
L'enfant de Yotam est Ahaz,\n
L'enfant d'Ahaz est Hizekiya,\n
L'enfant de Hizekiya est Manase,\n
Le fils de Manase est Amon,\n
Le fils d'Amon est Yoshiya,\n
Les fils de Josias étaient Econia et ses frères au moment de l'expulsion de Babylone.\n

Après l'expulsion de Babylone:\n
L'enfant d'Econia est Charter,\n
Le fils de Charter est Zelbabel,\n
Le fils de Zelbabel est Abiude,\n
Le fils d'Abiude est Eliya Kim,\n
Le fils d'Eliya Kim est Azor,\n
L'enfant d'Azor est Sadoku,\n
L'enfant de Sadoku est Akim,\n
Le fils d'Akim est Eriude,\n
Le fils d'Eliude est Eleazar,\n
Le fils d'Eléazar est Matane,\n
Le fils de Matane est Jacob,\n
Le fils de Jacob est le mari de Marie, Joseph.\n
"""


def get_word(tree, ix):
    surface = tree.token(ix).surface
    f = tree.token(ix).feature.split(",")
    return surface, f


def create_node(tree, chunk):
    s1, f1 = get_word(tree, chunk.token_pos + chunk.head_pos)
    s2 = None
    f2 = None
    type = 0
    if chunk.head_pos != chunk.func_pos:
        s2, f2 = get_word(tree, chunk.token_pos + chunk.func_pos)
        if f2[0] == 'Particule':
            if f2[1] == 'syndicat':  #"de"
                type = 1
            elif f2[1] == 'Assistance':  #"Ha"
                type = 2
            elif f2[1] == 'Assistant de connexion':  #"Quand"
                type = 3
            elif f2[1] == 'Assistant de cas':  #"par"
                type = 4
    if f1[0] == 'nom':
        if f1[1] == 'suffixe':
            s1 = tree.token(chunk.token_pos + chunk.head_pos - 1).surface + s1
    return {
        'text': s1,
        'type': type
    }


def find_child(t, child_name):
    """
Obtenir un nœud avec un enfant spécifié dans l'ascendance
    """
    for key, item in t.children_node.items():
        if key == child_name and item is None:
            return t
        elif item is not None:
            ret = find_child(item, child_name)
            if ret:
                return ret
    return None


def dump_family(family_tree):
    """
Vidage du diagramme de famille
    """
    print ('parent:', family_tree.name)
    for key, item in family_tree.pairs_node.items():
        print ('femme:', key)

    for key, item in family_tree.children_node.items():
        print ('Enfant:', key)
        if item:
            print (dump_family(item))


def create_graph_children(graph, p_node, child):
    n = pydot.Node(child.id,
                   label=child.name,
                   style="filled",
                   fillcolor="green",
                   shape = "box",
                   fontname=font_name)
    subg = pydot.Subgraph('', rank='same')
    subg.add_node(n)
    graph.add_subgraph(subg)
    if p_node:
        graph.add_edge(pydot.Edge(p_node, n))

    for key, item in child.pairs_node.items():
        pair = pydot.Node(str(uuid.uuid4()),
                          label=key,
                          style="filled",
                          fillcolor="pink",
                          shape = "box",
                          fontname=font_name)
        subg.add_node(pair)
        graph.add_edge(pydot.Edge(n, pair))

    for key, item in child.children_node.items():
        if item:
            create_graph_children(graph, n, item)
        else:
            nchild = pydot.Node(str(uuid.uuid4()),
                                label=key,
                                style="filled",
                                fillcolor="gray",
                                shape = "box",
                                fontname=font_name)
            graph.add_node(nchild)
            graph.add_edge(pydot.Edge(n, nchild))


def create_graph(family_tree):
    graph = pydot.Dot(graph_type='digraph',
                      fontname=font_name)
    create_graph_children(graph, None, family_tree)
    graph.write_png('example2_graph.png')


def main(argvs, argc):
    c = CaboCha.Parser("-u bible.dic")
    lines = sentence.split("\n")
    family_tree = None
    for line in lines:
        tree = c.parse(line)
        data = node()
        if tree.chunk_size() == 0:
            continue
        ids = {-1: None}
        children = []
        pairs = []
        for i in range(tree.chunk_size()):
            curid = i
            if i in ids:
                continue
            chunk = tree.chunk(i)
            attr = None
            cnn_type = 0
            while True:
                d = create_node(tree, chunk)
                ids[curid] = d
                if data.name is None:
                    data.name = d['text']
                if cnn_type == 1:  #Le morceau précédent se termine par «non»
                    if d['text'] == 'Enfant':
                        attr = 'children'
                elif cnn_type == 2:  #Le morceau précédent se termine par "ha"
                    if attr == 'children':
                        children.append(curid)
                elif cnn_type == 3:  #Même opération si le bloc précédent se termine par "et"
                    if attr == 'children':
                        children.append(curid)
                else:
                    attr = None
                if d['type'] == 4:  #Si le morceau se termine par "par", il est considéré comme un conjoint
                    pairs.append(i)
                else:
                    cnn_type = d['type']
                if not chunk.link in ids:
                    curid = chunk.link
                    chunk = tree.chunk(curid)
                else:
                    break
        for child in children:
            data.children_node[ids[child]['text']] = None

        for pair in pairs:
            data.pairs_node[ids[pair]['text']] = None

        if len(children) > 0:
            if family_tree is None:
                family_tree = data
            else:
                node_obj = find_child(family_tree, data.name)
                if node_obj:
                    node_obj.children_node[data.name] = data
    if family_tree:
        dump_family(family_tree)
        create_graph(family_tree)


if __name__ == '__main__':
    argvs = sys.argv
    argc = len(argvs)
    sys.exit(main(argvs, argc))

Cela générera un pedigree comme celui ci-dessous. example2_graph.png

Si vous écrivez dans un style similaire, vous pouvez probablement créer différents tableaux de famille.

Pour le moment, la structure de données qui vous permet de définir plusieurs conjoints permet à vos ancêtres de répondre à des activités d'accouplement vigoureuses, mais je ne sais pas qui et qui sont les enfants. ..

Recommended Posts

C'est Noël, donc je vais essayer de dessiner la généalogie de Jésus-Christ avec Cabocha
C'est Halloween donc je vais essayer de le cacher avec Python
Essayez d'obtenir le contenu de Word avec Golang
Essayez d'extraire les caractéristiques des données de capteur avec CNN
Essayez de résoudre le problème N Queen avec SA de PyQUBO
Mettez Cabocha 0.68 dans Windows et essayez d'analyser la dépendance avec Python
Essayez d'imaginer les données d'élévation du National Land Research Institute avec Python
Essayez de ne faire réagir que le carbone en bout de chaîne avec SMARTS
Essayez de séparer l'arrière-plan et l'objet en mouvement de la vidéo avec OpenCV
[Vérification] Essayez d'aligner le groupe de points avec la fonction d'optimisation de pytorch Partie 1
Essayez de résoudre le problème du fizzbuzz avec Keras
Essayez de résoudre le diagramme homme-machine avec Python
Essayez de dessiner une courbe de vie avec python
Comment essayer l'algorithme des amis d'amis avec pyfof
Essayez de simuler le mouvement du système solaire
Essayez de créer une table d'enregistrement de bataille avec matplotlib à partir des données de "Schedule-kun"
Essayez de résoudre le livre des défis de programmation avec python3
Ajoutez des informations au bas de la figure avec Matplotlib
Essayez de résoudre les problèmes / problèmes du "programmeur matriciel" (Chapitre 1)
Visualisons la pièce avec tarte aux râpes, partie 1
Essayez de résoudre le problème d'affectation du médecin de formation avec Python
Essayez d'estimer le nombre de likes sur Twitter
[Neo4J] ④ Essayez de gérer la structure du graphe avec Cypher
C'est un problème d'écrire "coding: utf-8" en Python, donc je vais faire quelque chose avec Shellscript
Essayez d'importer dans la base de données en manipulant ShapeFile d'informations numériques sur les terres nationales avec Python
Essayez de visualiser les nutriments des flocons de maïs que le champion de M-1 Milkboy a dit avec Python