半自動お笑い生成プログラム JokeGPT / ボケをfstring、題材を引数、引数を関連語の塊として処理

「ロシア人が消毒液を酒として飲んでいる」「出来事x以降、ホームレスが増えている」という内容の文言を生成したいとします。

```python
class Entity:#簡略化したコード
    def __init__(self, name, ti_inc, ti_dec):#実際は合計50種以上のattributeがあります。
        self.name = name
        self.ti_inc = ti_inc#そのアイテムの消費・需要が増えるタイミング
        self.ti_dec = ti_dec#そのアイテムの供給が減るタイミング
alcohol     =Entity("alcohol"     ,""            ,"prohibition era, Dry law")
disinfectant=Entity("disinfectant","pandemic"    ,"")
tent        =Entity("tent"        ,"camping boom","")
house       =Entity("house"       ,"real estate bubble", "housing crisis, Obama care")

def use_z_as_y(ins_z, ins_y):
    jokes=[f"Since the {ins_z.ti_inc}, the sales of {ins_z.name} have reached levels comparable to those during the {ins_y.ti_dec}."
    #大量の他のfstring...
    ]
    #略
use_z_as_y(disinfectant, alcohol)
use_z_as_y(tent, house)
#出力結果
Since the pandemic, the sales of disinfectant have reached levels comparable to those during the prohibition era.
Since the camping boom, the sales of camp gear shop have reached levels comparable to those during the Obama care.
```
で、上記のインスタンス変数は全てAIが作れます。上記のfstringは全て人間が作れます。
"ネタ番組やシットコムで見たボケをfstringに変換する作業"は人間が担当し、"様々な語を、その関連語をインスタンス変数として持つインスタンスにする作業"はAIが担当する。
というアプローチでの、お笑いの半自動生成を試みています。
JokeGPT : https://tarotoyota.pythonanywhere.com/
今のバージョンでは日本語のお笑いを生成する事を一切志向していませんが、今年中に取り掛かります。
```python
dog.name="dog"
dog.annual="head"
meat.unit="ounce, serving"
meat.annual="ton"

disinfectant.name="disinfectant"
alcohol.unit="shot"
alcohol.annual=""

def use_z_as_y(ins_z, ins_y):
    jokes=[f"How much does this {ins_z.name} cost per {ins_y.unit}?"
           f"The average annual sales of {ins_z.name} in various countries: (Area 1), (x) {ins_z.annual}, (Area 2), (x) {ins_y.annual}."
    #大量の他のfstring...
    ]
```
上記のようなベタな文に人力を浪費すべきでしょうか？
南スーダンに関するボケを作りたい場合は以下のような処理を用意しています。
```python
def except_for(items, exceptions):
    return [item for item in items if item not in exceptions]

cause_of_death=["suicide","murder","killed in battle","death from starvation","death from illness","death penalty","death due to adult disease"]
food_negative =["food poisoning, food waste, obesity, diabetes"]

death_from_starvation.name="death_from_starvation"
death_from_starvation.inverse_proportion=([except_for(cause_of_death, ["death from starvation"], food_negative)

def there_are_many_z(ins_z):
    jokes=[ f"(x) has the fewest number of {ins_z.inverse_proportion}."
            f"(x) president is improving the number of {ins_z.inverse_proportion}."
            #大量の他のfstring...
            ]
    #略
```
JokeGPTの出力結果を流し見て、めぼしい文を<strong>流用する</strong>。めぼしいものがないなら、生成結果にあるような構文を<strong>避けて</strong>自力で考える。
流用できるなら結構だし、流用できないなら<strong>避けるべき種類の文が明確化されて</strong>道しるべになって結構です。
しかも、<strong>ボケに使おうとしている語の大量の関連語</strong>をワンクリックで閲覧できる訳ですから役に立たないわけがありません。

もちろん上記のcause_of_deathもfood_negativeもほぼAIに作らせました。
人間が自力で上記のような処理をした場合「餓死や早死にに関連する語を列挙しよう。病死…癌…老齢年金…　10分じゃ終わらない、ブレインストーミングをしよう」となってしまいます。

# 面白さの計量
```python
primitive_info1=("Feminists are stupid.")
euphemized_sentence1=("(At the bookstore) A: Where can I find 'We Should All Be Feminists'? - B: Look near 'How to win 100% at roulette' and 'Cure Cancer with Baking Soda'.")
primitive_info2=("Feminism is a cult.")
euphemized_sentence2=("(At the bookstore) A: Where are Tarana Burke's books? - B: Look near Joseph Smith Jr. and  L. Ron Hubbard's.")
```
primtive_infoの面白さポイントが0であるなら、euphemized_sentenceの面白さポイントは確実に正の数です。これら2文の持つ意味は同じですが婉曲性の有無が異なります。

