Help us understand the problem. What is going on with this article?

「クソデカ羅生門」的な文章を生成したかった(過去形)

注意

これらの要素を含有しています

  • クソコード
  • 無知晒し
  • 満足度の低い結果

前置き

クソデカ羅生門ってのがちょっと前に話題になったじゃないですか、このむやみに巨大化する文法が好きになったので生成したいと思います

環境

  • Python 3.8.3
  • pip 20.1.1
  • mecab-python 0.996.2
  • nltk 3.5
  • (テキストエディタとしてVSCodeとNotepad++を使用)

準備とか

テキストデータの入手

青空文庫から素の羅生門をダウンロードします。ここにはルビ無しファイルがダウンロードできると書いてあったんですがルビありしか見つからなかったのでそっちをダウンロードしてルビを取り除きます。
まず青空文庫側が追加した底本表記とかを削除しまして、
image.png

テキストエディタ側の機能で||《[^《》]*》|※[[^[]]*]の正規表現にマッチする文字列を削除(無に置換)します。
image.png
あ、あと文字コードがShift-JISに設定されてたんですがなんかムカついたのでUTF-8に変更しました。

方向性を考える

とりあえず比較

これでとりあえずテキストデータの下準備は終わりました。ちょっとdifff.jpでクソ普通羅生門とクソデカ羅生門を比較してみましょう。
image.png
お分かりいただけたでしょうか。クソデカ羅生門は、改行なんかをのぞけば原文を全く削らずに完全な「足し算」でクソデカ化しているんです。つまるところ、クソデカ文章の生成の時も、語句そのものを変化させることはないように注意する必要があります。単純に品詞を過剰にするだけでは原文を崩してしまいますからね。

「一点特化」について

あとクソデカ化について言うところとしては、形容を盛りまくるというよりは一点特化である、ということです。例えば

その代りまた鴉がどこからか、たくさん集って来た。昼間見ると、その鴉が何羽となく輪を描いて、高い鴟尾のまわりを啼きながら、飛びまわっている。

っていうクソ普通羅生門の文章を、クソデカ羅生門はこうクソデカ化―――語呂が悪いのでクソデ化としましょう―――しています。

その代りまた超凶悪な鴉がどこからか、億単位でたくさん集って来た。昼間見ると、その鴉が何羽となく輪を描いて、クソ高い鴟尾のまわりを鼓膜破壊レベルの音量で啼きながら、亜音速で飛びまわっている。

このクソデ化は、私が思うに既存の形容を強化することに重点が置かれています。例えば「たくさん」は「億単位でたくさん」になりますし、「何羽」は「何羽」、「高い」は「クソ高い」になります。例えば「高い」を「デカくて高い」とかにして属性を増やすことも可能でしょうが、あえてそれをせずに既存の形容の強化に専念しているわけです。
また、既存の形容が存在しない場合は、新規の形容を作ってそれを強化しています。「鴉が」なら「凶悪な鴉が」となり、それがさらに「凶悪な鴉が」となります。そもそもタイトルからして「クソ」「デカ」「羅生門」ですからね、「クソ」で「デカ」を強化しているわけです。1

やっていく

とりあえずまくらせる

クソデ化にあたって「まくる」は重要です。こいつらはすぐに何かをしまくりますからね。
「まくらせる」ためには、

  1. 自立語の動詞を探す
  2. その原形を取得
  3. 原形から連用形に変換
  4. 「まくる」をつける

的な工程を踏めばよさそうです。
なんか他にうまい方法がある気がするんですが思い付かなかったので、IPA辞書を直接殴る方式(参考)でいきます。

データ用意

まずIPA辞書をダウンロードして解凍し、その中のVerb.csvというファイルをカレントディレクトリにコピーして開きます。こいつは動詞のデータが入ってるファイルですね。
中身はこんな感じになってます。
image.png
10列目に「連用形」が記されている行以外はいらないので消します。テキストエディタ(表計算ソフトではない)で開いて^(?!.*,連用形,).*$\nの正規表現にマッチする文字列を消したらいい感じになると思います。
image.png
こうなりました、連用形リスト.csvって名称で保存しときます。あと処理が面倒なので文字コードをUTF-8に変更しておきます。
更に「まくる」の活用に関するファイルも作ります。元のVerb.csvのこの部分
image.png
をコピーしてまくる.csvって名前でカレントディレクトリに保存します。こっちもUTF-8です。

コード

書きました。

# -*- coding: utf-8 -*-
import MeCab
import csv
t = MeCab.Tagger()
print("入力せよ")
text = input()
nodes_s = t.parseToNode(text)
output = ""
with open('連用形リスト.csv',encoding='UTF-8') as r, open("まくる.csv",encoding='UTF-8') as m:
    r_list = [list(x) for x in zip(*[row for row in (csv.reader(r))])]
    m_list = [list(x) for x in zip(*[row for row in (csv.reader(m))])]
