ひとはいつ未体験に挑戦するのか?〜Monoxerの学習データから探る〜

こんにちは、データエンジニアの田中です。
最近ミカンの皮をむくのが得意になりました。
最初に思い切りを持って二つに割くとやりやすくなります。

ということで、本記事はモノグサAdvent calender2025の23日目の記事です。

 

今年のテーマは「未体験への挑戦」です。

本記事ではMonoxerのデータを使って「ひとはいつ未体験に挑戦するのか」について書いてみようと思います。

新たな一歩を踏み出すきっかけって実は些細なことなのでは?、意外な違いで継続できるかどうかが変わってくるかも?など、未体験への挑戦についてデータから描けるものがないかみていきます。

Monoxerにおける「未体験」とは

Monoxerは解いて憶える記憶アプリです。

ビジネスとしては未就学児から社会人まで幅広いユーザーを対象にしていますが、現在メインのユーザーは中高生で、学校や塾に契約いただき、生徒がMonoxerで学習する形が多いです。その場合、学校や塾で学んだことを記憶するニーズがメインですので、「未体験」とはやや言い難い気がします(もちろん挑戦ではあり、非常に意義があることです!)。

今回のテーマに沿うような行動がアプリ上にないでしょうか?実はあります。

Monoxerでは、アプリをダウンロードして皆がすぐに学習を体験できるように、「初期搭載無料Book」というコンテンツが用意されています。例えば、かな点字や百人一首、ウクライナ語などのコンテンツは(おそらく学校や塾で学習を指導されるケースは多くはないため)、ユーザーが自主的に見つけて学習してみるケースが多いでしょう。

今回の記事ではこれらの初期搭載コンテンツ(以下、「該当コンテンツ」と呼びます)の学習を題材に、「未体験への挑戦」についてデータから探っていきたいと思います。

ひとはいつ未体験に挑戦するか

まずは、該当コンテンツを初めて学習する瞬間にフォーカスをあてて、「いつ未体験に挑戦するのか」を見ていきます。

最初はベーシックなところで、時間帯(朝・日中・午後)で分けて見てみましょう。

新しいことを始めるというと朝のイメージがありますが、今回の結果では、該当コンテンツを初めて学習する時間帯は、普段の学習よりも朝に行う割合が若干少ないという結果になりました。
(以下、具体的な定義や数字はマスクしています)

また、平日か土日かで分けてみると、普段よりも、該当コンテンツの初回学習をしやすいのは土日のほうだと分かります。

学校や塾では、授業のなかで明示的にMonoxerの学習を促すケースもあり、そこで該当コンテンツの初回学習をする可能性は低いため、いつもと違うタイミング(土日)でアプリを開いたケースが多いのではないかと推察されます。

では次に、「その時のアプリ利用のなかで該当コンテンツを初回学習するタイミング」を見ていきます。

アプリを開いたものの、なんとなくやる気が起きなくて該当コンテンツを開いてみるようなケースが多いのか、それとも普段学習しているものをある程度まとまった時間解いたあとに、気分転換としてアプリ内のほかのコンテンツとして該当コンテンツにたどり着いたケースが多いのでしょうか。

これに関しては、該当コンテンツを初めて学習した日、その前に別のコンテンツを何回学習していたかを見てみます。

その日の最初の学習として該当コンテンツを解いているケースもあれば(0回)、別のコンテンツを学習した後に該当コンテンツを解くケースもありそうです(1回以上)。

個人的にはアプリを開いたもののやる気が起きない際に他の場所を漁ることが多いので、6回以上別のコンテンツを解いたあとに該当コンテンツに挑戦する層がこれだけいるのは少し意外な結果でした。

未体験への挑戦は継続されたか

ここまではいつ該当コンテンツの学習に着手するのか、という観点で見てきました。

記憶として定着させるためには、単に一回だけ学習するのではなく、それを継続することが重要なのは言うまでもありません。

そこで、該当コンテンツの初回学習を終えたあと、そのコンテンツの学習が継続されたかどうかという切り口でも見ていきたいと思います。

上記と同じように時間帯や曜日で見てもあまり面白みはなかったので省略しますが、「いつもと同じ時間帯に初回学習を行ったかどうか」で比較すると、いつも勉強している時間帯とは別の時間帯に初回学習を始めたユーザーのほうが、やや継続的に該当コンテンツを解いていただけるようでした。

ちなみに一番継続していたケースに多かったのが「普段は夜の時間帯に最も学習しているユーザーが、朝の時間帯に該当コンテンツの初回学習を始めた」ケースだったので、新しいことを始めるのに適しているタイミングは朝、というのは一理あるのかもしれません。


続いて、先ほど円グラフで示した「該当コンテンツの初回学習前に、別のコンテンツを何回学習したかの人数比」について深掘り、その後学習が継続されたかを比較してみます。全体的には、アプリを開いて最初に該当コンテンツを解いたケースよりも、他の学習を何度かした後に該当コンテンツを解いたケースのほうが継続日数が多くなっています。

また、少し不思議なことに、1〜5回と6〜15回では前者のほうが継続的に学習いただいているという結果になっていました。
今回の簡単な集計だけでは多くのことは分かりませんが、もしかすると初回学習したときの疲れ具合や集中力によって、その後の継続率に違いがでている、といった傾向があるのかもしれません。

終わりに

ということで、今回はMonoxerの学習データから「未体験への挑戦」について見てきました。

実は私はモノグサに数か月前に転職してきたのですが、全人類がいきいきと人生を送れる社会となるように貢献していきたいという思いが転職のきっかけでした。

当社の行動指針の1つである「未体験への挑戦」は、自分たちがそれを体現するだけではなく、それを後押しするという意味でもすごく素敵だなと思っています。

今回分析の対象としたコンテンツを解いてもらうことがサービスの目的ではないですが、このような示唆をよりよい学習体験の設計のために生かしていければと思います。

実は今回紹介したコンテンツはアプリをダウンロードすれば誰でも無料で学習できます。

ぜひ解いてみてください!

 

また、モノグサ株式会社では一緒に働く仲間を募集しています。少しでも興味を持ってくださった方は、ぜひお話しましょう!

qiita.com

