[PYTHON] Wie macht man "die ersten drei Wörter, die man gefunden hat"?

Hast du das jemals auf Twitter oder Facebook gesehen? スナップショット17.jpeg Das habe ich erfunden. Sie können einige finden, indem Sie suchen.

** Wie machst du das? ?? Ich habe mich gefragt **, also habe ich einen Moment darüber nachgedacht. Der gesamte Code ist in Python3 implementiert. Wenn Sie 2.x verwenden und häufig Japanisch verwenden, ändern Sie. Wenn Sie den Zeichencode nur am Ein- und Ausgang beachten, müssen Sie sich keine Gedanken über Unicode oder Codec machen, sodass dies sehr einfach ist.

Strategie 1: Wählen Sie ein völlig zufälliges Hiragana

Strategie 1


import random

h, w = 16, 16
USE_HIRAGANAS = ('Aiue Okakikuke Kosashi' +
        'Was ist Nune no Hahifuhe Homami Mumemoya Yuyorari Rurewan' +
        'Gagiguge Gozajizuzezo Dajizu de Dobabibubebo Papipupepo')

for _ in range(h):
    print(''.join(random.choice(USE_HIRAGANAS) for _ in range(w)))

Ergebnisse der Strategie 1


Ruzuru Ponuzu Jijiranuyo Audo Pepo
Geyojiname Hikepe no Patsume Abo
Zuko Pozazago Gibabora Hiwa Chiro Yubu
Es ist wunderbar.
Nemejikabare Newaboru Kisupibina
Noupi Homi ni Reze Unazamomu Obotsu
Robuza Hopozae Shipsachi
Nato ist Gozae Koto Dometsuse Pizozuso
Keine Bräunung und Unebenheiten
Ntepabesoyusupibi ist ein Fremder
Meba und Hechinagake Yasuzumihoha
Yabudo Soewa ni Sajiya no Mobonunu
Mabiro Gozuru Yupiruji Wazumosa
Blick und Sozuma Hoa Osaji Gezu Hameki
Chikoshige Bikinebo Pezazubo
Ich habe Angst, dass ich Angst habe

Ich habe keine Lust, ein Wort zu finden. Es tut uns leid.

Strategie 2: Berücksichtigen Sie die Häufigkeit des Auftretens von Hiragana und wählen Sie häufig verwendetes Hiragana mit hoher Wahrscheinlichkeit aus.

Gcanna.ctd von cannadic Kai, das als Wörterbuch des japanischen Open-Source-Eingabesystems verwendet wird, wird als Beispiel für Hiragana-Zeichenfolgen verwendet. benutzt.

Übrigens war die Häufigkeit des Auftretens jedes Hiragana so. スナップショット19.jpeg (Informationen zum Anzeigen von Japanisch in matplotlib finden Sie unter hier, damit es nicht verwirrend wird.)

Hier ist ein Codebeispiel, das die Auswahl eines Hiragana mit hoher Wahrscheinlichkeit erleichtert.

Strategie 2


def make_text1(hist, height, width):
    n = sum(hist.values())
    keyvalues = hist.most_common()
    a = [keyvalues[0][1]]
    for x in keyvalues[1:]:
        a.append(a[-1] + x[1])

    def _get():
        x = random.randrange(n)
        for i,y in enumerate(a):
            if x < y:
                return keyvalues[i][0]

    return '\n'.join([''.join([_get() for _ in range(width)])
                     for _ in range(height)])

