メインコンテンツへスキップ
ブログ一覧に戻る
統計・データサイエンス

主成分分析(PCA)|多変量を2軸に要約する実務ガイド

2025年11月1日
最終更新: 2026年10月8日
14分で読めます

この記事でわかること

主成分分析PCAの仕組みと、標準化、主成分数、寄与率、係数とスコアの読み方を解説します。仮想の商品評価データをPythonで計算し、散布図と変数の相関を別々に確認。分散を多く残すことが予測や因果の説明を保証しない理由、欠測・外れ値への対応、新しいデータへの適用、評価時の情報漏洩まで扱う実務ガイドです。

2026年10月8日にscikit-learn 1.9.1のPCA、標準化、成分、説明分散、パイプラインと交差検証本文を再確認した。PCAは入力の分散を大きく説明する直交成分へ変換する教師なしの要約であり、標準化、欠測、外れ値、成分数、符号、学習範囲に依存する。説明分散が大きいことや2軸が見やすいことは、予測性能、因果、解釈、施策効果を保証しないため、学習データだけでfitし未見データで評価する。

商品を「耐久性・デザイン・価格・使いやすさ」で比べると、四つの表を見比べるだけでも大変です。二つの軸の地図にできれば、似た商品や異なる商品を探しやすくなります。そのための道具が、主成分分析(PCA)です。

ただし、見やすい地図を作れたからといって、購買の理由まで分かったわけではありません。PCAが多く残すのは、入力した数値の分散、つまり散らばりです。利益や満足度にとって重要な違いが残るかは別の問いです。本記事では、商品評価の仮想データを使い、計算、図、名前の付け方、後のデータへの適用までを確認します。

30秒で要点

  • PCAは、入力の分散を多く表す線形の軸を作る。二つに減らすこと自体が目的ではない。
  • 軸の係数、商品の座標、変数と軸との相関を区別する。軸に付けた名前は解釈である。
  • 前処理と残す軸数を決め、落とした変動も調べる。予測に使う場合は学習・評価を先に分ける。

PCAは「新しいものさし」を作る

厚みと重さが似た動きをする商品群を考えます。二つの値をそのまま並べる代わりに、両方が大きくなる方向へ一本のものさしを置くと、商品の主な違いを一つの位置で表せます。その方向で説明できなかった違いを、直角の別のものさしで表すのが次の段階です。

PCAは、元の数値列の線形結合で第一主成分、第二主成分といった軸を作ります。第一主成分は投影した値の分散が最大になる方向です。第二主成分は第一と直交する制約の下で分散が最大になる方向です。計算したデータの主成分スコア同士は無相関ですが、それだけで統計的な独立や別々の原因を示すわけではありません。PCA公式ガイド

表が収まらない場合は、横にスクロールできます

用語何を表すか読み替えてはいけないもの
主成分の係数元の各列を足し合わせる重みその変数が売上を生む因果効果
スコア各商品を新しい軸へ投影した座標商品の良さや偏差値の順位
寄与率その軸の分散÷入力全体の分散購入意向や売上の予測精度
累積寄与率残した軸の寄与率の合計全ての重要な情報が残った確率
相関負荷量元の変数と主成分スコアの相関係数そのもの、あるいは原因の強さ

「負荷量」は文献やソフトで係数を指す場合と、相関などの尺度を指す場合があります。表に定義がなければ、数値を比較する前に確認してください。scikit-learnのcomponents_は主成分の方向を表す係数です。本記事は相関を別途計算し、同じ名前で混ぜません。PCA公式仕様

何を1行にするかで、同じ名前の分析も変わる

商品を比較したいなら、1行が商品で、列は同じ方法で測った評価項目です。回答者の好みを比較したいなら、1行が回答者になります。商品ごとに多数の回答を集めた表では、「回答者と商品の組み合わせ」を1行にするのか、商品平均に集約するのかによって分析する変動が変わります。

商品平均を使えば回答者間のばらつきは図から消えます。個々の回答を入れれば、回答数の多い商品が強く影響し得ます。商品平均の違いから「人々の好みは二種類ある」と推測するなど、行の単位を途中で取り替えないようにします。

目的も先に分けます。既存商品の配置を説明する探索なら、そのデータ全体で軸を学習することがあります。翌期の需要予測を評価するなら、将来に見えない情報を使って軸や前処理を作らないよう、データを先に分割します。図を作る分析と将来の性能評価を、同じ実行結果で済ませないことが重要です。

中心化と標準化を選び分ける

PCAの前に各列の平均を引くのが中心化です。さらに各列を標準偏差で割るのが標準化です。scikit-learnのPCAは中心化を行いますが、標準化は自動では行いません。

