【令和4年版】スマホで読みやすいやる夫スレまとめサイトを作った

お久しぶりです。ikazameです。2年ぶりのブログ更新です。

元号令和にもうなんの違和感もなくなり、新型コロナウイルスもすっかり日常に溶け込んだ昨今、皆さんいかがお過ごしでしょうか?自分は就職して今は元気いっぱいサラリーマンやってます。

最近になって、やる夫スレをスマホでうまいこと読むアイディアをまた思いついたので、それを実装し、まとめサイトとして公開しました。前に作ったやる夫空間とはまた読み方が異なる実装を取っています。今日はそんなサイト「やる夫の縦読み」の紹介をさせていただきます。

作ったサイト

yaruonotateyomi.com

こちらが新サイト、やる夫の縦読みです。PCから見る限りはよくあるWordPress製のやる夫スレまとめサイトです。が、スマホから見るとまとめ記事表示の挙動がPCで見たときと大きく異なります。 百聞は一見にしかずということで、スマホでまとめ記事を表示したときの挙動をGIFアニメーションでご覧ください、スマホ向けというのが分かりやすいと思います。

やる夫スレをスマホの縦スクロールのみで読む様子1

やる夫の縦読みの大きな特徴は以下のとおりです。

AAもセリフも画面幅に収まる

スマホでなにか文書を読む時、重要視されるのは「縦のスクロールのみで文書が読めること」です。PC用の横幅が広いサイトや、PDFドキュメント、既存のPC向け前提のやる夫スレまとめサイトなどはスマホで表示すると横スクロールが発生し、内容全体を読むのに縦横両方のスクロールをする必要があります。

これでも全然読めると感じるか、読みにくいと感じるかは人それぞれかもしれません。が、現実にスマホの普及以降たいていのWebサイトはPC用以外にスマホ用サイズのデザインを用意するようになりましたし、電子書籍リーダーもPDF表示のみにとどまらず画面サイズに合わせて組版してくれる機能がつくようになっています。

既存のやる夫スレまとめサイトは(知る限り)拙作のやる夫空間以外に横スクロールせずに内容をすべて読めるサービスは存在していませんでした。どうしてやる夫スレでスマホの画面幅に合わせて縦読みで読むサービスが今まで存在しなかったか(何が技術的に難しかったのか)の説明は過去記事の「機械学習を用いたAAとセリフの自動分割 - ikazameのブログ」に詳しく書いてあります。

「やる夫の縦読み」でも、3年前にこのブログで発表した、縦読み実現のためのアンサーである「条件付き確率場によるAAセリフ分離」の技術を用いて、AA領域のみを縮小表示しセリフは元のサイズで表示することで、縦スクロールのみでやる夫スレを読めるようになっています。

セリフが本来の位置を尊重して表示される

以前公開したやる夫空間では、セリフはすべてAAの下側に表示される仕様になっていました。

[比較画像]

やる夫空間でのセリフ表示(AAの下側)

やる夫の縦読みでのセリフ表示(オリジナル位置尊重)

ほとんどのセリフがAAの右側に表示されるような古い時代のやる夫スレであれば、下側にセリフが移動しても違和感はありません。しかし、AA同士の掛け合いや、AAの左側に台詞があるときなどには、AAとセリフを大きく分離すると文脈を損なってしまいます。 上の画像の例でも、やらない夫にセリフには吹き出しが存在していますが、セリフを下側に移動すると吹き出しの意味がよく分からなくってしまいます。 やる夫空間ではAAとセリフを引き離してしまうことによって生じる問題を解決することができず、まとめを諦めたスレがいくつもありました。

やる夫の縦読みではこの問題を解決すべく、AAの表示に対してセリフが本来あった位置を計算し、その場所にセリフが表示されるようになっています。(本来こういった仕様をやる夫空間のときにも作るべきでしたが、そうしたほうがいいということに全く気づけていませんでした。コロンブスの卵というかなんというか)

この仕様のおかげで画面の狭いスマホでもPC表示と遜色ない表示を実現することができます。

なお画面幅に合わせて自動的にセリフに改行が入ってしまうため、オリジナル(PC表示)と比較して、セリフは縦方向に増えてしまいます。各セリフの元の位置を尊重しつつ、セリフが縦に増えることを許容すると、セリフ同士が重なって読めなくなってしまうため、セリフはスクロール量に合わせて順番に表示・非表示が切り替えられるようになっています。

やる夫の縦読みの今後