Hist geht übrigens von [collection.Counter type] aus (http://docs.python.jp/3/library/collections.html#collections.Counter). Es ist eine Unterklasse vom Typ "dikt" und ähnelt in Bezug auf die Benutzerfreundlichkeit "defaultdict (lambda: 0)", aber Dies ist sehr praktisch, da Sie zwischen Zählertypen addieren und mit Counter.most_common () ((Schlüssel, Wert), ...) in absteigender Reihenfolge abrufen können.

Infolgedessen wurde eine solche Liste von Hiragana erhalten.

Ergebnisse der Strategie 2


Kigorae Shiratsu Osen
Migodakote Azuchi Karigo no Ukuri
Bubuchi Dona Chinkefui Odakoshikofu
Yugitado Ganshin no Teumi Ii
Mesagen Aki de Biuro Hiroro
Vielleicht ist es leicht und leicht
Fuwanrosa Hiuta ist Ujimi Kakubo
Chitsuke-n-Mezan
Jiriyoji und Parugiko
Mach dir keine Sorgen
Toseda Sarago ist Sadamu Umomusin
Fuzoki Sezori Kuki Sachi Aiku Kafu
Riuuchi no Sato Toshito Mawachi
Chiira Utafuse Suma Biseki
Sohachi quietscht und quietscht
Nana Bakon Uta Hogiki Kuukoan

Es hat sich erheblich verbessert. Es ist sehr gut. Dies gibt Ihnen die Energie, danach zu suchen. Aber wäre es nicht ein bisschen besser?

Strategie 3: Berücksichtigen Sie die Übergangswahrscheinlichkeit von einem Hiragana zum anderen

Kurz gesagt, es ist der Markov-Prozess im ersten Stock. Hier ist ein Auszug aus dem Code. Markov ist übrigens "collection.defaultdict (collection.Counter)", und "markov ['a'] ['i']" zählt die Anzahl von "i" nach "a". Ich werde. Ursprünglich musste jedes Element durch "sum (markov ['a']. Values ())" geteilt werden, damit es eine Wahrscheinlichkeit darstellt. Da es jedoch übersprungen wurde, wird diese Funktion auch verwendet.

Strategie 3


def tee(func, arg):
    func(arg)
    return arg

def make_text2(markov, hist, height, width):
    '''Eine Liste von Hiragana, die auch das nächste Hiragana berücksichtigt.'''
    def _get(up, left):
        '''Betrachten Sie den Übergang vom oberen Zeichen und den Übergang vom linken Zeichen'''
        c = norm_markov[up] + norm_markov[left]
        x = random.random() * 2.0
        y = 0.0
        for k,v in c.most_common():
            y += v
            if x <= y:
                #print('_get:', up, left, '-->', k)
                return k

    #In Anbetracht des Übergangs vom oberen zum linken Zeichen sind die Spalte vor der 0. Spalte und die Zeile vor der 0. Zeile
    #Es wird notwendig sein, aber der Einfachheit halber werden wir eine Linie verwenden, die aus der Häufigkeit des Auftretens von Hiragana besteht.
    firstcol = make_text1(hist, 1, width)
    prevline = make_text1(hist, 1, width).strip()
    #print('firstcol', firstcol)
    #print('prevline', prevline)

    #Markov normalisieren.
    #Damit das Gewicht des Übergangs vom oberen Zeichen und des Übergangs vom linken Zeichen gleich bleibt.
    norm_markov = {}
    for k1,cnt in markov.items():
        c = Counter()
        n = sum(cnt.values())
        for k2,v in cnt.items():
            c[k2] = v / n
        norm_markov[k1] = c

    a = []
    for i in range(height):
        line = []
        functools.reduce(lambda x,j: tee(line.append, _get(prevline[j], x)),
                         range(width), firstcol[i])
        a.append(''.join(line))
        prevline = line
    return '\n'.join(a)

Übrigens, um Markov zu machen, können Sie Code wie diesen verwenden. (Ich habe viel weggelassen)

markov Lass uns machen


from collections import deque
from collections import defaultdict
from collections import Counter

def shiftiter(iterable, n):
    '''Generator which yields iterable[0:n], iterable[1:n+1], ...

    Example: shiftiter(range(5), 3) yields (0, 1, 2), (1, 2, 3), (2, 3, 4)'''
    # I used deque, but I'm not sure it is fastest way:(
    it = iter(iterable)
    try:
        a = deque([next(it) for _ in range(n)])
        yield tuple(a)
    except StopIteration:
        pass
    for x in it:
        a.popleft()
        a.append(x)
        yield tuple(a)


USE_HIRAGANAS = ('Aiue Okakikuke Kosashi' +
            'Was ist Nune no Hahifuhe Homami Mumemoya Yuyorari Rurewan' +
            'Gagiguge Gozajizuzezo Dajizu de Dobabibubebo Papipupepo')

markov = defaultdict(Counter)
with open(FILENAME, encoding=FILEENCODING) as f:
    for line in f:
        hiragana = line.split()[0]
        for x,y in shiftiter(hiragana, 2):
            if x in USE_HIRAGANAS and y in USE_HIRAGANAS:
                markov[x][y] += 1

Infolgedessen sieht es so aus.

Ergebnisse der Strategie 3


Kisetsu Gejinkatonta Saikigose
Kleiner Shizun Rakui Otsubishi Kimebui
Gashiani Kahoi Shinyo Sato
Ich bin so nett
Ruiga Hokkokine Ushin Wenn Gouri
Kehowaun Negoru Egipai Toushi
Du bist ein Fremder
Was ist Sankeda Ichichi?
Nigini Omotoyo Heuri Kochise
Nregoka Senka Funuya Shinkuso
Ken ist Mumeki Menshiro Kashiri Dakii
Naki Funamisai kann gut sein
Geriebenes Sushi
Tokei Jio-san oder Sonkaki Ogoto
Ngayama Yoshigoki Hojimami Shizu
Bichikuji Kobarichi Ichizumu Konguka

Möchten Sie danach suchen? Es ist zufällig, also muss ich es mehrmals machen und ein gutes auswählen, aber ich habe den Eindruck, dass es nutzlos ist. Es ist nicht schlecht.

Zukünftige Überlegungen für diejenigen, die noch nicht zufrieden sind

Markov-Prozess im zweiten Stock oder höher

Vielleicht möchten Sie es versuchen.

Wie man Buchstaben auswählt

Derzeit wird die Wahrscheinlichkeitsverteilung von der größten akkumuliert, auf 0 bis 1 normalisiert und mit einer Zufallszahl von 0 bis 1 ausgewählt. (Eigentlich ist es ein bisschen anders, aber es ist fast so) Aber muss ich ein Hiragana wählen, das nur mit einer Chance von 1% erscheint? Sollte es nicht ignoriert werden? Und ich denke. Als ich es jedoch so umgestaltete, dass nur etwa 80% ausgewählt werden konnten, wurde eine große Anzahl häufig verwendeter Hiragana wie "n" und "u" ausgewählt. Es scheint, dass einige Anpassungen sogar auf der Seite mit hoher Frequenz notwendig sind.

Der Code ist Github

Für Interessierte: Der Code wird auf github veröffentlicht. https://github.com/gyu-don/jikken/tree/master/markov Ich habe gcanna.ctd nicht hochgeladen, da das Anzeigen der Lizenz (GPL) mühsam war, aber ich habe die Ausgabe der aggregierten Daten hochgeladen, damit ich sie ohne sie ausführen kann. (Wenn jemand diesen Code mit GPL verwenden möchte, ist es in Ordnung, ihn zu verwenden.)

Sie können gcanna.ctd hier herunterladen. https://osdn.jp/projects/alt-cannadic/releases/

Recommended Posts

Wie macht man "die ersten drei Wörter, die man gefunden hat"?
Wie viel kennen Sie die Grundlagen von Python?
Wie sammelst du Informationen?
Verstehst du das Problem mit Monty Hall?
Machst du so etwas wie eine Rakete?
So verwenden Sie MkDocs zum ersten Mal
Sie können es in 3 Minuten tun! So erstellen Sie einen funktionierenden QR-Code (GIF)!