価格を円で表すか万円で表すかによって分散の大きさが変わります。単位の異なる列をそのまま使うと、数値の散らばりが大きい列が軸を支配する場合があります。公式の特徴量スケーリング例でも、標準化前後でPCAの方向が変わることを確認できます。スケーリングの公式例

一方、全て同じ単位で測った値なら、元の分散の大小を残す方が目的に合うこともあります。標準化すると、ほとんど変動しない雑音の多い項目にも一定の重みを与えます。標準化するかは、単位を揃える必要性と、どの違いを重要とみなすかで選びます。

本記事の製品評価は1〜10の便宜的な点数ですが、各項目を同程度の尺度で比較する教材として標準化します。これは順序尺度の心理測定が厳密な間隔尺度であるという証明ではありません。アンケートの回答段階を数値として扱う妥当性、回答者の違い、評点の天井・床も確認します。

欠測と外れ値は、計算前の独立した判断

未評価を0点に変えると、未評価の商品を「著しく低評価」として配置してしまいます。欠測が多い項目や商品の偏りを調べ、削除・補完の方針と補完された値の割合を残します。平均や中央値による補完は選択肢ですが、元の相関や分散を変える可能性があります。欠測処理の公式説明

一つの極端な観測が軸の向きを変えることもあります。入力ミスと実在する特殊商品を分け、条件を変えたときの軸や寄与率を比べます。StandardScalerは外れ値に敏感です。ロバストな尺度へ変えても、通常のPCAそのものがロバスト推定に変わるわけではありません。StandardScaler公式仕様

カテゴリを便宜的な整数で符号化してPCAへ入れるのも注意が必要です。ワンホット化後も、項目のカテゴリ数や稀な回答の標準化が重みを変えます。カテゴリ中心なら対応する別手法を含めて検討し、「ワンホット化して標準化すればよい」という機械的な順序にしません。

8商品の合成データで、寄与率と係数を読む

以下は実在商品ではない合成教材です。1行が1商品、四つの列はいずれも架空の評点です。priceは金額ではなく価格の高さを表す点数とします。「価格が高い」が「良い」とは限らない点も含めて読みます。

2026年10月4日にPython 3.12、scikit-learn 1.9.1、NumPy 2.5.3、pandas 3.0.6、SciPy 1.18.1、Matplotlib 3.11.2の隔離環境で検算しています。二つのPython例はそれぞれ単独で実行できます。既存システムの依存を更新する手順ではありません。

import numpy as np
import pandas as pd
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA

df = pd.DataFrame({
    "durability": [8,7,6,9,7,6,8,5],
    "design": [3,6,7,2,5,8,4,9],
    "price": [9,8,7,9,8,7,8,6],
    "usability": [4,6,7,3,5,8,5,9]
})
scaler = StandardScaler()
X = scaler.fit_transform(df)
pca = PCA(n_components=2, svd_solver="full")
Z = pca.fit_transform(X)
coefficient = pd.DataFrame(pca.components_.T,
    index=df.columns, columns=["PC1", "PC2"])
correlation = pd.DataFrame(np.corrcoef(X.T, Z.T)[:4, 4:],
    index=df.columns, columns=["PC1", "PC2"])
print("Variance ratio:", np.round(pca.explained_variance_ratio_, 6))
print("Cumulative:", round(pca.explained_variance_ratio_.sum(), 6))
print("Axis coefficients:\n", coefficient.round(3).to_string())
print("Variable-score correlations:\n", correlation.round(3).to_string())

第一主成分の寄与率は約0.976592、第二は約0.014094、累積は約0.990686です。百分率では約97.659%、1.409%、合計99.069%となります。分母は標準化した四つの入力列の分散の合計です。顧客の99.069%を説明できる、購買を99.069%予測できる、という意味ではありません。

表が収まらない場合は、横にスクロールできます

項目PC1の係数PC2の係数
耐久性 durability-0.499-0.516
デザイン design0.5030.300
価格の高さ price-0.4960.802
使いやすさ usability0.503-0.021

ここではPC1の正方向は、デザイン・使いやすさの点が高く、耐久性・価格の点が低い側です。「高価格・堅牢軸」と名付けるなら、どちら側を指すかを併記します。PC2は価格の正の係数と耐久性の負の係数が目立ちますが、寄与率は約1.4%にすぎません。大きな係数だけを取り上げて、データ全体の主要な違いと誇張しないようにします。

固有ベクトルの符号は任意です。PC1の係数とスコアを両方ともマイナス1倍しても、表している軸と再構成は同じです。異なる版や計算方法で符号が反転したとき、結果の意味が逆転したと即断せず、係数とスコアをセットで確認します。固有値が近いと、符号だけでなく部分空間内の軸が不安定になる場合もあります。

係数と相関が同じ数値にならない理由