ここまで色々書きましたが、おそらく皆さん興味があるのは「サイトの更新が続くかどうか」だと思います。どれだけ読みやすい環境を提供しても中身が無いと意味ないですし。前に公開したやる夫空間は完全にエターにしてしまったので。

やる夫の縦読み自体は、最初「彼らは友達が皆無スレをスマホで読みたい」というのを原動力につくりました。皆無スレのまとめはもうできてるので、こっから先どうしようかな〜という感じです。

とりあえず、年内は1日1記事更新できるような状態を続けたいなと思っています。ここに書いておくことで、もう逃げられないようにしておきます。

技術的な話

backendはwordpress、frontendはwordpressに乗っけたReact、あとやる夫スレの認識に自作のLSTM-CRFモデルを使っています。この辺の話もまたどっかでしたいと思います。

終わりに

というわけで新・スマホ向けやる夫サイト「やる夫の縦読み」をつくりましたという記事でした。

読んでみてご意見/ご感想あればこの記事でも縦読みのコメント欄でもいいので是非書き込みお願いします。フィードバックもらえるととても喜びます。


  1. ちなみにこのGIFで表示しているのは「薔薇水晶は極道の妻(おんな)になるようです」です。マジで面白いので読んだことなかったら読んでみてください。薔薇水晶は極道の妻(おんな)になるようです-記事一覧 | やる夫の縦読み

ブラウザで動くIME作った話

 

(1年もブログを更新してないなんて悪いやつだなぁ)

ブラウザ上で動作するIMEを作った。動作イメージは下のgifみたいな感じ。

f:id:ikazame:20200828210731g:plain

動作例


でもこいつは車輪の再発明。なんで車輪の再発明かというとajax IMEという素晴らしい先駆者がいるから
ajax IMEはもう15年ぐらい前のwebアプリ。本家はサーバが止まっていて、別の人が作ったigo-javascriptを用いた実装だけ公開されている。

http://shogo82148.github.io/IgoIME/

 

実装は、フロントエンドはReact製。バックエンドはMeCabで変換処理をしてる。
変換処理の部分は辞書のライセンスの関係で多分公開できないけど、気になる人はmecab-skkservあたりを見ればいいと思う。

 

ということで今日はフロントエンドのソースコードだけ公開しておく。
多分次の記事でこれ使った応用の話をするよ。

 

以下参考になった本。

 かな漢字変換だけじゃなく、固有表現抽出とかを研究でやる人にもおすすめの本。

(アフィIDはついてない。今の所)

 

AA・テキスト領域検出器公開

こんにちは,ikazameです.

この度AAデベロップメント界隈の重鎮 @scrpgil様 よりアスキーアート総合 Advent Calendar 2019 参加の打診をいただき,この記事を作成することとなりました. というわけでアスキーアート総合アドベントカレンダーの3日目の記事が始まります.

今回自分が語るネタはAA・テキスト領域検出器です.これは今年の5月に記事にしたやつで,やっとこさソースコード&デモを公開できる算段になりました.

AA・テキスト領域検出器

まずAA・テキスト領域検出器とは何なのかという話です.過去の記事をご覧いただければ同じことが書いてあるので軽く書きます.

AA・テキスト領域検出器はアスキーアートを含む(もしくは含まない)入力文書から,AAの領域,セリフの領域,レスヘッダの領域などを自動的に認識・抽出するツールです. 以下のようにアスキーアート自然言語のテキストが並列に扱われている文書から,AAの部分とテキストの部分を適切に分離し,AAスレのテキストのみを対象にした解析やAAスレの応用利用等を支援することができます.

デモサイト

上で説明したAA・テキスト領域検出器が実際に動いているデモを以下のURLで確認できます.

f:id:ikazame:20191202205250p:plain
AA・テキスト領域検出器

AA・テキスト領域検出器 - ikazame.dip.jp

上のテキストボックスに好きなAAを貼り付けて認識してみてください.なおデモサイトのAA表示にはaahub.org様のaahub fontsを利用させていただきました.

ソースコード

上のサイトで動いているデモと同じ機能を有した学習済みモデルと学習用スクリプトgithubで配布しています.学習データには「やる夫が銀行員になるようです」全8話のアノテーション済みデータを添付しています.ライセンスは何でもいいですが,使うときには一言うちのブログのURL入れといてもらえると嬉しいです.

aa_text_recognizer

使い方

README.mdに詳しく書いたので,そちらをご覧ください

AA・テキスト領域検出器の限界

AA・テキスト領域抽出器は機械学習を用いた識別モデルなので,不得手なデータに対してはおかしな出力をする可能性があります.例えば最近evianのTwitterアカウントがアスキーアートをつぶやいて話題になっていました.

