Slide 1

Slide 1 text

小田原で みんなで一句 詠みたいな PHP カンファレンス小田原2025 すてにゃん @stefafafan 1

Slide 2

Slide 2 text

早速ですが 2

Slide 3

Slide 3 text

俳句の判定したくありませんか? 3

Slide 4

Slide 4 text

どうすればいい?? 4

Slide 5

Slide 5 text

俳句かどうか判断する軸 何を俳句の特徴とするかは人によって様々 5-7-5 の17 音で構成される? 自由律も存在しますね 季語を含むべき? ( 有季派) 複数の季語を含むことは好まれない( 季重り) 切れ字の活用 「かな」 「や」 「けり」などの助詞 5

Slide 6

Slide 6 text

今回は5-7-5 を判定する事にのみ焦点を 当てることにします 6

Slide 7

Slide 7 text

今日のコードは実際に公開しています あとでみてください! https://github.com/stefafafan/phpcon-odawara-2025-talk 7

Slide 8

Slide 8 text

目次 PHP での文字数カウント PHP での形態素解析 番外編: AI に判定を任せられないか? まとめ 8

Slide 9

Slide 9 text

PHP での文字数カウント 日本語は便利で、おおよそ1 文字≒1 音と言えそう! 日本語の文字数を数えるにはどうすればいいのか strlen() : バイト数を返すのでちょっと違いそう mb_strlen() : マルチバイト文字の文字数を数えてくれるのでこれ が使えそう! grapheme_strlen() : 絵文字なども含む場合はこっちのほうがいい かも。今回は不要かな〜 9

Slide 10

Slide 10 text

check-haiku-v1.php 5-7-5 かどうかは気にせず、全体で17 文字あればOK としてみる! function isHaiku(string $input): bool { return mb_strlen($input) === 17; } 10

Slide 11

Slide 11 text

check-haiku-v1.php mb_substr() を使えば最初の5 文字などは抽出できそう! function describeHaiku(string $input): string { $first = mb_substr($input, 0, 5); $second = mb_substr($input, 5, 7); $last = mb_substr($input, 12); // ... } 11

Slide 12

Slide 12 text

check-haiku-v1.php の結果 小田原でみんなで一句詠みたいな 小田原でみ (5 音) んなで一句詠み (7 音) たいな (3 音) 合計: 15 音 俳句判定失敗!! 12

Slide 13

Slide 13 text

わかったこと 日本語は難しくて、ひらがなやカタカナ以外に漢字もある 単純な 文字数だけじゃ 成し遂げず(俳句) 13

Slide 14

Slide 14 text

PHP での形態素解析 14

Slide 15

Slide 15 text

形態素解析とは 文章を解析して、 「形態素」という単位に分割して判別していく作業 例えば「小田原でみんなで一句詠みたいな」という文章 「小田原」 「で」 「みんな」 「で」 「一句」 「詠みたい」 「な」のよう に分割することができる 15

Slide 16

Slide 16 text

形態素解析できると何が嬉しい 文章の区切り目がわかる ついでに読み仮名もわかる 漢字が入っていても大丈夫そう! 16

Slide 17

Slide 17 text

PHP での形態素解析 ライブラリを使う php-mecab igo-php 今回はこれを使います! 外部API を使う Yahoo! 日本語形態素解析API RakutenMA API Google Cloud Natural Language API 17

Slide 18

Slide 18 text

igo-php を使っての俳句判定 $igo->parse すると形態素ごとの配列が取得できる $result[i]->feature[8] には形態素の発音が含まれている $igo = new Igo\Tagger(); $result = $igo->parse($input); // 「小田原」の場合は「オダワラ」と出力される echo $result[0]->feature[8]; 18

Slide 19

Slide 19 text

check-haiku-v2.php 形態素解析ライブラリと mb_strlen() の合わせ技で判定 // 形態素に分割 $result = $igo->parse($input); // 形態素ごとにループし、読み仮名を mb_strlen で数えていく while ($count < $limit) { $count += mb_strlen($result[$i]->feature[8]); // ... } 19

Slide 20

Slide 20 text

check-haiku-v2.php の結果 小田原でみんなで一句詠みたいな 小田原で (5 音) みんなで一句 (7 音) 詠みたいな (5 音) 合計: 17 音 俳句判定成功 20

Slide 21

Slide 21 text

細かい改良も必要だった 集中 という単語は「しゅうちゅう」なので6 文字だけど、読む時は 4 音 小文字の ャュョ を含む場合は音数カウントからその分差し引く 伸ばし棒や小文字の ッ はそのまま1 音としてカウントしています PHP の読み方を把握していないのでハードコードしてあげたり $count -= preg_match_all('/[ャュョ]/u', $str); 21

Slide 22

Slide 22 text

番外編: AI に判定を任せられないか? 22

Slide 23

Slide 23 text

まずはChatGPT 4o で実験 次の文章の文字数を教えてください「小田原でみんなで一句詠みた いな」 ChatGPT: 「ご指定の文章は16 文字です」 ??? 漢字のままで15 文字、ひらがなに直したら17 文字のはずだが? 23

Slide 24

Slide 24 text

AI は文字数を数えるのが不得意 文字数を数えることは苦手 でもプロンプトを工夫すればどうにかできないか 24

Slide 25

Slide 25 text

AI 向けのプロンプトの工夫 プロセスを段階的に伝える まず文章を形態素ごとに分割してください 形態素ごとに音の数を数えてください 「ャ」 「ュ」 「ョ」のケースを考慮してください ... 絶対にJSON として返してくださいと伝える API レスポンスを json_decode して利用しやすい 25

Slide 26

Slide 26 text

check-haiku-v3.php openai-php/client というOpenAI 向けAPI クライアントで叩きます プロンプトはコード中に直接書く! $client = OpenAI::client($apiKey); $instructions = <<

Slide 27

Slide 27 text

check-haiku-v3.php の結果 場合によっては上手くいく 入力が「指示」っぽいと勘違いされることもある 申し訳ありませんが、そのリクエストにはお応えできません。俳句かどうかを判定するための文章を提供してください。 27

Slide 28

Slide 28 text

まとめ 28

Slide 29

Slide 29 text

ロジックで 割り切れぬもの 俳句かな 5-7-5 の判定はできても、 「俳句の美しさ」は奥が深い 29