components_の一行は長さ1の方向ベクトルです。相関は元の変数とスコアを、それぞれの標準偏差で調整した関係です。係数に主成分の標準偏差を掛け、元変数の標本標準偏差で割ると、その変数とスコアの相関になります。上のコードは定義が明確なcorrcoefで直接計算します。

StandardScalerは分母nの分散で標準化し、PCAのexplained_variance_は分母n - 1の標本分散を使います。そのため、標準化済みだからといってcomponents_.T * sqrt(explained_variance_)を無条件に相関と呼べません。n=8なら標準化した列の標本分散は8/7です。この違いも、計算の定義を合わせれば矛盾ではありません。

残す軸数は、図・再構成・予測で決め方が違う

寄与率を主成分ごとに並べたスクリープロットで減り方を見ると、候補を絞れます。累積寄与率80%や90%を基準にする運用もありますが、普遍的な合格線ではありません。重要な変数の変動がその残りに集中していることがあるからです。

表が収まらない場合は、横にスクロールできます

目的主に確かめるもの採用判断の例
全体像の可視化2軸の累積寄与率、各変数の表現、外れた点省いた軸にも重要な違いがあれば別図を添える
データ圧縮元空間への再構成誤差、必要な列の誤差全体の平均誤差だけでなく重要項目の誤差を確認
予測の前処理未使用データでの予測誤差と実行費用PCAなし・軸数違いを同じ分割で比較
クラスタ分析の前処理分類の変化、元特徴での解釈、安定性少数軸の図が分離していることだけで採用しない

PCAは目的変数を見ません。極端な合成例として、二つの無相関な特徴の分散が100と1で、予測したい値が二つ目そのものだとします。第一軸だけを残すと100/101、約99.01%の分散を保持していても、予測に必要な二つ目を捨てます。これは仕組みを確かめる反例であり、実務データの改善率ではありません。公式のPCRとPLSの比較例も、低分散の方向に予測情報がある場合を示しています。予測価値と分散の違いを示す公式例

情報量規準を使うなら、確率的PCAなどの尤度モデル、推定法、比較する候補を明示する必要があります。通常のPCAへAICやBICをそのまま万能の選択基準として付け足すことはできません。ここではまず寄与率と再構成、必要なら下流の検証結果で判断します。

12商品の地図と、変数の相関を併読する

次は四つの評点を持つ12商品の合成教材です。先ほどの8商品に4行を足した別の分析で、軸を学習し直します。二つの結果の軸を同じ意味だと固定せず、それぞれの係数を読みます。

スコアと変数の矢印を重ねる図をバイプロットと呼びますが、点と矢印の尺度の選び方で読み方が変わります。説明を曖昧にしないため、ここでは商品のスコア図と変数の相関図を別のパネルにします。両方でPC1とPC2は対応しますが、単位は異なり、二つのパネルを横断した距離比較はしません。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA

df = pd.DataFrame({
    "durability": [8,7,6,9,7,6,8,5,7,8,6,9],
    "design": [3,6,7,2,5,8,4,9,6,5,7,4],
    "price": [9,8,7,9,8,7,8,6,8,9,7,9],
    "usability": [4,6,7,3,5,8,5,9,6,5,7,4]
})
scaler = StandardScaler()
X = scaler.fit_transform(df)
pca = PCA(n_components=2, svd_solver="full")
Z = pca.fit_transform(X)
corr = np.corrcoef(X.T, Z.T)[:4, 4:]
fig, (ax, bx) = plt.subplots(1, 2, figsize=(11, 5))
ax.scatter(Z[:, 0], Z[:, 1])
for i, (x, y) in enumerate(Z, start=1):
    ax.annotate(str(i), (x, y), xytext=(4, 4), textcoords="offset points")
ax.set(xlabel="PC1 score", ylabel="PC2 score", aspect="equal")
bx.add_patch(plt.Circle((0, 0), 1, fill=False, color="gray"))
for name, (x, y) in zip(df.columns, corr):
    bx.annotate("", xy=(x, y), xytext=(0, 0),
                arrowprops={"arrowstyle": "->"})
    bx.text(x * 0.85, y * 0.85, name, fontsize=8)
bx.set(xlim=(-1.2, 1.2), ylim=(-1.2, 1.2), aspect="equal",
       xlabel="Correlation with PC1", ylabel="Correlation with PC2")
for axis in (ax, bx):
    axis.axhline(0, color="gray", linewidth=0.6)
    axis.axvline(0, color="gray", linewidth=0.6)
fig.tight_layout()
fig.savefig("pca-scores-and-correlations.png", dpi=150)
plt.close(fig)
print("Variance ratio:", np.round(pca.explained_variance_ratio_, 6))
print("Cumulative:", round(pca.explained_variance_ratio_.sum(), 6))
print(pd.DataFrame(corr, index=df.columns, columns=["PC1", "PC2"]).round(3))