このAAをAA・テキスト領域検出器をかけると以下のような出力がされます.

f:id:ikazame:20191202202309p:plain
evianのAAの認識結果

accountなんかはきちんと取れていますが,delete yourはちゃんと取れていません(でも人間が見ても"your"がAAの帽子に見えるような気もする). また,上記のデモサイトを試していただければ分かると思いますが,認識性能は案外低いです.自分もこのツールを使うときには,前処理として利用し必ず人間の目で確認して修正する作業を行います.

こういった状況は更に学習データを増やすことで解決する可能性がありますが,学習データを作るのは容易なことでは有りません,結構コスト(時間)がかかります. なので,AA・テキスト領域検出器に過度な期待はしないでくださいという,そういう話です.

結び

ソースコードを公開できる状態に持っていくのと,デモサイト作るのに心血を注ぎすぎて記事がめちゃくちゃ薄くなってしまいました.明日以降もAA界隈の猛者による超面白いアドベントカレンダーが続くと思うのでお楽しみに.

技術書典7に参加します(す05D)

皆様お久しぶりです,AAの記事を2個だけ書いてあと放っぽっていたikazameです.

来る2019/9/22(日)池袋で開催されます技術書展7で,私が記事を寄稿した本「465プロジェクト Vol.1」が頒布されることになりました.

今回私が寄稿した記事は「やる夫スレAAのMLTification」です.MLTificationはWikificationを参考にして考えたオリジナルの造語で,アスキーアートのいわゆるエンティティリンキングをルールベースで行うような内容になっています.最終的な目的は「"セリフからAAを自動的に予測する機構"のための教師データの作成」で,記事内ではMLTificationを用いた教師データの作成実験や評価等を行っています.

f:id:ikazame:20190915194219p:plain
図 1 MLTificationの動作イメージ(本文より)

「465プロジェクト Vol.1」内にはあと2記事別な人が書いた記事が乗っていて,内容はScalaの話とPython Botの話だそうです.3記事も載っていてお値段は500円となっております,お得ですね(印刷費の関係で自分は1円ももらえないっぽいですが,安さのためなら仕方ない)

今回の技術書展には,知り合いに誘われて参加することになったため文化等がよく理解できていないのですが,どうやらウチのサークル「465プロ」は参加の選考で落ちてしまったらしく,知り合いのサークルに委託本という形で参加するようです.それでも世間に自分の書いた記事を出せるというのは中々ない貴重な体験のため,今から当日を結構楽しみにしているikazameです.ご参加の際にはぜひ「す05D SoNeO:Automata (ソネオオートマタ)」にぜひお立ち寄りください.自分も当日見に行く予定なので,見つけたら話しかけてみてくださいね(?).終わり

techbookfest.org ※上のページからプレビューが見れますが,ほとんど書き換えたのでぜんぜん違うものになっています.

P.S. あとこれは技術書店に関係ありませんが,6月に記事で公開したやる夫スレのAAを認識する機械学習のモデル,もう温める意味がなくなったので9月中にこのブログで公開します.

10/01追記: 9月中に公開するという約束守れませんでした,もし待ってた人いたらごめんなさい. 可及的速やかに作業します.

機械学習を用いたAAとセリフの自動分割

はじめに

前回の記事 ではAAとセリフ等のテキストを分割することでスマートフォンでも閲覧するようにやる夫スレを再編集する方法について記述しました.しかし,AAとセリフを人手で分離しようとするとかなりの労力とコストが掛かってしまいます.
そこでこの記事では機械学習を用いて,特にやる夫スレをターゲットにしたAAとセリフの分割をおこないます.

抽出の方法

AAスレからセリフとAAを分離するなんと事がそんなに簡単にできるかというと意外に簡単にできてしまいます. 簡単のために以下のようなデータを考えます.

⊂二二二( ^ω^)二⊃  ブーン

こういったデータが入力された時,領域認識では考えたい領域にラベリングすることを考えます.以下のようなデータが出力されることを期待するわけです

入力:⊂二二二( ^ω^)二⊃  ブーン
出力:AAAA AAAAAAAAOOSSS

ここでAというラベルはAA(今回は顔文字ですが)を,Sはセリフを,Oは領域外(Outside)を表します. こうして入力に対して期待する出力は作ることができました.ではどうやってこういった出力を出す機械学習モデルを定義しましょうか? これもまたコロンブスの卵というか,考えた人は頭がいいなあと思うのですが,実はこの問題は分類モデルを逐次的に適用するだけで解けてしまう問題なのです. 例えば,ωがAなのか,Sなのか,Oなのかを考える時は,この文字と周囲4文字をあわせた窓幅5の文字を素性d={ , ^, ω, ^, )}とする分類問題を解きます.