careers.monoxer.com

 

QL(Quality Lead)を導入しました

 

この記事は モノグサ Advent Calendar2025 2日目の記事です。

こんにちは!やまもと@テスト番長です。
日差しがすっかり冬らしくなり、朝は布団から出られなくなった今日この頃、皆様いかがお過ごしでしょうか?
今年のモノグサアドカレのテーマは「未体験への挑戦」ということで、モノグサQAチームでのトライについて少しお話ししたいと思います。

今年、私たちQAチームは様々な新しい試みに踏み出しました!
その中の一つが「QL(Quality Lead)」というロールの運用です。

エンジニアリングの世界では「Tech Lead(TL)」という役割が一般的ですが、QAでは一般的ではありません。TLがチームの技術面をリードするのと同じように、“品質のリード役”が居たら良いのではないか──そんな問題意識から始まりました。

QLとは

QLは簡単に言えば「QA版のTech Lead」です。
QLはプロダクトの『品質・コスト・納期(QCD)』を軸にチームをリードします。制度設計そのものはTLと同じでありつつ、対象が“開発プロセスやコード”から“品質プロセス”に変わったイメージです。

もちろんこれまでもQAエンジニアは、テスト計画やリリース判断など品質に深く関わってきました。
しかし、それらの活動は担当者個人のホスピタリティによって支えられている面が大きいのが現状でした。そこで、QAチーム内で検証プロセスや品質の方向性を見極め、リードする役割としてQLを設けることにしました。

ちなみにモノグサ社内では、Devチームで規定されている「TL」ロールのサブセットという建て付けになっています。(制度上はTLということです。)

QLの主な役割は、大きく2つあります。
1つは検証プロセスのリード。テスト計画やテストケースのレビュー、リリースチェックリストの確認などを通じ、開発チーム全体の品質活動を整理・加速させます。

もう1つはプロダクトマネジメントへの橋渡し。バグ管理やアサイン調整を行いながら、PdMが長期計画を立てる際に品質観点から助言したり、他職種と連携してプロセス改善に取り組んだりします。

一方で、QLは「人のマネジメント」はしません。
チームメンバーのタスクを補助することはありますが、あくまでフォーカスは“品質そのものの推進”にあります。
モノグサでのTLの建て付けもそのようになっており、マネジメント関連の制度設計とは分離されています。

今年の4月に1人、9月にもう1名が任命され、チームの牽引役として活躍してくださっています。

QL導入の効果は?

運用を始めたばかりの今は、まだ手探りで動いていただいている状態です。
QLの成すべきことはケースバイケースで、「品質をどう定義し、どうリードするか」という問いに正解はありません。
それでも、開発と品質の間を行き来しながら、プロダクトの「良い体験」を支え、新たに作っていくために新しい形を模索しています。

具体的な動き方としては、気になることがあるとメンバーにヒアリングやアドバイスを行ったり、テストツールの使い方をハンズオンしていただいたりする機会は結構あります。
裁量という点でノンタイトルより動きやすく、お節介を焼きやすくなった、というのはあるかもしれません。

マネージャーが頻繁に細かな指摘をしてしまうと、「口うるさく言われている」ように感じてしまい、チームの雰囲気が暗くなりがちです。その役割をQLという別のロールが担ってくれることで、必要な指摘はしっかり行いながらも、雰囲気は守られていると思います。

“未体験への挑戦”とは、未知の領域に飛び込むこと。
QL制度の導入は、まさにその第一歩でした。
品質をリードするという役割が、チームとプロダクトにどんな変化をもたらすのか——この挑戦の続きを、来年も続けたいと思います。

モノグサQA募集中です

色々なことを考えたり試しながら、毎日わいわい楽しく仕事をしております。

面白そうだなと思った方は、ぜひご応募ください!

このブログ記事が何かのご参考になりましたら幸いです。

 

モノグサ株式会社では一緒に働く仲間を募集しています。

少しでも興味を持ってくださった方は、ぜひお話しましょう!

careers.monoxer.com

qiita.com

 

Monoxer Intern Report #21_Book編集画面のUI/UX改善

自己紹介

モノグサのソフトウェアエンジニアインターンに参加させていただいた、青柳と申します。普段は早稲田大学で計算機科学を専攻しています。また、学業とは関係なく趣味でもソフトウェア開発をよくやっていて、最近は特にWebサービスを作っていることが多いです。例えば、今年(2025年)は主に自分の知り合い向けにTwitterクローンを開発しました。

参加を決めた理由

今回モノグサのインターンに申し込んだきっかけとしては大きく分けて二つあります。

まず一つは大学のサークルの後輩からオススメされたことです。彼は昨年度既にモノグサのインターンに参加していたので、その口コミがモノグサに興味を持つきっかけになりました。

もう一つのきっかけは、以下の大橋さんの記事です。

note.monoxer.com

自分は普段趣味でよく音楽ゲーム(いわゆる音ゲー)をプレイしていて、この記事の題材であるSOUND VOLTEX(サウンドボルテックス)というゲームも最近よく遊んでいるので、この記事を読んで「おもしろい会社だなあ」と思っていました。

今年の夏季のインターンを考える時期になり改めてモノグサの募集を確認したところ、タスクによってフロントエンド/バックエンド、Web/モバイルをどれくらいやるか自分で決められそうというのと、給与面なども他のところと比較して高い水準だったので今回このインターンに申し込むことにしました。

取り組んだこと

背景

今回私が主に担当したのは、Web管理画面の中にあるBook編集画面の改修です。まず「Web管理画面とは何か?」というところから解説します。

「Monoxer」というアプリケーションは、学習者が使うモバイルアプリと管理者(学校の先生など)が使うWeb管理画面の2要素から構成されています。管理画面では、記憶する対象をまとめたものである「Book」の作成・編集・配信や、小テストの作成・配信などを行うことができます。

以下に、実際のBook編集画面をお見せします。

 

このBook編集画面では収録されているエントリ(学習で記憶したい対象)が一覧になって表の形式で並んでおり、必要に応じてエントリを編集することができます。ただし、編集することができるのは下書き状態(学習者には公開されていない)のエントリのみで、一度公開してしまったエントリについては直接編集をすることができない仕様になっています。しかしそういう仕様とはいえ、公開されているエントリの内容を後から修正したくなることもあります。