while nodes_s:
    nodes_a = nodes_s.feature.split(",")
    if nodes_a[:2] == ["動詞", "自立"] and not nodes_s.feature.split(",")[6] in ["する","ある"]:
        ori = nodes_a[6]
        type = nodes_a[5]
        renyo = r_list[0][r_list[10].index(ori)]
        mak = m_list[0][m_list[9].index(type)]
        if mak == "まくり" and nodes_s.next.feature.split(",")[7][0] in "タチツテト":
            mak = "まくっ"  # タ接続でうまくいかない場合があったので例外処理
        output += renyo + mak
    else:
        output += nodes_s.surface
    nodes_s = nodes_s.next
print("\n出力:\n" + output)

雑なコードですみません。
こいつを実行します。

入力
下人は、老婆が死骸につまずきながら、慌てふためいて逃げようとする行手を塞いで、こう罵った。老婆は、それでも下人をつきのけて行こうとする。下人はまた、それを行かすまいとして、押しもどす。二人は死骸の中で、しばらく、無言のまま、つかみ合った。しかし勝敗は、はじめからわかっている。下人はとうとう、老婆の腕をつかんで、無理にそこへじ倒した。丁度、鶏の脚のような、骨と皮ばかりの腕である。

出力
下人は、老婆が死骸につまずきまくりながら、慌てまくりふためきまくって逃げまくろうとする行手を塞ぎまくっで、こう罵りまくった。老婆は、それでも下人をつきまくりのけて行こうとする。下人はまた、それを行かしまくるまいとして、押しもどす。二人は死骸の中で、しばらく、無言のまま、つかみ合いまくった。しかし勝敗は、はじめからわかりまくっている。下人はとうとう、老婆の腕をつかみまくっで、無理にそこへじ倒しまくった。丁度、鶏の脚のような、骨と皮ばかりの腕である。
とりあえず意図したこと「らしきこと」は何となくできてる気がします。いろいろと不備はありますが
このままだと「まくりすぎ」なので、調整は必要でしょうね。

「しまくらない」を殺す

このコードだと特定の文字を入れたときに不自然な感じになっちゃいます。
例えば下人の行方は、誰も知らない。を入力したとして、
出力されるのは下人の行方は、誰も知りまくらない。です。
いや、何?って話ですよ、知りまくらないって何?
明らかにおかしいのでコードを変更します。

#前略
while nodes_s:
    nodes_a = nodes_s.feature.split(",")
    if nodes_a[:2] == ["動詞", "自立"] and not nodes_s.feature.split(",")[6] in ["する","ある"]:
#後略

ここのifをちょっと弄りまして、

while nodes_s:
    nodes_a = nodes_s.feature.split(",")
    if nodes_a[:2] == ["動詞", "自立"] and (not nodes_s.feature.split(",")[6] in ["する","ある"]) and not nodes_s.next.feature.split(",")[4] in ["特殊・ナイ"]:

こうします。
これはタ接続時の例外処理と似たような処理で、処理中のnodeの次のノードをnext先読みすることで判定しています。
これでちゃんと下人の行方は、誰も知らない。が出力されます。

「まくっで」を殺す

「選んで」とかが「選びまくっで」とかになっちゃうのでこいつを殺します。
雑にreplaceでキルします。
printの1行前にoutput = output.replace("まくっで","まくって")を突っ込んだら解決しました
あ、あとまくらられみたいなのもあったのでこいつもreplaceでまくられに置換しましょう

以下略

まあこんな風に不自然な場所を人為的に直しました
過程を移すのが面倒なので略しまして、結果としてこんなコードができました

# -*- coding: utf-8 -*-
import MeCab
import csv
t = MeCab.Tagger()
print("入力せよ")
inp = input()
def makuring(text):
    nodes_s = t.parseToNode(text)
    output = ""
    with open('連用形リスト.csv',encoding='UTF-8') as r, open("まくる.csv",encoding='UTF-8') as m:
        r_list = [list(x) for x in zip(*[row for row in (csv.reader(r))])]
        m_list = [list(x) for x in zip(*[row for row in (csv.reader(m))])]
    while nodes_s:
        nodes_a = nodes_s.feature.split(",")
        if nodes_a[:2] == ["動詞", "自立"] and (not nodes_s.feature.split(",")[6] in ["する", "ある", "なる", "いる","言う","云う","行く"]) and not nodes_s.next.feature.split(",")[4] in ["特殊・ナイ", "特殊・ヌ"]:
            ori = nodes_a[6]
            type = nodes_a[5]
            if ori in r_list[10]:
                renyo = r_list[0][r_list[10].index(ori)]
                mak = m_list[0][m_list[9].index(type)]
                if mak == "まくり" and nodes_s.next.feature.split(",")[7][0] in "タチツテト":
                    mak = "まくっ"  # タ接続でうまくいかない場合があったので例外処理
                output += renyo + mak
            else:
                output += nodes_s.surface
        else:
            output += nodes_s.surface
        nodes_s = nodes_s.next
    return output.replace("まくっで", "まくって").replace("まくらられ", "まくられ").replace("まくっだ", "まくった")