y* = argmax_y Score(y|d)

ここでyはラベルです.よく見ると文書分類のモデルと何ら変わらない式がでてきました.このように問題を定式化できたのであとはSVMでもパーセプトロンでも対数線形モデルでも何でもいいので分類モデルで最初の文字から最後の文字まで解いていけばいいだけです.実際には上のようなBoWではなく文字の登場位置を考慮した素性テンプレートを作成し,形態素単位でラベリングされることも多いです.

しかし,このモデルにはまだ改善点があります.例えばωの2文字前は「 」(全角スペース)なわけですが,普通空白はAAの一部ではなくAAと台詞の間の空白な感じがするのでOとラベリングされてしまう可能性が高くなります.しかし,1つ前の文字も1つあとの文字もAAなのですから,この空白もAAなのですから,としてラベリングしてほしいと考えます.

そこで考慮するのが隣接コストです.直感的には,単にラベルだけを眺めた時AAの文字が連続することは往々にしてあることですが,AAとOが繰り返し登場するというのは考えにくいことです.ここからAAからAAからへの隣接コストは低いが,AAからOへの隣接コストは少し高めという設定をし,全体でコストが低くなるようなラベルシーケンスを出力することを目標にするわけです.隣接コストは何で書いてもいいのですが,普通は行列で表されます

A_{i,j}

ラベルiからjへの隣接コストはA_{i,j} と表現されます.ここではラベルが1つ前のラベルのみに依存する構造を仮定しましたが,これは2つ前のラベルでも構いません.しかし,2つ前のラベルにも依存させるようにすると計算量が爆発します(経験則です,計算量出したわけじゃないけど).

特に,対数線形モデルに隣接コストを取り入れて系列データに適用させたモデルを条件付き確率場(CRF)といいます

こういった形で入力シーケンスに対して,出力ラベルシーケンスを予測するようなモデルを考えることができました.今回はこのモデルを使ってAAとセリフの分割を予測します.

データセット

今回実験に利用したやる夫スレは以下のものです.

データはVIPやパー速等の過去ログ倉庫から引っ張ってきました.唯一,やる夫が銀行員になるようですの第3話だけはやる夫板で投下が行われたため,yyカキコの閉鎖に伴い過去ログを手に入れることができなかったので,まとめブログ様からデータをお借りしました.

これらのテキストから事前に人手でAAの領域とセリフなどのテキストの領域にアノテーションを行いました.アノテーション作業は最初はbratでやっていましたが,途中からAAが扱えないbratに嫌気が差したので自分でアノテーションツール作ってやりました.作成したアノテーションデータは以下のようになっています

AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, O, O, O, O, O, Serifu, Serifu, Serifu, Serifu, Serifu, Serifu, Serifu, Serifu, Serifu, Serifu, Serifu, AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, AA, O, O, O, Serifu, Serifu, Serifu, Serifu, Serifu, Serifu, Serifu, Serifu, Serifu, Serifu, Serifu, Serifu, Serifu, Serifu, Serifu, Serifu, Serifu

f:id:ikazame:20190531215739p:plain
図1. ラベルと対応するAA

このアノテーションデータは図1の3,4行目に対応しています.やる夫の顔の部分はAAとしてラベリングし,セリフの部分にはSerifuとラベリングしています.また,AAと台詞の間の空白はO(Outside)としました.

ラベルの種類

抽出対象のラベルは前回の記事での分析をもとに以下の7種類を定義しました.

表1. ラベルの定義

ラベル名 意味
O ラベリング対象でない文字
AA アスキーアート
Gion ドンッ!キリッ!などの擬音
Jinobun キャラクタのセリフでない地の文
Res_Header 名前欄などのレスヘッダ
Serifu キャラクタのセリフ
Text_in_AA AA内に含まれるテキスト(看板,吹き出しなど)

評価実験

実験の設定

まずデータセットの19の文書の内,2割を開発セットとして分離します.採用したスレの種類と数がちょうどよかったので,各スレの第1話を開発セットとしました.開発セットはパラメータチューニングに利用します.残りの文書を用いて交差検定を行い,モデルの性能を確認します.

実験スクリプトpythonを用いて作成し,CRFモデルはpycrfsuiteを利用しました. 考慮する素性は,表層系と文字種であり,窓幅は5としました.