これは例えば、問題文や解答に誤植があったときや、時代に合わせて問題文・解答などを修正したいときのようなケースです。このような場合、従来のBook編集画面でエントリを編集するには①一度編集したいエントリを複製して同内容の下書きエントリを作成し、②作成した下書きエントリにて修正をして、③複製元のエントリを削除して、④修正した下書きエントリを公開する——という手続きを踏む必要がありました。エントリの編集をしたいのに複製をするというのはあまり直感的な操作ではありませんし、必要な操作のステップも多いです。こういった背景があり、今回のインターンではこのBook編集画面のエントリ編集のUI/UX改善というテーマに取り組むことになりました。

改善手法

前述した仕様を変更して公開済みエントリを編集できるようにするためにはバックエンド(サーバー側で行う処理)の改修も必要となり簡単なタスクではないため、まず「フロントエンド(クライアント側で行う処理)だけで対応できないか?」という方向で実装を決めていきました。結果としては、以下の図のように公開済みエントリのメニュー内に「下書きに戻し編集」機能を追加する形になりました。

この機能を呼び出すと指定したエントリが下書き状態に戻り、かつ自動的にエントリの内容の入力欄(以降は単に入力欄と呼びます)が開いた状態になるので、そのまますぐに内容を編集できます。

これは内部的には、エントリを複製して下書きエントリを作成したあとに自動的に複製元エントリを削除して、下書きエントリの編集画面を開くという機能の組み合わせによって実装されています。従来のBook編集画面でのエントリの編集フローで必要だった操作のうち、いくつかをまとめて扱いやすくした形です。

ただし、既に学習者に配信済みのエントリを編集してしまうと学習者の「記憶度」や学習計画の進捗といったデータに影響を与えてしまうため、「下書きに戻し編集」ボタンを押した際には以下のようなモーダルを表示して、意図せずにエントリを編集してしまうことを防ぐようにしています。

実際の開発の流れ

今回のインターンタスクに取り組むにあたって、まず「UIをどのように変更するか?」という点をデザイナーの方と相談しました。画面のレイアウトなどに変更が加えられる機能の開発になるため、エンジニアの自分1人だけで全て進めることはできません。このようなケースでは、デザインのプロであるデザイナーさんと共同で作業を進めていくことになります。

モノグサでは、画面のデザインについて議論する場として主に Figmaを利用しています。今回の開発では最初にデザイナーの方にベースとなる案を作成していただき、そこにコメントをつけていく形でディスカッションを行っていました。また、「この点については詳細に意見を共有したい」というときにはミーティングを適宜設けて話し合いをすることもありました。必要な議論が一通り済んだ段階でデザインがfixの状態となり、その後は決められたUIとなるようにエンジニア側で実装を進めていく形になります。

デザインの話し合いの段階では、公開済みのエントリについても下書きエントリと同様に「削除」ボタンの左に「編集」ボタンを表示するという案や、最終的に採用された仕様ではモーダル内に表示しているアラートをエントリの入力欄内で表示する案がありましたが、「配信済みエントリを編集することの影響を知らないまま編集をしてしまわないか?」などの観点から最終的には現在のような画面デザインとなりました。

実装の段階では大きく分けて二つの対応をしました。一つはエントリの複製処理の改修で、もう一つはエントリ一覧の表コンポーネントの状態管理の改修です。順番に説明します。

公開済みエントリのメニューから「上に複製」あるいは「下に複製」を選択すると、公開済みエントリの内容をコピーした下書きエントリを作成するエントリの複製処理が呼ばれます。下書きに戻す処理を実装しようとしたときに、エントリの複製自体はこの既存の機能を流用することでできるのですが、今回のケースでは複製したあとに作成された下書きエントリの入力欄を自動的に開くようにしたいです。このために下書きエントリの情報(IDなど)を複製の後続処理で使えるようにしたいのですが、従来の仕様では複製時には複製処理を呼び出すだけで返り値を受け取っておらず、まずこの部分を変更する必要がありました。これが大きな変更点の一つ目です。

ただ、複製して作成された下書きエントリを受け取るようにすることはできたものの、肝心の入力欄を自動で開くというところにもう一つ壁がありました。

それは、それぞれのエントリは自分自身以外の「編集中かどうか」フラグを操作できないという点です。今回の機能では複製元エントリを複製した後に作成した下書きエントリの状態(編集中フラグ)を操作したいのですが、これらは異なるエントリであるため従来の実装ではお互いの状態を変更することはできませんでした。

そこで、それぞれの行のコンポーネントで状態管理を行っていたところを親であるエントリ一覧のテーブルのコンポーネントで状態管理を行うように変更しました。これが二つ目の変更点です。

この二点の改修さえしてしまえば、あとは既存の機能をいくつか組み合わせることで今回のメインタスクの実装をすることができます。実際ここまで開発が進んだ後は、かなりスムーズに残りの実装が進みました。

インターンの感想

モノグサでのインターンは6週間というかなり長めの期間でしたが、その分かなり詳細にモノグサの文化を知ることができました。

就業型インターンに参加するのは実はモノグサが3社目なのですが、他の企業と比較してモノグサの良いところはボドゲ会やおやつ会、TechTalkなどのような直接の業務以外での社内交流の機会があること、そしてそれを可能とするようなゆとりのある働き方ができること、だと思っています。ものぐさで行こう

モノグサでエンジニアとして自分が働く姿を想像できるようになった、インターンらしいインターンだったと思います。

機能の開発に関しては、最終的にはあっさりという感じでしたが途中詰まったりする場面もありました。

自分が元からNext.jsの経験があり、さらにメインタスクもフロントエンドの改修ということで技術的に新しいことをやる感じにはならないのかなと思っていたのですが、エントリの複製処理の改修の際にRedux-Sagaで実装された処理をRedux ToolkitのRTK Queryに移行するという対応をすることになり、どちらもまったく名前も知らないところから作業することになったので大変でしたし、商用サービスでのdata fetchingの勉強になりました。