12商品の寄与率はPC1が約95.929%、PC2が約2.651%、合計約98.579%です。8商品での合計99.069%とは異なります。商品の数だけでなく分布が変わると、軸も寄与率も変わります。

12商品の仮想評点を標準化してPCAを実行した図。上段は等尺度のPC1・PC2スコアで商品番号を配置、下段は同じ主成分と4変数の相関ベクトルを半径1の円内に表示する。2軸の累積寄与率は98.579%だが、予測精度ではない。
12行の合成教材を実計算。上は商品スコア、下は変数とスコアの相関で、異なる単位の二つの図です。PC1・PC2の符号を同時に反転しても同じ幾何を表します。実在商品や顧客の地図ではありません。

図を読むときの順序

最初に、上の図で商品番号と元の表を対応させます。近い商品は残した二軸の範囲で似ています。二次元で近いことから、落とした軸でも近いとは限りません。横軸と縦軸を同じ長さの単位で描いているので、点間の距離や方向を図の伸縮で誇張していません。

次に下の相関図を見ます。右へ向く変数はPC1と正、左へ向く変数はPC1と負の相関です。長い矢印は、その変数の変動が二軸によく表されていることを示します。「事業上重要な変数」という意味ではありません。矢印が短い変数は、この二軸だけでの読み取りを控え、残した以外の軸も調べます。

相関を表すベクトル同士の角度は、二軸に十分表されている変数同士なら、元変数の相関を近似的に読む助けになります。投影で失った成分があるため、直交して見えるだけで元の相関がゼロと断定できません。必要なら元データの相関行列で確かめます。

最後に、解釈の名前を付けます。「堅牢・高価格側」のように測った項目へ戻れる名前と、「高級志向」のように心理を推測した名前を区別します。商品評価表に購買者の志向や購入理由がなければ、それらは別途確認する仮説です。

新モデルを同じ地図へ置くには、軸を固定する

既存商品で作った地図に新商品を追加したい場合、保存したscalerのtransformを使い、その結果へ既存pcaのtransformを使います。新商品だけの平均や標準偏差を計算し直したり、毎回PCAを学習し直したりすると、ものさし自体が変わります。

学習し直すことが必要な場合もあります。その際は更新日、対象商品の集合、前処理、軸の係数を記録し、旧図との違いが商品変化なのか軸変更なのかを切り分けます。元の範囲を大きく外れる商品でも座標は計算できますが、その配置だけで妥当な比較になったとは判断しません。

予測にPCAを使う場合は、学習側だけで補完・標準化・PCAを学習し、評価側へ変換を適用します。交差検証でも各分割の中で学習させます。Pipelineはその手順を揃える助けになりますが、翌月の売上で作った特徴を今月の予測へ混ぜるような元データの漏洩は自動では直せません。前処理と情報漏洩の公式説明

因子分析や非線形手法へ切り替える前に

PCAは変数の分散を合成軸で要約します。一方、因子分析は共通の潜在因子と変数固有の変動を分けるモデルです。「質問項目の背後にどんな特性があるか」を考えるとき、単に寄与率が高いPCAの軸を心理的な因子と呼ぶことは避けます。どちらも軸に名前を付けただけで、原因が実証されたことにはなりません。

曲がった構造の可視化にはカーネルPCAなどの非線形手法が候補になります。ただし、見た目の塊や距離の意味、設定への依存は方法ごとに異なります。別手法の美しい地図がPCAより「正しい」とは限りません。何を保存する地図なのか、新しい観測へ適用できるのかを確認してから比べます。

最小の検証は、元の表へ戻れるかどうか

まず、目的に関わる数値列を少数選び、1行の単位、対象期間、欠測、単位を記録します。中心化だけの案と標準化した案を比べ、軸の係数と寄与率がどの程度変わるかを見ます。外れた一行を機械的に捨てず、その値の理由も確認します。

次に、二軸で近い商品と遠い商品をそれぞれ選び、元の数値へ戻って説明します。図の読み手が「この位置だから優秀」と言ったら、どの評点をどう組み合わせた位置なのかを確かめます。予測へ進むなら、PCAなしの基準モデルと同じ評価条件で比べることが次の小さな検証になります。

練習として、価格が第一軸をほぼ支配したときは単位と標準化を、二つの相関矢印が近いときは元の相関を、群が弧状に見えたときは残す軸や線形性を確認してください。「2軸では説明が足りない」「軸の名前をまだ決められない」も、データに即した結論です。

潜在因子のモデルへ進むなら因子分析、対象のグループ分けならクラスター分析、ほかの問いと手法を比較するならデータサイエンス手法ハブを参照してください。

よくある質問(FAQ)