本実験は15の文書を1個抜き検定して評価しました(15-Fold交差検定とも言える).

パラメータチューニング

開発セットのデータを使ってパラメータチューニングを行います.チューニング対象はCRFの(対数線形モデルの)L1正則化項の係数c1とL2正則化項の係数c2です.この辺の話はCRFSuiteのHPに乗っています.パラメータチューニングはGrid Searchで行い,sklearn.model_selectionのGridSearchCVを利用しました.

ちなみに余談ですが,対数線形モデルは正則化項がないと学習できません.正則化項がないとあるラベルのみに出現する素性への重みが無限になってしまうからです.詳しくは髙村本読んで下さい.

c1={0.01, 0.1, 0, 1, 10}, c2={0.1, 0, 1, 10, 100}の直積をGrid Searchして最適なパラメータを探しました.結果は図2のようになりました.

f:id:ikazame:20190531221048p:plain
図2. グリッドサーチの結果

0の位置がおかしいせいで数値がちゃんと並んでませんがこれは私がアフォだったからです.みなさんはこんなことしないようにしましょう.

しかし,髙村本に書いてあった通り正則化項の係数が0だった時に学習性能が大きく落ちることを確認できたのは意義深い発見でした.

とにかく{'c1': 10, 'c2': 0.1}が最適なパラメータだとわかったので,実験にはこの値を用います.

(これは後で気づいたんですが,グリッドサーチの結果がこれだけはしっこだったのなら,c1=10, c2=0.1を中心としてもう一回グリッドサーチするべきでした.もう後の祭りなのでこの経験は次回に活かします)

評価指標

実験の評価指標には適合率(Precision),再現率(Recall),F1値を用いました.定義は以下のとおりです

 Precision = \frac{抽出した正解ラベル数}{抽出したラベル数}

 Recall = \frac{抽出した正解ラベル数}{正解ラベル数}

 F1 = \frac{2 \times Precision \times Recall}{Precision +  Recall}

また,実験結果の評価は文字単位での性能とチャンク単位での性能の2種類で行いました.これはAAとセリフの分割において,AAは端っこの1文字ぐらいの抽出に失敗しても大域的な影響は小さいため,AAは文字単位での抽出精度を上げることが目的になるからです.対してセリフは端っこの1文字を取り逃してしまうとそのせいで話の辻褄が合わなくなるなど大きな影響が出る可能性があります.そのため,セリフはチャンク単位での抽出性能に重きをおいて確認します.

実験結果の評価にはconllevalを用いました.

結果

実験結果は以下のようになりました.

表2. 抽出結果(文字単位)

ラベル名 precision recall FB1 Support
AA 98.79 99.15 98.97 850898
Gion 58.32 47.59 52.41 811
Jinobun 82.23 68.54 74.76 23639
Res_Header 99.56 99.85 99.70 202281
Serifu 92.04 96.11 94.03 115857
Text_in_AA 20.36 6.13 9.43 393
All 97.88 98.11 97.99 1191090

表3. 抽出結果(チャンク単位)

ラベル名 precision recall FB1 Support
AA 66.82 60.33 63.41 7870
Gion 62.50 38.92 47.97 104
Jinobun 18.35 9.70 12.69 436
Res_Header 89.62 91.19 90.40 3247
Serifu 90.61 93.02 91.80 6868
Text_in_AA 23.53 4.65 7.77 34
All 78.37 73.60 75.9 19762

まず,表1に文字単位での抽出性能を示します.文字単位で抽出はCRFでも大変良い結果が出ることが分かりました.特に,学習データも十分な量が準備できたAA, Res_Header, Serifuの3ラベルについての性能がかなり高い事がわかります.対して,そもそも抽出が難しいと考えられるGion, Text_in_AAについては結果は振るわないものとないっています.また,Serifu同様学習データが十分に確保できていると考えられるJinobunのRecallが少々低いことが気になります.これは,JinobunとSerifuの区別が注目トークンの周辺文脈だけでは曖昧なため,JinobunとラベリングするべきところをSerifuとラベリングしてしまう事が多かったためと考えられます.SerifuのPrecisionが下がっている原因同様です.

続いて,チャンク単位での抽出結果を表2に示します.こちらは文字単位での抽出結果よりいからか性能が低くなる結果になりました.学習したモデルの予測は,文字ごとに捉えると正しいラベルがついているものが多いが,一連のセリフやAA全体で正しいラベルを付ける能力があるかというとそうではないということが分かります.しかし,それでもSerifuの性能は文字単位のときと変化が少ないため,一度認識できたセリフはその1連の塊で間違えることがないということが分かります.

