BETA

GCPの無料枠を使って青空文庫を類似検索できるサービスをSPAで作ってみた

投稿日:2020-07-28
最終更新:2020-07-31

青空文庫を類似検索できるサービスを作ってみました
https://aozora-search.ruroufumi.com/

はじめに

以前,知らない人と手紙でやりとりするサービスを作りました.
https://qrunch.net/@serenard/entries/5MkSyrJ4Vi9eZNvB?ref=qrunch
1年半ほど経ちましたが,少ないながらもずっと利用してくれている人がおり,また,自分自身もそこから新しい趣味を開拓したり,衝撃的な体験をできたりと,やってよかったなと思います.(機能的なアップデートをほとんどかけられていないのは本当に申し訳がないです...)

近頃大きな改修をかけようとしていて,それに追随して,もう少しSEOを強くしたいな〜とか,広告も試したいな〜など考えていたのですが,プライベートで会話を行うというサービスの性質的に,パブリックにコンテンツが出ないめ,どうしようかと悩んでいました.

最終的に,サービスに登録していない人でも使えるツールをサービス内に作ることにしました.
内容は,サービスを使ってくれている人も,書いたり届いたりした長い文章を使ってプラスで少し楽しめるように,入力した文章に近い青空文庫の小説を探してくれるというものにしました.

以下,その過程などを書いていこうと思います.

過程

青空文庫のデータセット作成

以下をもとに行いました

https://serenard.hatenablog.com/entry/2019/04/07/164337

類似検索モデルの作成

モデルとしては,今回は突っ込めばとりあえずそれっぽい結果が出そうなdoc2vec(in gensim)を使うことにしました.
色々手法を試すべきだとは思ったのですが,モデル自体は後でいくらでも変更可能なので,一番簡単そうなものを採用しました.
また,精度評価についても,厳密なものでなく,以下のような感覚的基準で行いました

  1. 実際の青空文庫の作品の文章を入れると,それが上位の結果として帰ってくる(作品の類似検索にも使えるようにするため.また,最低限の信憑性を持たせるため)
  2. 入力に対する結果の小説の文章がが,全く反対のものになっていない(現代的な文章を入れたら現代的な文章が,カタカナ語がたくさん入ると洋書作品が返ってくるなど)

精度を厳密に定義するのは難しそうなので,不信感を抱かせない最低限の結果を返すという点に注力しました.

サービスの実装

バックエンドはflask,フロントエンドはreact-hooksを使って実装しました.
元のサービスはdjangoにて実装し,さくらVPSにてホストしていたのですが,以下の理由で別サービスとして切り出しました

  • djangoのコードを肥大化させていくモチベがない
  • 単一ページで何回も入力を行うような機能なのでSPAで作りたい
  • (ないとは思うが)この機能による負荷で,貧弱かつスケールしづらい本サービスの環境に影響を与えたくない

デプロイ

apiサーバーのデプロイにはCloud Runを,クライアントのデプロイにはApp Engineを用いました(無料枠のためにregionはusにしました).
どちらも無料枠が結構大きい?,かつyaml1枚でデプロイができ,オートスケールもあるので,とりあえずデプロイしたいという場合にはすごく楽です.
特にcloud runはローカルで使っている開発用コンテナを以下のようなyamlだけで何も考えず直でdeployできるのが体験として最高でした.

apiVersion: serving.knative.dev/v1  
kind: Service  
metadata:  
  name: aozora-search  
spec:  
  template:  
    spec:  
      containers:  
      - image: us.gcr.io/gcp_project_id/aozora-search-image:latest  
        env:  
        - name: CLIENT_HOST  
          value: https://aozora-search.ruroufumi.com  
        resources:  
          limits:  
            memory: "2Gi"  

ドメインについては,元サービスのものからサブドメインを切ってapp engineに設定しました.
通常のドメインの設定は簡単なのですが,サブドメインを与える場合は特殊なようで,以下の記事がとても参考になりました(DNS周りについても少しだけ理解が深まりました).

https://blog.kakakikikeke.com/2019/02/how-to-set-custom-domain-on-gae.html

最後に

雑ではありますが,青空文庫の類似検索サービスを作成した過程について書いてみました.
実装期間はモデルの学習を含めておおよそ6日程度でした(青空文庫がgithubで管理されているのでデータセットの作成がすごく楽でした.とてもありがたいです).
既存の技術を組み合わせただけで特別なノウハウは何もないのですが,SPAアプリを楽に無料でデプロイするケースとして参考になりましたら幸いです.

現状,副題だけ違う同一作品が結果に大量に含まれてしまうなど色々問題もあるので,様子を見て少しずつ修正をしていく予定です.

手紙をやりとりするサービスも合わせて,よかったら触っていただけると嬉しいです
https://ruroufumi.com
https://aozora-search.ruroufumi.com/

目的の一つだった広告については,今はコロナの影響でGoogle adsenseの審査が止まっているようでした...
青空文庫の一部にも著作権が残っているものがあるようなので,その部分の考慮も抜けていました

技術ブログをはじめよう Qrunch(クランチ)は、プログラマの技術アプトプットに特化したブログサービスです
駆け出しエンジニアからエキスパートまで全ての方々のアウトプットを歓迎しております!
or 外部アカウントで 登録 / ログイン する
クランチについてもっと詳しく

この記事が掲載されているブログ

@serenardの技術ブログ

よく一緒に読まれる記事

0件のコメント

ブログ開設 or ログイン してコメントを送ってみよう