- 技術 💻
多変量解析とは|種類7つと選び方を同じ架空データで実演
結論
多変量解析とは、売上・広さ・駅からの距離のように、たくさんの変数を同時に扱って「何がどれだけ効いているか」「どんなまとまりがあるか」を調べる統計手法の総称です。当てたい値(目的変数)があるなら重回帰分析・ロジスティック回帰・判別分析、ないなら主成分分析・因子分析・クラスター分析、と目的で選びます。変数を1つずつ見ると逆の結論になることがあり、それを防ぐのが多変量解析の大きな役目です。
この記事でわかること
- 多変量解析の種類一覧と、目的と変数の種類から手法を選ぶ手順
- 架空の300店舗のデータに重回帰・ロジスティック回帰・判別分析・主成分分析・因子分析・クラスター分析・MANOVA を当てた実行結果と読み方
- 多重共線性・標準化忘れ・過学習を再現した数値と、自分のデータで1行で確かめる方法
この記事で実際に動かしたもの:乱数で作った架空の飲食チェーン300店舗のデータ(床面積・席数・駅からの距離・駐車場・広告費・周辺人口・売上・黒字かどうか・業態)を、Python 3.13 の作業用の仮想環境で scikit-learn と statsmodels に通し、7つの手法の出力、VIF(分散拡大係数)、過学習の度合い、10万行での計算時間、よくあるエラーの原文を記録しました。
「多変量解析」は、マーケティングの資料・品質管理・医療の論文・機械学習の入門書など、いろいろな場面で出てきます。ところが、重回帰分析も主成分分析もクラスター分析もまとめて「多変量解析」と呼ばれるため、最初に「結局どれを使えばよいのか」で迷いがちです。最初に、手法を選ぶ流れを図で示します。
flowchart TD
A[当てたい値は?] -->|ある| B[値の種類]
A -->|ない| C[目的]
B --> D[量:重回帰<br>2値:ロジスティック<br>区分:判別分析]
C --> G[まとめる:主成分・因子<br>分ける:クラスター]
よく調べられることの答えを先にまとめます。
| 知りたいこと | 答え | 詳しい節 |
|---|---|---|
| 多変量解析とは | 3つ以上の変数を同時に扱い、関係やまとまりを調べる手法の総称 | 多変量解析とは(単変量・2変量との違い) |
| 多変量解析の種類 | 予測する手法(重回帰・ロジスティック回帰・判別分析など)と、要約する手法(主成分分析・因子分析・クラスター分析など) | 多変量解析の種類一覧 |
| 多変量解析の選び方 | 当てたい値があるか、その値が量か2値か区分か、で決める | 多変量解析の選び方 |
| なぜ1つずつ見てはいけないのか | 今回のデータでは、床面積だけを見ると黒字に不利、他の変数と一緒に見ると有利、と逆になった | 多変量解析とは(単変量・2変量との違い) |
| 多重共線性とは | よく似た変数を同時に入れると係数が不安定になる現象。VIF が 55.6 になり、係数の誤差が約4.4倍に | 多重共線性を再現する |
| 主成分分析と因子分析の違い | 主成分分析は情報をまとめる、因子分析は共通の原因を探す。今回は広告費の扱いで差が出た | 主成分分析と因子分析 |
| データは何件必要か | 変数に対して件数が少ないと過学習する。40件・34変数で学習時の決定係数 0.992、検証では −1.233 | 件数と変数の数(過学習)と計算時間 |
| Python でのやり方 | statsmodels(係数と p 値を読む)と scikit-learn(予測・分類・要約)を使い分ける | 最初の5分:架空データを用意して相関を見る |
確認環境:Ubuntu 24.04.5 LTS(カーネル 6.18)の上で、Python 3.13.18 の venv を作業用のフォルダー(/dev/shm/t232)に作り、scikit-learn 1.9.1・statsmodels 0.15.0・pandas 3.0.1・NumPy 2.5.4・SciPy 1.18.1 を pip で入れて実行しました。マシンは CPU 2コアのため、並列処理の指定(n_jobs)は2までにしています。データはすべて乱数で作った架空のもので(作り方のコードは本文に載せています)、実在の店舗・人物のデータは使っていません。手法の前提や引数の意味は、scikit-learn と statsmodels の公式ドキュメントで確かめた範囲で書きました。図は mermaid-cli 11.16.0 で描画を確かめています(確認日 2026年10月29日)。
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「多変量解析とは|種類7つと選び方を同じ架空データで実演」
多変量解析とは(単変量・2変量との違い)
この節では、多変量解析という言葉の意味と、変数を1つずつ見る分析と何が違うのか、なぜわざわざ同時に扱うのかが分かります。
多変量解析(multivariate analysis)とは、1つの対象について測った複数の変数を、ばらばらにではなく同時に扱って、変数どうしの関係や、対象のまとまりを調べる統計手法の総称です。「多変量」は、変数(変わる量)が多いという意味です。1つの変数だけを見る分析を単変量解析(平均・中央値・ヒストグラムなど)、2つの変数の関係を見る分析を2変量解析(相関係数・クロス集計・単回帰など)と呼び、3つ以上を同時に扱うと多変量解析になります。
| 分析の段階 | 扱う変数 | 代表的な手法 | 分かること |
|---|---|---|---|
| 単変量解析 | 1つ | 平均・中央値・標準偏差・ヒストグラム | 売上の分布、外れ値の有無 |
| 2変量解析 | 2つ | 相関係数・散布図・クロス集計・単回帰 | 床面積と売上はどのくらい一緒に動くか |
| 多変量解析 | 3つ以上 | 重回帰・ロジスティック回帰・判別・主成分・因子・クラスター | 他の条件をそろえたときの床面積の効き方、店舗のタイプ分け |
1つずつ見ると逆の結論になる例
多変量解析が必要になる理由を、今回の架空データで示します。「床面積が広い店ほど黒字になりやすいか」を、床面積だけを使ったロジスティック回帰と、駅からの距離・広告費・周辺人口と一緒に入れたロジスティック回帰で比べました。
床面積だけ : area の係数 -0.0150(広いほど黒字になりにくい)
4つの変数を同時に : area の係数 +0.0205(広いほど黒字になりやすい、p=0.0002)
単純な相関係数 : 床面積と黒字 r = -0.35
床面積だけを見ると「広い店は不利」に見えますが、4つを同時に入れると「広い店は有利」に逆転しました。理由は、このデータでは広い店ほど郊外にあり、駅から遠く、周辺人口が少ないためです。床面積だけの分析では、駅からの遠さや人口の少なさによる不利が、すべて床面積のせいにされてしまいます。他の変数の影響をそろえたうえで1つの変数の効き方を見る、というのが多変量解析(特に重回帰・ロジスティック回帰)のいちばんの役目です。
multivariate と multivariable の違い
英語では、目的変数(結果)が複数あるモデルを multivariate、説明変数(原因の候補)が複数あるモデルを multivariable と呼び分けることがあります。この厳密な使い方では、売上という1つの結果を4つの説明変数で説明する重回帰分析は multivariable にあたります。statsmodels の statsmodels.multivariate にある MANOVA(多変量分散分析)は、公式ドキュメントのとおり従属変数を複数(nobs × k_endog)受け取る、狭い意味の multivariate の手法です。
今回のデータで、業態(駅前小型・郊外大型・住宅地)によって「売上」と「広告費」の組がまとめて違うかを MANOVA で確かめました。
type Value Num DF Den DF F Value Pr > F
----------------------------------------------------------------
Wilks' lambda 0.8382 4.0000 592.0000 13.6552 0.0000
Pillai's trace 0.1622 4.0000 594.0000 13.1073 0.0000
Hotelling-Lawley trace 0.1926 4.0000 354.1626 14.2335 0.0000
Roy's greatest root 0.1900 2.0000 297.0000 28.2181 0.0000
Wilks のラムダが 0.8382(1 に近いほど差がない)で、p 値は表示の桁では 0.0000 でした。業態によって売上と広告費の組み合わせに差がある、と読みます。日本語の解説や実務では、重回帰分析も含めて広く「多変量解析」と呼ぶのが一般的なので、この記事も広い意味で使います。論文を読み書きするときだけ、どちらの意味かを確かめると誤解を防げます。
多変量解析の種類一覧(目的変数あり・なし)
この節では、多変量解析の主な手法を「当てたい値(目的変数)があるか」で2つに分けた一覧と、それぞれで何が分かるかが分かります。
多変量解析の手法は、目的変数があって「予測・要因分析」をする手法と、目的変数がなく「要約・分類」をする手法の2つに大きく分かれます。機械学習の言葉では、前者が教師あり学習、後者が教師なし学習にあたります。
目的変数あり(予測・要因分析)
重回帰分析:売上のような量を当てる
ロジスティック回帰:黒字か赤字かのような2値の確率を当てる
判別分析:業態のような区分を当てる
コンジョイント分析・共分散構造分析(SEM)など
目的変数なし(要約・分類)
主成分分析:多くの変数を少ない軸にまとめる
因子分析:変数の裏にある共通の原因を探す
クラスター分析:似た対象をグループに分ける
多次元尺度構成法・コレスポンデンス分析など
| 手法 | 目的変数 | 説明変数 | 主な使い道の例 |
|---|---|---|---|
| 重回帰分析 | 量(売上・点数) | 主に量(質的はダミー変数に) | 売上の要因分析、需要予測 |
| ロジスティック回帰 | 2値(購入した・しない) | 量・質どちらも | 解約予測、合否・発症の確率 |
| 判別分析 | 区分(3つ以上も可) | 主に量 | 顧客の区分の判定、品種の判定 |
| コンジョイント分析 | 好み・選択 | 商品の属性(価格・機能) | どの属性がどれだけ選ばれる理由になるか |
| 共分散構造分析(SEM) | 複数(潜在変数を含む) | 複数 | 満足度とロイヤルティの関係の検証 |
| 主成分分析 | なし | 量 | 多くの指標を総合点や2次元の図にまとめる |
| 因子分析 | なし | 量(アンケートの点数など) | 回答の背景にある「価格重視」などの因子を探す |
| クラスター分析 | なし | 量(標準化して使う) | 顧客・店舗のセグメント分け |
| 多次元尺度構成法・コレスポンデンス分析 | なし | 類似度・クロス集計表 | 商品やブランドの位置関係を図にする |
日本で生まれた「数量化理論」の I〜IV 類も多変量解析の一種で、質的なデータ(はい・いいえ、選択肢)を数値として扱う方法です。おおまかには、I 類が質的な説明変数による重回帰、II 類が質的な説明変数による判別分析、III 類がコレスポンデンス分析、IV 類が多次元尺度構成法に対応します。古典的な教科書やアンケート分析の資料でこの名前が出てきたら、上の表の手法に読み替えると理解しやすくなります。
この記事では、Python で手軽に試せて使われる場面の多い、重回帰・ロジスティック回帰・判別分析・主成分分析・因子分析・クラスター分析・MANOVA の7つを、同じデータに当てて結果を比べます。
多変量解析の選び方(目的とデータの尺度から決める)
この節では、手元のデータと知りたいことから、どの多変量解析を選べばよいかを順番に決める方法が分かります。
選ぶときは「何を知りたいか(目的)」を先に決め、次に「当てたい値はあるか」「その値はどんな種類か」を確かめます。手法から入ると、分析はできても問いに答えていない結果になりやすいためです。
- 1問いを1文で書く「売上の差は何で説明できるか」「店舗はいくつのタイプに分かれるか」のように、答えの形が見える文にする
- 2当てたい値(目的変数)があるか決めるあれば予測・要因分析の手法、なければ要約・分類の手法に絞る
- 3目的変数の尺度を確かめる量なら重回帰、2値ならロジスティック回帰、3つ以上の区分なら判別分析か多項ロジスティック回帰
- 4説明変数の尺度を確かめる質的な変数(業態・地域)はダミー変数に変える。順序のある評価(5段階)はどちらで扱うか決めておく
- 5要約なら作りたいものを決める軸(総合点)なら主成分分析、背後の原因なら因子分析、グループなら クラスター分析
- 6件数と変数の数を見比べる変数に対して件数が少ないなら、変数を減らすか、要約してから予測に使う
データの尺度は、名義尺度(業態・性別のように区別だけ)、順序尺度(満足度の5段階のように順番がある)、間隔尺度(気温のように差に意味がある)、比率尺度(売上・距離のように0に意味がある)の4つに分けて考えます。名義尺度と順序尺度をまとめて質的データ、間隔尺度と比率尺度をまとめて量的データと呼びます。
| 知りたいこと | 目的変数の種類 | 選ぶ手法 | 今回のデータでの例 |
|---|---|---|---|
| 量を予測したい・要因の大きさを知りたい | 量 | 重回帰分析 | 売上を床面積・距離・広告費・人口で説明 |
| 起きる確率を知りたい | 2値 | ロジスティック回帰 | 黒字になる確率 |
| どの区分に入るか当てたい | 区分 | 判別分析 | 業態(3種類)を当てる |
| 指標が多すぎるのでまとめたい | なし | 主成分分析 | 6変数を2つの軸に |
| 回答の背後にある共通の要因を知りたい | なし | 因子分析 | 規模に関わる共通因子 |
| 似たもの同士に分けたい | なし | クラスター分析 | 店舗を3グループに |
| 複数の結果がまとめて違うか確かめたい | 複数の量 | MANOVA | 業態で売上と広告費の組が違うか |
手法は組み合わせて使うこともよくあります。たとえば、主成分分析で変数を少ない軸にまとめてから重回帰分析で予測する、クラスター分析で作ったグループを判別分析で新しい対象に当てはめる、因子分析で得た因子の得点を使ってクラスター分析をする、といった流れです。
最初の5分:架空データを用意して相関を見る
この節では、この記事で使う架空データの作り方と、多変量解析の前にかならず見ておきたい「相関の強い変数の組」をターミナルの1行で確かめる方法が分かります。
多変量解析の前に、単変量(分布・外れ値・欠損)と2変量(相関)を見ておくのが基本の手順です。今回の架空データは、店舗の業態ごとに床面積や駅からの距離の傾向を変えて作りました。売上は「床面積1m²あたり +2.0、距離1mあたり −0.05、広告費1万円あたり +3.0、人口1千人あたり +2.5」に誤差を足した式で作っているので、分析の結果が正しい値に近いかを確かめられます。
import numpy as np, pandas as pd
def make_stores(n=300, seed=232):
rng = np.random.default_rng(seed)
t = rng.choice([0, 1, 2], size=n, p=[0.4, 0.3, 0.3]) # 0駅前小型 1郊外大型 2住宅地
area = np.where(t == 0, rng.normal(80, 12, n),
np.where(t == 1, rng.normal(190, 25, n), rng.normal(120, 18, n)))
seats = 0.45 * area + rng.normal(0, 3, n) # 床面積とほぼ比例
dist = np.where(t == 0, rng.gamma(2, 80, n),
np.where(t == 1, rng.gamma(4, 400, n), rng.gamma(3, 200, n)))
parking = np.where(t == 1, rng.normal(40, 8, n),
np.where(t == 2, rng.normal(12, 4, n), rng.normal(1, 1, n))).clip(0)
ad = rng.normal(30, 8, n).clip(5)
pop = np.where(t == 0, rng.normal(60, 10, n),
np.where(t == 1, rng.normal(25, 8, n), rng.normal(40, 9, n)))
sales = 150 + 2.0*area - 0.05*dist + 3.0*ad + 2.5*pop + rng.normal(0, 45, n)
cost = 200 + 1.6*area + 2.0*ad + rng.normal(0, 40, n)
profit = (sales - cost > rng.normal(80, 30, n)).astype(int)
names = np.array(['駅前小型', '郊外大型', '住宅地'])
return pd.DataFrame(dict(area=area.round(1), seats=seats.round(0), dist=dist.round(0),
parking=parking.round(0), ad=ad.round(1), pop=pop.round(1),
sales=sales.round(0), profit=profit, type=names[t]))
make_stores().to_csv('stores.csv', index=False)
作ったデータの先頭と要約は次のとおりです。area は床面積(m²)、seats は席数、dist は駅からの距離(m)、parking は駐車場の台数、ad は月の広告費(万円)、pop は周辺人口(千人)、sales は月の売上(万円)、profit は黒字なら1です。
area seats dist parking ad pop sales profit type
0 153.0 69.0 3088.0 45.0 17.9 24.0 310.0 0 郊外大型
1 217.2 96.0 847.0 45.0 27.5 21.1 622.0 1 郊外大型
2 178.8 84.0 643.0 44.0 27.7 18.2 633.0 0 郊外大型
3 81.7 37.0 510.0 0.0 34.0 40.1 432.0 0 駅前小型
4 75.4 29.0 141.0 3.0 45.1 55.7 607.0 1 駅前小型
業態の件数:駅前小型 114 / 郊外大型 95 / 住宅地 91 黒字の割合:0.57
自分で確かめる①:相関の強い変数の組をターミナルの1行で出す
CSV のあるフォルダーでターミナルを開く
pandas と NumPy が入った Python が使える状態にする。手元の CSV の名前に合わせて下の stores.csv を書き換える。
相関係数の絶対値が 0.8 を超える組を出す
相関行列の右上半分だけを取り出し、強く一緒に動く変数の組を一覧にする。
出てきた組は、同時に入れるか決める
重回帰やロジスティック回帰に両方入れると、次の節で見る多重共線性が起きやすい。
$ python -c "import pandas as pd,numpy as np;c=pd.read_csv('stores.csv').select_dtypes('number').corr();u=c.where(np.triu(np.ones(c.shape,bool),1)).stack();print(u[u.abs()>0.8].round(2))"
area seats 0.99
parking 0.86
seats parking 0.86
dtype: float64
床面積と席数の相関が 0.99 と、ほぼ同じ情報を持っていることが分かりました。データの読み込みや列の選び方そのものは、関連記事「pandasの使い方 逆引き81選|pandas 3.0の実行結果つき」で扱っています。
重回帰分析:売上を4つの要因で説明する
この節では、多変量解析の代表である重回帰分析を statsmodels で実行し、係数・p 値・決定係数・標準化係数の読み方が分かります。
重回帰分析は、1つの量(売上)を、複数の説明変数の足し算(重み付きの和)で表す手法です。係数は「他の説明変数を同じ値にそろえたとき、その変数が1増えると目的変数がどれだけ変わるか」を表します。statsmodels の OLS は、公式ドキュメントにあるとおり切片(定数項)を自動では入れないため、sm.add_constant で加えます。
import statsmodels.api as sm
X = sm.add_constant(d[['area', 'dist', 'ad', 'pop']])
m = sm.OLS(d.sales, X).fit()
print(m.summary2().tables[1].round(4))
Coef. Std.Err. t P>|t| [0.025 0.975]
const 162.8481 19.8541 8.2022 0.0 123.7744 201.9218
area 1.9467 0.0839 23.2070 0.0 1.7816 2.1118
dist -0.0509 0.0046 -11.1256 0.0 -0.0599 -0.0419
ad 3.0588 0.3252 9.4074 0.0 2.4189 3.6988
pop 2.3351 0.2269 10.2902 0.0 1.8885 2.7817
R2 0.685 adjR2 0.68 n 300
データを作ったときの本当の値(床面積 2.0・距離 −0.05・広告費 3.0・人口 2.5)に近い係数が得られ、どれも 95% 信頼区間([0.025, 0.975] の列)の中に本当の値が入っています。決定係数(R2)0.685 は、売上のばらつきの約69%をこの4つで説明できたという意味です。
| 出力の項目 | 意味 | 今回の値の読み方 |
|---|---|---|
| Coef.(係数) | 他をそろえたとき、1単位増えたときの変化 | 床面積が1m²広いと売上が約1.95万円増える |
| Std.Err.(標準誤差) | 係数の推定のぶれの大きさ | 小さいほど安定。後の節で多重共線性により大きくなる |
| P>|t|(p 値) | 係数が本当は0だとしたら、これほど離れた値が出る確率 | 4つとも非常に小さい |
| [0.025, 0.975] | 係数の 95% 信頼区間 | 0 をまたがなければ、向きはほぼ確か |
| R2・adjR2 | 説明できたばらつきの割合(adj は変数の数で補正) | 0.685・0.680 |
係数の大きさは単位に左右されるので、「どの変数がいちばん効いているか」を比べるときは、すべての変数を平均0・標準偏差1にそろえた標準化係数を見ます。今回は床面積 1.288、距離 −0.538、人口 0.510、広告費 0.309 で、床面積の影響がいちばん大きいと読めます。ただし、これは「このデータの範囲で、他をそろえたときの関連の強さ」であって、床面積を広げれば必ず売上が増えるという因果を示すものではありません。
p 値の意味と誤解しやすい点は、関連記事「p値とは|意味・有意水準・よくある誤解をPythonで実演」で扱っています。係数を求める計算の中身(残差の二乗和を最小にする)は、関連記事「最小二乗法とは|公式・手計算の例とPythonでの求め方を実例で解説」で扱っています。単回帰と重回帰の違いや、ロジスティック回帰の結果の読み方をさらに詳しく知りたい場合は、当ブログの回帰分析の解説記事もあわせて読むと理解が深まります。この記事では、回帰を多変量解析の一つとして、他の手法との使い分けに絞って見ていきます。
多重共線性を再現する(席数を足すと係数が揺れる)
この節では、相関の強い説明変数を同時に入れたときに何が起きるかを実測し、VIF で見つけて直す方法が分かります。
多重共線性(マルチコ)とは、説明変数どうしが強く相関しているために、係数の推定が不安定になる現象です。予測の精度はあまり落ちないのに、係数の大きさや符号が、データの少しの違いで大きく変わります。床面積と相関 0.99 の席数を、先ほどの重回帰に加えてみました。
Coef. Std.Err. t P>|t| [0.025 0.975]
const 162.0802 19.7822 8.1932 0.0000 123.1475 201.0130
area 1.2990 0.3671 3.5388 0.0005 0.5766 2.0213
seats 1.4526 0.8015 1.8124 0.0709 -0.1248 3.0300
dist -0.0513 0.0046 -11.2354 0.0000 -0.0603 -0.0423
ad 3.0613 0.3239 9.4513 0.0000 2.4239 3.6988
pop 2.3369 0.2261 10.3380 0.0000 1.8920 2.7818
R2 0.688
VIF {'area': 55.6, 'seats': 54.4, 'dist': 2.2, 'ad': 1.0, 'pop': 2.3}
決定係数はほとんど変わらないのに、床面積の係数は 1.95 から 1.30 に下がり、標準誤差は約4.4倍に広がりました。席数の p 値は 0.0709 で、「席数は売上と関係ない」と読めてしまいます。実際は、床面積と席数がほぼ同じ情報を分け合っているだけです。
どれだけ不安定になるかを、データを復元抽出(ブートストラップ)で200回作り直して確かめました。
| 係数 | 平均 | 標準偏差 | 最小〜最大 | 負になった割合 |
|---|---|---|---|---|
| 床面積(席数なし) | 1.95 | 0.08 | 1.70〜2.14 | 0% |
| 床面積(席数あり) | 1.32 | 0.41 | 0.13〜2.38 | 0% |
| 席数(席数あり) | 1.41 | 0.89 | −0.88〜4.11 | 6% |
席数を入れると、床面積の係数のぶれは約5倍になり、席数の係数は200回中6%で負(席が多いほど売上が減る)になりました。60店舗だけを取り出した5回の分析では、床面積の p 値が 0.014〜0.207 の間で揺れ、「効いている」と「効いていない」の結論が入れ替わりました。
自分で確かめる②:VIF をターミナルの1行で出す
$ python -c "import pandas as pd,statsmodels.api as sm;from statsmodels.stats.outliers_influence import variance_inflation_factor as v;X=sm.add_constant(pd.read_csv('stores.csv')[['area','seats','dist','ad','pop']]);print({c:round(v(X.values,i),1) for i,c in enumerate(X.columns) if c!='const'})"
{'area': 55.6, 'seats': 54.4, 'dist': 2.2, 'ad': 1.0, 'pop': 2.3}
列の名前を手元のデータに合わせて書き換えれば、そのまま使えます。定数項を加えてから計算する点に注意します(加えないと値が変わります)。statsmodels の公式ドキュメントでは、VIF が 5 を超えると強い共線性がある、という目安が紹介されています。10 を目安にする教科書もあります。
似た変数の扱い
今回は席数を外すと VIF がすべて 3 未満になった
係数の読み方
符号の逆転は共線性のサインであることが多い
ロジスティック回帰と判別分析:黒字・業態を当てる
この節では、目的変数が2値や区分のときの多変量解析として、ロジスティック回帰と判別分析を実行し、オッズ比と正解率の読み方と、2つの手法の違いが分かります。
ロジスティック回帰は、黒字か赤字かのような2値の結果が起きる確率を、説明変数から求める手法です。係数を指数にしたもの(exp)がオッズ比で、「その変数が1増えると、黒字になるオッズ(起きる確率÷起きない確率)が何倍になるか」を表します。
coef p OR
const -5.9356 0.0000 0.0026
area 0.0205 0.0002 1.0207
dist -0.0019 0.0000 0.9981
ad 0.0602 0.0030 1.0620
pop 0.0788 0.0000 1.0820
床面積10m²あたりのオッズ比 1.227 / 距離100mあたり 0.830 / 疑似決定係数 0.309
床面積が10m²広いと黒字のオッズは約1.23倍、駅から100m遠いと約0.83倍になる、と読みます。1単位あたりのオッズ比は1に近くて読みにくいので、意味のある幅(10m²・100m)に直して伝えるのがコツです。
予測の性能は、データを学習用7割・評価用3割に分けて測りました。評価用90店舗での正解率は 0.756、AUC は 0.870 でした。何も考えずに全部「黒字」と答えた場合の正解率は 0.567 なので、それよりはっきり高い値です。
混同行列(行=実際、列=予測。0=赤字 1=黒字)
[[24 15]
[ 7 44]]
判別分析(線形判別分析、LDA)は、各グループの平均がいちばん離れて見える方向を探し、新しい対象がどのグループに入るかを判定する手法です。3つ以上の区分も1回で扱えます。駅からの距離・周辺人口・広告費の3つから業態を当てたところ、5分割の交差検証で平均正解率 0.850 でした。
予測 住宅地 郊外大型 駅前小型
正解
住宅地 24 2 1
郊外大型 6 23 0
駅前小型 4 0 30
郊外大型の6店舗が住宅地と判定されるなど、中間的な住宅地との境目で間違いが出ています。床面積と駐車場も入れると正解率は 0.997 まで上がりましたが、業態を決めた変数そのものを使っているので、当たって当然の結果です。判別に使う変数が、答えを作った情報を含んでいないかは、いつも確かめておきたい点です。
| 比べる点 | ロジスティック回帰 | 判別分析(LDA) |
|---|---|---|
| 出すもの | 確率とオッズ比 | 所属するグループと判別の軸 |
| 前提 | 分布の前提がゆるい | 各グループが正規分布で、ばらつきの形が同じ |
| 黒字の判定(AUC、5分割) | 0.84 | 0.84 |
| 3区分以上 | 多項ロジスティック回帰で対応 | そのまま扱える。判別の軸は最大で区分の数−1本 |
| 向く場面 | 要因の効き方を説明したい | 前提に近いデータで、区分を図で分けて見せたい |
scikit-learn のユーザーガイドにあるとおり、LDA は教師ありの次元削減にも使え、軸の数は区分の数より少なくなります(3区分なら最大2本)。今回の2本の軸は、区分の違いの 98.8% と 1.2% を担っていました。
主成分分析と因子分析:6変数を2つの軸にまとめる
この節では、目的変数がないときの多変量解析として主成分分析と因子分析を実行し、標準化の有無で結果がどう変わるかと、2つの手法の違いが分かります。
主成分分析(PCA)は、たくさんの変数の情報をできるだけ失わずに、少ない数の合成変数(主成分)にまとめる手法です。床面積・席数・距離・駐車場・広告費・人口の6変数に当ててみました。
標準化なし 寄与率 [0.997 0.002 0. 0. 0. 0. ]
PC1 PC2
area 0.045 0.874
dist 0.999 -0.053 ← 第1主成分はほぼ「距離」だけ
...
標準化あり 寄与率 [0.685 0.166 0.062 0.058 0.028 0.002] 累積2つで 0.851
PC1 PC2
area 0.472 0.042
seats 0.471 0.041
dist 0.414 -0.012
parking 0.458 0.033
ad -0.050 0.998
pop -0.414 -0.003
標準化しないと、第1主成分が全体の 99.7% を占め、その中身はほぼ距離だけになりました。距離は数千 m の単位で、ばらつき(分散)が他の変数より桁違いに大きいためです。標準化すると、第1主成分(68.5%)は床面積・席数・距離・駐車場がプラス、人口がマイナスの「郊外の大型店らしさ」、第2主成分(16.6%)はほぼ広告費だけ、と読める軸になりました。第1主成分の平均は、郊外大型 2.66、住宅地 −0.25、駅前小型 −2.02 で、業態の違いをよく表しています。
自分で確かめる③:標準化の有無で寄与率が変わるか1行で見る
$ python -c "import pandas as pd;from sklearn.decomposition import PCA;from sklearn.preprocessing import StandardScaler as S;X=pd.read_csv('stores.csv')[['area','seats','dist','parking','ad','pop']];print(PCA().fit(X).explained_variance_ratio_[:2].round(3),PCA().fit(S().fit_transform(X)).explained_variance_ratio_[:2].round(3))"
[0.997 0.002] [0.685 0.166]
左が標準化なし、右が標準化ありの第1・第2主成分の寄与率です。左の第1主成分だけが極端に大きいなら、単位の大きい変数に引っぱられている可能性が高いと分かります。主成分分析の手順と、寄与率・負荷量の読み方の詳細は、関連記事「主成分分析(PCA)とは|手順・寄与率・負荷量の読み方をPythonで実演」で扱っています。
因子分析は、観測した変数の裏に「共通の原因(因子)」があると考え、その因子を推定する手法です。同じ6変数で、2因子・バリマックス回転の因子分析を行いました。
F1 F2
area 0.983 0.157
seats 0.985 0.142
dist 0.659 0.478
parking 0.806 0.454
ad -0.053 -0.073
pop -0.690 -0.372
第1因子は床面積・席数・駐車場が大きく、「店の規模」と読めます。違いが出たのは広告費です。主成分分析では第2主成分を広告費が1つで占めましたが、因子分析ではどちらの因子にもほとんど載りませんでした。広告費は他の変数と共通する部分がなく、その変数だけの独自の部分として扱われたためです。scikit-learn のユーザーガイドでも、PCA はすべての方向のノイズを同じ大きさと仮定するのに対し、因子分析は変数ごとに異なるノイズの大きさを推定する点が違いとして説明されています。
| 比べる点 | 主成分分析 | 因子分析 |
|---|---|---|
| 考え方 | 変数を合成して要約する(変数→主成分) | 共通の因子が変数を生む(因子→変数) |
| 他と関係の薄い変数 | 1つで主成分になることがある(今回の広告費) | どの因子にも載らず、独自の部分になる |
| 軸の数の決め方 | 累積寄与率(例:8割)で決めることが多い | 固有値や解釈のしやすさで決め、回転させる |
| 向く場面 | 総合点・次元削減・図での可視化 | アンケートの背景にある心理的な要因の推定 |
クラスター分析(k-means):店舗をグループに分ける
この節では、クラスター分析の代表である k-means で店舗をグループに分け、グループの数の決め方と、標準化しないと何が起きるかが分かります。
クラスター分析は、似ている対象どうしを同じグループ(クラスター)にまとめる手法です。答え(業態)を教えずに、6変数だけから店舗を分けられるかを試しました。業態の情報は、分けた結果がどれだけ本当の業態と一致するか(調整ランド指数 ARI。1 で完全一致、0 で偶然並み)を測るときだけ使っています。
| グループ数 k | inertia(小さいほどまとまる) | シルエット係数 | 業態との一致(ARI) |
|---|---|---|---|
| 2 | 802.8 | 0.496 | 0.546 |
| 3 | 629.0 | 0.330 | 0.940 |
| 4 | 533.9 | 0.316 | 0.710 |
| 5 | 467.2 | 0.281 | 0.574 |
| 6 | 413.1 | 0.291 | 0.538 |
シルエット係数(まとまりのよさの目安)は k=2 がいちばん高かった一方、本当の業態に近いのは k=3(ARI 0.940)でした。駅前小型と住宅地が近いため、2つに分けると「郊外大型」と「それ以外」になるのが数値上は自然だったのです。グループの数は、指標だけで機械的に決めず、分けた結果を説明できるか、使い道に合うかで決めるのが大切です。
k=3 の各グループの平均
area seats dist parking ad pop sales
0 80.3 36.2 148.3 1.2 31.2 59.1 546.1 ← 駅前小型 109店 + 住宅地 1店
1 190.6 85.8 1657.6 40.0 29.8 25.5 601.1 ← 郊外大型 95店
2 117.3 53.0 594.4 11.9 29.7 37.4 536.7 ← 住宅地 90店 + 駅前小型 5店
標準化せずに同じ k-means を実行すると、ARI は 0.329 まで下がりました。距離の単位が大きいため、ほぼ距離だけで分けてしまい、駅前小型114店がすべて1つのグループに入る一方、郊外大型は3つに割れました。k-means は距離をもとに分けるので、単位の違う変数を混ぜるときは標準化が欠かせません。scikit-learn のユーザーガイドでは、k-means が「グループが丸く(凸で等方的に)まとまっている」ことを前提にしており、細長い形や入り組んだ形は苦手だと説明されています。初期値によって結果が変わるため、n_init で何度かやり直して最もよい結果を使います。
1k-means
グループの数を先に決めて分ける。大きなデータでも速い。丸いまとまりが前提。
2階層型クラスター分析
近いものから順につなぎ、樹形図(デンドログラム)で全体を見てから数を決める。件数が多いと重い。
3混合ガウスモデル
楕円形のまとまりを扱え、各グループに入る確率を出せる。
4DBSCAN
密度で分け、グループの数を決めなくてよい。どこにも入らない外れ値を見つけられる。
件数と変数の数(過学習)と計算時間
この節では、変数を増やしすぎたときに起きる過学習を数値で確かめ、各手法の計算時間がデータの大きさでどう変わるかが分かります。
変数の数に対してデータの件数が少ないと、学習に使ったデータにだけよく当てはまり、新しいデータでは当たらない「過学習」が起きます。4つの本物の説明変数に、売上と関係のない乱数の変数を10個・30個足して、学習に使ったデータでの決定係数と、5分割の交差検証(学習に使っていない部分)での決定係数を比べました。
| 件数 | 変数の数 | 学習データでの R2 | 交差検証での R2 |
|---|---|---|---|
| 40 | 4 | 0.755 | 0.702 |
| 40 | 14 | 0.871 | 0.488 |
| 40 | 34 | 0.992 | −1.233 |
| 300 | 4 | 0.685 | 0.654 |
| 300 | 14 | 0.692 | 0.640 |
| 300 | 34 | 0.714 | 0.593 |
40件に34変数を入れると、学習データでは 0.992 とほぼ完ぺきに当てはまるのに、交差検証では −1.233 と、平均値で予想するより悪くなりました(R2 がマイナスになるのはその意味です)。300件あれば同じ34変数でも 0.593 にとどまります。乱数の変数でも、入れれば学習データでの決定係数は必ず上がるので、決定係数の高さだけでモデルを選ばず、学習に使っていないデータで確かめることが大切です。件数の目安としては「1変数あたり10〜20件以上」がよく挙げられますが、あくまで目安で、結果の安定性を交差検証で確かめるのが確実です。
計算時間は、同じ作り方で10万店舗のデータも作り、各手法の学習を3回測って最短の値を取りました(CPU 2コア)。
| 手法 | 300件 | 10万件 |
|---|---|---|
| 重回帰(statsmodels OLS) | 1.4ms | 12.7ms |
| ロジスティック回帰 | 2.5ms | 94.0ms |
| 判別分析(LDA) | 1.3ms | 186.9ms |
| 主成分分析 | 0.3ms | 1.8ms |
| 因子分析(2因子) | 3.2ms | 2402.3ms |
| k-means(k=3、10回やり直し) | 5.6ms | 179.7ms |
数百件の分析なら、どの手法も一瞬で終わります。10万件では因子分析が約2.4秒と目立って遅く、反復計算の重さが出ました。変数が6個程度なら、件数が増えても手法の選択で困ることはほとんどありません。時間がかかるのは、件数がさらに大きいときや、階層型クラスター分析のように件数の2乗で重くなる手法を使うときです。
よくあるエラーとつまずき(原文つき)
この節では、Python で多変量解析を行うときによく出るエラー・警告の原文と、原因と直し方が分かります。
いちばん気づきにくいのは、エラーが出ないまま結果が間違っているケースです。statsmodels で定数項を加え忘れると、エラーは出ずに決定係数が 0.993 と表示されました(加えた場合は 0.685)。定数項がないときの決定係数は計算の基準が変わり、見かけ上大きくなるためです。
| 出た原文・症状 | 原因 | 直し方 |
|---|---|---|
| エラーなしで R2 が 0.993 と高すぎる | statsmodels の OLS・Logit に定数項を加えていない | sm.add_constant(X) を通す。formula で書けば自動で入る |
ValueError: could not convert string to float: '郊外大型' |
文字列の列をそのまま scikit-learn に渡した | pd.get_dummies や OneHotEncoder でダミー変数にする |
ValueError: Input X contains NaN. |
欠損値が残っている(k-means・回帰など多くの手法で出る) | 欠損の理由を確かめ、行を除くか、値を補う |
ValueError: n_components=8 must be between 0 and min(n_samples, n_features)=6 with svd_solver='covariance_eigh' |
主成分の数を変数の数より多く指定した | n_components を変数の数以下にする |
ConvergenceWarning: Maximum Likelihood optimization failed to converge. Check mle_retvals と RuntimeWarning: overflow encountered in exp |
説明変数で結果が完全に分かれる(完全分離)。係数 12.03・標準誤差 173.6 と異常な値に | 答えを作った変数を外す。必要なら正則化つきのロジスティック回帰にする |
SingularMatrixWarning: The design matrix is rank-deficient. The model parameters are not uniquely determined. |
ある変数が他の変数のちょうど何倍か(完全な共線性) | 重複した列(単位を変えただけの列など)を外す |
UserWarning: The design matrix is poorly conditioned (condition number=1.43e+16). VIF calculations may be numerically unstable. |
完全な共線性のまま VIF を計算した(VIF は 1.0×1015) | 上と同じく重複した列を外してから計算する |
標準化
今回は k-means の一致度が 0.329 から 0.940 に上がった
評価の仕方
評価用のデータの情報が学習に漏れるのを防ぐ
このほか、外れ値や入力ミスをそのままにすると、重回帰の係数や主成分の向きが大きく引っぱられます。多変量解析の前に、単変量の分布で極端な値がないか確かめておくのが確実です。分布の形やばらつきの考え方は、関連記事「確率分布とは|種類一覧・平均と分散・選び方をPythonで実演」で扱っています。
判断表:多変量解析を使う・使わない
この節では、多変量解析を使うべき場面と、使わずに単純な集計で済ませたほうがよい場面、使う前に確かめることが分かります。
多変量解析は強力ですが、問いが単純なときや、データが足りないときに使うと、かえって誤った結論につながります。
| 状況 | 判断 | 理由 |
|---|---|---|
| 結果に関係しそうな要因が複数あり、互いに関係している | 使う(重回帰・ロジスティック回帰) | 1つずつ見ると、今回の床面積のように結論が逆になる |
| 指標が多すぎて全体像がつかめない | 使う(主成分分析) | 少ない軸にまとめて図にできる |
| 顧客や店舗をいくつかのタイプに分けたい | 使う(クラスター分析) | 分けたグループの平均を見て、施策を変えられる |
| 2つのグループの平均の差を知りたいだけ | 使わない(t 検定・集計) | 2変量の分析で答えが出る |
| 件数が変数の数に比べて少ない | 変数を減らしてから使う | 40件・34変数では交差検証の R2 がマイナスになった |
| 「Xを変えればYが増える」と因果を言い切りたい | 多変量解析だけでは言えない | 係数は関連であり、ランダム化した実験などの設計が要る |
| 欠損・外れ値・入力ミスを確かめていない | 先にデータを確かめる | 係数や主成分の向きが大きく引っぱられる |
分析を始める前に、次の点を確かめておくと失敗が減ります。
- 1問いを1文で書き、当てたい値があるかを決めた手法は問いから選ぶ
- 2単変量で欠損・外れ値・入力ミスを確かめたNaN が残ると多くの手法がエラーになる
- 3相関の強い組と VIF を確かめた0.8 を超える組、VIF 5 や 10 を超える変数
- 4単位の違う変数を標準化した主成分分析・因子分析・k-means では特に大事
- 5学習に使っていないデータで確かめた交差検証か、評価用データを分けておく
- 6結果を因果ではなく関連として説明した「他の条件をそろえたときの関連」と書く
よくある質問
この節では、多変量解析についてよく検索される疑問への答えが分かります。
Q. 多変量解析と重回帰分析の違いは何ですか?
A. 多変量解析は複数の変数を同時に扱う手法の総称で、重回帰分析はその中の一つです。重回帰分析は「1つの量を複数の説明変数で説明する」手法で、他に主成分分析やクラスター分析なども多変量解析に含まれます。英語の厳密な使い方では、重回帰分析は multivariable と呼ばれることがあります。
Q. 多変量解析にはどんな種類がありますか?
A. 当てたい値があるときの重回帰分析・ロジスティック回帰・判別分析・コンジョイント分析・共分散構造分析と、ないときの主成分分析・因子分析・クラスター分析・多次元尺度構成法・コレスポンデンス分析が代表的です。
Q. 多変量解析の具体例を教えてください。
A. 店舗の売上を広さ・立地・広告費から説明する(重回帰)、解約しそうな顧客の確率を出す(ロジスティック回帰)、顧客をタイプ分けする(クラスター分析)、多くの評価項目を総合点にまとめる(主成分分析)、アンケートの回答から「価格重視」「品質重視」といった傾向を見つける(因子分析)などがあります。
Q. Python ではどのライブラリを使えばよいですか?
A. 係数・p 値・信頼区間を表で読みたいときは statsmodels、予測の精度を測ったり、主成分分析・クラスター分析・判別分析をしたりするときは scikit-learn が使いやすいです。今回の確認でも、重回帰・ロジスティック回帰・MANOVA は statsmodels、それ以外は scikit-learn を使いました。R でも標準の機能で多くの手法を実行できます。
Q. 多重共線性はどう見つけて、どう直しますか?
A. 説明変数どうしの相関と VIF で見つけます。直し方は、相関の強い変数の片方を外す、主成分分析で1つの軸にまとめる、正則化(リッジ回帰など)を使う、のいずれかです。今回は席数を外すと VIF がすべて 3 未満になりました。
Q. データは何件あれば多変量解析ができますか?
A. 決まった数はありませんが、変数1つあたり10〜20件以上がよく目安にされます。今回の実測では、40件・34変数で交差検証の決定係数がマイナスになりました。件数が少ないときは、変数を絞るか、学習に使っていないデータで安定しているかを確かめます。
Q. 標準化はいつ必要ですか?
A. 主成分分析・因子分析・k-means のように、変数のばらつきの大きさや距離で計算する手法では、単位の違う変数を混ぜるならほぼ必須です。重回帰分析では予測の結果は変わりませんが、係数の大きさを比べたいときは標準化係数を使います。
Q. Web サイトの「多変量テスト」と多変量解析は同じですか?
A. 別のものです。多変量テストは、Web ページの見出し・画像・ボタンなど複数の要素の組み合わせを同時に出し分けて、どの組み合わせの成果がよいかを比べる実験の方法です。結果の分析に多変量解析の考え方を使うことはありますが、言葉としては区別します。
Q. 多変量解析の結果から因果関係は分かりますか?
A. 多変量解析だけでは分かりません。重回帰の係数は「他の変数をそろえたときの関連」で、入れていない要因の影響や、逆向きの因果を除けないためです。因果を確かめたいときは、ランダムに割り当てた実験などの設計を組み合わせます。
Q. 主成分分析とクラスター分析はどう使い分けますか?
A. 主成分分析は「変数」をまとめて軸を作り、クラスター分析は「対象(店舗・顧客)」をまとめてグループを作ります。主成分分析で2次元にまとめてから散布図を描き、クラスター分析の結果で色分けすると、グループの違いが見やすくなります。
まとめ
この節では、この記事の要点を5つにまとめます。
- 多変量解析とは、3つ以上の変数を同時に扱って関係やまとまりを調べる手法の総称で、1つずつ見ると逆になる結論(今回の床面積)を防げる。
- 種類は2つに大別できる。当てたい値があれば重回帰・ロジスティック回帰・判別分析、なければ主成分分析・因子分析・クラスター分析。
- 選び方は、問いを1文にする→当てたい値の有無→その値の尺度(量・2値・区分)→説明変数の尺度、の順に決める。
- 多重共線性と標準化に注意する。席数を足すと VIF 55.6・標準誤差4.4倍、標準化しない k-means は一致度 0.329 にとどまった。
- 過学習と因果に注意する。学習に使っていないデータで確かめ、結果は「他をそろえたときの関連」として伝える。
参考・出典
この節では、この記事で確かめた公式ドキュメントの一覧が分かります(確認日 2026年10月29日)。
- scikit-learn「2.3. Clustering」https://scikit-learn.org/stable/modules/clustering.html
- scikit-learn「1.2. Linear and Quadratic Discriminant Analysis」https://scikit-learn.org/stable/modules/lda_qda.html
- scikit-learn「2.5. Decomposing signals in components (matrix factorization problems)」https://scikit-learn.org/stable/modules/decomposition.html
- statsmodels「statsmodels.regression.linear_model.OLS」https://www.statsmodels.org/stable/generated/statsmodels.regression.linear_model.OLS.html
- statsmodels「statsmodels.discrete.discrete_model.Logit」https://www.statsmodels.org/stable/generated/statsmodels.discrete.discrete_model.Logit.html
- statsmodels「statsmodels.stats.outliers_influence.variance_inflation_factor」https://www.statsmodels.org/stable/generated/statsmodels.stats.outliers_influence.variance_inflation_factor.html
- statsmodels「statsmodels.multivariate.manova.MANOVA」https://www.statsmodels.org/stable/generated/statsmodels.multivariate.manova.MANOVA.html
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「多変量解析とは|種類7つと選び方を同じ架空データで実演」
株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。
WE ARE HIRING
RJCで一緒に開発しながら、
成長を楽しみませんか?
RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!
- 127日年間休日
- 12時間平均残業時間
- 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!
ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。