また,チャンク単位での誤りは人間が後処理で正しいラベルをつけ直さなければならない数を示します.人間がいかにらくできるかという指標がチャンク単位の結果なので,もう少し底上げの必要があるでしょう.

結果のビジュアライズ

ここまでの話はきっとピンとこない人が多いと思うので,実験結果をビジュアライズしたものを以下に示します.

まずうまく行った例から,図3はやる夫が銀行員になるようです 第2話の冒頭のレスです.図4は今回作ったモデルに図3のレスを入力し,得られた出力ラベルシーケンスをもとにAAの文字に色を付けた状態を表に示します.このように,AAスレの一部を入力することで,その文字列に含まれるAAとセリフと地の文とレスヘッダを自動的に抽出できるようになりました.

f:id:ikazame:20190531220213p:plain
図3. やる夫が銀行員になるようです第2話の冒頭レス
f:id:ikazame:20190531220219p:plain
図4. 図3のラベリング結果

今度はうまく抽出できなかった例を示します.図5は同様に銀行員スレからお借りしたレスです.ここでは文字列「チョリース」はSerifuとして,その直前の空白列はO(Outside)として認識して欲しいデータですが,ここでは両者ともをAAとして認識していまいました.これはカタカナの連続はAAになることが多いために起こった誤りだろうと考えられます.確かに薄目で見ればチョリースがAAに見えるかも……?

f:id:ikazame:20190531220337p:plain
図5. チョリース

また図6について,ここでは吹き出しの中の文字列「いらっしゃいませ!」「ありがとうございました!」などはすべてText_in_AAとして認識してほしいのですが,ここでは一部をSerifuとして誤認識しています.Serifu扱いしてこれらの文字列をAAから抜き出してしまうとAAが崩れてしまう原因になります.

f:id:ikazame:20190531220358p:plain
図6. 吹き出しのAA

まとめと今後

本記事ではAAスレからAAやセリフ,地の文などを自動的に認識し,ラベリングする実験を行い,その実験方法と結果の報告を行いました.結果はそこそこ使い物になりそうなモデルが完成しました. また,このモデルを使うことで前回の記事で示した,「AAと文章を分離させる」ことを自動的に達成できるようになりました(他にもいくつか問題点は残っていますが,そのうちご紹介します)

あと,今後というかすでにやったことが1つ.本記事の機械学習モデルを利用して,AAとセリフなどの自動認識を行って両者を分離することでやる夫スレをスマホで読みやすい形式に変換するツールを作成し,それを用いたやる夫スレのまとめサイトを作りました. 以下のサイトです.

やる夫空間

今の所,今回学習データに使用したスレとほか少ししかスレをまとめることができていません.というか見て分かる通りガッツリ開発中のサイトなので,この先どんな追加・更新していくかは不明です.まとめてほしいスレがあったらここに書いてもらえれば追加するかも知れせん(まだ本腰入れて作るかどうか決めてないので,追加しなかったらすいません).

また,今回作成したモデルは近いうちにどこかで公開したいと思います. それでは.

やる夫スレをスマホで読みやすくする方法を考えた

やる夫スレがスマホからも見やすければいいのに,と常々そう思っていました.自分はやる夫スレがかなり好きで,数年前にはPCで過去の名作を大量に読み漁っていました.もともと個性もキャラクターも設定されていなかったはずの白饅頭やる夫が数々の無名作者の手によってここまでのコンテンツに育てられたというのはネットの歴史の中でも他に例を見ない,特異なものだと思います.またそんなやる夫スレの歴史の中ではたくさんの大変面白い物語が存在しています. しかし,残念なことに現状やる夫スレまとめサイトスマホから快適に見る方法は存在しません(恐らく).そもそも横長のPCで閲覧することを前提として作られたやる夫スレは,画面が横に短いスマートフォンで閲覧するには不向きなコンテンツです.画面サイズがかなり制限されるスマホで快適に閲覧したというのがそもそも無理な要求ですが,それでもこんなにたくさんあるやる夫スレの名作がPCを持っていないと見られないという状況はやる夫スレにとっても読者にとってももったいないことだと感じます. そこで今回,やる夫スレをスマホで見る時の見づらさの原因と,その解決策について色々思案してみたので,その記録をここに書き残します

スマホで見づらいやる夫スレ

そもそもMS P ゴシック互換フォントを当ててくれているかどうかから怪しいし.仮にフォントがAA表示に対応してものであっても,画面が横に短いスマホではたいていAAが見切れてしまいます.

