統計 - TECH PLAY - TECH PLAY

TECH PLAY

統計

統計(とうけい)は、データの収集、整理、分析、解釈、および表現に関連する学問分野です。統計は、数値データや事実を収集し、それらを整理してパターンやトレンドを見つけ、データの特性や相互関係を分析することを通じて、情報や知識を得るための方法です。

近年、統計は改めて注目されている分野です。そこには以下のような理由があります。

ビッグデータの活用: 近年インターネットやセンサー技術の進歩により、膨大な量のデータが生成されるようになりました。これらのデータはビッグデータと呼ばれ、統計手法を使って分析することで、重要な情報やパターンを抽出することが可能です。ビッグデータの解析には統計手法が欠かせないため、統計への注目も高まっています。

機械学習と人工知能の進歩: 機械学習や人工知能の分野では、統計的手法が広く活用されています。機械学習モデルのトレーニングやパラメータの推定には、統計的手法が不可欠です。また、機械学習モデルの評価や解釈にも統計が重要な役割を果たしています。機械学習と統計の組み合わせにより、データ駆動型の予測や意思決定が可能となり、それに伴って統計への関心も高まっています。

偽情報の検出と信頼性の向上: インターネットやソーシャルメディアの普及に伴い、偽情報やフェイクニュースの問題も増えています。統計手法を使ってデータの信頼性を評価し、偽情報を検出する取り組みが行われています。統計的な手法による信頼性の向上は、情報の正確性と信頼性を高めるために重要です。

経済・社会科学の分野での応用: 経済や社会科学の分野では、統計手法がデータ分析や政策立案に広く活用されています。例えば、経済指標の予測や市場動向の分析、社会調査や人口統計の解析などに統計が欠かせません。経済・社会の理解と問題解決に統計が不可欠であることから、統計への関心も高まっています。

TECH PLAYには統計を学べるイベントやコンテンツが掲載されています。
統計を学んで仕事や学習に役立てましょう。

イベント

マガジン

技術ブログ