また、自分が最近になってからReactに入門したこともあり、やや古い方式であるクラスコンポーネントに馴染みが無かったので、最初はコードの意味を読むのに少し苦労しました。こちらは、プロダクトのメンテナンスという面で勉強になった気がします。

インターンを総合して振り返ると、最終的にはインターン期間中にメインタスクの機能を実際にリリースするところまで到達できたのでかなり満足しています。機能リリース後には他のチームの方から「大変ありがたい」というコメントもいくつかいただき、非常に嬉しかったです。

開発を通して、デザイナーの方、エンジニアの方、QAの方などたくさんの人にお世話になりました。プロダクトの開発に対する知識がまた一層深まったと感じます。今回インターンのタスクに関わってくださった全ての方に、ここで改めて感謝をしたいと思います。ありがとうございました。

仕事のあとは

趣味の音ゲーで交流ができて良かったです。#club-rhythm-gameのみなさんありがとうございました!

(左上が私です)



 

競技プログラミングのコンテストを開催しました

 

2025年8月8日、弊社オフィスで 競技プログラミングのコンテストを開催しました。

さまざまな企業や異なるフィールドで働く競技プログラマー同士が垣根を越えて親睦を深めるためのコンテストを開催するという思いを込めて、Monoxer Programming Contest for Engineersと名づけられました。参加者の募集はXの投稿などにて、社員から広くお知らせし、コンテスト当日にはオンラインも含め、計48名の方にご参加いただきました。

ソフトウェアエンジニアの @tobisatisより、主に問題作成者視点での振り返り記事をお届けします。

開催に向けての準備

社員で作問作業を行うプロジェクト自体が、モノグサとして初めての挑戦でした。約2時間のチーム戦を行うことが先に決まっており、逆算しておおまかな配点と問題数を決めていくところから着手しました。2ヶ月強の限られた時間の中、4人のメンバーで問題を完成させる必要がありましたが、全員が経験豊富というわけではなく、特に私は作問自体も初めて、さらに想定解を作成するためのPythonを書くのも初めてという「初めて尽くし」の状態でした。それでも密にSlackなどでのメンバー間でやり取りを行い、また事前に問題を解いてくれた3人のtesterの協力もあって、無事に作問作業を終えることができました。

特にI問題作成(問題はAからLまで12問ありました)において、印象的なエピソードがあります。私が原案から想定解まで作成した問題があったのですが、想定解と解説に重大な誤りがあることを  @kona0001が指摘してくれました。1問につき2人の担当者をつけるという体制を作っていたことが幸いでした。修正後、万全を期すため値が大まかにあっているかを確かめるシミュレーションコードを書いたのですが、それは平均値を比べるだけの根拠のないものでした。それを、  @kobae964が推定値の不確かさまで調べるものに洗練させてくれたことで、問題として完成することができました。チームで助け合うこと、協力し合うことの素晴らしさをあらためて感じた瞬間でした。

もちろん、他の問題にもそれぞれドラマがあります。幅広い難易度を取り揃えた12問となっていますので、ぜひ解いてみてください。

コンテスト中の控室

コンテスト中、作問者は会議室に集まって順位表を眺めていました。

1分も経たないうちに最初の正答コードが提出され、システムが無事に動いていることを確認できたときには、みんながほっとした表情を浮かべました。システムに用いたMOFEの運営者のkichi2004様、ありがとうございました。

順調に問題は解かれていき、各問題において最初の正答コードが提出されるたびに控室は盛り上がりを見せました。私は普段は参加者側なので、順位表を眺めて楽しむというのは初めての経験で、とても新鮮でした。68分が経過し、全問題に正答コードが提出された瞬間、会場の盛り上がりは頂点を迎えました。

コンテスト終了後の懇親会

コンテスト終了後は、ピザや寿司などを食べながら、参加者全員と運営スタッフたちで懇親会を行いました。普段、会うような機会がない業界で働いている方、また出身や年齢もバラバラな方同士が、「コンテスト」という縁で集まり、交流し、繋がっていく。一つのコンテストが人と人を繋げる場となっていることを嬉しく感じました。懇親会の中盤で、それぞれの問題の解説を参加者に行ってもらうパートでは、非常に難しい問題などもある中、みなさま真剣に耳を傾け、熱心に聞かれていたのが、とても印象的でした。

 

終わりに

どのような形になるかは未定ですが、今後もコンテストの開催を続けていきたいと考えています。

「ものぐさで行こう」という文化をもつ我々と競プロを作り上げていく活動に興味のある方、ぜひ一度カジュアル面談にてお話ししてみませんか?

careers.monoxer.com

Monoxer Intern Report #20_外部成績分析機能の機能拡張


自己紹介

初めまして。モノグサのソフトウェアエンジニアインターンに参加させていただいた片岡です。普段は東京科学大学(旧東京工業大学)で数理科学や計算機科学を専攻しています。

参加を決めた理由

AtCoder のモノグサプログラミングコンテストを通してモノグサを知り、教育 × IT の分野に取り組んでいるということで興味を持っていました。AtCoderJobs でインターンの募集を見つけ、実際のプロダクト開発を経験することで自身の成長に繋げたいという思いもあり、応募を決めました。

取り組んだこと

Monoxer はユーザ向けのスマホアプリや管理者向けの Web アプリから成りますが、私は主に Web アプリの開発に携わらせていただきました。

メインタスクの背景

管理者向けの Web アプリには、β版として一部の顧客に利用可能である、外部成績分析という機能があります。この機能は、外部試験等の成績データを入力すると、Monoxer に蓄積されたユーザの学習データと併せて比較分析を行うことができるものです。たとえば「英語の試験の成績と英単語帳の記憶度との間に相関があるか?」といったことを一目で確認できます。

メインタスク

この外部成績分析機能には、ユーザの学習データを選択する際の操作性に改善の余地がありました。というのも、以前の学習データ取り込み分析機能では、以下の手順で操作をする必要がありました。

 

  1. 分析対象としたい Book とクラスを選び、学習データ算出のリクエストをする。
  2. 算出された学習データを選択する。
     この手順では「やっぱりこの Book / クラスは分析対象から外したい」という場合に、再度学習データ算出のリクエストを送る必要があり、柔軟な分析を行うことが難しい状況でした。そこで今回のインターンでは、以下の機能を追加し、より柔軟な分析を可能としました。
  3. 算出された学習データに含まれる Book やクラスを、分析対象から選び直せるようにする。

 