下の図はiPhone Xの画面サイズをPC版のGoogle Chormeで仮想的に再現したビューにAAをはめ込んだものです.図1のように小型のやる夫のAAですら台詞が入ると変なところに改行が挟まってしまい表示が崩れます.図2は翠星石のAAを表示しているものですが,これだけ大型のAAをだともう元のキャラクターが誰だったのかもわからないような状況です.

f:id:ikazame:20190428180951p:plain:w300
図1. やる夫の画像
f:id:ikazame:20190428180956p:plain:w300
図2. 翠星石の画像

上の例はあくまでひどく見づらいときの例です.大抵のまとめサイトの場合,大型AAは画面外にはみ出してそれをスクロールで見るような環境を提供してくれます.しかし,スマートフォンで読む電子書籍やWebサイトなどは縦にスクロールで流すアクションのみで快適に読めるものが多く,いちいち縦や横やと指を動かさなければいけないようなまとめサイトは快適であるとは言い難いものです. その他にやる夫スレをスマホで見やすく閲覧するための工夫の1つとして,2chmateやAAHubなどが採用しているAAの拡大縮小があります.図3,図4は手元でAAの縮小を実験してみた例です.大型AAが画面に収まらないなら小さく表示すればいいというのは当然の発想ではありますが,図4のようにセリフの文字まで一緒に縮小されてしまい,文字が読みづらくなってしまうという弱点が存在します.

f:id:ikazame:20190428182416p:plain:w300
図3. 大型AA(等倍)
f:id:ikazame:20190428182453p:plain:w300
図4. 大型AA(縮小)

色々と例を上げて考えてみましたが,やる夫スレがスマホで見づらいというのは,結局以下の問題点に帰着しそうです.

  • 一つのコマ単位(AA+セリフ)が横に長く,自動改行が挟まってしまい表示が崩れる
  • きれいに表示することに拘ると,ピンチインや横向きのスクロールが不可欠になり,快適な読書の妨げになる
  • 縮小の工夫は有用だが,絵であるAAと,文章であるセリフを同じフォントサイズで表示しているため,文字が潰れる問題が生じる

やはり横に長く画面が大きいPC用に制作されたやる夫スレを縦長の狭いスマホ画面で読みやすく表示するというのは一筋縄ではいかない問題のようです. そこで今回は2つの問題点を解決する方法として「AAとセリフを分割してやる夫スレを再編集してしまう」ことを提案します.

やる夫スレの再編集

この記事で提案する手法の一番の要は「AAと文章を分離させてしまう」ことです.AAをスマホの画面内に収める縮小の工夫の利点を活かしつつ,文字が潰れて読めないような状況を防ぎたいという目的からこの発想にいきつきました.いくつか例を交えて説明します.

AAとセリフの分割

f:id:ikazame:20190428212659p:plain:w300
図5. 銀行員のやる夫
図5はスマホでやる夫スレを表示したときのイメージです.問題点1で述べたように,横に長いセリフが自動改行で強制的に区切られてしまいAAの表示が崩れてしまいます.図5のコマからAAとセリフを分割して,セリフをAAの下部に表示するようにすると,図6のような表示形式に変形することができます.図6の表示形式では長いセリフも画面外にはみ出してしまう心配がありません(AAは折り返すことができないが,文章は書籍や新聞のように途中で折り返すことができる) .
f:id:ikazame:20190428212702p:plain:w300
図6. 銀行員のやる夫 (ルール適用後)
通常の顔のすぐ横に台詞があるやる夫スレを見慣れていると,セリフがAAの下に来るのはなんだか違和感があるような気もしますが,一応AAとセリフの崩れなくコマを表示することができました.

AAが大きい場合 (翠星石とか)

続いて図7のAAの場合,こちらはセリフの長さなど関係なく,AAが元から大型であるため,AAの途中での改行が大量に発生してしまい元の形を認識する事もすら難しいものです.このケースではAAとセリフを分割してセリフを下に追いやるだけでは問題を解決できないため,もう1つの工夫としてAAの縮小を行います.具合的にはAAのフォントサイズとセリフのフォントサイズを別々のものにし,AAを画面内に収まるサイズに調整してセリフは読みやすい元のサイズを維持する.この処理を施した結果図8のようなコマが出来上がるわけです. この例ではAAとセリフを分解したことで,読みやすい文字のサイズを維持しつつAAに縮小処理を行って全体像をスマホの画面に収められるようになりました.

地の文がある時