はじめに こんにちは、データシステム部MLOpsブロックの 木村 です。MLOpsブロックではZOZOTOWN、WEAR by ZOZOをはじめとして、弊社で提供するさまざまなサービスに関わるML機能を開発・運用しています。 ZOZOTOWNでは、ユーザーと商品を同じベクトル空間で表現するembeddingを、ホーム画面やメールマガジンなど複数の推薦機能で共有しています。このembeddingは、embedding配信基盤REP(Recommendation Embedding Platform)が定期的に更新し、各推薦機能に配信しています。REPの詳細は以下の記事で紹介しています。 techblog.zozo.com embeddingを共有すると、モデルを1回改善するだけでその効果をすべての推薦機能に届けられます。一方で、embeddingの品質が下がったときは、その影響もすべての推薦機能に同時に広がります。しかも品質の下がったembeddingからでも推薦結果はそれらしく出続けるため、気づかないまま影響が続きかねません。 そこで本記事では、REPが配信するembeddingの品質を、配信データ・ベクトル空間・推薦スコアの3つの観点で数値化し、毎日監視する仕組みを紹介します。起こりうる障害パターンの整理から、監視指標と閾値の設計、運用設計までを説明します。embeddingを複数のシステムで共有している方や、MLモデルの出力の品質監視を検討している方の参考になれば幸いです。 本記事の内容は2026年10月時点の情報であることにご留意ください。 目次 はじめに 目次 背景・課題 REPによるembeddingの配信 既存の監視で捉えられなかった範囲 本システムが担う監視レイヤー embeddingで起こりうる障害パターン 3つの障害パターン 監視指標と閾値の設計 監視する3つの観点 配信データの監視 行数 NULL率 ゼロベクトル率 鮮度 主キー重複 行数トレンド比 ベクトル空間の監視 実効次元 kNN purity@10 alignment 推薦スコアの監視 BigQuery上での推薦スコアの再現 PSIによる比較基準との差の計測 比較基準の持ち方 閾値の考え方 記録から決めたベクトル空間の下限 ユーザーと商品を平均した表示の落とし穴 PSIの一般的な目安との違い 運用設計 通知を起点にした対応 モデルの入れ替えへの追従 推薦スコアのアラートの切り分け 導入効果 異常なembeddingの検知 embeddingの状態の説明 今後の展望 まとめ 背景・課題 REPによるembeddingの配信 REPが配信するembeddingは、Two-Towerモデルで学習しています。Two-Towerモデルはユーザー用と商品用の2つのネットワークを持ち、それぞれのベクトルを同じ空間に出力するモデルです。ユーザーと商品のベクトルの類似度が高いほど、その商品がユーザーに合っていることを表します。 このembeddingを複数の推薦機能で共有しているため、新しい推薦機能もモデルを一から作らずに使い始められます。参照する機能は今後も増える見込みです。 REPではモデルのアーキテクチャの違いをモデル種別と呼び、モデル種別ごとにembeddingを生成しています。いずれも学習済みモデルで全ユーザー・全商品分を日次で再生成しています。加えて、直近1時間に行動したユーザーと商品メタデータが変化した商品を、1時間ごとに差分更新しています。どちらの処理も図中のembeddingテーブルに書き込み、各推薦機能はこのテーブルから読み込みます。以下ではこのテーブルを配信テーブルと呼びます。 既存の監視で捉えられなかった範囲 REPには品質監視を導入する前から2種類の監視がありました。 1つはジョブの監視です。学習パイプラインやembedding生成ジョブが失敗すると、Slackに通知が届きます。ただしこの監視が見ているのはジョブが成功したかどうかだけです。ジョブが成功扱いで終わったのに、配信テーブルのembeddingが0本だったり、本数が通常より大きく減っていたり、ベクトルが破損していたりするケースには気づけません。 もう1つは、学習時のオフライン評価によるモデルのデプロイ判定です。評価値が下限値を下回るモデルはデプロイされないため、明らかに性能の低いモデルが配信されることは防げます。しかしこのデプロイ判定だけでは配信テーブルのembeddingの品質を保証できません。理由は次の3つです。 モデルの評価値が事前に設定した下限値を超えているかしか見ていない 学習時だけの評価で、定期更新の結果の評価は行っていない モデルの世代交代による推薦品質の変化を見ていない まずデプロイ判定は、モデルの評価値が事前に設定した下限値を超えているかだけを見ています。評価値には推薦の精度と多様性を使っていますが、どちらもテストデータ全体を1つの数値にまとめたものです。embeddingの空間がどのような構造になっているかは見ていません。 また上記の判定は学習時にのみ実行されますが、学習の後にはembeddingの再生成、配信テーブルへの書き込み、配信するembeddingの切り替えといった処理が続きます。これらの工程で起きた問題は評価の対象外です。特にembeddingの再生成は、学習時の評価とは別の実装で動いています。学習時と再生成時では、モデルの読み込み方、特徴量を作るクエリ、対象のユーザーと商品、実行するハードウェアは、必ずしも同じではありません。そのため学習時の評価が良くても、再生成したembeddingが同じ品質になるとは限りません。差分更新で毎時書き換わるembeddingも、品質を確かめる仕組みはありません。 さらにデプロイ判定は、モデルの世代が変わったときに推薦品質がどれだけ変わったかを見ていません。モデルは毎日再学習するため、どの世代も基準を満たしたまま、推薦品質が以前と大きく変わることがあります。推薦品質の大きな変化は、誰も判断しないまま全推薦機能に届きます。 これらとは別に、推薦機能ごとにクリック率や売上などのビジネス指標も監視しています。embeddingの品質が下がると推薦の質も落ち、時間差でビジネス指標にも影響が現れます。ただビジネス指標はセールや施策など多くの要因で変動します。指標が下がった時点で分かるのは「下がった」という事実だけで、embeddingが原因かどうかを切り分けるまでに時間がかかります。 実際に別の推薦システムではエラー率やレイテンシが正常なまま推薦結果だけが変化し、異常と判断するまでに約1週間を要したことがあります。この事例は以下の記事で紹介しています。 techblog.zozo.com 本システムが担う監視レイヤー ここまでの整理から、私たちに欠けていたのは配信テーブルのembeddingそのものを毎日検査する監視だと考えました。embeddingの本数や鮮度といったデータの状態から、ベクトル空間の構造、推薦スコアの分布までを対象にします。既存の監視と本システムの関係は次のとおりです。 監視レイヤー 観測対象 分かること ジョブの監視(既存) ジョブの成否 処理が動いたか デプロイ判定(既存) 学習直後のモデルの評価値 モデルが最低限の性能を満たしているか 品質監視(本システム) 配信テーブルのembedding データとして破損していないか、空間が崩壊していないか、推薦の傾向が急変していないか ビジネス指標の監視(既存) ユーザーの行動 事業に影響が出ているか 本システムは既存の監視を置き換えるものではなく、それぞれの間を埋める位置づけです。以降ではまずembeddingで起こりうる障害パターンを整理し、そのうえで監視指標と閾値の設計、運用設計を説明します。 embeddingで起こりうる障害パターン 監視指標を設計する前に、embeddingにどのような異常が起きうるかを洗い出しました。異常の種類によって、どこを見れば気づけるかが異なるためです。 3つの障害パターン 洗い出した障害パターンは次の3つです。以下ではユーザーと商品のembeddingの類似度を推薦スコアと呼びます。各推薦機能はこの推薦スコアをもとに推薦する商品を選んでいます。 障害パターン 内容 例 データとしての破損 配信テーブルのembeddingが、データとして破損する embeddingが0本になる、本数が通常より大きく減る、NULLを含む、書き込みが止まる ベクトル空間の崩壊 データの形式は正しいまま、空間が潰れる どのユーザーのembeddingも似た向きになり、区別がつかない 推薦の傾向の急変 推薦スコアの分布が、ある日を境に大きく変わる 推薦スコアの水準全体が動く データとしての破損は上流のデータ処理が止まったり、推論が一部の行で失敗したまま書き込みが完了したりすると起こります。特徴量が欠損した商品に対して、その値を0で埋めて推論すると、意味のないベクトルが生成されることもあります。書き込みが止まって古いembeddingが残り続ける、同じユーザーや商品の行が重複する、本数が通常より大きく増減する、といった書き込みの異常もこのパターンに含めています。 ベクトル空間の崩壊は学習が発散した場合や、十分に学習されていないモデルの出力が書き込まれた場合に起こります。どのユーザーのembeddingも似た向きになるため、どのユーザーにも似た商品が推薦されます。以下ではこの状態をembeddingの崩壊と呼びます。本数もNULLの割合も正常なため、データとしての破損と同じ検査では見つかりません。 推薦の傾向の急変はembeddingの空間が崩壊していなくても起こります。モデルや特徴量を変更したときに起こることもあれば、その日の学習だけ分布が大きくずれて起こることもあります。このパターンは変化そのものが異常とは限らない点が、ほかの2つと異なります。意図したモデル改善でも分布は変わるため、変化に気づいたうえで意図したものか異常なのかを切り分ける必要があります。 監視指標と閾値の設計 3つの障害パターンに対して、それぞれ観点を分けて監視しています。仕組みはBigQueryの scheduled query で指標を毎日集計し、閾値を超えたらクエリを失敗させるというものです。scheduled queryは、BigQueryで定期的にクエリを実行する機能です。 閾値を超えたときはクエリの中でBigQueryの ERROR() 関数を呼び、クエリをわざと失敗させます。私たちのチームではscheduled queryの失敗をSlackに通知する汎用的なアラートをもともと運用していました。品質の異常をクエリの失敗に変換することで、監視のために新しい通知の仕組みを作らずに済みました。 集計した指標はすべて1つの結果テーブルに毎日追記します。結果を記録してからクエリを失敗させるため、閾値を超えた日の値も残ります。この結果テーブルがこれまで存在しなかったembeddingの品質の数値になり、ダッシュボードで推移を確認できます。 監視する3つの観点 障害パターンごとに、次の観点と指標を割り当てました。 障害パターン 監視の観点 指標 データとしての破損 配信データ 行数、NULL率、ゼロベクトル率、鮮度、主キー重複、行数トレンド比 ベクトル空間の崩壊 ベクトル空間 実効次元、kNN purity@10、alignment 推薦の傾向の急変 推薦スコア Population Stability Index(比較基準の日との分布の差) 指標はモデル種別ごとに計算し、監視の対象は配信が有効になっている全モデル種別です。 以降では観点ごとに、何を見ているかとどう判定しているかを説明します。 配信データの監視 配信データの観点では、配信テーブルがデータとして健全かを次の6つの指標で検査しています。いずれの指標も、ユーザーと商品それぞれで計算します。 指標 何を数えているか 閾値 行数 配信テーブルのembeddingの本数 0本 NULL率 破損したembeddingの割合 0.1%超 ゼロベクトル率 全要素が0のembeddingの割合 0.1%超 鮮度 配信テーブルへの最後の書き込みからの経過時間 12時間超 主キー重複 同じユーザーID・商品IDの重複行数 1行以上 行数トレンド比 当日の本数を、直近7日の本数の中央値で割った値 直近の水準から大きく増減 行数トレンド比を除く5つの指標は、正常な状態がはっきりしています。正常に生成されたembeddingであれば、本数が0になることはなく、破損したembeddingやゼロベクトルの割合もほぼ0です。同じIDの行が重複することもありません。そのため、比較の基準を持たない絶対的な閾値で判定しています。 絶対的な閾値であれば、異常な状態が続いている限り毎日アラートが鳴ります。過去の値と比べる方式では、異常な状態が数日続くとその値が新しい基準になり、アラートが止まってしまうことがあります。 行数 行数は、配信テーブルに入っているembeddingの本数です。この指標は、embeddingが配信テーブルに届いているかを見るためのものです。 行数が0になる原因として、上流のデータの欠落や、絞り込みの条件による全件の除外、書き込みのキーの不一致などが考えられます。いずれもジョブ自体は成功扱いで終わることがあるため、ジョブの監視では気づけません。 閾値は0本です。本数の異常としてはもっとも極端な値ですが、A/Bテストのたびに入れ替わる全モデル種別で同じ閾値を使えるよう、この値にしています。本数が大きく増減したかどうかは、行数トレンド比で捉えます。 NULL率 NULL率は、配信テーブルのembeddingのうち、破損したものが占める割合です。embeddingそのものがNULLの行と、要素にNULLやNaNを含む行などを、破損したembeddingとして数えています。 NULL率 = 破損したembeddingの本数 ÷ 配信テーブルのembeddingの本数 この指標は、推論の一部が失敗したまま書き込まれていないかを見るためのものです。推論が一部の行で失敗しても、ジョブ全体は成功扱いで終わることがあります。その場合、失敗した行のembeddingは破損したまま配信テーブルに書き込まれ、推薦に使えないembeddingが配信されます。 閾値は0.1%です。正常時はほぼ0なので、1,000本に1本以上破損したembeddingが混ざっていれば、何らかの処理の不具合を疑います。 ゼロベクトル率 ゼロベクトル率は、全要素が0のembeddingが占める割合です。 ゼロベクトル率 = 全要素が0のembeddingの本数 ÷ 配信テーブルのembeddingの本数 この指標は、形式としては正しいものの、中身のないembeddingが書き込まれていないかを見るためのものです。全要素が0のembeddingはNULLやNaNを含まないため、NULL率では数えられません。一方で、ユーザーのembeddingであればどの商品との内積も0になり、商品のembeddingであればどのユーザーとの内積も0になります。そのため推薦には使えません。embedding生成ジョブの一部が失敗し、値の入っていない初期値のまま書き込まれた場合などに発生します。閾値はNULL率と同じく0.1%です。 鮮度 鮮度は、配信テーブルへの最後の書き込みから検査時点までの経過時間です。この指標は、書き込みが止まっていないかを見るためのものです。 閾値は、書き込みが止まってから気づくまでの最大の遅れから決めました。検査は1日1回なので、書き込みが止まってから気づくまでには、閾値に最大24時間を加えた時間がかかります。閾値を24時間にすると最大48時間、12時間にすると最大36時間です。差分更新は毎時動くため、正常に動いていれば経過時間は12時間を大きく下回ります。そこで、正常時と十分に区別でき、検知の遅れも短くできる12時間を閾値にしました。 次の図は、閾値ごとに、書き込みが止まった時刻と、それを検知する検査の関係を示しています。 正常時の経過時間には余裕があるため、閾値は12時間よりさらに短くできます。短くするほど、書き込みが止まった日のうちに検査で捉えられる場合が増え、翌日の検査まで持ち越される場合が減ります。一方で、差分更新が一時的に遅れただけでもアラートが鳴りやすくなります。各推薦機能がどの程度の鮮度を求めているかを確かめながら、段階的に閾値を下げていく必要があります。 主キー重複 主キー重複は、配信テーブルで同じユーザーIDや商品IDが重複している余分な行の数です。 主キー重複 = 行数 − 重複を除いたIDの数 この指標は、1つのユーザーや商品に対して、embeddingが1つだけ配信されているかを見るためのものです。差分更新の入力に同じIDが複数含まれていると、同じユーザーや商品の行が重複して書き込まれることがあります。重複があると、各推薦機能がembeddingを結合したときに行が増え、同じ商品が重複して推薦されるおそれがあります。正常時は0なので、1行でも重複があれば異常と判断します。 行数トレンド比 行数トレンド比は、当日の本数を、直近7日の本数の中央値で割った値です。 行数トレンド比 = 当日の行数 ÷ 前日までの直近7日の行数の中央値 この指標は、本数が0にならないまま大きく増減していないかを見るためのものです。本数が直近の水準から大きく変動した場合は、上流のマスタデータの更新が遅れた、データを絞り込む条件が変わった、といった可能性があります。6つの指標のうち、これだけは過去の値と比べています。 比較の基準に中央値を使っているため、直近7日の中に一時的な増減を含んでも、基準はその影響を受けにくくなっています。履歴が7日分たまるまでは判定しません。 ベクトル空間の監視 ベクトル空間の観点では、embeddingの崩壊を検知するため、空間の構造を表す次の3つの指標を計算しています。いずれの指標も、全件ではなくサンプリングしたembeddingで計算しています。全件で計算すると、ベクトル同士を掛け合わせる計算が多くなり、毎日の実行には重すぎるためです。 指標 対象 何を見ているか 実効次元 ユーザー・商品 ベクトルを構成する次元のうち、実質何本の軸にばらつきが乗っているか kNN purity@10 商品 近い10商品のうち、同じカテゴリの商品の割合 alignment 商品 同じ商品の色違い同士の類似度 次の図は、3つの指標が見ているものを、正常な空間と異常な空間で比べた模式図です。 実効次元 実効次元は、embeddingのベクトルを構成する次元のうち、実質的に何本の軸にばらつきが乗っているかを表す指標です。ユーザーと商品それぞれで計算します。この指標は、embeddingのばらつきが少数の軸に潰れていないかを見るためのものです。 正常に学習できたembeddingでは、ユーザーや商品の違いが複数の軸に分散して表現されます。一方、embeddingが崩壊すると、ばらつきが1〜2本の軸に集中します。図の左列下段のように、点が1本の線の上に並んだ状態です。この状態ではどのユーザーのembeddingも似た向きになるため、どのユーザーにも似た商品が推薦されます。 実効次元には、共分散行列の固有値の散らばりから求めるparticipation ratioを使っています 1 。 participation ratio = (固有値の和)^2 ÷ (固有値の二乗の和) すべての軸に均等にばらついていれば次元数に近づき、1本の軸に集中していれば1に近づきます。 ただし、実効次元だけでは捉えられない異常もあります。実効次元は、ばらつきがいくつの軸に広がっているかしか見ていません。たとえば意味のない乱数のようなembeddingでも、ばらつきは多くの軸に広がるため、値は高くなります。空間の中身が意味のある構造を保っているかは、次のkNN purity@10とalignmentで確かめます。 kNN purity@10 kNN purity@10は「ある商品の近傍10商品のうち、同じカテゴリの商品が占める割合の平均」と定義しています。 kNN purity@10 = 平均(近い10商品のうち、同じカテゴリの商品の数 ÷ 10) この指標は、商品の空間が、カテゴリという意味のまとまりを保っているかを見るためのものです。カテゴリには、商品マスタに登録されている商品の分類を使っています。商品のembeddingが正常であれば、トップスの近くにはトップスが、スニーカーの近くにはスニーカーが集まります。図の中央列上段のように、同じカテゴリの商品がまとまっている状態です。商品の空間が崩れると、近くにさまざまなカテゴリの商品が混ざり、この値が下がります。 反対に、値が高いほど良いわけでもありません。近い10商品がすべて同じカテゴリになると、推薦も同じカテゴリの商品に偏り、ユーザーが新しい商品に出会う機会が減ります。どの程度のまとまりが適切かは、モデルの特性によって変わります。一方で値が低すぎる状態は、モデルにかかわらず空間が崩れていることを表すため、下限を閾値にしています。 alignment alignmentは「同じ商品の色違い同士のembeddingのcosine類似度の平均」と定義しています 2 。 alignment = 平均(同じ商品の色違いペアのcosine類似度) この指標は、本来近くにいるべき商品のペアが、実際に近くにいるかを見るためのものです。kNN purity@10がカテゴリという大きなまとまりを見るのに対して、alignmentは個々の商品の単位で、空間の細かい構造が保たれているかを見ています。 色違いの商品はデザインや用途がほぼ同じなので、正常な空間では近くに位置するはずです。商品の空間が崩れると、色違い同士が無関係な商品と同じくらい離れ、この値が下がります。alignmentも、高ければ良いわけではありません。色違い同士のembeddingが完全に重なると、色違いのスコアがそろって高くなるため、推薦に同じ商品の色違いばかりが並ぶおそれがあります。ただし値が低すぎれば空間が崩れているため、kNN purity@10と同じく下限を閾値にしています。 なお、kNN purity@10とalignmentは商品のembeddingだけで計算しています。ユーザーには、商品のカテゴリや色違いに相当する、近くにいるべき相手の手がかりがないためです。ユーザーのembeddingについては、実効次元に加えて、推薦スコアの分布で見ています。推薦スコアについては、後の「 推薦スコアの監視 」で詳しく説明します。 推薦スコアの監視 推薦スコアの観点では推薦の傾向の急変を検知します。推薦品質の変化は直接測れないため、推薦スコアの分布の変化から捉えます。そのために推薦スコアをBigQuery上で再現し、比較基準の日の分布と比べています。 BigQuery上での推薦スコアの再現 推薦スコアは、ユーザーと商品をそれぞれサンプリングし、ユーザーごとに類似度の高い上位10商品をBigQueryの VECTOR_SEARCH 関数 で求めて再現します。上位10商品に絞ることで、各推薦機能が実際に推薦する商品に近い範囲の推薦スコアを見ています。この方法であれば、各推薦機能のシステムに手を加えず、SQLだけで完結します。 PSIによる比較基準との差の計測 推薦スコアの分布と比較基準の日の分布を、Population Stability Index(以下、PSI) 3 で比べています。PSIは2つの分布がどれだけずれているかを1つの数値で表す指標です。KS検定やWasserstein距離も候補にしましたが、区間ごとの件数を数えるだけで計算でき、BigQueryのSQLで簡単に書けるPSIを選びました。 PSIは、比較基準の日の推薦スコアを同じ割合ずつの区間に分け、当日の推薦スコアが各区間に入る割合のずれを足し合わせた値です。 PSI = Σ(当日の割合 − 比較基準の割合)× ln(当日の割合 ÷ 比較基準の割合) 分布がまったく同じなら0になり、ずれが大きいほど値が大きくなります。閾値は0.5に置いています。この値にした理由は「 閾値の考え方 」で説明します。 PSIとは別に、推薦スコアの上位1%・中央値・下位1%も毎日記録しています。これらには閾値を置かず、PSIのアラートが鳴ったときの切り分けに使います。 比較基準の持ち方 REPでは同じモデル種別でも再学習のたびにembeddingが新しい世代に変わります。この世代をembeddingバージョンと呼びます。 比較基準の分布はモデル種別ごとに1世代だけ持っています。embeddingバージョンごとには持たず、日々の再学習で比較基準を更新することもありません。再学習やバージョンの切り替えで分布に異常が起きたことこそ、この監視で検知したいためです。バージョンごとに比較基準を取り直すと、異常なバージョンの分布が新しい比較基準になってしまいます。 比較基準を定期的に更新する運用もしていません。毎日再学習しているモデルでは比較基準が古くなるにつれて、分布との差が少しずつ開きます。ただし比較基準が古くなって起きるのは、異常がないのに鳴る誤検知です。崩壊を見逃す方向には働かないため、定期的に更新しなくても検知したいものは検知できます。鳴ったときに意図した変化だと確認できれば、その時点で比較基準を取り直します。 閾値の考え方 3つの観点の閾値はいずれも、正常時にはまず出ない値に置いています。日々の小さな揺れでは鳴らさず、いつもと大きく違う動きをしたときだけ鳴らす方針です。配信データの閾値は各指標の項で説明したので、以降ではベクトル空間と推薦スコアの閾値を決めた経緯を説明します。 記録から決めたベクトル空間の下限 ベクトル空間の3指標は、導入当初はアラートを鳴らさず記録だけにしていました。これらの指標を本番の監視に使うのは初めてで、正常時の値の水準も、日々の揺れの大きさも分かりませんでした。初めて使う指標にいきなり閾値を置くと、誤検知を招きかねません。 記録を続けた結果、3つの指標とも正常時はほぼ横ばいで推移すると分かりました。そこで正常時の値と、崩壊したときに理論上とる値の間に下限を置き、アラートに切り替えました。たとえば実効次元は、崩壊すると1に近い値まで下がります。正常時の値はそれよりはるかに高いため、間に下限を置けば崩壊を検知できます。kNN purity@10とalignmentも同じ考え方です。 上限の閾値は置いていません。各指標の項で述べたように、値が高すぎる状態も良いとは限りませんが、どこからが高すぎるかはモデルの特性によって変わり、正常な値との境目を決められないためです。モデル種別ごとに値の水準が違うのは、空間の性質が違うためで、品質の優劣は表しません。 また3つの指標とも、計算できなかった日もアラートを鳴らします。商品マスタからカテゴリを取得できないなどの理由で計算できないままにすると、その間に空間が崩れても気づけないためです。 ユーザーと商品を平均した表示の落とし穴 ダッシュボードを作った当初、実効次元をユーザーと商品で分けずに平均して表示していました。その結果、ユーザーの実効次元が商品の実効次元よりかなり低いことに気づかず、ユーザーの値に近すぎる位置へ閾値を置いていました。ユーザーと商品を分けて表示して初めて、ユーザーの値が日々の揺れで閾値を割りかねないと分かりました。そこで閾値を下げました。 背景・課題で、デプロイ判定はテストデータ全体を1つの数値にまとめた評価値しか見ていないと書きました。監視を作った私たち自身も、ダッシュボードで同じ落とし穴にはまっていたことになります。性質の異なるものを1つの数値にまとめると、片方の異常がもう片方に埋もれます。指標を集約して表示するときは、何と何を混ぜているかを確認する必要があります。 PSIの一般的な目安との違い 推薦スコアのPSIは、導入当初は一般的な目安を参考に閾値を0.2に置いていました。PSIには「0.1未満は変化なし、0.1〜0.25は中程度の変化、0.25以上は大きな変化」という広く使われる目安があります。 この目安は信用スコアリングの実務に由来する経験則です 4 。信用スコアリングのモデルは一度作ると長期間使い続けるのが一般的です。その前提で、モデルを作った時点からデータがどれだけずれたかを測るための目安です。PSIの値はサンプルの件数や区間の数によっても変わります。そのため私たちは、この目安をそのまま使うのではなく、監視するモデルの性質に合わせて閾値を決めるべきだと考えました。 REPのモデルは毎日再学習しますが、推薦スコアの分布の動き方はモデル種別の特性によって違います。日々のPSIはおおむね小さい一方、揺れの大きいモデル種別では、embeddingバージョンが切り替わった日に一般的な目安を超えることを実際に観測しました。一般的な目安のままでは、異常がないこの日にもアラートが鳴ります。 これに対して崩壊が起きた場合は推薦スコアが一部の区間に集中し、空になる区間が生まれます。空の区間があるとPSIは大きく跳ね上がるため、日々の揺れとははっきり区別できます。そこで閾値を0.5に上げ、崩壊に相当する急変だけを検知する位置に置きました。 揺れ方の違いは推薦スコアに限らず、実効次元にも表れます。揺れの小さいモデル種別に合わせて閾値を詰めると、揺れの大きいモデル種別だけが頻繁に鳴ります。そのためどのモデル種別でも正常時には届かない値を、閾値の基準にしています。揺れの大きいモデル種別の利用を終えれば、推薦スコアの閾値をさらに下げられる見込みです。 運用設計 運用は「人が動くのは通知が来たときだけ」という原則で設計しました。人の作業が多い監視は忙しい時期に確認が途切れ、続かなくなるためです。 通知を起点にした対応 品質の数値はダッシュボードで見られるようにしましたが、人が毎日ダッシュボードを確認する運用にはしていません。定期的なレビューもしていません。 人の習慣だけに頼る監視では、確認が途切れた時期に空間が崩壊すると、数週間気づけない可能性があります。そのため異常に気づく役割はアラートに任せています。 ダッシュボードは3つの観点に対応した3つのセクションで構成しており、アラートが届いたときに原因を調べる場所として使います。ほかにもモデルを変更した直後の状態の確認や、関係者にembeddingの状態を説明するときにも使えます。 モデルの入れ替えへの追従 REPではA/Bテストのたびに新しいモデル種別の配信が始まり、テストが終わると配信を止めます。REPの本番導入から約2か月で4本のA/Bテストを実施しており、モデル種別は頻繁に入れ替わります。モデル種別が入れ替わるたびに監視の設定を変える運用では、作業が漏れたときに監視されないモデルが配信されることになります。そこでモデル種別が入れ替わっても、監視の設定を変えなくてよい仕組みにしました。 監視の対象は配信が有効になっている全モデル種別です。A/Bテストで比較のために配信している新しいモデル種別も、配信が有効になった時点で自動的に監視対象に入ります。比較のためのモデル種別も一部のユーザーに実際に配信されており、そのembeddingの品質が下がれば、そのユーザーへの推薦の質も落ちるためです。 ただし推薦スコアの監視だけは、比較基準がないとPSIを計算できません。比較基準のないモデル種別は推薦スコアの統計だけを記録し、アラートは鳴らしません。現在は新しいモデル種別の配信が始まったら手作業で比較基準を作っています。今後は配信開始の初日に、比較基準を自動で作る予定です。 モデル種別の利用を終えるときも、監視のための手順はありません。配信を止め忘れたモデル種別は、書き込みが止まったまま監視対象に残るため、鮮度の指標が閾値を超えてアラートが鳴ります。止め忘れに気づく仕組みを、既存の指標がそのまま担っています。 推薦スコアのアラートの切り分け 推薦スコアのアラートで分かるのは、分布が大きく変わったことだけです。意図したモデル改善をした場合でも鳴ることがあるため、鳴ったときは何が起きたかの切り分けから始めます。 この点で、配信データやベクトル空間のアラートとは扱いが異なります。配信データとベクトル空間は、正常なembeddingではまず取らない値に閾値を置いているため、鳴ればほぼ異常と判断し、上流の処理やembedding生成ジョブのログから原因を調べます。 推薦スコアのアラートの切り分けには、ベクトル空間の3指標と推薦スコアの統計の推移を使います。代表的な状況と、考えられる原因および対応の例は次のとおりです。 状況 考えられる原因 考えられる対応 実効次元が急落した、または上位1%の推薦スコアが1.0に張り付いた 学習の事故による崩壊 健全なモデル種別へ配信を切り替え、前の世代のモデルでembeddingを再生成する ベクトル空間の指標は平常で、直近にモデルや特徴量の変更があった 意図した変化 モデルを開発したチームに想定どおりか確認し、想定どおりなら比較基準を取り直す ベクトル空間の指標は平常で、変更もなかった その日の学習だけ分布がずれた 記録して様子を見る。翌日以降も続けば再判断する ベクトル空間の指標は平常で、下位1%の推薦スコアだけが下がった 一部のユーザーのembeddingの品質低下 スコアの低いユーザーを特定し、特徴量の欠損など、そのユーザーの上流のデータを調査する 問題が起きたときの対処としては、前の世代のモデルでのembeddingの再生成、再学習、直近のリリースの取り消し、健全なモデル種別への配信の切り替えなどが考えられます。監視の役割は、こうした対処が必要なタイミングを知らせることです。 導入効果 異常なembeddingの検知 以前はジョブが成功扱いで終わっていれば、配信テーブルのembeddingの品質が下がっていても、誰も気づけませんでした。ビジネス指標に影響が出て初めて、原因を探し始める状態でした。 現在は配信データの6指標、ベクトル空間の3指標、推薦スコアの分布を、配信が有効な全モデル種別について毎日検査しています。たとえば書き込みが止まった場合は、最大でも36時間以内にアラートが届きます。配信データとベクトル空間のアラートであれば、鳴った時点で原因の範囲もかなり絞り込めます。 embeddingの状態の説明 embeddingは数値の並びであり、中身を見ても良し悪しは分かりません。以前は「毎日きちんと更新されている」以上のことを、embeddingを作っている私たちも説明できませんでした。 現在は毎日蓄積される指標から、embeddingの状態を説明できます。たとえばユーザーのembeddingは商品のembeddingより少ない軸で違いを表現していることが分かりました。商品の空間がカテゴリや色違いのまとまりを保っていることも、数値で確かめられます。またモデル種別によって、推薦スコアの分布が日々揺れやすいものと揺れにくいものがあることも、PSIの推移から分かりました。モデルを変更した直後に、新しいモデルがどのような空間を作っているかを確認する場面でも使えます。 今後の展望 運用を続ける中で、この監視だけでは捉えられないことも見えてきました。 まず推薦スコアの監視で分かるのは、分布が「変わった」ことまでです。推薦が「悪くなった」かどうかは分かりません。現在はベクトル空間の指標やモデルの変更履歴と突き合わせて、人が切り分けています。 ベクトル空間と推薦スコアの閾値は、運用しながら置いた暫定の値です。今後はアラートが鳴った日の推薦の品質を確認した記録をためて、どの程度の変化が推薦の劣化につながるのかを見極めます。そのうえで閾値を見直していきます。 最後にこの監視で分かるのはembeddingの異常の有無と、その状態の推移までです。embeddingが推薦のタスクにどれだけ適しているかまでは評価できていません。embeddingを使う推薦機能が増えるほど、embedding自体の良さを測る評価軸が必要になります。この評価軸の整備にも取り組んでいきます。 まとめ 本記事では複数の推薦機能に配信するembeddingの品質を監視する仕組みを紹介しました。 embeddingを複数の推薦機能で共有すると、異常が起きたときの影響がすべての機能に広がります。それにもかかわらず、既存の監視はジョブの成否やデプロイ判定、ビジネス指標しか見ておらず、配信テーブルのembeddingそのものを検査する監視はありませんでした。 そこでembeddingで起こりうる障害をデータとしての破損、ベクトル空間の崩壊、推薦の傾向の急変の3つに整理しました。それぞれに対応させて、配信データ・ベクトル空間・推薦スコアの指標を設計しました。仕組みはBigQueryのscheduled queryだけで構築し、異常時は既存の通知経路でSlackに知らせています。運用は「人が動くのは通知が来たときだけ」という原則で設計し、モデルが入れ替わっても監視の設定を変えなくてよい仕組みにしました。 結果として異常なembeddingに気づける体制ができ、これまで説明できなかったembeddingの状態も数値で説明できるようになりました。 本記事で紹介した知見が、embeddingを複数のシステムで共有している方や、MLモデルの出力の品質監視を検討している方の参考になれば幸いです。 最後に、ZOZOでは一緒にサービスを作り上げてくれる方を募集中です。ご興味のある方は、以下のリンクからぜひご応募ください。 corp.zozo.com Peiran Gao et al. "A theory of multineuronal dimensionality, dynamics and measurement." bioRxiv, 2017. https://www.biorxiv.org/content/10.1101/214262v2 ↩ Tongzhou Wang and Phillip Isola. "Understanding Contrastive Representation Learning through Alignment and Uniformity on the Hypersphere." ICML 2020. https://proceedings.mlr.press/v119/wang20k.html ↩ Bilal Yurdakul and Joshua Naranjo. "Statistical properties of the population stability index." The Journal of Risk Model Validation, 14(4), 2020. https://doi.org/10.21314/JRMV.2020.227 ↩ J du Pisanie and IJH Visagie. "On testing the hypothesis of population stability for credit risk scorecards." ORiON, 36(1), 2020. https://doi.org/10.5784/36-1-678 ↩
はじめに 「生成AIを導入すれば、組織の生産性は上がるのか」——現場でDXを推進するマネージャーや、日々の業務でAIを使いながらどこか違和感を抱いているエンジニア・知識労働者の方も多いのではないでしょうか。 私が担当しているプロダクトの開発チームでも、AIコーディングツールを導入しています。しかし導入後、生成されたコードが十分に確認されないままプルリクエストとして上がり、レビューで差し戻すというやり取りが何度も発生しました。コードを書く速度は上がったはずなのに、レビューと手戻りに追われ、少なくとも私には、チーム全体の生産性はAI導入前より下がっているように感じました。 こうした経験を
ランサムウェア攻撃者の本当の目的とは? ランサムウェア対策を考えるうえで、最初に理解しておきたいのが攻撃者の目的です。

動画

書籍