本プログラムは"Feminism is a cult."のように一切の婉曲性を有さない"原始情報"を"婉曲文"に変換するためのプログラムであると定義できます。本記事での"fstring"と"婉曲文"はほぼ同義です。

上記のように(0, 1)というスケールを超えた計量化の実現が課題です。感覚的には、1つのfstringに含まれるプレースホルダが1つのものよりも、2つのものの方が面白く、3つのものは更に面白い傾向にある気がします。そして…
```python
primitive_info2=("Feminism is a cult.")
euphemized_sentence2=("(At the bookstore) A: Where are Tarana Burke's books? - B: Look near Joseph Smith Jr. and  L. Ron Hubbard's.")
euphemized_sentence3=("(At the bookstore) A: Where are Tarana Burke's books? - B:  Religious book section is over there.")
```
euphemized_sentence3よりもeuphemized_sentence2の方が優れている気がしませんか？
ins_z, ins_y=(gender_studies, cult_religion)の場合、y.nameとの距離を比べると、y.book_common_nameよりy.celebrityの方が遠い訳です。
数値化の必要性の有無は別として、このような各アトリビュートのy.nameとの距離は数値化可能だと思います。

# 棋譜DBと棋士、コーパスと芸人

仮にその国の大統領や外相に何か安牌な発言をさせる場合、南スーダンなら癌や経済犯罪の少なさに絡めて、北朝鮮なら肥満の少なさやヴィーガンの多さに絡めて、スターリン時代のソ連なら、懲役刑を食らってる政治犯の少なさに、ドイツなら、特定の人種の失業者の少なさに絡めて何か言うだとか、そういった<strong>莫大かつ安牌かつ単純な連想ゲーム</strong>は機械に委任して、より高度なボケに集中すべきです。
ソ連→死刑が多い→(懲役刑, 再犯率)が少ない
ソ連→囚人が多い→(ホームレス, 失業者)が少ない, 更生者が多い
ソ連→餓死が多い→(病死, 肥満)が少ない, 一時期レニングラードの食料自給率が世界一だった
このような演算はワンクリックで済ませた方がよいです。将棋指しが棋譜データベースを利用すべきなら、芸人さんも同様です。

2~3つの語の関連語をfstringに当てはめまくる<strong>単純当てはめ</strong>だけで生成できる単純なボケの制作は、機械に丸投げして効率化すべきです。単純当てはめで生成できない、複雑かつ使用例の少ない、しかも使用可能なシチュエーションが限定的な、高度なボケにリソースを注ぐべきです。

そうすればお笑いコンテンツ全体のクオリティupが期待できます。まあ高度なボケももうすぐAIが作るかもしれませんが…

このプログラムで処理できる主なボケは、英語圏のお笑いでありがちな、<strong>二以下引数ボケ</strong>です。
二以下引数ボケというのは私が勝手に今 命名したものなのですが、つまり"Subject uses z as y","Subject categorizes z as y","Subject often z","For Subject, z is inferior to y"みたいな形式で表せる原始情報を婉曲文に変換したものです。
英語圏のコメディで多用される皮肉表現はほぼ全て単純当てはめで生成できると見ています。

# 文章整形について
ホームレスの多さを示すボケを生成して

A subway tunnel collapsed, killing 40 people. The crew and passengers were safe.

という文が出力されたとします。ユーザーは"この文を使うには、テレビニュースでアナウンサーがこの文言を口にするシーンが必要だ"と考え、文体を改変し、特定の地名やミスリードをその文に追加する事になります。そのような改変は、ユーザー側の手元にある、そのエピソードのプロットによって最適な形が変わるので、現状、出力結果の文をより最適な形に整形する作業はユーザー自身が担当するのが最適だと判断しました。

# むすび

ブラックボックスが生じず、強い指向性をもって生成可能な上、人間がコンテンツを学習してそれをfstringに直すというプロセスは、人間のクリエイターが行う"学習"のそれとほぼ同一であり、倫理的・著作権的にホワイトです。
統計を取った訳ではありませんが、fstring化可能なボケを全て書き表した場合、合計で100メガバイトもある訳がなく、何人かでキーボードをカチャカチャすれば十分に網羅可能な量だと考えます。
JokeGPTは書きたてのサービスで、まだめちゃくちゃな生成結果が発生します。githubに公開しているコードはグチャグチャなので近いうち整形します。
が、コメディを一つの膨大なコーパスだと考えた場合、そのうちの無視できない量のボケはこのメソッドで処理可能だと確信しています
2024年1月25日現在、引数として入力可能な語は最大53種のインスタンス変数を持ちます。
200種以上のインスタンス変数は必要ないんじゃないかと思います。