ここまではやる夫スレのコマを再編集して表示を見やすく変形することを考えていましたが,逆にコマを再編集したせいで見づらくなってしまう例も出てきます.図9はやる夫が選挙に出馬するようです からの1コマで,ここには「AA」と「セリフ」と「地の文」が共存しています.このコマにこれまでと同様セリフを認識してAAの下側に移動させる処理を施すと図10のようになります.

f:id:ikazame:20190428212645p:plain:w300
図9. やらない夫
f:id:ikazame:20190428212649p:plain:w300
図10. やらない夫 (ルール適用後)

AA+セリフの強制改行がなくなり見やすくなったように見えますが,実は,セリフと地の文が1つの塊の文書になってしまい,どこまでがやらない夫の発言なのかひと目では分からなくなってしまっています.ストーリー系のやる夫スレ(≒地の文がほとんどないやる夫スレ)であればこのような問題は起こりづらいいのでいいのですが,地の文を多用する学ぶ系作品ではこの再編集でまともに読めないようになってしまいます.

そこで今度はコマの分解にルールを1つ追加します.これまではコマ=AA+セリフに分解していたものを,コマ=AA+セリフ+地の文として考え(+じゃなくて∪かも?),同じ文書でもセリフと地の文の区別をつけるようにします.そしてコマの再編集の際,地の文はフォントの色やフォントの種類,囲いなどをつかってセリフと別物であることを表現します.このルールを適用して図5のやらない夫のAAを再編集すると図11のようになりました.

f:id:ikazame:20190428212653p:plain:w300
図11. やらない夫 (地の文ルール適用後)

これでセリフと地の文をひと目で区別できるようになり,作品を読んでいる時もスムーズに文章を読めるようになるんじゃないかと思います.

AA内テキストと擬音

あとはちょっとした細かいことですが,さらに2つ小さな工夫を追加します.

f:id:ikazame:20190428213804p:plain:w300
図12. VIP銀行
図12はVIP銀行を表現した大型AAで,セリフ等はありません.しかし,AA内では一部「VIP BANK」のような文字列が使われており,スマホ画面に収まるようAAを縮小するとこれらの文字が潰れて読めなくなる可能性があります.かといって,これらの文字列をセリフのようにAAから抜き取ってしまうと,AA全体の表示が崩れてしまいます(これらの文字はAAの一部だから). そこで,こういったAA内部に埋め込まれているような文字列はセリフともAAとも違う新しいグループ,AA内テキストとして捉えることにします.そしてAA下部に注釈のようにこれを配置し,AAの縮小により文字列が読めなくなっても何が書いてあるのか分かるようにする工夫を行います.コレに関しての例は省略しますが.これでAA内テキストの文字が潰れる心配もなくなりました.

f:id:ikazame:20190428214052p:plain:w300
図13. ドンッ
テキストとして捉えられるAAの一部について考えたので,今度はAAとして捉えられるテキストの一部を考えます.図10は「」の1コマ.やる夫が〇〇した擬音「ドンッ」がコマ内に存在します.「ドンッ」は文字列なのでセリフの一部と捉えられるかもしれません.しかし,この場合の「ドンッ」はやる夫が拳を机に叩きつけたときの音なので,AAのすぐ近くに表示したほうが臨場感が出て良さそうです.また,「ドンッ」自体は横に長い文字列でないため,セリフと違って強制改行や画面に収まらないなどの心配もありません.そこで,「ドンッ」や「キリッ」のような擬音はテキストであってもAAの一部として考え,セリフの分解処理にはかけないようにします.こちらも例は省略します.

まとめと次回

ここまで5つのコマを例に出し,スマホ画面に収まるように表示させるべくコマの再編集方法とコマの構成要素をAA,セリフ,地の文,AA内テキスト,擬音の5つにグループ化することを提案しました.ここまでの規則を既存のやる夫スレに手を動かして適用していけば,スマホでも見やすいような形式に変換することが可能になると思います.しかし1スレ1スレ手で編集を続けていったのではこの膨大な作業がいつになったら終わるのやらわかったものではありません. そして恐らくこの記事の内容ぐらいのものなら過去思いついた人が他にもいる気がします.それでもやっぱりこの手の話が今まで表に出てこなかったのは手動でAAとテキストを分離するコストの高さがネックになっていたためでないかと思います. 次回は機械学習の手法を用いてコンピュータに自動でAAを認識させ,AAとセリフの分割を全自動で行わせます.また,この記事で提案した編集ルールもコンピュータに覚えさせ,自動的にやる夫スレの変換を行うようなことをしようと思います.