ついでにこれらを関数という扱いにしてみました。
これでとりあえず「まくり」処理は完成です。

数字をくっつける

クソデカ羅生門はクソデ化にあたって数字もクソデ化しています。レートは100倍~10000倍くらいですかね?あと盗賊に対する6万人などの、「妙に具体的な数字が与えられる」事象も多発してます。
とりあえず既存の数字を10の2~4乗倍する感じにしました。

# -*- coding: utf-8 -*-
import MeCab
import csv
from kanjize import int2kanji, kanji2int
import random
t = MeCab.Tagger()
print("入力せよ")
inp = input()
kan_dic = { "百": "百","五": "五","5": "五","八": "八","・": "・","兆": "兆","9": "九",
            "七": "七","三": "三","0": "〇","0": "〇","万": "万","零": "〇","四": "四",
            "7": "七","2": "二","4": "四","1": "一","6": "六","〇": "〇","十": "十",
            "六": "六","8": "八","3": "三","二": "二","○": "〇" ,"千": "千","一": "一",
            "億": "億","九": "九","ひゃく": "百","ゼロ": "〇","いち": "一"} # IPA辞書を加工して作った数字の正規化用辞書

#(略)
def incr(text):
    nodes_s = t.parseToNode(text)
    output = ""
    int_flag = False
    count = 0
    while nodes_s:
        count += 1
        nodes_a = nodes_s.feature.split(",")
        if nodes_a[1] == "数" and nodes_s.surface in kan_dic.keys():
            if not int_flag:
                int_flag = True
                kansuji = ""
            kansuji += kan_dic[nodes_s.surface]
        else:
            if int_flag:
                int_flag = False
                random.seed(kansuji)
                output += int2kanji(kanji2int(kansuji) * (10 ** random.randint(2,4)))
            elif count > 1:
                if nodes_s.prev.surface in ["何", "なん", "幾"] and nodes_s.prev.feature.split(",")[1] == "数":
                    random.seed(nodes_s.surface)
                    output += random.choice(["千","万","億"])
            output += nodes_s.surface
        nodes_s = nodes_s.next
    return output

print("\n出力:\n" + makuring(incr(inp)))

入力
広い門の下には、この男のほかに誰もいない。ただ、所々丹塗の剥げた、大きな円柱に、蟋蟀が一匹とまっている。羅生門が、朱雀大路にある以上は、この男のほかにも、雨やみをする市女笠や揉烏帽子が、もう二三人はありそうなものである。それが、この男のほかには誰もいない。

出力
広い門の下には、この男のほかに誰もいない。ただ、所々丹塗の剥げまくった、大きな円柱に、蟋蟀が千匹とまりまくっている。羅生門が、朱雀大路にある以上は、この男のほかにも、雨やみをする市女笠や揉烏帽子が、もう五千人はありそうなものである。それが、この男のほかには誰もいない。
「ニ三人」が「ニ万三千人」(これはこれで間違った解釈ですが)じゃなくて「五千人」になっちゃってるのは、漢字と数字の相互変換に使ってるkanjizeってライブラリの仕様によるものだと思います。直せる気もしますが面倒なのでやめときます。

「たくさん」の処理

クソデ化の時、「たくさん」が「億単位でたくさん」になるじゃないですか、あれの処理をします
なんかnltkとWordnetでいい感じになりそうなのでこの記事を参考に

pip install nltk
python -c "import nltk;nltk.download('wordnet')"
python -c "import nltk;nltk.download('omw')"

をコマンドプロンプトで実行して環境を整えます。
さて、試しに「たくさん」の類語を出力してみます。(さっき貼った記事のコードほぼそのままです、すみません)

from nltk.corpus import wordnet

synsets = wordnet.synsets("たくさん", lang='jpn')
takusan_synset = synsets[0]
synonyms = takusan_synset.lemma_names("jpn")
print(synonyms)

出力
['たくさん', '厖大', '多量', '大量', '数多', '沢山', '浩大', '潤沢', '総やか', '豊', '豊か', '豊富', '豊満', '豊潤', '豊饒']
いいですね、いかにもたくさん、って感じ
この吐き出されたリストをそのまま「たくさんっぽい言葉」の配列として保存して、その配列に含まれる言葉を類語として持っている言葉に具体的な数字をつける方向で行きましょう
(盗人を6万人にするのは方法が思いつかなかったので諦めました)

