「association rule」は統計データ分析の文脈で扱う重要概念のひとつ。 本ページでは「association rule」を取り巻く中核キーワードを以下にチップで一覧化する。 各キーワードは関連する概念・手法・道具立てを含み、 文献検索や学習計画の起点になる。
これらのキーワードは「association rule の理解 → 適用 → 検証」のプロセスを構成する。 各章で詳しく解説する。
🍰 まずはやさしく
セットで売れる組み合わせを探す方法です。
意外な商品のつながりを見つけるために使います。
コンビニで一緒に買われやすいお菓子を探すようなものです。
この章ではルールの基本と評価の方法を学びます。
アソシエーションルール ── 条件付き確率に基づく関連ルール
🍰 まずはやさしく
ネットショップのオススメ機能のような仕組みです。
データのつながりから便利な提案をするために使います。
スマホで買い物をする時に出る「おすすめ」が例です。
このページでは定義から実装までを順番に解説します。
Amazonの「この商品を買った人はこちらも」、 スーパーの陳列最適化、 クロスセル提案――どれもアソシエーションルールが基礎にあります。
本ページでは「association rule」を扱う。 統計データ分析コンペティション (2026) の教材で、 SSDSE-B-2026 (47 都道府県 × 複数年 × 100 超列) の実データを使った再現可能な学習を目指す。
「association rule」は統計・データサイエンスの体系における重要概念のひとつ。 本ページは「定義・直感・数式・実装・落とし穴・関連手法」の 6 視点で構成され、 各視点は独立して読めるが順序通り読むと体系的な理解が得られる。
🍰 まずはやさしく
「Aを買う人はBも買う」という直感的なルールです。
データから意外な組み合わせを発見するために使います。
参考書を買った人が別の教科書も買うような例です。
ここでは具体的な物語や表を使ってイメージを掴みます。
1990 年代、 米国大手スーパー Osco Drug がレシートデータ 120 万件を解析した結果、 金曜夕方に紙おむつとビールを同時購入する人が異常に多い と判明したという逸話があります(厳密には伝説要素も含む)。 「赤ちゃんを寝かしつけた後、 父親が今晩の缶ビールも買いにくる」という仮説が立てられ、 二商品の棚を近づけたところ売上が伸びたとされています。
EC サイトのレコメンドエンジンは、 ユーザーの購買履歴を巨大な「バスケット」とみなし、 アソシエーションルールを使って 意外な共起ペア を抽出します。 例: 統計学の入門書を買った人は、 高確率で R 言語の教科書も買う ── これは support 0.02 / confidence 0.4 / lift 6.0 のような数字で評価されます。
| TID | パン | バター | 牛乳 | ビール | おむつ |
|---|---|---|---|---|---|
| 1 | 1 | 1 | 0 | 0 | 0 |
| 2 | 1 | 1 | 1 | 0 | 0 |
| 3 | 0 | 0 | 1 | 1 | 1 |
| ... | ... | ... | ... | ... | ... |
各行が「1 回のレジ通過 = 1 トランザクション」、 各列が「ある商品が含まれていたかの 0/1 ダミー」です。 アソシエーション分析はこの巨大な 0/1 行列から 「A=1 のとき B=1 になりやすい」 という条件付き構造を見つけます。
本ページでは商品の代わりに 都道府県の特性 をアイテムとして扱います。 47 都道府県 × {高齢化率 (≥中央値), 人口 (<中央値), 出生率 (≦中央値), 全国人口シェア (<中央値)} を 0/1 ダミー化し、 「高齢化率が高い県は人口も少ない」のようなルールを抽出します。 EC バスケットと同じ枠組みで、 公的統計から地域構造を読み解けます。
🍰 まずはやさしく
ルールの強さを数字で表す計算式のことです。
そのルールが本当に正しいか判断するために使います。
部活の道具をセットで買う人がどれくらいいるか数える例です。
ここでは支持度などの3つの指標について詳しく読みます。
アイテム集合 $A, B \subseteq I$($I$ は全アイテム集合)、 トランザクション集合 $\mathcal{T}$ について、 ルール $A \Rightarrow B$ は次の指標で評価します。
| Lift 値 | 解釈 | 具体例 |
|---|---|---|
| > 1 | 正の関連(共起しやすい) | パン → バター (1.33) |
| = 1 | 独立(情報なし) | 天候 → 卵 |
| < 1 | 負の関連(相互排他的) | 紅茶 → 麦茶 (0.6) |
前節の数式は記号が多くて怖く見えますが、 言葉に直すと 「何人中、 何人が、 一緒に買ったか」 という単純な数え上げです。 一つずつ読み解きましょう。
複数指標を併用する理由: Confidence だけ高くてもターゲット顧客が少なければビジネスインパクトはなく、 Lift だけ高くても 偶然の高 Lift(多重比較問題)に騙される。 実務では Support ≥ X% かつ Confidence ≥ Y% かつ Lift ≥ Z の AND 条件でフィルタするのが定番。
スーパーのレジ集計で次のクロス表が得られたとします。
| バター あり | バター なし | 合計 | |
|---|---|---|---|
| パン あり | 400 | 200 | 600 |
| パン なし | 100 | 300 | 400 |
| 合計 | 500 | 500 | 1000 |
→ Lift 1.33 は 「パンを買った人はそうでない人より 33% 余分にバターを買う」 という意味。 Leverage 0.10 は「独立を仮定したときより 100 件多く同時購入が発生」を表します。
公的統計 SSDSE-B-2026 から 47 都道府県の 2023 年データを取り、 A = 高齢化率(65 歳以上人口 / 総人口)が中央値以上、 B = 総人口が中央値未満とダミー化します(中央値: aging=31.78%、 pop=1,549,000 人)。
| B(人口少) | ¬B(人口多) | 合計 | |
|---|---|---|---|
| A(高齢化高) | 17 | 6 | 23 |
| ¬A(高齢化低) | 6 | 18 | 24 |
| 合計 | 23 | 24 | 47 |
→ Lift = 1.51 は 「高齢化率が高い県は、 ランダム抽出より 51% 多く人口少県に該当する」。 Confidence 0.739 は「高齢化高の県のうち約 74% が人口少県」。 地方部の人口減少と高齢化が同時進行している統計的構造が、 たった 2 つのダミー変数の表から読み取れます。
n=10,000、 ある稀少商品 X (Support 0.001) と 別の稀少商品 Y (Support 0.001) が偶然 2 件だけ同時購入。 Support(X∩Y)=0.0002、 Confidence(X⇒Y)=0.2、 Lift=200。 一見強烈なルールに見えるが、 サンプル数が 2 では 偶然 の域を出ません。 必ず Support と組み合わせ閾値で枝刈り する習慣を。
最後にもう一段階深く、 SSDSE-B-2026 から抽出された具体的なルール 6 件を取り上げ、 Support / Confidence / Lift の数字を一つひとつ「人間語」に翻訳する。 抽象的な指標の話を、 47 都道府県という馴染みあるサンプルで体感したい。
| # | ルール | Support | Confidence | Lift | 解釈 |
|---|---|---|---|---|---|
| R1 | pop_low ⇒ aging_high | 0.362 | 0.739 | 1.51 | 人口が少ない県は高齢化率も高い。 地方圏で人口減と高齢化が同時進行する典型構造。 |
| R2 | aging_high ∧ pop_low ⇒ share_small | 0.362 | 1.000 | 2.04 | 高齢化高かつ人口少の県は、 全国人口シェアも例外なく小さい。 Confidence 1.00 の完全含意で Lift も最大。 |
| R3 | aging_high ⇒ birth_low | 0.298 | 0.609 | 1.24 | 高齢化が進む県は出生率(出生数/総人口)も低め。 Lift 1.24 とやや正の連関。 |
| R4 | pop_low ⇒ birth_low | 0.234 | 0.478 | 0.98 | 人口の少なさと出生率の低さはほぼ独立(Lift≈0.98<1)。 代表ルール中で唯一 Lift が 1 を下回り、 共起は偶然期待とほぼ同じ。 |
| R5 | share_small ⇒ aging_high | 0.362 | 0.739 | 1.51 | 全国人口シェアの小さい県は高齢化率が高い。 share_small は pop_low と同一集合のため R1 と完全一致する。 |
| R6 | aging_high ⇒ pop_low | 0.362 | 0.739 | 1.51 | R1 の逆方向。 Lift は対称で同値だが、 Confidence の意味(どちらを条件に置くか)が変わる点に注意。 |
A1101(総人口)・A1303(老年人口)・A4101(出生数)から作った 4 ダミー(aging_high / pop_low / birth_low / share_small)に対して算出した検証済みルールから採っている。 SSDSE-B-2026 に存在しない指標(県内総生産・完全失業率など)は使っていない。 Support / Confidence / Lift の値は ②・⑤ の実行結果と一致する(2023 年 47 都道府県で再計算・検証済み)。 注意点: R5 の share_small(人口シェア中央値未満)は pop_low(総人口中央値未満)と数学的に同一の集合になるため、 R5 は R1(0.362 / 0.739 / 1.51)と完全一致する。 また R4「pop_low ⇒ birth_low」は Lift≈0.98<1 で、 人口の少なさと出生率の低さはほぼ独立(正の連関ではない。 実測 2×2 表 11 県 ≒ 独立期待 11.3 県、 χ²≈0・p≈1.0)。 「人口減・少子・高齢の三重苦」のうち統計的に強く結び付くのは 高齢化↔人口減 であり、 出生率低との共起は弱い点に留意する。最も基本となるルール R1「pop_low ⇒ aging_high」(およびその逆方向 R6)を例に、 47 都道府県の生データから Support / Confidence / Lift がどう計算されるかを手で追ってみる。 使うのは実在列 A1101(総人口)と A1303(老年人口)から作った 2 ダミーだけ。
この計算で重要なのは「独立なら何件起きるはずか」を出して、 実際の件数と比べているところ。 Lift はこの比率そのもの。 47 県という小規模サンプルでも、 この共起は χ² 検定で χ²=9.37・p=0.0022(本ページ Python ④ の出力)と有意になり、 偶然ではない構造だと確認できる。
代表 6 ルールの中で R4「pop_low ⇒ birth_low」だけが Lift≈0.98 と 唯一 1 を下回る。 これは何を意味するか? 人口が少ない県と出生率が低い県の共起は偶然期待とほぼ同じ(独立)で、 正の連関はない。 R2(Lift 2.04)や R5(1.51)のように明確に共起する組み合わせとは対照的で、 「人口が少ない ⇒ 出生率も低い」という直感は 2023 年データでは支持されない。
具体的に: 人口が中央値未満の県は 23 件、 そのうち出生率も中央値未満は 15 件。 もし独立なら 23 × (23/47) = 11.3 件のはずなので、 実際は +3.7 件多い。 これは「人口減の県は出生数も細る」傾向を反映しているが、 沖縄のように人口が中位でも出生率が高い県などの例外が混じるため Lift が伸びない。 こうした「例外が分布を引き下げる」現象も、 Lift の数字だけ追っていると見落とす。
Lift の大小だけでは「その共起が統計的に偶然でないか」は判定できない。 そこで各ルールの 2×2 分割表に χ² 検定をかける。 検証済みの R1/R6(aging_high ⇔ pop_low)を例にとると:
一般に Lift が 1 から離れるほど χ² も大きくなり p 値は小さくなるが、 両者は別の尺度である。 Lift が 1.3 程度の弱いルール(R4 など)は、 47 県という小標本では χ² 検定で有意水準に届かないこともある。 だから「Lift だけでなく χ² も併記」して、 統計的な裏づけの有無を明示する習慣をつけたい。
ダミー変数を増やして数百〜数千のルールを一斉に χ² 検定にかけ、 p < 0.05 のものを「有意」として採用すると、 N 件のルールに対しおよそ N × 0.05 件が偶然に有意判定されて紛れ込む。 Bonferroni 補正では p の閾値を 0.05/N まで厳しくして、 全体(ファミリー単位)での偽陽性率を 5% 以下に抑える。 これを適用すると弱い共起のルールははじき出され、 Lift も χ² も大きい強いルールだけが「真に有意」として残る。 安全側に倒すなら必須の処理。
アソシエーションルール分析は「バスケット分析」のイメージが強いが、 実は 6 つの業界で全く違う形で使われている。 ここでは各業界の代表的なユースケース 4 件ずつ、 計 24 件を一覧化する。 自分の業務に近い行を探して「何を item 化すべきか」のヒントにして欲しい。
| 業界 | ユースケース | トランザクション | アイテム | 期待される発見 |
|---|---|---|---|---|
| 小売 | 棚配置最適化 | レシート 1 枚 | 商品 SKU | 共起率の高い商品を近接配置 |
| クロスセル推薦 | 注文 1 件 | カテゴリ | バンドル販売の組み合わせ | |
| 廃番判断 | 月間売上 | 商品 + 顧客属性 | 特定属性に依存する商品 | |
| 来店時刻×商品 | レシート+時刻 | 商品+時間帯 | 朝コーヒー × パン などの組合せ | |
| 医療 | 併用薬リスク | 処方箋 1 枚 | 薬剤コード | 相互作用のある併用パターン |
| 合併症パターン | 入院 1 回 | ICD-10 病名 | 同時診断されやすい疾患の組 | |
| 検査値異常組合せ | 受診 1 回 | 検査値(区間化) | 特定疾患を示唆する複合異常 | |
| 副作用報告 | FAERS 1 件 | 薬剤 + 副作用 | 既知+未知の副作用シグナル | |
| Web | 回遊パス分析 | セッション 1 回 | 閲覧ページ | CV につながる回遊パターン |
| CV ファネル改善 | ユーザー単位 | 行動イベント | CV 前のキーアクション | |
| 検索クエリ共起 | セッション内検索群 | 検索語 | 関連語提案・拡張 | |
| 広告クリック傾向 | セッション | クリック広告 ID | 効果的なバナーセット | |
| 金融 | 不正取引検知 | 取引 1 件 | 特徴量(区間化) | 高 Lift の組合せ=不正パターン |
| 商品クロスセル | 顧客 1 人 | 保有商品 | 保険+投信などの組合せ | |
| 解約予兆 | 顧客 1 人+月 | 取引行動 | 解約前の行動パターン | |
| ポートフォリオ分析 | 投資家 1 人 | 保有銘柄 | 同時保有されやすい銘柄群 | |
| 公共統計 | 地域類型化 | 都道府県 1 件 | 指標(区間化) | 類似指標の地域グループ |
| 政策評価 | 市区町村×年 | 政策+アウトカム | 政策と成果の共起傾向 | |
| 災害脆弱性 | 地区 1 件 | 物理+社会指標 | 複合的脆弱性パターン | |
| 人口動態 | 国勢調査メッシュ | 年齢×職業 | 移動が起きやすい属性組合せ | |
| 製造 | 不良連鎖検知 | 製品 1 個 | 検査項目 | 同時に不良になる項目組 |
| 設備故障パターン | 設備×時間窓 | センサーアラート | 故障前の共起アラート | |
| サプライチェーン | 発注 1 件 | 部品コード | 一緒に注文される部品セット | |
| 品質特性連動 | ロット 1 件 | 工程パラメータ | 品質と相関するパラメータ組 |
24 件を眺めると、 「トランザクションをどう定義するか」と「アイテムをどう設計するか」が業界ごとにまったく違うことが分かる。 これがアソシエーションルール分析の汎用性と、 同時に難しさの源泉。 ライブラリは Apriori / FP-Growth で共通化できても、 「何を行と列にするか」の設計は業務知識が握っている。
アソシエーションルール分析は古典手法だけに、 複数言語で複数のライブラリが乱立している。 実装を選ぶときの目安として、 主要な 7 ライブラリを「対応アルゴリズム」「速度」「可視化」「ドキュメント」の 4 軸で比較する。
| 言語 | ライブラリ | 対応アルゴリズム | 速度 | 可視化 | 使い分け |
|---|---|---|---|---|---|
| Python | mlxtend | Apriori, FP-Growth | 中 | なし(自作) | 学習・小〜中規模・教育用途の定番 |
| Python | PyCaret | Apriori 内包 | 中 | 基本グラフ内蔵 | AutoML パイプラインに組み込みたいとき |
| Python | efficient-apriori | Apriori 最適化版 | 高 | なし | 数百万トランザクション向け |
| R | arules | Apriori, Eclat | 高 | arulesViz 連携 | 研究・統計分析・可視化重視 |
| R | arulesSequences | 系列パターン | 中 | 基本 | 時系列イベント分析 |
| Java | SPMF | 160+ アルゴリズム | 高 | CLI のみ | 最新アルゴリズム検証・ベンチマーク |
| Scala/Spark | MLlib FP-Growth | FP-Growth 分散版 | 最高 | 外部連携 | 10億トランザクション以上 |
教育用途や小〜中規模分析なら mlxtend、 統計検定や高度な可視化が必要なら arules + arulesViz、 100 万件超の本番運用なら Spark MLlib FP-Growth、 最新研究を試したいなら SPMF ── という選び方が無難。 本サイトでは教育目的から mlxtend を採用しているが、 同じ結果が R でも再現できるはず。
| トランザクション数 | アイテム種類 | 推奨実装 | 想定時間 |
|---|---|---|---|
| 〜1万 | 〜100 | mlxtend Apriori | 数秒 |
| 10万 | 数千 | mlxtend FP-Growth | 数十秒 |
| 100万 | 〜1万 | efficient-apriori / arules | 数分 |
| 1000万〜 | 数万 | Spark MLlib | 十数分〜時間 |
「いまの mlxtend が遅くなった」と感じたらまず FP-Growth に切り替え、 それでもダメなら efficient-apriori、 さらにダメなら Spark へ移行する流れが定石。 ただし移行には時間とコストがかかるので、 最初から十分なスケーラビリティを見越して設計したい。
本文中の FAQ では基本 5 問を扱ったが、 ワークショップ等で初学者から繰り返し質問される 6 問を追加で整理する。
最初に「Support × Lift × χ² の p 値」の 3 点で機械的に絞り込み(例: Support > 0.05、 Lift > 1.3、 p < 0.01)、 残ったルールを Lift 降順で並べる。 上位 20 件だけを目視で確認し、 業務知識で残すかを判断する。 全件読もうとしない。
主な原因は (1) min_support の閾値の解釈差(相対値か絶対件数か)、 (2) アイテム集合の最小サイズの違い、 (3) Confidence のカウント方法(双方向で重複出力するか否か)、 (4) 浮動小数の丸め誤差。 同じ閾値設定なのに違う場合はドキュメントを必ず確認。
(1) 候補ルール「X⇒Y」を抽出 → (2) ランダムに割り当てた A 群には X の購入時に Y をレコメンド、 B 群には何もしない → (3) 一定期間後、 両群の Y 購入率を比較 → (4) z 検定か Bayesian A/B test で差を検証 → (5) 効果量と CI を報告。 ルールがデータマイニング由来でも、 介入の効果は実験で確認する原則は変わらない。
月次か四半期で再抽出し、 Support と Lift の変化を時系列で追う。 Support が半減した/Lift が 1 を下回ったルールは「死んだ」と判断して入れ替える。 「ルールのライフサイクル管理」を最初から運用設計に組み込む。
まず PCA や階層クラスタリングで「似たアイテム」をグループ化し、 グループ単位のアソシエーション分析を行う。 全 SKU を直接放り込むと候補集合が爆発する。 また min_support を高め(0.05 以上)に取って大物だけを残す。
数式や Lift の話は最小限にして、 (1) 1 行のルール例(「商品 A を買った人は 9 割が商品 B も買う」)、 (2) ルールを使った施策の予想売上効果(「年間 +XX 万円」)、 (3) A/B テストの結果(「対照群比 +X%」)の 3 点に絞る。 統計指標を全部出すと「で、 結局何ができたの?」になりがち。
ここまで読み進めたら、 アソシエーションルール分析の基礎・応用・落とし穴は一通り把握できているはず。 次の学習ステップとして、 以下の 4 つの方向に進むのが効果的。
最終的に、 アソシエーションルール分析は「機械が見つけた仮説の山を、 人間が業務知識と統計検定で絞り込む」協働プロセス。 全自動で施策まで決められる手法ではないが、 仮説生成器としては今でも一級品。 業務側との対話のきっかけとして使うのが正しい。
本サイトでは引き続き、 Apriori, Lift, バスケット分析 などの関連トピックで深掘りを続けて欲しい。 また、 SSDSE-B-2026 を使った相関分析(相関係数)と比較すると、 同じデータから違う知見が出ることに気づくはず ── アソシエーションは「カテゴリ的共起」、 相関は「連続的共変動」を測る、 という補完関係を体感できる。
アソシエーションルールは「同時購入の発見」だけでなく、 メニュー設計・棚配置・キャンペーン計画など実務の意思決定を支える。 以下の 5 原則は、 SSDSE-B-2026 や POS データを使った教育現場・現場運用で繰り返し効いた知見である。
この 5 原則を守れば、 「ルールは出たけど打ち手にならない」という典型的失敗 (lift 過信、 支持度過小、 季節性無視) を避けられる。 SSDSE-B-2026 都道府県データで「人口規模 × 産業構造 × 観光客数」のクロスを切り出すと、 観光業依存県の特徴的バスケットが浮かび上がる。 教育現場では、 まず 3 変数 × 3 ビンの単純な設定から始めて、 学習者にルール解釈を体験させると効果的である。
本概念は、 SSDSE-B-2026 都道府県データのような実データを扱うあらゆる場面で重要な役割を果たす。 統計分析・機械学習モデリング・ビジネス意思決定のすべての段階で、 本概念の理解度がアウトカムの質を決定づける。 教育現場での活用としては、 まず基本定義を踏まえた上で、 SSDSE データを使った具体的演習を通じて概念を定着させ、 次に発展的応用課題で深掘りするカリキュラム設計が効果的である。 学習者は単に公式を覚えるのではなく、 「なぜこの概念が必要か」「どのような場面で誤用が起きるか」「どう他の概念と接続するか」を体系的に理解することが求められる。
実務適用においては、 ドメイン専門家との密な連携が成功の鍵となる。 本概念を技術者だけで運用すると、 ビジネス価値とのギャップが生じやすい。 定期的なレビュー、 結果の可視化、 ステークホルダーとの対話を通じて、 概念の適用が実際の意思決定改善につながっているかを継続的に検証することが重要である。 また、 関連用語・派生手法との位置関係を明確にし、 過去の文脈・現代の応用・将来の発展形を一連の知識体系として捉えることで、 本概念の真価が発揮される。
アソシエーションルールマイニング (Apriori, FP-Growth) では膨大なルールが生成される。 ルールを「使える順」に並べ替えるための主要指標 3 つを、 SSDSE-B 都道府県データの「特定の人口・産業構成パターン」に当てはめて読み直す。
ルール A ⇒ B における trans (A ∧ B) の総 trans に対する割合。 つまり「データ全体で A も B も同時に観察された頻度」。 SSDSE-B-2026 で「人口 100 万未満 ⇒ 高齢化率 30% 超」というルールを考えると、 47 都道府県のうち何件が両方に該当するかを 47 で割った値が support になる。 一般に support が低すぎるルール (例: 0.01 未満) はノイズの可能性が高く、 まず support の閾値で粗くフィルタする。
P(B | A) = trans (A ∧ B) / trans (A)。 「A が起きたとき、 どれだけの割合で B も起きるか」を示す。 SSDSE で「人口 100 万未満 ⇒ 高齢化率 30% 超」が confidence 0.85 なら、 「人口 100 万未満の県の 85% は高齢化率 30% 超」と読める。 ただし B が極めて頻出するなら confidence は自動的に高くなるので、 単独では誤判定する。
P(B | A) / P(B)。 1 を超えれば A の発生で B の発生確率が押し上げられている (正の関連)、 1 未満なら抑制方向、 1 ちょうどなら独立。 lift は「B 単独の発生確率」を base line に置くので、 confidence が見落とすケースを救う指標。 SSDSE-B-2026 で B = 高齢化率 30% 超の base rate を 0.55 とすると、 上のルールの lift = 0.85 / 0.55 ≈ 1.55 で、 「人口 100 万未満を見ると高齢化率 30% 超が 1.55 倍効きやすい」と解釈できる。
カテゴライズして trans を組み立てれば、 都道府県データでも association mining が成立する。 たとえば「人口階級 (S/M/L)」「産業構成 (第 1 次・2 次・3 次の最大シェア)」「高齢化率階級」を各都道府県のフラグ集合とし、 47 trans の market basket に見立てると、 「第 1 次産業優位 ⇒ 高齢化率 35% 超 (conf 0.8, lift 1.6)」のようなルールが取れる。 単純な相関係数では拾えない条件付きパターンを発見するのが利点。
Amazon, Netflix, YouTube などの「これも買っています/見ています」推薦は、 アソシエーションルールマイニング (ARM) の代表的応用。 (1) 協調フィルタリング (Collaborative Filtering) は 1995 GroupLens の発展系、 (2) Item-based (Sarwar 2001) はユーザー類似度より計算効率的、 (3) Matrix Factorization (Netflix Prize 2006-2009) で精度向上、 (4) 近年は Neural Collaborative Filtering で深層学習統合。 ARM は説明可能性が高く、 NCF はスケール性が高い、 という両極端を補完的に使う。
通常の ARM は集合演算 (A, B が同時に発生) だが、 順序を考慮する Sequential Pattern Mining: GSP, PrefixSpan, SPADE。 例: 「ノート PC を購入 → 30 日以内に外付け HDD」「映画 X を視聴 → 続編 Y を視聴」のような順序関係。 SSDSE-B-2026 は時系列がないが、 仮想的に「2020 年人口減少県 → 2026 年高齢化県」のような時系列 ARM を考察可能。
Apriori は支持度の単調性で剪定するが、 高次元 (10,000+ アイテム) では候補爆発。 FP-Growth (Han 2000) は FP-tree で線形時間に近い性能、 RElim (Borgelt 2005)、 LCM (Uno 2004) が高速。 大規模 e-commerce では Apache Spark の MLlib FPGrowth が標準。 SSDSE-B-2026 の 47 都道府県 × 100 指標規模では Apriori で十分。
無限に流入するイベントストリームから「最近のホット」ルールを発見する必要がある場合、 (1) Sliding Window: 過去 N 分のルール、 (2) Damped Window: 時間減衰、 (3) Landmark: 固定起点。 Lossy Counting, Sticky Sampling などの近似アルゴリズム。 リアルタイム異常検知、 IoT センサー連携、 不正検知などで応用。
(1) Anti-monotonic 制約: 価格が一定以下、 (2) Monotonic 制約: 利益が一定以上、 (3) Succinct 制約: 特定カテゴリ含む、 (4) Convertible 制約: 数学変換で扱える。 SSDSE-B-2026 で「人口減少率 5% 以上の県のみ」のような制約付き ARM が可能。
ソーシャルネットワーク、 引用ネットワーク、 知識グラフでの「頻出部分グラフマイニング」は ARM の拡張。 gSpan (2002), Gaston (2004), MoSS。 「同じ研究テーマの研究者は同じ大学に所属」「同じ趣味の人は同じ地域に住む」のようなパターン発見。
support, confidence, lift に加えて: (1) Leverage = P(A ∩ B) - P(A) × P(B)、 (2) Conviction = P(A) × P(¬B) / P(A ∩ ¬B)、 (3) Jaccard = |A ∩ B| / |A ∪ B|、 (4) Cosine = P(A ∩ B) / √(P(A) × P(B))、 (5) Phi = (P(A ∩ B) - P(A)P(B)) / √(P(A)P(B)P(¬A)P(¬B))。 タスクと文脈に応じて選ぶ。
通常 ARM は相関ベースだが、 因果アソシエーション (Cooper 1997, Spirtes 2000) は do-calculus で因果効果を推定。 「政策 A を実施した県 → 5 年後の人口維持」のような因果関係を観察データから推定する手法。 SSDSE-B-2026 で「DX 投資と労働生産性」の因果関係を ARM + IV (操作変数) で分析可能。
(1) mlxtend は教育的、 Apriori, FP-Growth, Association Rule mining の標準実装、 (2) efficient-apriori はメモリ効率、 (3) pyECLAT は ECLAT アルゴリズム、 (4) Apache Spark MLlib は分散処理。 SSDSE-B-2026 で都道府県を「basket」、 各指標を「item」として ARM 実行可能。
「都道府県 = basket、 (i) 人口減少率 5% 以上、 (ii) 高齢化率 35% 以上、 (iii) 第 1 次産業優位 = item」として ARM を実行。 例えば「(i, ii) → (iii) は support=0.15, confidence=0.85, lift=1.7」と読み取れる。 ベン図と組み合わせて 47 都道府県の構造を視覚化。 教育教材として極めて有効。
ARM ルールは「IF A THEN B (support, confidence, lift)」と明示的なので、 XAI の代表的な手法の一つ。 (1) Decision Tree ルール抽出、 (2) RuleFit (Friedman 2008)、 (3) Anchors (Ribeiro 2018) などの XAI 手法は ARM と概念的に類似。 ブラックボックス AI (深層学習) を ARM で近似することで、 「なぜそう判断したか」の説明が可能になる。
文書集合の単語共起ネットワーク、 N-gram 共起、 トピックモデル (LDA, BERTopic) は ARM と概念的に隣接する。 (1) 単語 trans = 文、 item = 単語として ARM 適用、 (2) 「医療」と「AI」が同時に出る論文集合の特徴抽出、 (3) ニュース記事の「政策 → 経済指標」連想分析、 (4) SNS の「ハッシュタグ共起」分析 (Instagram, Twitter) など、 産業界・行政・研究で幅広い。 SSDSE-B-2026 の都道府県データに自由記述レポートを組み合わせれば、 多モーダル ARM の教材になる。
(1) 1993 Agrawal, Imielinski, Swami が IBM Almaden で AIS アルゴリズム発表、 (2) 1994 Agrawal & Srikant が Apriori で剪定法を確立、 (3) 1995 Park, Chen, Yu の DHP でハッシュ最適化、 (4) 1996 Savasere, Omiecinski, Navathe の Partition で大規模対応、 (5) 2000 Han, Pei, Yin の FP-Growth で候補生成不要に、 (6) 2003 Wang, Han, Pei の Closed Pattern Mining、 (7) 2010 年代以降は GPU 並列化、 分散計算、 ストリーミング対応へと進化。 30 年以上の歴史を経ても基本概念は変わらず、 教科書的に学ぶ価値が高い。
市場バスケット分析は購買履歴を扱うため、 プライバシー懸念が常に存在する。 (1) Differential Privacy (Dwork 2006) で ε-DP 保証、 (2) Federated Association Rule Mining で分散データを統合せず学習、 (3) Secure Multi-party Computation でクライアント間の暗号化集計、 (4) k-anonymity, l-diversity, t-closeness などの匿名化技法。 EU GDPR, 日本の個人情報保護法、 米国 CCPA への対応は実務で必須。 SSDSE-B-2026 は公開データなのでプライバシー問題は生じないが、 企業実務では中心課題になる。
(1) 小売 (Walmart, セブン-イレブン): 棚配置最適化、 クロスセル、 (2) 金融 (クレジットカード会社): 不正検知、 信用スコアリング、 (3) 医療 (病院): 症状-診断-治療パターン、 副作用検出、 (4) 通信 (NTT, au): 顧客行動分析、 解約予測、 (5) Web (Google, Facebook): クリック・コンバージョン、 (6) 製造 (Toyota, Sony): 不良品連鎖、 工程最適化、 (7) 教育 (e-learning): 学習パターン、 ドロップアウト予測。 業界ごとに「basket」「item」の定義が異なるが、 数学的枠組みは共通。
1993 年 Agrawal の Apriori 以降、 機械学習・深層学習・LLM の発展でも、 アソシエーションルールは「説明可能性の高い」「ドメイン専門家が直感的に理解できる」手法として現役。 SSDSE-B-2026 のような実データで、 ARM の数学的厳密さと業務的実用性を結びつける経験が、 データサイエンス学習者にとって貴重な教材となる。 今後 LLM がデータ分析の主流になっても、 「なぜそのルールが導かれたか」を説明する手段として ARM は残り続けるだろう。
合成バスケットで {おむつ} → {ビール} ルールを評価する (12 件のバスケット)。
| 項目集合 | 出現 | 支持度 |
|---|---|---|
| {おむつ} | 8 | 0.667 |
| {ビール} | 6 | 0.500 |
| {おむつ, ビール} | 5 | 0.417 |
1 2 3 4 5 6 7 8 9 | s_a = 8/12 s_b = 6/12 s_ab = 5/12 conf = s_ab / s_a lift = conf / s_b lev = s_ab - s_a*s_b print(f"conf = {conf:.3f}") print(f"lift = {lift:.3f}") print(f"leverage = {lev:.3f}") |
💬 手計算 (Step 2-4) 0.625 / 1.250 / 0.083 と Python 出力が完全一致。
このラボのテーマは「ルールの探索」です。 個々のルールの指標を電卓のように計算する体験はアソシエーション分析のページにあります。 ここでは一歩進んで、 固定の 12 バスケットから 1 対 1 の候補ルール 20 本をすべて数え上げ、 最小支持度 (min_support) と 最小確信度 (min_confidence) の 2 本のしきい値でルール群がどう絞り込まれるかを体感します。 スライダーを動かす(または散布図のしきい値線を指/マウスでドラッグする)と、 一覧表と散布図がリアルタイムに更新されます。 上げすぎると発見がゼロになり、 下げすぎると lift ≤ 1 のノイズルールが紛れ込む ── このトレードオフがルールマイニングの核心です。
| ルール A ⇒ B | |A∩B| / |A| | support | confidence | lift | 判定 |
|---|
Apriori などのアルゴリズムが内部でやっていることは、 本質的にこのラボと同じです。 ① 候補となる組合せの出現回数を数え、 ② min_support で「そもそも滅多に起きない組合せ」を足切りし、 ③ 残った頻出集合から A ⇒ B の向きを付けて min_confidence(条件付き確率 P(B|A) の下限)で足切りする。 上の表で「|A∩B| / |A|」の列を見れば、 confidence が単なる割り算だと分かります。 デフォルト(0.20 / 0.60)では 20 本中 6 本が採用され、 その筆頭は ビール ⇒ おむつ(support 0.250、 confidence 1.000、 lift 3.00)です。 プリセット「🧱 厳しすぎ」に切り替えると、 このデータの最大支持度が 0.333(パン⇔バター)なので min_support 0.35 には 1 本も届かず発見ゼロになり、 「🌊 ゆるい」では lift < 1 の負の関連ルールまで大量に紛れ込みます。 しきい値の 2 本の線が「発見の量と質」を直接コントロールしていることを、 線をドラッグして確かめてください。
(1) しきい値の恣意性。 min_support / min_confidence には理論的な正解がありません。 このラボでも 0.05/0.30 なら 11 本、 0.20/0.60 なら 6 本、 0.35/0.80 なら 0 本と、 分析者の設定ひとつで「発見」の数が激変します。 実務ではしきい値を複数試す感度分析を行い、 レポートには採用した値を必ず明記します。 「有意になるまでしきい値を下げる」のは p-hacking と同型の誤りです。
(2) 組合せ爆発。 ここでは 5 商品 × 1 対 1 に限定したので候補は 20 本でしたが、 条件部・結論部に複数アイテムを許すと 5 商品でも 180 本、 50 商品では約 7 × 1023 本になり全列挙は不可能です。 min_support による足切り(枝刈り)は「趣味」ではなく、 計算を成立させるための必須の仕掛けです。 さらにルールを大量に検定すれば偶然の「有意」も大量に混じるため、 カイ二乗検定と多重検定補正(本文の Bonferroni の節)が要ります。
(3) リフト無視。 デフォルト設定で採用される 6 本のうち、 バター ⇒ 牛乳は confidence 0.600 で合格に見えますが lift は 0.90、 つまり牛乳の基礎率 0.667 より低い「負の関連」です。 牛乳のような人気商品が結論部にくると confidence は自動的に高く出ます。 チェックボックス「lift > 1 のみ」を入れて、 このルールが弾かれるのを確認してください(リフト値参照)。 逆に ビール ⇒ おむつは lift 3.00 でも該当バスケットは 3 件だけ。 少数件の高 lift は偶然かもしれず、 support と lift の両にらみが欠かせません。
全列挙が不可能な規模で探索を成立させる鍵が Apriori の反単調性(anti-monotonicity)です。 「アイテム集合を大きくすると支持度は決して増えない」ため、 例えば {ビール} 単独が min_support 未満なら、 {ビール, パン} や {ビール, パン, 牛乳} などビールを含む上位集合をすべて数えずに捨てられます。 このラボの縦線(min_support)を右に動かすと点が左側から消えていくのは、 まさにこの枝刈りを 1 対 1 ルールで見ている状態です。 FP-Growth はさらに進んで、 トランザクション全体を FP-tree という圧縮された木構造に 2 回のスキャンで格納し、 候補生成そのものを省いて頻出集合を列挙します(アイテム数が数万を超える EC ログではこちらが定番)。 こうして絞り込んだルールは「この商品を買った人はこちらも」型のレコメンドシステムの説明可能な部品になります。 なお、 採用されたルールはあくまで共起の記述であり、 棚配置やクーポンなどの介入判断には A/B テストによる因果の確認が別途必要です。
このコードでやること: 公的統計 SSDSE-B-2026 から 47 都道府県の 2023 年データを抽出し、 「高齢化率高 / 人口少 / 出生率低」の 3 つの真偽指標を中央値基準でダミー化する(A1101 総人口・A1303 老年人口・A4101 出生数から算出)。
📥 入力データ (SSDSE-B-2026 抜粋):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | import pandas as pd df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932') df = df.iloc[1:] # 1 行目は日本語ヘッダなので除外 df['year'] = pd.to_numeric(df['SSDSE-B-2026'], errors='coerce') pref = df[(df['year']==2023) & df['Code'].str.endswith('000')].copy() for c in ['A1101','A1303','A4101']: pref[c] = pd.to_numeric(pref[c], errors='coerce') pref['aging_rate'] = pref['A1303'] / pref['A1101'] pref['birth_rate'] = pref['A4101'] / pref['A1101'] basket = pd.DataFrame({ 'A_aging_high': (pref['aging_rate'] > pref['aging_rate'].median()), 'B_pop_low': (pref['A1101'] < pref['A1101'].median()), 'C_birth_low': (pref['birth_rate'] < pref['birth_rate'].median()), }).astype(int) print(basket.head()) |
📤 実行結果:
💬 結果の読み方: 47 都道府県 × 3 アイテムの 0/1 行列が完成。 例えば青森県は (A,B,C) = (1,1,1) で「高齢化高・人口少・出生率低」の三重苦タイプ。 これでバスケットデータと完全に同型になり、 mlxtend がそのまま動かせる。
このコードでやること: ①で作った 47 県 × 3 アイテムのバスケットに対し、 mlxtend.frequent_patterns.apriori で頻出アイテム集合、 続いて association_rules でルールを生成し Lift 順に並べる。
📥 入力: ①の basket DataFrame(47 行 × 3 列の 0/1)
1 2 3 4 5 6 7 8 9 | from mlxtend.frequent_patterns import apriori, association_rules # min_support 0.3 = 47 件中 14 件以上で出現するアイテム集合のみ freq = apriori(basket.astype(bool), min_support=0.3, use_colnames=True) rules = association_rules(freq, metric='lift', min_threshold=1.0) rules = rules.sort_values('lift', ascending=False) print(rules[['antecedents','consequents','support','confidence','lift']]) |
📤 実行結果 (主要部分):
※ min_support=0.3(47 件中 15 件以上)かつ lift ≥ 1 を満たすのはこの 2 ルールのみ。 「高齢化高 ⇒ 出生率低」(support 0.298)はわずかに閾値に届かず、 min_support を 0.2 に下げると lift 1.24 で出現する(実測値)。
💬 結果の読み方: トップは 「高齢化率が高い県 ⇒ 人口が少ない県」 で Lift=1.51。 これは「ランダムに県を抽出した場合の 1.51 倍の確率で、 高齢化高県は同時に人口少県でもある」。 逆方向 (B⇒A) も Lift は同じだが Confidence は対称的に解釈する点に注意。
このコードでやること: ライブラリに頼らず、 mlxtend が内部で何をしているかを numpy だけで再現。 結果が②と一致することを確認する。
📥 入力: ①の basket から A=A_aging_high, B=B_pop_low の 2 列だけ取り出す
1 2 3 4 5 6 7 8 9 10 11 | import numpy as np A = basket['A_aging_high'].values B = basket['B_pop_low'].values n = len(A) support = ((A==1) & (B==1)).sum() / n confidence = ((A==1) & (B==1)).sum() / (A==1).sum() lift = confidence / ((B==1).sum() / n) leverage = support - (A==1).mean() * (B==1).mean() print(f'Support={support:.3f}, Conf={confidence:.3f}, Lift={lift:.3f}, Lev={leverage:.3f}') |
📤 実行結果:
💬 結果の読み方: mlxtend の出力と完全一致。 association_rules ライブラリは内部で 「& のビット演算 → sum → 割り算」 をしているだけと分かる。 アルゴリズムの中身がブラックボックスではないことを確認することで、 結果の妥当性検証も自分でできるようになる。
このコードでやること: Lift 1.51 が 偶然 ではなく統計的に有意な共起であることを、 scipy.stats.chi2_contingency で 2×2 分割表のカイ二乗検定により確認する。
📥 入力: ③の A, B(2×2 のクロス表に変換)
1 2 3 4 5 6 7 8 | from scipy.stats import chi2_contingency table = pd.crosstab(basket['A_aging_high'], basket['B_pop_low']) print(table) chi2, p, dof, expected = chi2_contingency(table) print(f'chi2={chi2:.3f}, p={p:.4f}, dof={dof}') |
📤 実行結果:
💬 結果の読み方: p = 0.0022 で p < 0.01、 独立仮説は強く棄却される。 「高齢化高 ⇔ 人口少」の共起は偶然ではない統計的構造。 Lift=1.51 という値に、 χ² 検定の裏付けが加わって解釈の信頼性が大きく増す。 実務では 「Lift だけでなく必ず有意性検定」 を併記するのが望ましい。
min_threshold=0.5 以下で逆検索する設計が必要。基本的な落とし穴は本文上部にまとめたが、 実務で「論文化/本番運用」を意識すると追加で意識しなければならない注意点がある。 8 件にまとめる。
「アソシエーションルール分析を始める」と言われたとき、 何から手をつければよいかを 5 ステップで整理する。 SSDSE-B-2026 のような公的統計データでも、 オンライン小売のログでも、 基本フローは同じ。
| # | ステップ | やること | 注意点 |
|---|---|---|---|
| 1 | 目的と KPI の合意 | 「何を見つけたいか」「効果はどう測るか」を関係者で文書化 | 数字を出すだけのプロジェクトにしない |
| 2 | アイテム設計 | SKU そのまま / カテゴリ / ブランド / 階層的を選択。 連続値はビン化。 | 粒度で結果が劇的に変わる |
| 3 | 頻出集合抽出 | Apriori / FP-Growth / Eclat を選び、 min_support を調整 | 候補爆発に注意(メモリ監視) |
| 4 | ルール評価とフィルタ | Lift, Conviction, χ² で篩い分けし、 業務的に意味あるものを残す | 多重検定補正を忘れない |
| 5 | 施策と効果検証 | A/B テスト等で因果を確認し、 KPI へのインパクトを測定 | ルール≠因果。 必ず実験で確認 |
5 ステップのうち、 多くのチームは「3. 抽出」だけに時間を使い、 1, 2, 4, 5 が手薄になる。 結果として「面白いルールは出たが、 ビジネスに使われない」という典型的失敗が起きる。 重要度の配分は「3 が 30%、 残り 70% を 1, 2, 4, 5 に均等」くらいがちょうど良い。
最終的な実務指針: 「意味のあるルールは少ない」「絞り込みが価値の 8 割」「採用後の効果検証で生き残る」 ── この 3 点さえ守れば、 アソシエーションルール分析は十分実用に耐える。
アソシエーションルールを軸に、 関連概念を上位・並列・派生で整理:
教師なし学習
│
┌────────────────┼────────────────┐
│ │ │
クラスタリング 次元削減 アソシエーション
│
┌─────────────────────────┼─────────────────────────┐
│ │ │
頻出パタン抽出 評価指標 時系列拡張
│ │ │
┌───────┼───────┐ ┌──────┼──────┐ ┌────────┼────────┐
Apriori FP-Growth Eclat Support Confidence Lift GSP PrefixSpan SPADE
│
系列パタン分析
│
┌──────┴──────┐
EC履歴 医療経過
アイテム集合 $X \subseteq Y$ なら $\mathrm{Support}(X) \geq \mathrm{Support}(Y)$ が常に成り立つ。 これは 「Y を含むトランザクションは必ず X も含む」 ためで、 集合が大きくなるほど Support は単調に減少する性質を意味する。
この性質を 逆方向に活用 したのが Apriori の核心:
「ある集合 $X$ が頻出 (Support ≥ min) でなければ、 $X$ を含むすべての上位集合も頻出ではない」
→ 探索木の枝刈りができる。
L₁ ← {頻出 1-itemset} # 1 個ずつアイテムをスキャン
k ← 2
while L_{k-1} ≠ ∅:
C_k ← 候補生成(L_{k-1}) # k-itemset の候補
C_k ← C_k から、 部分集合が L_{k-1} にない候補を除外(枝刈り)
各トランザクションを 1 回スキャンして Support 計算
L_k ← {c ∈ C_k : Support(c) ≥ min_support}
k ← k + 1
return ∪ L_k
5 件のバスケット { {A,B,C}, {A,C}, {A,B}, {B,C}, {A,B,C,D} } で実行:
| ステップ | 候補 | Support | 採否 |
|---|---|---|---|
| L₁ | {A},{B},{C},{D} | 4/5, 4/5, 4/5, 1/5 | D 落選 |
| C₂ | {AB},{AC},{BC} | 3/5, 3/5, 3/5 | 全部採用 |
| C₃ | {ABC} | 2/5 | 採用 (=min) |
| L₃ | {ABC} | 2/5 | 終了 |
D を含む候補 ({AD},{BD},...) は L₁ で D が落ちた時点で 一切評価しない ── これが枝刈りの効果。 もし D の出現が 1 回なら、 {AD},{BD},{CD},{ABD},{ACD},{BCD},{ABCD} の 7 候補を全て省略できる。
Apriori の弱点は「k ごとに DB を再スキャン」「候補生成のコスト」。 FP-Growth はトランザクションを FP-tree(頻出パタン木) として 2 回目のスキャンで構築し、 そこから直接マイニングする。 大規模データで Apriori より 10〜100 倍高速。
FP-tree (例)
root
│
┌────┴─────┐
A:4 B:1
│ │
┌┴──┐ C:1
B:3 C:1
│
C:2
│
D:1
各ノードに「アイテム名 : カウント」が乗り、 同じ接頭辞は共有される。 メモリ上で再帰的にマイニングすれば、 何度も DB を読まなくて済む。 mlxtend, Spark MLlib いずれも FP-Growth 実装を提供している。
| 年 | 出来事 |
|---|---|
| 1993 | Agrawal, Imielinski, Swami が SIGMOD で原典論文を発表。 アソシエーションルール概念の誕生。 |
| 1994 | Agrawal & Srikant が Apriori アルゴリズムを VLDB で提案。 モノトニシティを使った枝刈り。 |
| 1996 | Srikant & Agrawal が GSP(系列パタン)を提案。 |
| 2000 | Han, Pei, Yin が FP-Growthを発表。 候補生成不要・高速化。 |
| 2001 | Pei らが PrefixSpan を発表(系列パタンの高速版)。 |
| 2003 | Zaki らが Eclat を改良。 垂直格納で高速化。 |
| 2014 | Apache Spark MLlib に FP-Growth が標準実装、 ビッグデータ対応が容易に。 |
| 2018〜 | 深層学習推薦が主流化、 アソシエーションは 説明可能性とコールドスタート 用途に役割が再定義される。 |
業界・データ規模により異なる。 EC で 1 万 SKU × 100 万トランザクションなら 0.001〜0.01、 47 都道府県のような小規模なら 0.1〜0.3。 「ルール数が手作業で読める量(10〜100 件)」を目安に二分探索的に調整する。
用途による。 「このルールを使ったレコメンドが当たる確率」を知りたいなら Confidence。 「このペアは特別に共起しやすいか」なら Lift。 実務では両方の閾値で AND フィルタするのが定番(例: Conf ≥ 0.3 かつ Lift ≥ 1.5)。
通常は 離散化(ビニング)して 0/1 ダミーに変換。 本ページの SSDSE 例も「中央値で 2 値化」した。 等頻度ビン、 等幅ビン、 ドメイン知識による境界設定など複数の方法がある。 ビン境界次第で結果が変わるため、 複数設定で頑健性を確認するのが望ましい。
対策: ① 閾値を上げる、 ② Lift 上位 N 件だけ表示、 ③ Closed Itemset(情報を失わずに圧縮した代表)に限定、 ④ ルールクラスタリング(似たアンテシデント/コンセクエントをまとめる)、 ⑤ 可視化(散布図: x=Support, y=Confidence, 色=Lift)。
決定木は 「予測すべきターゲット変数」が決まっていてそれを最大限当てるためのルールを学習。 アソシエーションは 「全アイテムの組み合わせ」を網羅的に探索しターゲット不問。 探索的データ分析でアソシエーション、 教師あり予測で決定木、 と使い分ける。
通常の頻出アイテム集合は冗長({A,B} が頻出なら {A},{B} も自動的に頻出)。 これを抑えるための代表抽出:
FPClose, CLOSET+ などのアルゴリズムが closed itemset を直接マイニング。 ルール数が 1/10〜1/100 に減るため、 出力解釈が現実的になる。
min_support を決めるのが難しい場合、 「Lift 上位 K 件だけほしい」と直接指定するアプローチ。 TopKRules, TKS などのアルゴリズムが該当。 ビジネス側からは「とりあえず面白いルールを 20 件」と指示できる利点。
「コンセクエントに必ず特定商品を含む」「アンテシデントは 3 アイテムまで」など制約付き探索。 mlxtend では association_rules 後にフィルタするが、 SPMF の TopKClassRules などは 探索段階で制約を組み込み高速化 する。
「A を買うと B を買わない」(Lift < 1, 排他的)も重要。 標準 Apriori は頻出パタンしか見ないため、 ネガティブを発見するには $P(A \cap \bar{B})$ の集合に対し別途マイニングが必要。 BookCrossing データで「ハードボイルド読者はラブロマンス読まない」のような排他構造を発見できる。
「年齢 [30-40] かつ 年収 [400-600万] ⇒ 自動車保有」のように 連続値の範囲をアンテシデントに含めるルール。 ビニング境界を 動的に最適化する Srikant & Agrawal (1996) の手法が古典。
「乳製品 ⇒ パン」(カテゴリ階層)と「ヨーグルト ⇒ クロワッサン」(細粒度)を 同じ枠組みで扱う。 階層を上下に動かしながら適切な粒度を見つける。
| 手法 | 入力 | 出力 | アソシエーションとの違い |
|---|---|---|---|
| アソシエーションルール | バスケット (0/1) | A⇒B 形式の関係 | 教師なし、 ターゲット不問 |
| 決定木 | 特徴量+ラベル | 分類規則ツリー | 教師あり、 ターゲット固定 |
| クラスタリング | 特徴量行列 | グループ分け | 関係でなくサンプル群を作る |
| 相関分析 | 連続値ペア | 相関係数 1 つ | 連続値特化、 規則は出ない |
| 協調フィルタリング | ユーザー×アイテム評価 | 未評価予測値 | ユーザー個別予測(規則ではない) |
| 因果推論 | 介入+共変量 | 因果効果 ATE | 介入の効果。 共起と別物 |
横軸 Support、 縦軸 Confidence、 点の色を Lift で染める散布図。 右上にあるほど「広く成立し信頼性も高い」、 色が濃いほど「Lift も高い」。 良いルールは右上+濃色の点。
行=アンテシデント、 列=コンセクエント、 セル=Lift のヒートマップ。 ルール数が多くてもパタンを一目で把握できる。 R の arulesViz::plot(rules, method="matrix") や Python の seaborn.heatmap で実装可能。
ノード=アイテム、 エッジ=ルール、 矢印の太さ=Confidence、 色=Lift。 商品間の関係構造をネットワークとして俯瞰できる。 NetworkX, Cytoscape, Gephi などで描画。
複数アイテムの組み合わせをラインで結ぶ。 「3 アイテム以上のルール」を視覚化するのに有効。
| 目的 | 推奨設定 |
|---|---|
| スーパーのバスケット(数万行) | min_support=0.01, min_confidence=0.3, min_lift=1.2 |
| 医療レセプト(100 万行超) | min_support=0.001, FP-Growth, FDR 補正 |
| 公的統計の地域分析(47 件) | min_support=0.3, min_lift=1.0, χ²検定併用 |
| Web ログ(時系列重要) | PrefixSpan, 系列パタン分析 |
| レコメンド(コールドスタート) | Top-K, 説明可能 Confidence 表示 |
これまでの①〜④を統合し、 SSDSE-B-2026 から「都道府県の構造的ルール」を Top-10 出力する完成版スクリプト。 環境構築 → データ取得 → ダミー化 → Apriori → 結果整形を 1 ファイルで実行できる。
このコードでやること: SSDSE-B-2026 から 4 つの指標(高齢化率、 人口、 出生率、 全国人口シェア)を抽出し、 mlxtend で Lift 上位 10 ルールを出力する完全版。
📥 入力データ: data/raw/SSDSE-B-2026.csv (565 行 × 112 列)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | import pandas as pd from mlxtend.frequent_patterns import apriori, association_rules # 1. データ読み込み df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932').iloc[1:] df['year'] = pd.to_numeric(df['SSDSE-B-2026'], errors='coerce') pref = df[(df['year']==2023) & df['Code'].str.endswith('000')].copy() # 2. 4 指標を計算 for c in ['A1101','A1303','A4101']: pref[c] = pd.to_numeric(pref[c], errors='coerce') pref['aging'] = pref['A1303'] / pref['A1101'] pref['birth'] = pref['A4101'] / pref['A1101'] pref['pop_share'] = pref['A1101'] / pref['A1101'].sum() # 3. 中央値で 0/1 ダミー化(バスケット形式) basket = pd.DataFrame({ 'aging_high': pref['aging'] > pref['aging'].median(), 'pop_low': pref['A1101'] < pref['A1101'].median(), 'birth_low': pref['birth'] < pref['birth'].median(), 'share_small': pref['pop_share'] < pref['pop_share'].median(), }) # 4. Apriori → association_rules → Top-10 freq = apriori(basket, min_support=0.3, use_colnames=True) rules = association_rules(freq, metric='lift', min_threshold=1.0) top10 = rules.sort_values('lift', ascending=False).head(10) print(top10[['antecedents','consequents','support','confidence','lift']]) |
📤 実行結果:
💬 結果の読み方: トップ層は share_small ⇔ pop_low(Lift 2.043)── これは人口シェアが総人口の単調変換であるため share_small と pop_low が同一の集合になることの数学的必然(自明ルール)。 続く 3 要素ルール(aging_high ∩ pop_low ⇒ share_small)も Confidence 1.00 で、 「高齢化高 ∩ 人口少」の県は 100% 全国シェア小。 一方「aging_high ⇔ pop_low」は Lift=1.51 と実質的な連関を示す。 birth_low を含むルールは Lift が 1.0 前後にとどまり Top-10(min_support=0.3)には残らない ── 出生率低との共起は弱い、 というのがデータの示す実態である。
| 値 | バスケット規模別の意味 |
|---|---|
| 0.5+ | 超頻出(コンビニの飲み物等、 ほぼ全員) |
| 0.1〜0.5 | 高頻度(人気商品の組合せ) |
| 0.01〜0.1 | 中頻度(実務的に意味あるルール) |
| 0.001〜0.01 | 稀(医療レセプト等の異常検知) |
| <0.001 | 超稀(偶然と区別困難) |
| 値 | 意味 |
|---|---|
| 1.00 | 完全な含意(A を買うと必ず B も買う) |
| 0.7〜1.0 | 強い含意(実用的ルール候補) |
| 0.3〜0.7 | 中程度(要 Lift 併用評価) |
| <0.3 | 弱い(基本的に不採用、 ただし Lift が極端に高ければ参照可) |
| 値 | 解釈 |
|---|---|
| > 10 | 非常に強い共起(特殊な組み合わせ。 偶然か確認) |
| 3〜10 | 強い共起(実務で有用、 報告レベル) |
| 1.5〜3 | 中程度(多くの実務ルールはここ) |
| 1.0〜1.5 | 弱い正の関連(Support と組み合わせて評価) |
| ≈ 1.0 | 独立(情報なし) |
| < 1.0 | 負の関連(排他、 競合商品など) |
MemoryError / 計算が終わらない原因: min_support が小さすぎて頻出アイテム集合が爆発。 対策: ① min_support を 10 倍に上げる、 ② Apriori → FP-Growth に切り替え、 ③ 稀少アイテムを事前に除去(Support < 0.001 のアイテム削除)、 ④ Spark MLlib で分散実行。
原因: 閾値が厳しすぎ、 またはアイテム同士の共起が薄い。 対策: ① min_support / min_threshold をログスケールで段階的に下げる、 ② num_itemsets=len(basket) を明示、 ③ basket がスパース過ぎないか確認(密度 10% 以下なら閾値見直し)。
TypeError on boolean basket原因: mlxtend は内部で True/False を期待。 int 0/1 を渡すと警告 or エラー。 対策: basket.astype(bool) で型を揃える、 または fpgrowth(basket.astype(bool), ...)。
原因: A⇒B と B⇒A が別ルールとして出力される(Confidence が方向ごとに異なるため)。 対策: 分析目的に応じ、 ① frozenset で antecedent ∪ consequent をキーにユニーク化、 ② antecedent サイズが小さい方だけ保持する、 など後処理で重複除去。
原因: 「人気アイテム同士が機械的に高 Support」現象。 対策: ① ドメイン知識で trivial なルールを除外({食パン}⇒{バター}など自明な組合せ)、 ② Lift とともに Conviction や Kulczynski を併用、 ③ Closed itemset に限定。
「Amazon のレコメンド」は多くがアソシエーションではなく 協調フィルタリング + 行列分解 + 深層学習。 では今なぜアソシエーションを学ぶのか?
| 観点 | アソシエーション | ML 推薦 (CF / DL) |
|---|---|---|
| 説明可能性 | ○ 「Aを買った人の73%がBも買う」 | △ ブラックボックス |
| コールドスタート | ○ アイテムベースで対応 | × ユーザー履歴必須 |
| パーソナライズ精度 | △ 全ユーザー共通 | ◎ 個人最適化 |
| 計算コスト | ○ 軽量(前計算) | △ GPU/大規模学習 |
| スパースデータ耐性 | ○ 強い | △ 行列分解で吸収 |
| 監査・規制対応 | ◎ ルール提示で説明容易 | × SHAP 等の解釈技術必要 |
結論: 現代の推薦システムは 「ML 推薦をメインに、 アソシエーションで補助/フォールバック/説明可能ルール表示」 という ハイブリッドが定石。 また、 規制業界(医療、 金融)では 説明可能性 が要件のため、 アソシエーションが第一選択となることも多い。
R では arules / arulesViz パッケージが定番。 Python (mlxtend) との対応:
| 操作 | Python (mlxtend) | R (arules) |
|---|---|---|
| 頻出アイテム集合 | apriori(basket, min_support=0.05) | apriori(trans, parameter=list(supp=0.05)) |
| ルール生成 | association_rules(freq, metric='lift') | apriori(..., parameter=list(supp=, conf=)) |
| FP-Growth | fpgrowth(basket, ...) | fim4r パッケージ |
| 可視化 | seaborn / networkx | arulesViz::plot(rules) |
| 系列パタン | spmf-py | arulesSequences::cspade |
R 版の方が可視化機能 (arulesViz) が充実しているため、 ルール探索・分析フェーズで R を使い、 本番システム連携で Python (Spark MLlib FP-Growth) を使う、 というハイブリッドも一般的。
SSDSE-B-2026 から 4 指標 (高齢化率高, 人口少, 出生率低, シェア小) を 2 値化し、 min_support=0.3 で Apriori を回した結果の 主要ルール一覧。
| アンテシデント | コンセクエント | Support | Conf | Lift | 解釈 |
|---|---|---|---|---|---|
| 高齢化高 ∩ 人口少 | シェア小 | 0.362 | 1.000 | 2.043 | 三重指標で地方確定 |
| シェア小 ∩ 高齢化高 | 人口少 | 0.362 | 1.000 | 2.043 | 同値(順列違い) |
| シェア小 ∩ 人口少 | 高齢化高 | 0.362 | 0.739 | 1.510 | シェア小∩人口少=人口少(同一集合)なので R1 と一致 |
| 高齢化高 | シェア小 | 0.362 | 0.739 | 1.510 | share_small≡pop_low ゆえ高齢化⇒人口少と同値 |
| シェア小 | 高齢化高 | 0.362 | 0.739 | 1.510 | 対称性(R1 と一致) |
| 高齢化高 ∩ 出生率低 | 人口少 | 0.213 | 0.714 | 1.460 | 少子高齢→人口減 |
| 人口少 ∩ 出生率低 | 高齢化高 | 0.213 | 0.909 | 1.858 | 人口減・少子→高齢 |
| 高齢化高 | 出生率低 | 0.298 | 0.609 | 1.244 | 高齢の県の6割は少子 |
| 高齢化高 | 人口少 | 0.362 | 0.739 | 1.510 | 代表ルール |
| 人口少 | 出生率低 | 0.234 | 0.478 | 0.977 | ほぼ独立(Lift<1、共起は偶然並み) |
share_small(人口シェア中央値未満)は pop_low(総人口中央値未満)と数学的に同一集合のため、 両者を含むルールは自明(Lift 2.043)で新情報を持たない。 「人口少 ⇒ 出生率低」は Lift≈0.98<1(2×2 表 11 県 ≒ 独立期待 11.3 県、 χ²≈0・p≈1.0)で無相関。 したがって「高齢化・人口減・少子化の三重苦が一体で進む」という図式は 2023 年データでは部分的で、 実測上は 高齢化↔人口規模 の連関が中心となる。この分析は 47 サンプルで実施しており、 統計的検出力は限定的。 ルールは 相関構造の記述として読むべきで、 因果関係(例: 高齢化が出生率を下げる)は別途、 自然実験や時系列パネルデータで検証する必要があります。
アソシエーションルール分析の結果を表だけで眺めると、 個々のルールの数字に圧倒されて全体像を見失う。 ここでは SSDSE-B-2026 都道府県 47 件を「高齢化率 高/低」「人口 多/少」「出生率 高/低」「全国人口シェア 大/小」のダミー変数(item)にエンコードしたあと、 算出された Support / Confidence / Lift の分布そのものを 3 つの可視化で見渡す。 こうすると「ほとんどのルールは Lift=1 付近に集中する/一部のルールだけが極端」という構造が一目で分かる。
x 軸に Support、 y 軸に Confidence を取り、 点の色を Lift で塗ると、 右上(高 Support × 高 Confidence)にあるほど「頻出で当たり前のルール」、 左上(低 Support × 高 Confidence)にあるほど「珍しいが起きると確実なルール」だと読める。 SSDSE-B では右上に「人口少 ⇒ 全国人口シェア小」の自明ルールが密集し、 左上に「高齢化率高 ⇒ 出生率低」のような地方構造を映すルールが点在する。
図 r520-1: 抽出されたルールの Support × Confidence 散布図(分布イメージ)。 右上ほど「みんなが知っていて外れない」当たり前のルール。 左上ほど「珍しいが起きると確実」のレアルール。
この散布図を見ずに表だけ眺めると、 Lift=1.5 の中ほどのルールを過大評価しがち。 散布図は「全体に対して、 そのルールが分布のどこに位置しているか」を強制的に意識させる装置として効く。
Lift は「もし前件と後件が独立なら 1」になる指標。 全ルールの Lift 値をヒストグラムにすると、 ほとんどが Lift=1 付近に集中し、 ロングテールで Lift=2 や Lift=3 のルールが少数だけ顔を出す。 これは「大半のルールは独立で意味がない」「本当に意味があるルールは少数の外れ値」という構造を示す。
図 r520-2: 全ルールの Lift 値ヒストグラム(分布イメージ)。 Lift=1 付近に大きな山があり、 Lift>2 の領域はごく少数しかない。
ヒストグラムの「Lift=1 の山」が大きいほど、 そのアイテム集合は実は互いに独立に近い。 つまり association_rules() が大量に出力したルールの 90% 以上は「偶然の共起」に過ぎない可能性が高い。 だからこそ minimum lift threshold(例: lift > 1.2)でのフィルタが実務では必須となる。
前件(antecedent)に含まれる item 数を 1, 2, 3 と変えたとき、 Lift 値の分布がどう動くかを箱ひげで比較する。 一般に前件サイズが増えるほどルールは具体的になり Lift は上がりやすい(ただし Support は下がる)。 SSDSE-B では前件サイズ 2 のときに Lift の中央値が 1.5 付近まで上がるが、 サイズ 3 では Support 不足で外れ値が支配的になる。
図 r520-3: 前件サイズ別 Lift 値分布。 サイズが大きくなるほど Lift は上振れするが、 ばらつきも増える。
この図から学べる実務指針: 「前件サイズは小さく保つ(1〜2 個)」のが解釈性とサンプル数のバランスで最も実用的。 サイズ 3 以上は「面白いが追試できない」傾向にある。
このコードでやること: SSDSE-B-2026 を読み込み、 4 指標を 2 値化し、 mlxtend で Apriori → association_rules を実行、 散布図・ヒストグラム・箱ひげの 3 図を一度に保存する。
📥 入力データ(data/raw/SSDSE-B-2026.csv 抜粋):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | import pandas as pd import numpy as np import matplotlib.pyplot as plt from mlxtend.frequent_patterns import apriori, association_rules # 1. SSDSE-B-2026 を cp932 で読み込み、2 行目の日本語ヘッダを除外 df = pd.read_csv('data/raw/SSDSE-B-2026.csv', encoding='cp932').iloc[1:] df['year'] = pd.to_numeric(df['SSDSE-B-2026'], errors='coerce') pref = df[(df['year']==2023) & df['Code'].str.endswith('000')].copy() # 2. 実在列 A1101/A1303/A4101 から連続量指標を計算 for c in ['A1101','A1303','A4101']: pref[c] = pd.to_numeric(pref[c], errors='coerce') pref['aging'] = pref['A1303'] / pref['A1101'] pref['birth'] = pref['A4101'] / pref['A1101'] pref['pop_share'] = pref['A1101'] / pref['A1101'].sum() # 3. 中央値で 0/1 ダミー化(バスケット形式) basket = pd.DataFrame({ 'aging_high': pref['aging'] >= pref['aging'].median(), 'pop_low': pref['A1101'] < pref['A1101'].median(), 'birth_low': pref['birth'] < pref['birth'].median(), 'share_small': pref['pop_share'] < pref['pop_share'].median(), }) # 4. Apriori → ルール生成 → 3 図を描画 freq = apriori(basket, min_support=0.10, use_colnames=True) rules = association_rules(freq, metric='lift', min_threshold=0.5) rules['ant_size'] = rules['antecedents'].apply(len) fig, axes = plt.subplots(1, 3, figsize=(15, 4.5)) axes[0].scatter(rules['support'], rules['confidence'], c=rules['lift'], cmap='viridis', alpha=0.7) axes[0].set_xlabel('Support'); axes[0].set_ylabel('Confidence') axes[1].hist(rules['lift'], bins=30, edgecolor='black') axes[1].set_xlabel('Lift'); axes[1].set_ylabel('Frequency') axes[2].boxplot([rules[rules['ant_size']==k]['lift'] for k in [1,2,3]], tick_labels=['1','2','3']) axes[2].set_xlabel('Antecedent size'); axes[2].set_ylabel('Lift') plt.tight_layout(); plt.savefig('rules_3figs.png', dpi=120) print('saved:', len(rules), 'rules') |
📤 実行例:
💬 結果の読み方: ルールの大半は Lift≒1(独立、 つまり無意味)に集中し、 意味のある共起はロングテールの少数に限られる。 そこから Lift>1.5 を採用し、 さらに前件サイズを 1〜2 に絞れば「実務で使える」少数のルールが残る。 → アソシエーションルールは「大量に作って、 統計的に絞る」のが正しい使い方。 具体値は 4 指標の中央値 2 値化の結果に依存する(本ページ Python ①〜④ が再現可能な検証済みルール)。
アソシエーションルールの落とし穴は「指標の意味を取り違える」「Support と Confidence と Lift の三角関係を曖昧にする」の 2 点に集約される。 以下 10 問は、 実務で「やってしまいがちな誤解」を狙い撃ちにしている。 1 問 30 秒で解いて、 最後の解説で答え合わせをして欲しい。
| # | 問題 | 選択肢 |
|---|---|---|
| Q1 | Support の定義として正しいものは? | (a) X⇒Y の確率 / (b) X∩Y の出現割合 / (c) X が来たとき Y が来る条件付き確率 / (d) X と Y の独立性 |
| Q2 | Confidence が 1.0 のルールが必ず「強い因果」を示すと言えるか? | (a) はい / (b) いいえ、 Support が低いと意味がない / (c) 必ず Y → X も成り立つ |
| Q3 | Lift = 1 のルールが意味するのは? | (a) 前件と後件が独立 / (b) 100% の確率 / (c) 偶然のレベルを超える共起 |
| Q4 | min_support を下げると何が起きる? | (a) ルール数増加・計算時間増加 / (b) ルール数減少 / (c) Confidence が下がる |
| Q5 | Apriori の「反単調性」とは? | (a) 子集合が頻出でなければ親集合も頻出ではない / (b) 親集合が頻出なら子集合も頻出 / (c) すべての集合は単調増加する |
| Q6 | 連続変数(高齢化率 32.1% など)をそのまま Apriori に投入するとどうなる? | (a) 各値がユニーク item となり Support が極端に小さくなる / (b) 自動的に区間化される / (c) エラーになる |
| Q7 | Lift と相関係数の関係は? | (a) どちらも独立性を 1 や 0 で示す / (b) Lift は相関係数の絶対値そのもの / (c) Lift は方向(正/負)を区別しない |
| Q8 | FP-Growth が Apriori より速い理由は? | (a) tree 構造でデータベース全体を圧縮しスキャン 2 回で済む / (b) GPU を使う / (c) 並列化されている |
| Q9 | 「おむつ ⇒ ビール」伝説が現代でそのまま当てはまらない理由は? | (a) 都市伝説で実証がない / (b) Lift が低かった / (c) min_support が高すぎた |
| Q10 | Conviction の定義は? | (a) (1-Support(Y)) / (1-Confidence) / (b) Support(X∩Y) - Support(X)Support(Y) / (c) Lift と同じ |
| # | 正解 | 解説 |
|---|---|---|
| Q1 | (b) | Support は P(X∩Y) ── 全トランザクション中で X と Y が同時に現れる割合。 確率と紛らわしいが「割合」と覚える方が直感的。 |
| Q2 | (b) | Confidence=1.0 でも Support が極小(例: 0.001)なら、 たった数件の偶然で 100% になっただけ。 サンプル数を必ず併記する。 |
| Q3 | (a) | Lift = P(Y|X)/P(Y) なので、 X と Y が独立なら P(Y|X)=P(Y) となり Lift=1。 1 から離れるほど共起の偏りが強い。 |
| Q4 | (a) | min_support を下げると候補集合が爆発し、 ルール数と計算時間が急増する。 メモリ枯渇の原因 No.1。 |
| Q5 | (a) | 反単調性(Apriori property): 子集合が頻出でない(min_support 未満)なら、 その親集合は絶対に頻出にならない。 これで枝刈りが効く。 |
| Q6 | (a) | 連続変数はそのままだと各値がユニーク item 扱いになり、 Support がほぼ 1/N。 ビン化(区間化)してから投入するか、 中央値で 2 値化する。 |
| Q7 | (c) | Lift は X と Y が「同時に起きやすい度合い」を独立基準=1 で測る。 一方、 相関係数 r は -1 から +1 まで方向を区別する。 Lift >1 は正相関と類似だが値の対応関係はない。 |
| Q8 | (a) | FP-Tree(Frequent Pattern Tree)を 1 回目スキャンで構築し、 2 回目で頻出パタンを再帰的に抽出。 Apriori の k 回スキャンより圧倒的に速い。 |
| Q9 | (a) | Walmart の事例として有名だが、 原典は曖昧で再現報告がない都市伝説。 ただし「直観に反するルール発見」の比喩としては有用。 |
| Q10 | (a) | Conviction = (1-Support(Y)) / (1-Confidence)。 Confidence=1 のとき無限大、 独立のとき 1。 Lift と違って「ルールが破れた頻度」を測る非対称指標。 |
採点目安: 9-10 問正解 = 実務投入レベル、 7-8 問 = 監督下なら OK、 5-6 問 = もう一度本文を読み直そう、 4 問以下 = Support/Confidence/Lift の定義から復習。
アソシエーションルール分析では Support / Confidence / Lift の 3 大指標だけでなく、 状況に応じて 10 種類以上の補助指標が使われる。 以下は実務でよく登場する 11 種類を一覧化したもの。 列「独立時の値」「最大値」「対称性」を併記したので、 自分の分析に合うものを選ぶときの目安にして欲しい。
| 指標名 | 定義式(簡略) | 独立時 | 最大 | 対称性 | 主な用途 |
|---|---|---|---|---|---|
| Support | P(X∩Y) | P(X)P(Y) | min(P(X),P(Y)) | 対称 | 頻度フィルタ |
| Confidence | P(Y|X) = P(X∩Y)/P(X) | P(Y) | 1 | 非対称 | 予測精度 |
| Lift | P(Y|X)/P(Y) | 1 | 1/max(P(X),P(Y)) | 対称 | 独立性検出 |
| Conviction | (1-P(Y))/(1-Conf) | 1 | ∞ | 非対称 | 含意の強さ |
| Leverage | P(X∩Y) - P(X)P(Y) | 0 | 0.25 | 対称 | 独立からの差分 |
| Jaccard | P(X∩Y)/P(X∪Y) | 類似度依存 | 1 | 対称 | 集合類似度 |
| Cosine | P(X∩Y)/√(P(X)P(Y)) | √(P(X)P(Y)) | 1 | 対称 | ベクトル類似度 |
| All-Confidence | P(X∩Y)/max(P(X),P(Y)) | 類似度依存 | 1 | 対称 | 不均衡対策 |
| Kulczynski | (Conf(X⇒Y)+Conf(Y⇒X))/2 | 類似度依存 | 1 | 対称 | 不均衡対称化 |
| χ² 統計量 | Σ(O-E)²/E | 0 | N | 対称 | 統計的検定 |
| 相互情報量 | Σ p(x,y)log p(x,y)/(p(x)p(y)) | 0 | H(X) or H(Y) | 対称 | 情報理論 |
選び方の目安:
① 頻出フィルタ目的なら Support 一択 / ② 「X が起きたとき Y が起きやすいか」を非対称に見たいなら Confidence / ③ 偶然との差を見たいなら Lift か Leverage / ④ クラス不均衡が激しいなら All-Confidence や Kulczynski / ⑤ 統計的に「無相関」を棄却したいなら χ² 検定。
実務では「Support + Lift + χ²」の 3 点フィルタを順に適用するのが定石。
論文や実装ドキュメントを読むときに「これは何だっけ?」と止まらないように、 周辺で頻出する 20 語を一気に整理する。 各語は基準ページの関連語ともリンクしているので、 詳細はリンク先で深掘りして欲しい。
| 用語 | 説明 |
|---|---|
| トランザクション | 一回の購買・閲覧・観測など、 アイテム集合の単位レコード。 レシート 1 枚、 来訪セッション 1 回が典型例。 |
| アイテム / アイテム集合 | トランザクションに含まれる要素単位(商品 ID、 カテゴリなど)と、 その有限部分集合。 |
| 頻出アイテム集合 | min_support 以上の支持率をもつアイテム集合。 Apriori が探索する対象。 |
| 前件 (antecedent) | ルール X⇒Y の X 側。 「条件」や「仮定」と訳されることもある。 |
| 後件 (consequent) | ルール X⇒Y の Y 側。 「結論」や「推論」と呼ばれることも。 |
| Maximal frequent itemset | 部分集合を含まない最大の頻出集合。 出力ルールを圧縮するときに使う。 |
| Closed frequent itemset | Support が同値となる親集合を持たない頻出集合。 Maximal と Frequent の中間表現。 |
| Top-K mining | min_support を明示せず「上位 K 件のルールだけ欲しい」とする変種。 ヒープ管理で効率化する。 |
| Quantitative rule | 「年齢 [30-40)」のように連続値を区間化したルール。 区間境界の決め方が品質を左右する。 |
| Multilevel rule | 「飲料」→「炭酸飲料」→「コカ・コーラ」のような階層構造を含むルール。 |
| Negative association | 「X を買うと Y を買わない」型のルール。 補完財/競合財の検出に有効。 |
| Sequential pattern | 時間順序付きのアイテム列に対するパターンマイニング。 PrefixSpan などが代表。 |
| FP-Tree | トランザクション集合を圧縮するプレフィックスツリー。 FP-Growth の中核データ構造。 |
| Eclat | Equivalence Class Transformation。 ビット集合の交差で Support を求める縦型方式。 |
| Conviction | (1-P(Y))/(1-Confidence)。 Confidence と Lift の中間的役割で「ルールがどれだけ強く含意するか」を示す。 |
| All-Confidence | P(X∩Y)/max(P(X), P(Y))。 X, Y の不均衡に頑健な対称指標。 |
| Kulczynski 指数 | (Conf(X⇒Y) + Conf(Y⇒X))/2。 不均衡データで Lift が暴れるときの代替。 |
| Imbalance Ratio (IR) | |P(X)-P(Y)| / (P(X)+P(Y)-P(X∩Y))。 1 に近いほど不均衡。 |
| バスケット分析 | アソシエーション分析の小売分野での呼び名。 ABC 分析と組み合わせるのが王道。 |
| Curse of dimensionality | item 数が増えると候補集合が指数的に増加し、 計算量と意味のなさが両方爆発する。 |
本ページの用語対照表に一行だけ登場した Kulczynski / Imbalance Ratio / 閉じた頻出集合 を、 実際の数字で動かして補強する追記。 既出の落とし穴(多重比較・人気商品の罠・稀少アイテム)とは別の、 「リフトそのものが持つ構造的な弱点」と「n=47 でルールをどこまで信じてよいか」に焦点を当てる。
例 1 の架空のレシート 1,000 枚(パン 600・バター 500・同時 400)に、 パンもバターも含まないレシートを 9,000 枚継ぎ足して n=10,000 にしてみる。 パンとバターの関係自体は 1 ミリも変わっていないのに、 指標は次のように動く(架空データによる思考実験)。
Lift の分母 $P(A)P(B)$ は「A も B も含まない行」が増えるだけで小さくなるため、 無関係なトランザクションを足すほど Lift は勝手に上がる。 この性質を「null-invariant でない」と呼ぶ。 一方 $\mathrm{Kulc}(A,B) = \tfrac{1}{2}\{P(B \mid A) + P(A \mid B)\}$ と $\mathrm{IR} = |P(A)-P(B)| \,/\, \{P(A)+P(B)-P(A \cap B)\}$ は A・B の行だけから決まるので不変(null-invariant)。 全店舗ログのように「対象カテゴリと無関係なカゴ」が大量に混ざるデータでは、 Lift のランキングは分析対象の切り出し方ひとつで一変する。 Kulc で強さ・IR で偏りを併読し、 Lift は「同じトランザクション集合内での比較」に限って使うのが安全。
手法選択フローで名前だけ出た Closed Itemset の中身。 頻出集合 $X$ が「$X$ と同じ Support を持つ真の上位集合が存在しない」とき閉じた(closed)、 「頻出な真の上位集合が存在しない」とき極大(maximal)と呼ぶ。 極大 ⊆ 閉 ⊆ 頻出 の包含関係にあり、 閉集合だけ保存すれば全頻出集合の Support を無損失で復元できる(極大は個数が最少だが Support 情報を落とす)。
本ページの代表ルール表がまさに好例で、 share_small と pop_low は同一集合のため R5 は R1 の完全な複製だった。 {pop_low} は {pop_low, share_small} と Support が同じ ── つまり {pop_low} は閉じていない ── ので、 閉集合マイニング(mlxtend では fpmax が極大版)を使えばこの種の複製ルールは列挙の段階で自動的に潰せる。 アイテム数が増えるほどルール本数は閉集合ベースで桁単位に減り、 多重比較の母数(検定回数)も同時に減るという一石二鳥の前処理になる。
R1「pop_low ⇒ aging_high」の 2×2 表(17, 6 / 6, 18)は 47 県しかない。 Confidence 0.739 はあくまで点推定で、 二項比率 17/23 の Wilson 95% 信頼区間は [0.535, 0.875] と幅が広い(信頼区間)。 それでも関連の有無自体は、 Fisher の正確検定で p ≈ 0.0012(オッズ比 8.5)、 Yates 補正付き χ² ≈ 9.37(p ≈ 0.0022、 カイ二乗検定)と明瞭に有意。 本ページの 4 ダミーから作れる 1⇒1 の有向ルールは 4×3 = 12 本なので、 Bonferroni 補正後も 0.0012 × 12 ≈ 0.015 < 0.05 で生き残る(多重比較)。
教訓は二つ。 (1) 小標本では「Lift 1.51」の一点だけでなく、 正確検定の p 値と Confidence の区間をセットで報告する(区間はブートストラップでも可)。 (2) 補正の母数は「作り得たルール総数」で数える ── 有意に見えたルールだけ数えて補正すると偽陽性対策にならない。 R1 のように補正後も残るルールだけが、 解釈(相関であって因果ではない)に進む資格を持つ。
アソシエーションルール X⇒Y は、 トランザクション化 → 頻出集合列挙 → ルール生成 → 評価のパイプラインで動く。
SSDSE-B-2026 で「{高齢化率_高, 人口密度_低} → {一次産業_高}」が lift=2.1 で得られた場合、 これは共起構造の記述であって因果ではない点を明示し、 政策議論に使うときの解釈の責任を分離する。
アソシエーションルール抽出の選択は「アイテム数」「希少パターンの重要度」「順序の有無」の 3 軸で判定。
確信度 confidence + リフト lift の 2 指標だけでなく、 conviction (1-support(Y))/(1-confidence) や leverage (P(X∩Y)-P(X)P(Y)) も併用すると redundant rule 除去が容易。