実装を振り返って

今回の機能追加にあたり、主に以下の開発作業を行いました。

 

  • フロントエンド(TypeScript / React)
    • 分析対象の Book とクラスを柔軟に再選択できる画面の実装。
    • 検索機能およびページネーション機能の実装。
    • RTK Query を用いた効率的なデータ取得処理の実装。
  • バックエンド(Scala / Play Framework)
    • 分析対象の変更を反映するための API の修正。
    • 検索やページネーションに対応するための API の追加。
    • 変更を加えた API の動作を保証するためのユニットテストの追加。

 

今回のインターンを通して、フロントエンドからバックエンドまで、幅広い技術領域に触れることができました。特に Controller 層、Service 層、DAO 層といったレイヤを意識した開発や、モックのフレームワークを用いたテストの実践が印象的でした。インターン参加前と比較して、技術的な視野が大きく広がったことを実感しています。

インターンの感想

インターンに参加するのは今回が初めてでしたが、実際のプロダクト開発に携わることができ、とても貴重な経験となりました。技術的なスキルはもちろんのこと、プロダクト開発に必要なコミュニケーション、デザイナーや営業の方々との連携など、チームでの開発に欠かせない要素を肌で感じることができ、プロダクト開発に対する理解が深まりました。このような素晴らしい機会を提供してくださったメンターさんをはじめとするモノグサの皆様に感謝申し上げます。約 1 か月半、本当にお世話になりました!

 

p.s. 飯田橋には美味しいランチのお店が多い

 

因果推論の考え方

この記事は Monoxer Advent Calendar 2024 23日目の記事です。

はじめに

モノグサでData Scientistをやっている力徳と申します。

モノグサには、今年の8月からjoinしていますが、その前の会社では、R&D Engineer、Data Engineer、Data Scientist、ML Engineer、NLP Engineerとしてたくさん(笑)の会社で働いておりました。

簡単にいうと、データ分析に関わる雑用係をいろんな会社でやっていました(笑)

そのときに、biz系組織の方々からよく要望としてもらっていたのが

  • KPIを押し上げる”ドライバー”を見つけたい!
  • データから"ビジネスインサイト"を抽出したい!
  • 施策の効果を検証したい!

などです。

これはだいたいどこの会社でも言われてました。これらの問題はKPIのような目的変数と因果関係がある"変数"を見つける、もしくは、その因果関係を推定する問題として捉えることができ、因果推論と呼ばれるデータサイエンスのテクニックを適用することができます。

今回は、この因果推論についてうす〜く解説したいと思います。

相関と因果の違い

まず、相関と因果は異なるという話を聞いたことがある方は多いのではないでしょうか? 下の図はその説明によく利用される 国別の「1人当たり年間チョコレート消費量と人口10万人当たりのノーベル賞受賞者」の関係性を示した散布図です。

縦軸が人口10万人当たりのノーベル賞受賞者、横軸が1人当たり年間チョコレート消費量を表しています。この散布図からチョコレートの消費量とノーベル賞受賞者数には相関があり、さらにそれはチョコレートの成分が脳に良い影響を及ぼしているからだという仮説を 参考情報[1]の不定期メモでは主張していたようです。

しかし、[2]の解説記事でも紹介されているように、チョコレートをたくさん食べるとその効果として頭がよくなり国のノーベル賞受賞者数が増加する、つまり、チョコレートの消費量とノーベル賞受賞者数には原因と結果の関係、因果関係があるというのは考えづらく、それぞれの量に共通する影響因子(交絡因子)がある、つまり疑似相関の可能性が高そうだと考えられます。

直感的にはそれっぽいですが、この相関と因果の違いをきちんと判別するフレームワークはあるでしょうか? このフレームワークが因果推論と呼ばれる統計学の1分野です。相関や相関係数なども統計学で曖昧性なく定義されているように、因果効果も統計学の言葉で定義することができます。

因果効果の定義

ルービンによる因果モデルにおいて、ある対象者 $i$に対する(潜在的)結果変数 $y_i$へのある処置$z$の因果効果は、それぞれの場合の結果変数の差として表現されます。

$$ y_{i, z=1} - y_{i, z=0} $$

ここで、$z=1$は因果の原因となるある処置を施した場合を表し、$z=0$は処置を施さなかった場合を表します。

処置を施されたグループは処置群(Treatment Group)、施されなかったグループは対照群(Control Group)と呼ばれます。ここで注意するのは、必ずしもこの比較が同一対象に対して全く同じ条件でできないということです。 例えば、ガンの治療薬のある患者への効果の因果関係を確かめるために、同じ患者$i$に治療薬を投薬した場合と、しなかった場合を比較することはできません。

ある勉強方法と学力向上の因果関係を推定するために、同じ学生$i$に対して、その勉強法を試した場合と試さなかった場合を同時に比較することはできません。

このようなどちらか片方の処置が実現され、他方の処置が実現されない場合には上の因果効果はどのように評価したらよいでしょうか?

答えは,1個人、1対象の因果効果を測定するのではなく、公平に選別された多人数からなる処置群と対照群での平均をもって因果効果の推定値とすることです。

$$ E(y_{z=1}) - E(y_{z=0}) $$

ここで、$E$は処置群、対照群それぞれの結果変数の平均(期待値)を表します。

これは、50%/50%で完全にランダムに分割されたユーザーに対するAB testであり、Webサービスなどの施策の効果検証によく使われている手法です。

AB testによる効果の検証が施策の結果への因果を推論と同等であることがわかると思います。

では、AB test、ランダムに処置群と対照群に割り当てて比較することが難しい場合、もしくは、完全にはランダムに割り当てていることが保証できない場合はどうすればよいでしょうか?

医学、教育の分野では倫理的な理由などから完全にランダムなAB testを実施することが難しい場合が多々あります。 また、AB testとして完全に計画されてない設定で得られた観察データからある処置効果の因果効果を推定したい場合があります。

この場合に使用できるテクニックの1つが傾向スコアとIPW推定量です。