# -*- coding: utf-8 -*-
import MeCab
import csv
from kanjize import int2kanji, kanji2int
import random
from nltk.corpus import wordnet
#(略)
blacklist = []
t = MeCab.Tagger()
takusan = [ 'たくさん', '厖大', '多量', '大量', '数多', '沢山', '浩大',
            '潤沢', '総やか', '豊', '豊か', '豊富', '豊満', '豊潤', '豊饒']
#(略)
def embod(text):
    global blacklist
    nodes_s = t.parseToNode(text)
    output = ""
    while nodes_s:
        nodes_a = nodes_s.feature.split(",")
        if not (nodes_a[1] in ["動詞", "助詞", "記号", "助動詞"] or nodes_s.surface in blacklist):
            synsets = wordnet.synsets(nodes_s.surface, lang='jpn')
            synsets_a = []
            for i in synsets:
                synsets_a += i.lemma_names("jpn")
            if len(set(takusan) & set(synsets_a)) > 0:
                random.seed(nodes_s.prev.prev.surface +nodes_s.prev.surface) #なんか一つの入力に対する生成結果が常に同じの方がいい気がしたのでシード設定
                output += random.choice(["万単位で","億単位で","兆単位で"])
            else:
                blacklist += nodes_s.surface
        output += nodes_s.surface
        nodes_s = nodes_s.next
    return output

なんか処理が長くなる予感がしたんでブラックリストをつけて実行時間短縮を図りました。
入力
その代りまた鴉がどこからか、たくさん集って来た。昼間見ると、その鴉が何羽となく輪を描いて、高い鴟尾のまわりを啼きながら、飛びまわっている。ことに門の上の空が、夕焼けであかくなる時には、それが胡麻をまいたようにはっきり見えた。鴉は、勿論、門の上にある死人の肉を、啄みに来るのである。――もっとも今日は、刻限が遅いせいか、一羽も見えない。ただ、所々、崩れかかった、そうしてその崩れ目に長い草のはえた石段の上に、鴉の糞が、点々と白くこびりついているのが見える。下人は七段ある石段の一番上の段に、洗いざらした紺の襖の尻を据えて、右の頬に出来た、大きな面皰を気にしながら、ぼんやり、雨のふるのを眺めていた。
出力
その代りまた鴉がどこからか、兆単位でたくさん集いまくって来た。昼間見まくると、その鴉が何千羽となく輪を描きまくって、高い鴟尾のまわりを啼きまくりながら、飛びまわりまくっている。ことに門の上の空が、夕焼けであかくなる時には、それが胡麻をまきまくったようにはっきり見えまくった。鴉は、勿論、門の上にある死人の肉を、啄みまくりに来まくるのである。――もっとも今日は、刻限が遅いせいか、千羽も見えない。ただ、所々、崩れまくりかかった、そうしてその崩れ目に長い草のはえまくった石段の上に、鴉の糞が、点々と白くこびりつきまくっているのが見えまくる。下人は七千段ある石段の一番上の段に、洗いざらした紺の襖の尻を据えまくって、右の頬に出来まくった、大きな面皰を気にしながら、ぼんやり、雨のふりまくるのを眺めまくっていた。
なかなかいい感じじゃないでしょうか。

「ニ三人」の処理

さっき「直せる気もしますが面倒なのでやめときます」って書いたんですが、なんか思ったより楽な気がしてきたので直していきます。

#(略)
        else:
            if int_flag:
                int_flag = False
                if len(kansuji) > 1:
                    if all((s in "一二三四五六七八九") for s in [kansuji[0],kansuji[1]]): #最初の2文字が両方一~九であった場合「ニ三」の同類とみなす
                        output += kansuji[0]
                        kansuji = kansuji[1:]
                random.seed(kansuji)
                output += int2kanji(kanji2int(kansuji) * (10 ** random.randint(2,4)))
#(略)

入力
広い門の下には、この男のほかに誰もいない。ただ、所々丹塗の剥げた、大きな円柱に、蟋蟀が一匹とまっている。羅生門が、朱雀大路にある以上は、この男のほかにも、雨やみをする市女笠や揉烏帽子が、もう二三人はありそうなものである。それが、この男のほかには誰もいない。
出力
兆単位で広い門の下には、この男のほかに誰もいない。ただ、所々丹塗の剥げまくった、大きな円柱に、蟋蟀が千匹とまりまくっている。羅生門が、朱雀大路にある以上は、この男のほかにも、雨やみをする市女笠や揉烏帽子が、もう二三千人はありそうなものである。それが、この男のほかには誰もいない。

完璧か?

形容の追加・クソデ化

前置き(長い)

ついに来てしまいました………おそらく一番の難関というかこれを書いている今も方法をよく理解してないです
いや、どうすればいいの?
えっと、とりあえず「まだ形容されてない単語」に「新しく形容をつける」みたいなことをやってみようと思います

↑この文章を書いたのが3日前です……3日間隙あらばHacknetやってました………生産性がなさすぎる
「いやほんとどーしよーな~~~~~」みたいな感じでへらへら笑いながらHacknetでPointclickerのデータ改竄してましたからね………酷い奴だ
でですね、3日間の間にCabochaを使って係り受け解析すれば「形容がついてる文章」と「ついてない文章」で分けられるのでは?ということを思いつきました
そういうわけでとりあえずここからCabochaをインストールして………
あれっ
あの、今インストールしてテストしてるところなんですが、何も出力しません
これ何かしらに失敗しましたわ、どうしようもない
そういうわけで、Cabocha以外の係り受け解析器を探します

これだ

COTOHA APIです。知人の話ではこいつには構文解析(つよい)機能があるらしいじゃないですか、俺はこれで未来を掴むぜと思ったんですがなんか知らないけど「利用規約読みました」のチェックボックスがクリックできなかったので諦めます。もう終わりだ

こうなったら

気合で何とかします。プランを練りましょう
えーっとですね、「形容されている」か「されていない」かを判定して、されていない場合はあたらしく適当につける、みたいなことをやればいいはずです。
まず「形容されるべき言葉」とでも言うべきものがあるはずです。とりあえず一般名詞(盗人や蟋蟀など)と自立動詞(啼くや飛び回るなど)などは「形容されるべき言葉」である、ということにしましょう。
そして「この形容されるべき言葉」が形容されているかの判定にはひとつ前の形態素が格助詞または句点であるかを用いることにします。なんかこれでいい感じになる気がしたのでこうします。
これを元に関数を作ってみましょう。

#(略)
def deco(text):
    nodes_s = t.parseToNode(text)
    output = ""
    count = 0
    while nodes_s:
        nodes_a = nodes_s.feature.split(",")
        count += 1
        if nodes_a[:2] in [["名詞", "一般"], ["名詞", "固有名詞"], ["動詞", "自立"]] and count > 1:
            if nodes_s.prev.feature.split(",")[0] in ["連体詞"] or nodes_s.prev.feature.split(",")[1] in ["格助詞", "句点", "読点", "並立助詞"]:
                output += "クソデカ"
        output += nodes_s.surface
        nodes_s = nodes_s.next
    return output

print("\n出力:\n" + makuring(embod(incr(deco(inp)))))

とりあえずまだ形容されてないっぽい形態素の一個前に「クソデカ」と付ける関数ができました。動詞と名詞の区別すらつけてませんが、これでとりあえずやってみましょう。

入力
広い門の下には、この男のほかに誰もいない。ただ、所々丹塗の剥げた、大きな円柱に、蟋蟀が一匹とまっている。羅生門が、朱雀大路にある以上は、この男のほかにも、雨やみをする市女笠や揉烏帽子が、もう二三人はありそうなものである。それが、この男のほかには誰もいない。

出力
兆単位で広い門の下には、このクソデカ男のほかに誰もいない。ただ、クソデカ所々丹塗の剥げまくった、大きなクソデカ円柱に、クソデカ蟋蟀が千匹とまりまくっている。クソデカ羅生門が、クソデカ朱雀大路にクソデカある以上は、このクソデカ男のほかにも、クソデカ雨やみをクソデカする市女笠やクソデカ揉烏帽子が、もう二三千人はありそうなものである。それが、このクソデカ男のほかには誰もいない。
う~~~~~~~~~~~~ん
いけるか…?いやでもなぁ、う~~~~ん
まだ判断しづらいですし、ちょっと改修します

def deco(text):
    nodes_s = t.parseToNode(text)
    output = ""
    count = 0
    while nodes_s:
        nodes_a = nodes_s.feature.split(",")
        count += 1
        if count > 1:
            if nodes_s.prev.feature.split(",")[0] in ["連体詞"] or nodes_s.prev.feature.split(",")[1] in ["格助詞", "句点", "読点", "並立助詞"]:
                if nodes_a[:2] in [["名詞", "一般"], ["名詞", "固有名詞"]]:
                    output += "クソデカ"
                elif nodes_a[:2] in [["動詞", "自立"]]:
                    output += "メチャクチャ"
        output += nodes_s.surface
        nodes_s = nodes_s.next
    return output