傾向スコア、IPW推定量

傾向スコア、IPW(Inverse Probability Weighting)推定量による因果の推論は、大雑把にいうと"仮想的"なAB testを実施することと言えます。

そもそも、因果効果とは

  1. ある同一対象に対して処置を施す場合と施さない場合でその結果の差として因果を定義できます。
  2. それができない場合、完全にランダムに分けられた処置群、対照群の平均の差として因果効果を推論します。

2.のAB testでは対象を完全にランダムに分けることで、それぞれの対象のグループは特性的に偏っているとは考えらないと状態になっています。十分なサイズがあれば、処置群と対照群には"同じ"ような特性を持った対象がいて、その”同じ”ような特性を持ったペア同士の結果の差として効果を推定していたわけです。

2.のAB test, 完全にランダムに処置群と対照群に分けられない場合は、同じように”似た”対象を特定し、その”似ている”者同士で結果の差を推定、因果推論を行います。対象が処置群に割り当てられる確率を”傾向スコア”といい、この傾向スコアを使って、公平に結果の差の平均を推定する方法が IPW推定による因果推論です。

傾向スコア

対象$i$の共変量を $\boldsymbol{x}_i=(x_1, x_2,\cdots, x_k)$とし, $z_i$を処置の割り付け変数, $y_i$を結果変数とします。共変量というのは対象$i$の特徴、特性を示すもので、機械学習の文脈では特徴量、素性、説明変数と呼ばれるものです。例えば、あるサービスのユーザーの年齢、性別などのデモグラフィック情報や利用履歴情報だったりします。

AB testの様に、ランダムに分けられているわけではない処置群と対照群の$n$個のデータ $D$ がある場合

$$ D = \left\{ (y_i, z_i, \boldsymbol{x}_{i}) \mid i = 1, 2, \cdots, n \right\} $$

傾向スコア$e_i$は対象 $i$ の割り付け変数 $z=1$への割り付け確率 $$ e_i = P(z=1|\boldsymbol{x_i}) $$ として定義されます。データ$D$があるのでロジスティク回帰のような確率出力できる2値分類器により容易に推定することができます。

傾向スコアを使う理由の”お気持ち”はどのようなものでしょうか。今の場合処置群と対照群がランダムに割り当てられているわけではなく、単純に各群の結果変数の平均の差を取った場合”偏り”がある可能性があります。この”偏り”を補正する目的で傾向スコアが導入されました。

”強く無視できる割当条件”と呼ばれるある条件を処置群、対照群が満たしている場合、因果効果はIPW推定量と呼ばれる 傾向スコア $e_i$による重み付け推定値で推定できます。

因果効果のIPW推定量

IPW(Inverse Probability Weighting)推定量もRubinによる導入されました。前節からの説明と同じく、因果効果は以下のように"公平"な結果変数の差(の平均)として定義されます:

$$ y_{z=1} - y_{z=0} $$

AB testの場合はランダムに2群に分けてられるので”公平”性が満たされているので平均の差がそのまま因果効果を示していました。 偏りのありえる場合では傾向スコア$e_i$(の逆数)で重み付けすることでこの偏りを調整することができます。

$$ \begin{aligned} \widehat{E}(y_{z=1}) &= \frac{\sum_{i=1}^n \frac{z_i y_i}{e_i}}{\sum_{i=1}^n \frac{z_i}{e_i}}, \\ \widehat{E}(y_{z=0}) &= \frac{\sum_{i=1}^n \frac{(1-z_i) y_i}{1-e_i}}{\sum_{i=1}^n \frac{(1-z_i)}{1-e_i}} \end{aligned} $$

として傾向スコアで重み付け平均 $\widehat{E}(y_{z=1,0})$を使って形式的にはAB testの場合と同じ様に

$$ \widehat{E}(y_{z=1}) - \widehat{E}(y_{z=0}) $$

として、"強く無視できる割り付け"条件を満たしいる場合には因果効果を推定できます。

傾向スコアによるIPW推定量から因果フォレストへ

因果効果を推定する場合

  1. AB testを実行し、結果の平均の差で判定する
  2. AB testのようにランダムに2群を分けることが困難な場合は、傾向スコアによる重み付き平均の差で判定する

の2つを利用することができました。フレームワークとしては決まっており容易に因果推論を行うことができます。 ただし、2.の傾向スコアを用いて因果効果の推定をする場合は、傾向スコア推定の性能に大きく依存している問題があります。つまり、傾向スコアの推定値の信頼性が大きくない場合は因果効果の推定の信頼性も低くなる可能性があります。また、その影響度合いもはっきりとはわかってない状況です。また、最終的な推定値を得るために、独立な傾向スコアの推定と因果効果の推定の2段階の推定を行っていることも好ましい方法でないとも考えられます。

このような背景のもとで、最近、機械学習の手法をベースにした因果効果の推定手法が開発されました。それが決定木やランダムフォレストをベースにした因果ツリー、因果フォレストです。参考情報[5],[6],[7]

これら決定木ベースの因果推論手法は傾向スコアを用いる手法に比べて以下の優位性を持っています。

  1. 因果効果の推論用に通常の決定木、ランダムフォレストとほぼ同じ学習で推論器を構築できる。
  2. 得られた因果ツリー、因果フォレストは統計的に好ましい性質を持っていることが(ある条件のもとで)数学的に証明されている。
  3. この因果ツリー、因果フォレストを使って、全体としての処置の因果効果の推定はもちろん、各対象に対して影響を個別に推定できる。(異質処置効果の推定)

特に2.の統計的に好ましい性質(漸近正規性とそれに基づく信頼区間の推定)は実用上有益であり、傾向スコアが持っていなかった特性です。

また、統計的機械学習分野では1つのブレークスルーとして評価されていて、今後の学術上の発展と、実ビジネスへの応用も期待されています。

最後に

今回、因果推論の考え方を傾向スコアとそのIPW推定量といっしょにうす〜く解説しました。また、最新の因果推論の技術である因果ツリー、因果フォレストについてもこれまたうす〜く紹介しました。

この因果フォレストについては1、2年前から知っており、その漸近正規性の証明をぜひ理解したいと思っていました。今回のアドベントカレンダーの記事の執筆の話があって、真っ先に思い浮かんだテーマがこの因果フォレストでした。一ヶ月くらいあれば、証明の理解ができるだろうと踏んでいたのですが。。。。その証明が難解すぎて、このようなうす〜い紹介になってしまいました。

モノグサではデータドリブンな物事の進め方は普通になっており、AB testによる効果検証や学力の向上の効果の推定などにもデータ分析の手法、考え方が広く利用されています。

このような、データサイエンティストには夢のような環境であるモノグサ株式会社では 一緒に働く仲間を募集しています。私に因果フォレストの漸近正規性の証明を教えてくださる方お待ちしています!

参考情報

  1. Messerli FH. Chocolate consumption, cognitive function, and Nobel laureates. N Engl J Med. 2012 Oct 18;367(16):1562-4. doi: 10.1056/NEJMon1211064. Epub 2012 Oct 10. PMID: 23050509.
  2. チョコレートを食べると ノーベル賞がもらえるか?
  3. 統計的因果探索 (機械学習プロフェッショナルシリーズ)
  4. 調査観察データの統計科学: 因果推論・選択バイアス・データ融合 (シリーズ確率と情報の科学)
  5. Estimation and Inference of Heterogeneous Treatment Effects using Random Forests
  6. ランダムフォレストによる因果推論と最近の展開
  7. EconML

qiita.com

careers.monoxer.com

アプリストアのオーナーアカウントを共用アカウントに入れ替えた話

こんにちは!やまもと@テスト番長です。暑くて長い夏がようやく終わったと思ったら今年もあと残り3ヶ月、冷凍おせちをどこで買うか悩み始めた今日この頃です。

僕はモノグサでQM(Quality Management)チームのマネージャーを務めさせていただいております。今年、アプリストアのオーナーアカウントを共用アカウントに入れ替える作業をQAチームで行いましたのでその時の体験談をご紹介したいと思います。

経緯

MonoxerはAndroidとiOSの各プラットフォームに対応しており、それぞれのストアの管理者権限はCTOがオーナーとなっておりました。

組織が拡大するにつれ、ストアで発生する諸々の対応をCTOが逐一行うのは非効率的になっていました。

今後の事業展開を踏まえ、設定を変える手間がかさみそうなことから、今回アプリストアのオーナーアカウントの入れ替えを行うことになりました。

モノグサではサービスのリリース作業をQAチームで担当しており、ストア周りの設定に触れることも多いため、検討の結果QAマネージャーの私が移行作業の担当を引き受けることになりました。

iOSはオーナーを簡単に引き継ぐことのできる仕組みがあったのですが、Androidはオーナーを永続的なものと定義していて引き継がれることを前提としておらず、結果、アプリの譲渡と同じプロセスを踏む必要がありました。

(現在は会社組織の場合は個人アカウントで登録しないように注意書きがあるようです)

移行作業で色々と苦労がありましたので、同じような作業をする方がいらっしゃったら参考になるよう経験したことを書き残しておきたいと思います。

事前に調べたこと、決めたこと

アカウント移行で万が一サービス停止したら大問題ですので、移行の影響を綿密に調査して段取りを決めていかねばなりません。

情報収集の際に参考にしたサイトを以下に挙げます。(先人の方々に感謝です。)

・Zaim アプリの所有者権限を変更した際の苦労話 https://note.com/y_sumida/n/n91b0265c439a

・iOS/Androidアプリを譲渡またはアカウントを移行する方法 https://backapp.co.jp/blog/12099

調査が進むにつれ、色々と面倒な作業があることがわかりました。

iOSはAccount Holderを移譲すればOKで、割とシンプルでした。

問題はAndroidです。FAQを調べたところ、オーナー権限の譲渡は出来ないようでした。現行のデベロッパーアカウントは個人のアカウントで登録されており、他の用途でも使っているので共用に変えるわけにも行きません。

念の為サポートにも問い合わせしましたが、やはり譲渡手続きになるとのことで腹を括って準備を開始しました。

基本的に譲渡手続きであるため、移行できない情報(=譲渡の場合渡す必要のない情報)が幾つかあり、そのケアが必要かどうか整理する必要がありました。

また、デベロッパーIDが変わるため、登録してある箇所は全部入れ替える必要があります。

当該のヘルプを確認し、洗い出しを進めました(下記は2024年4月頃の情報です。最新情報はヘルプをご参照ください。)

  • 移行できる情報

    • アプリのユーザー、ダウンロードの統計情報、評価およびレビュー、コンテンツのレーティング、ストアの掲載情報
  • 移行できない情報や設定

    • 一括エクスポート レポート、売上レポート、収益レポート
      • この時点でストア課金が無く収益は見ていませんでした。
      • ここを考慮しないで済んだのはラッキーでした。
    • テスター グループなど
      • デベロッパー / テスターは最初から登録し直す必要があります。
  • 連携し直しになる統合サービス

    • Google アナリティクス
    • Google Developers Console プロジェクト
    • Firebase連携
    • FCM (Firebase Cloud Messaging)
      • Push通知で使っているため確認が必要でしたが、GCPのサポートに問い合わせた結果、対応不要でした。
  • Ad SDK の統合(AdMob を含む)
    • 未使用
  • managed Google Play ****限定公開アプリ
    • 該当せず
  • Google Play Developer API
    • 使用箇所があれば新しいデベロッパー IDに更新する必要あり

統合サービスへの影響を洗ううち、入れ替え時のラグが若干あるかもしれないことが気になり出し、影響度のヒアリングを行いました。アナリティクスなどが見れなくなって困ることがないか社内に確認を取りましたが、幸い数日程度のラグであれば問題ない状況でした。

切り替えに時間がかかるため、移行時期はビジネス上影響の出にくい時期を選ぶことにしました。

4月は新学期でMonoxerの導入作業が活発に行われているため、無用なトラブルを避けるために5月のGW以降に実施することになりました。

いざ移行開始

まずは移行先のアカウントを準備するところから始めます。

アカウントの管理方法、2段階認証の方法やネーミングも決めなくてはいけません。地味に手間なところです。

Android側の移行ではPlay Storeのデベロッパー名が一時的に変わるため、開始のタイミングでカスタマーサクセスチームを通じて全社に周知を行いました。

iOSアプリの移行手順

手順は以下の通りでした。

https://developer.apple.com/jp/support/account-holder-transfer/

  1. 受諾側アカウント(共用アカウント)の下準備
    1. メールアドレスを振り出してApple IDを取得
    2. 組織にデベロッパーとして招待する
    3. 本人確認を終わらせる
      1. ファクタ認証必須のため、電話番号も準備
  2. Account Holderの譲渡
    1. 現在のAccount Holder(CTO)が、受諾側アカウントを指定して譲渡手続きを行う
  3. Account Holderを受諾
    1. 受諾側アカウントに通知が来るので、契約を確認して同意する
      1. Account Holderになった旨の通知が届く
  4. サブスクリプションの更新設定
    1. 以前のAccount Holderが、サブスクリプションの自動更新をオフにする
    2. 新しいAccount Holderが、サブスクリプションに登録
      1. 有効期限の30日前から可能

概ね問題なく完了しました。

Androidアプリの移行手順

移行作業の開始を社内に宣言し、以下の手順を実施していきました。

  • 現在のデベロッパー名を「monoxer.com」→「monoxer.com(旧)」に変更
    • 移行先のアカウントを「monoxer.com」にするため、一時的にリネームしておく必要がありました。
    • 審査しているのか、反映まで2日ほどかかりました。
  • 移行先のアカウントでデベロッパー登録を行う(有料
    • デベロッパー登録には審査があり、完了までしばしリードタイムがあります。2023年ころに比べると、登録に必要な情報が増えているようでした。
    • D-U-N-S ナンバー
      • 入力する必要があり、情報を取得しました。
    • デベロッパーの連絡先登録
      • 確認の音声メッセージが会社番号に届く仕組みなのですが、早く終わらせたかったため 一時的に仮の番号で登録し、後日正式な番号に入れ替えました。
    • その他会社情報
      • 住所、ウェブサイト、メールアドレスなどが必要です。

ここまでで一旦移行先のアカウントが作成されました。アプリの配信や譲渡を受けられるような状態にするには、さらに追加で諸々の設定を進めていきます。

  • 本人確認
    • 会社設立証書、登記簿、税務署からの何らかの書類、納税証明書が必要
      • アップロードの容量制限が厳しく、今回使用した資料ではPDFをダウンサイズしておく必要がありました。
    • 確認書類に記載のある経営者が、身分証明書を送って登録する必要がありました。
  • Google Payments 販売アカウントを作成
    • Google Search Consoleで会社のウェブサイトを認証登録します
    • 案内に沿ってお支払いプロファイルを作成します
    • 銀行口座登録
      • 銀行口座を登録すると、確認用のデポジットが振り込まれます。
      • 経理に協力をお願いして確認を終えました。
  • 移行先のアカウントでテストアカウント、グループ等を作成し直す
    • 現行のアカウントと同じ内容で登録し直しました。
    • Googleからの連絡をMLにしてメンバーを招待すると良いようです。
  • GCPのサービスアカウントを招待する
    • 手元の環境ではユーザーとして登録すればOKでした。
  • レポートのダウンロード(念の為)
    • レポートは利用していないと聞いており対応不要なものでしたが、2024年分について落とせるものは落としておきました。

一連の設定が終わったらいよいよ移行リクエストです。

  • アプリの移行リクエストを送る
    • 元のアカウントと移行先アカウントの登録取引 ID を調べて元のアカウントからサポートに依頼します。
    • 新しいアカウントの準備が全部完了していないと、アプリの移行は行えません。

移行リクエストを送ってから2日程度でリクエストが処理されました。 移行後に一連の動作確認を行い、移行完了となりました。

  • 移行完了の確認
    • Play storeでアプリをダウンロード出来ること
    • push通知を送信出来ること
    • Firebaseで各種情報を閲覧可能なこと
    • アプリをアップデート出来ること(旧アカウントで作成したビルドを使いましたが、新アカウントでもビルドすべきでした。このあたりは後述します)

移行で躓いたポイント

移行中、幾つか躓いたポイントがあったので愚痴注意喚起しておきます。

想定外① Apple Developer Appの本人確認書類アップロード

iOS側の移行は概ね順調に進みましたが、一点困ったのが本人確認が運転免許証では通らず、パスポートを引っ張り出してやっと通ったことです。写りの問題なのかもしれませんが、もっと簡単に認証できると嬉しいところですね。

想定外② Google Play Consoleの移行先アカウントの本人確認

どうしても経営陣に作業依頼をせねばならず、使ったPDFが一発で通らなかったこともあり手間取りました。会社の書類と本人の確認と段階が分かれてるとありがたいなと思いました。

想定外③ Google Play Consoleのお支払いプロファイル

銀行のデポジット手続きは認識していたのですが、会社のウェブサイトをGoogle Search Consoleへ登録する必要があり、確認用のファイルをサイトにアップロードするのに少々時間を食いました。

そして作業漏れ発生

移行作業にはなんだかんだで1ヶ月程度かかり、一通り片付けてほっとしたところで作業漏れが判明しました。

Androidアプリの新しいバージョンのビルドをするところでCIが失敗、原因はGCPのサービスアカウントに対してmonoxerアプリのアクセス権限を付与出来ていなかったせいでした。

アプリ譲渡前の待ち時間に開発者アカウントを登録し直したため、その時点ではmonoxerアプリへの紐付けがまだ出来ておらず、作業漏れとなってしまいました。

GCPのサービスアカウントおよび開発メンバーのデベロッパーアカウントの紐付けを行い、すぐに復旧させることが出来ました。

最後に

こういう作業はふつう、インフラ系だったシニアなDevの方などが担当する作業で、QAがこの手の作業をすることは珍しいのではないでしょうか。慣れないところも多く、沢山の方の手助けをいただいてなんとか完了することが出来ました。 この記事が何かのご参考になれば幸いです。

モノグサQA募集中です

モノグサ株式会社では一緒に働く仲間を募集しています。 少しでも興味を持ってくださった方は、ぜひお話しましょう!