動詞なら「メチャクチャ」、名詞なら「クソデカ」が付くようにしました
これでちょっとわかりやすくなったんじゃないでしょうか

入力
広い門の下には、この男のほかに誰もいない。ただ、所々丹塗の剥げた、大きな円柱に、蟋蟀が一匹とまっている。羅生門が、朱雀大路にある以上は、この男のほかにも、雨やみをする市女笠や揉烏帽子が、もう二三人はありそうなものである。それが、この男のほかには誰もいない。

出力
兆単位で広い門の下には、このクソデカ男のほかに誰もいない。ただ、クソデカ所々丹塗の剥げまくった、大きなクソデカ円柱に、クソデカ蟋蟀が千匹とまりまくっている。クソデカ羅生門が、クソデカ朱雀大路にメチャクチャある以上は、このクソデカ男のほかにも、クソデカ雨やみをメチャクチャする市女笠やクソデカ揉烏帽子が、もう二三千人はありそうなものである。それが、このクソデカ男のほかには誰もいない。

良さげ

とりあえず語彙を増やしてみる

クソデ化詞の豊富さがクソデカ羅生門の魅力の一つです。クソデ化詞は大雑把に分類すると、「名詞につくもの」(デカい・巨大な)と「動詞につくもの」(馬鹿みたいに・メチャクチャ)と「形容詞につくもの」(超・クソ)の3種類です。「形容詞につく物」はクソデ化詞に付く場合もあるのでちょっと特殊なポジションですね。機械的に生成するのも可能な気がしますがめんどくさいので人力で生成しました。

  • 名詞につくものリスト: ["デカい","大","激・","巨大","象くらいある","ヤバい","ビッグ","とんでもない","ものすごい","世界最強の"](ここで力尽きました)
  • 動詞につくものリスト: ["メチャメチャ","馬鹿みたいに","マジで","気持ち悪いくらい"](ここで力尽き略
  • 形容詞につくものリスト ["超","メチャメチャ","馬鹿みたいに","マジで","クソ","めちゃくちゃ","ガチで","えげつない","人類史に残るほどに"](ここで略

メッチャ適当にやったせいで語彙力が貧弱になってしまいました……まぁいいです、これでやってみましょう
とりあえず名詞と動詞をクソデ化します

def deco(text):
    nodes_s = t.parseToNode(text)
    output = ""
    count = 0
    while nodes_s:
        nodes_a = nodes_s.feature.split(",")
        count += 1
        if count > 1:
            if nodes_s.prev.feature.split(",")[0] in ["連体詞"] or nodes_s.prev.feature.split(",")[1] in ["格助詞", "句点", "読点", "並立助詞"]:
                random.seed(nodes_s.prev.surface + nodes_s.surface + nodes_s.next.surface) #雑に前後を参照してシード決定
                if nodes_a[:2] in [["名詞", "一般"], ["名詞", "固有名詞"]]:
                    output += random.choice(["デカい","大","激・","巨大","象くらいある","ヤバい","ビッグ","とんでもない","ものすごい","世界最強の"])
                elif nodes_a[:2] in [["動詞", "自立"]]:
                    output += random.choice(["メチャメチャ","馬鹿みたいに", "マジで", "気持ち悪いくらい"])
        output += nodes_s.surface
        nodes_s = nodes_s.next
    return output

あ、あと関数の順番をちょっと変えました

print("\n出力:\n" + makuring(deco(embod(incr(inp)))))

入力
作者はさっき、「下人が雨やみを待っていた」と書いた。しかし、下人は雨がやんでも、格別どうしようと云う当てはない。ふだんなら、勿論、主人の家へ帰る可き筈である。所がその主人からは、四五日前に暇を出された。前にも書いたように、当時京都の町は一通りならず衰微していた。今この下人が、永年、使われていた主人から、暇を出されたのも、実はこの衰微の小さな余波にほかならない。だから「下人が雨やみを待っていた」と云うよりも「雨にふりこめられた下人が、行き所がなくて、途方にくれていた」と云う方が、適当である。その上、今日の空模様も少からず、この平安朝の下人の

出力
作者はさっき、「下人が大雨やみをマジで待ちまくっていた」とマジで書きまくった。しかし、デカい下人は雨がマジでやんでも、格別どうしようとメチャメチャ云う当てはない。ふだんなら、勿論、ものすごい主人の家へ馬鹿みたいに帰りまくる可き筈である。所がそのヤバい主人からは、四五千日前にとんでもない暇を馬鹿みたいに出しまくられた。前にも書きまくったように、当時京都の町は千通りならず衰微していた。今このビッグ下人が、永年、メチャメチャ使いまくられていた主人から、ヤバい暇を馬鹿みたいに出しまくられたのも、実はこの衰微の小さなものすごい余波にメチャメチャほかならない。だから「下人が大雨やみをマジで待ちまくっていた」とメチャメチャ云うよりも「雨にメチャメチャふりこめまくられた下人が、気持ち悪いくらい行き所がなくて、兆単位で巨大途方にマジでくれまくっていた」と馬鹿みたいに云う方が、適当である。その上、今日の空模様も少からず、この兆単位で巨大平安朝の下人の

う~~~~ん
まぁいいか(いいのか?)

マジでない

クソデカ羅生門は基本的に「ない」を「マジでない」にします。Falseというそれ以上強めようのない言葉を「確実性」という観点からデカくしてるんですね、さすがだ

def deco(text):
    nodes_s = t.parseToNode(text)
    output = ""
    count = 0
    while nodes_s:
        nodes_a = nodes_s.feature.split(",")
        count += 1
        if count > 1:
            if nodes_s.prev.feature.split(",")[0] in ["連体詞"] or nodes_s.prev.feature.split(",")[1] in ["格助詞", "句点", "読点", "並立助詞"]:
                random.seed(nodes_s.prev.surface + nodes_s.surface) #雑に前を参照してシード決定(エラーが出たのでprevだけ参照するように)
                if nodes_a[:2] in [["名詞", "一般"], ["名詞", "固有名詞"]]:
                    output += random.choice(["デカい","大","激・","巨大","象くらいある","ヤバい","ビッグ","とんでもない","ものすごい","世界最強の"])
                elif nodes_a[:2] in [["動詞", "自立"]]:
                    output += random.choice(["メチャメチャ","馬鹿みたいに", "マジで", "気持ち悪いくらい"])
        if nodes_a[0] == "形容詞" and nodes_a[6] == "ない":
            output += "マジで"
        output += nodes_s.surface
        nodes_s = nodes_s.next
    return output

入力
作者はさっき、「下人が雨やみを待っていた」と書いた。しかし、下人は雨がやんでも、格別どうしようと云う当てはない。ふだんなら、勿論、主人の家へ帰る可き筈である。所がその主人からは、四五日前に暇を出された。前にも書いたように、当時京都の町は一通りならず衰微していた。今この下人が、永年、使われていた主人から、暇を出されたのも、実はこの衰微の小さな余波にほかならない。だから「下人が雨やみを待っていた」と云うよりも「雨にふりこめられた下人が、行き所がなくて、途方にくれていた」と云う方が、適当である。その上、今日の空模様も少からず、この平安朝の下人の Sentimentalisme に影響した。申の刻下りからふり出した雨は、いまだに上るけしきがない。そこで、下人は、何をおいても 差当り明日の暮しをどうにかしようとして――云わばどうにもならない事を、どうにかしようとして、とりとめもない考えをたどりながら、さっきから朱雀大路にふる雨の音を、聞くともなく聞いていたのである。

出力(シード周りを弄ったのでさっきと生成される乱数が変わってます)
作者はさっき、「下人がものすごい雨やみをメチャメチャ待ちまくっていた」と気持ち悪いくらい書きまくった。しかし、ものすごい下人は雨が馬鹿みたいにやみまくっても、格別どうしようと気持ち悪いくらい云う当てはない。ふだんなら、勿論、巨大主人の家へマジで帰りまくる可き筈である。所がその激・主人からは、四五千日前にものすごい暇をメチャメチャ出しまくられた。前にも書きまくったように、当時京都の町は千通りならず衰微していた。今この世界最強の下人が、永年、馬鹿みたいに使いまくられていた主人から、ものすごい暇をメチャメチャ出しまくられたのも、実はこの衰微の小さなとんでもない余波にメチャメチャほかならない。だから「下人がものすごい雨やみをメチャメチャ待ちまくっていた」と気持ち悪いくらい云うよりも「雨にメチャメチャふりこめまくられた下人が、マジで行き所がマジでなくて、デカい途方にメチャメチャくれまくっていた」と気持ち悪いくらい云う方が、適当である。その上、今日の空模様も少からず、このとんでもない平安朝の下人のSentimentalismeに影響した。とんでもない申の刻下りからマジでふりまくり出した雨は、いまだに上りまくるけしきがマジでない。そこで、ものすごい下人は、何を気持ち悪いくらいおきまくっても差当り明日の暮しをどうにかしようとして――云わばどうにもならない事を、どうにかしようとして、気持ち悪いくらいとりとめまくりもマジでない考えを気持ち悪いくらいたどりまくりながら、さっきからビッグ朱雀大路にメチャメチャふりまくる雨の音を、馬鹿みたいに聞きまくるともマジでなく聞きまくっていたのである。

理解不能だけどまぁ…

形容詞をクソデ化

ちょっと辛くなってきたのでこれで終わりにしたい
obiv関数を作って形容詞のクソデ化を行います。クソデ化詞はさっき載せたリストを使用し、関数を二重がけすることでクソデ化に厚みを持たせます。(冗長にならないようクソデ化率を50%くらいにしましょう)

def obiv(text):
    nodes_s = t.parseToNode(text)
    output = ""
    count = 0
    while nodes_s:
        count += 0
        nodes_a = nodes_s.feature.split(",")
        if nodes_a[0] == "形容詞":
            random.seed(nodes_s.surface + str(count))
            if random.random() < 0.5:
                output += random.choice(["超","メチャメチャ","馬鹿みたいに","マジで","クソ","めちゃくちゃ","ガチで","えげつない","人類史に残るほどに"])
        output += nodes_s.surface
        nodes_s = nodes_s.next
    return output
print("\n出力:\n" + obiv(obiv(makuring(deco(embod(incr(inp)))))))

入力
作者はさっき、「下人が雨やみを待っていた」と書いた。しかし、下人は雨がやんでも、格別どうしようと云う当てはない。ふだんなら、勿論、主人の家へ帰る可き筈である。所がその主人からは、四五日前に暇を出された。前にも書いたように、当時京都の町は一通りならず衰微していた。今この下人が、永年、使われていた主人から、暇を出されたのも、実はこの衰微の小さな余波にほかならない。だから「下人が雨やみを待っていた」と云うよりも「雨にふりこめられた下人が、行き所がなくて、途方にくれていた」と云う方が、適当である。その上、今日の空模様も少からず、この平安朝の下人の Sentimentalisme に影響した。申の刻下りからふり出した雨は、いまだに上るけしきがない。そこで、下人は、何をおいても 差当り明日の暮しをどうにかしようとして――云わばどうにもならない事を、どうにかしようとして、とりとめもない考えをたどりながら、さっきから朱雀大路にふる雨の音を、聞くともなく聞いていたのである。

出力
作者はさっき、「下人がものすごい雨やみをメチャメチャ待ちまくっていた」と気持ち悪いくらい書きまくった。しかし、ものすごい下人は雨が馬鹿みたいにやみまくっても、格別どうしようと気持ち悪いくらい云う当てはない。ふだんなら、勿論、巨大主人の家へマジで帰りまくる可き筈である。所がその激・主人からは、四五千日前にものすごい暇をメチャメチャ出しまくられた。前にも書きまくったように、当時京都の町は千通りならず衰微していた。今この世界最強の下人が、永年、馬鹿みたいに使いまくられていた主人から、ものすごい暇をメチャメチャ出しまくられたのも、実はこの衰微の小さなとんでもない余波にメチャメチャほかならない。だから「下人がものすごい雨やみをメチャメチャ待ちまくっていた」と気持ち悪いくらい云うよりも「雨にメチャメチャふりこめまくられた下人が、マジで行き所がマジでなくて、デカい途方にメチャメチャくれまくっていた」と気持ち悪いくらい云う方が、適当である。その上、今日の空模様もマジでマジで少からず、このとんでもない平安朝の下人のSentimentalismeに影響した。とんでもない申の刻下りからマジでふりまくり出した雨は、いまだに上りまくるけしきがマジでない。そこで、ものすごい下人は 、何を気持ち悪いくらいおきまくっても差当り明日の暮しをどうにかしようとして――云わばどうにもならない事を、どうにかしようとして、気持ち悪いくらいとりとめまくりもマジでない考えを気持ち悪いくらいたどりまくりながら、さっきからビッグ朱雀大路にメチャメチャふりまくる雨の音を、馬鹿みたいに聞きまくるともマジでなく聞きまくっていたのである。
もう終わりにしていいですか、若干辛くなってきた

感想

あんまり高精度なクソデ化ができませんでした………Cabochaを使えればもうちょっと高度なのができたと思うんですが色々面倒でして……いつかインストールに成功したら再チャレンジしたいです、もうちょっと「対象によって変わるクソデ化詞」が欲しかったね(例:「亜音速で」)

参考

https://web.archive.org/web/20171212152621/http://adsmedia.hatenablog.com/entry/2016/10/20/002211
https://qiita.com/pocket_kyoto/items/1e5d464b693a8b44eda5
https://qiita.com/matsuatsu/items/fc696741a994f011f91e


  1. 「クソデカ」は2つで1セットみたいなところありますが、「デカ羅生門」でも意味は通じますし、それに更に「バカ」を足すことで「バカデカ羅生門」とかも作れるので、分離したそれと考えました。 

gaqwest
学生です。使えるプログラミング言語はScratchと診断メーカーとBrainFuckです。最近暇だったのでRubyを始めました。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした