Tracks
線形回帰は、統計学と機械学習における基本的な手法で、変数間の関係をモデル化するのに役立ちます。簡単に言うと、1つ以上の要因に基づいて結果を予測できるようにするものです。不動産価格の算定、売上予測、リスク評価など、幅広い分野で活用されています。
このチュートリアルでは、scikit-learnにおける線形回帰を取り上げ、その仕組み、有用性、そしてscikit-learnを使った実装方法を解説します。最後には、データに基づいた予測のために線形回帰モデルを構築・評価できるようになります。

部屋数に対する住宅価格の散布図
線形回帰と機械学習
住宅価格の推定に限らず、線形回帰は機械学習において重要な役割を果たします。
- ロジスティック回帰、ニューラルネットワーク、サポートベクターマシンなど、より高度な手法を理解するための基礎モデルです。
- 学習が高速で、迅速なプロトタイピングに最適です。
- ベースラインとして比較に使えます。高度なモデルが大きく上回らないなら、複雑性を正当化できないかもしれません。
- (ディープラーニングのような)一部の手法と異なり、解釈が容易です。
- 特徴量選択に役立ち、有用な予測因子を特定できます。
シンプルでありながら、効率性・解釈性・汎用性の高さから、線形回帰は機械学習において不可欠なツールであり続けています。
線形回帰とscikit-learnライブラリ
scikit-learnライブラリを使うと、線形回帰を簡単に実装できます。このライブラリには多くの利点があります。
- インターフェースが一貫しています。各種MLアルゴリズムの実装コードは似た構造です。
- コードがシンプルで、複雑な数学や実装の詳細は抽象化されています。たとえば学習データへのフィットは
model.fit(X_train, y_train)の1行で済みます。 - モデル係数へ簡単にアクセスできます。
- モデル性能を評価するための指標が組み込まれています。
- Pipelineを使えば、スケーリングや特徴量選択などの前処理と線形回帰(他のMLアルゴリズムも)が簡単に統合できます。
scikit-learnが初めての場合は、Pythonライブラリを実践的に学べるMachine Learning with scikit-learnコースをご覧ください。
線形回帰を理解する
単回帰では、データは「最適な直線」でモデル化されます。この直線の式は次のとおりです。
![]()
ここで、m は傾き、b は切片です。
「重回帰」は、1つの予測変数のケースを複数の予測変数(部屋数、海からの距離、近隣の中央値所得など)に拡張します。式は次のように一般化されます。
![]()
ここで各 xi は独立変数で、対応する bi はその係数です。3次元では直線は平面に、さらに高次元では「超平面」になります。
係数と切片はどのように解釈するのでしょうか。切片は、すべての独立変数が0のときの y の予測値、言い換えると、予測因子の寄与がないときの従属変数の基準値です。各係数 bi は、他の独立変数を一定に保ったまま、xi が1単位変化したときの従属変数 y の変化量を表します。
環境のセットアップ
scikit-learnのインストールは簡単です。コマンド pip install scikit-learn を実行するだけです。特定のバージョン(例:1.2.2)をインストールしたい場合は、バージョン指定を追加します: pip install scikit-learn==1.2.2. Anacondaを使用している場合、scikit-learnは既にインストール済みのはずです。もしAnacondaディストリビューションで改めて必要な場合は conda install scikit-learn を使用してください。
scikit-learnを使う際には、いくつかのライブラリが必須または推奨です。特徴量とラベルの格納には numpy が必要です。データの読み込み、前処理、探索には pandas の利用が推奨されます。
scikit-learnを使っているなら、データ前処理にはすでにpandasを使っていることが多いでしょう。結果の可視化には matplotlib や seaborn(または両方)を使うのが一般的です。これらのライブラリは、先ほどの例と同様にpipでインストールできます。1つのコマンドで複数ライブラリをまとめてインストールすることも可能です:
pip install scikit-learn numpy pandas matplotlib seaborn.
sklearnで線形回帰を実装する
データセットを読み込む前に、定番のライブラリをインポートしましょう。
# Import libraries.
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
データセットの読み込み
よく知られたCalifornia housingデータセットを使いましょう。
# Read in California housing dataset.
from sklearn.datasets import fetch_california_housing
housing = fetch_california_housing()
データの準備
データを学習用とテスト用に分割します。sklearn.model_selection から train_test_split() をインポートし、テストデータの割合と random_state を指定して実行します。ここでは単回帰として、平均部屋数に対応する特徴量を使います。
# Import train_test_split.
from sklearn.model_selection import train_test_split
# Create features X and target y.
X = pd.DataFrame(housing.data, columns=housing.feature_names)[["AveRooms"]]
y = housing.target # Median house value in $100,000s
# Split the dataset into training (80%) and testing (20%) sets.
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
データを学習用・テスト用に分割したので、続いて特徴量を標準化します。すべての変数を同一スケールに揃えることで、モデル性能や数値安定性の向上が期待できます。
# Import StandardScaler.
from sklearn.preprocessing import StandardScaler
# Instantiate StandardScaler.
scaler = StandardScaler()
# Fit and transform training data.
X_train_scaled = scaler.fit_transform(X_train)
# Also transform test data.
X_test_scaled = scaler.transform(X_test)
このコードにおける StandardScaler は、平均を取り除き、分散が1になるようにスケーリングする前処理ツールです。スケールの違いによって一部の特徴量がモデルを支配してしまうのを防ぎます。
スケーラーは fit_transform() で学習データに当てはめてから変換します。テストデータは transform() で別途変換し、学習データと同じ係数でスケーリングすることで、データ漏洩を防ぎます。
線形回帰モデルの学習
線形回帰モデルを作成するには、sklearn.linear_model から LinearRegression() をインポートし、インスタンス化して変数に代入します。
# Import LinearRegression.
from sklearn.linear_model import LinearRegression
# Instantiate linear regression model.
model = LinearRegression()
学習データでモデルをフィットするのは簡単です。
# Fit the model to the training data.
model.fit(X_train_scaled, y_train)
予測の実行
モデルを学習したので、テストデータに対して予測を行います。
# Make predictions on the testing data.
y_pred = model.predict(X_test_scaled)
モデル性能の評価
テストデータで予測したら、実際の値とどれだけ一致しているかを確認する必要があります。回帰アルゴリズムの性能評価にはいくつかの指標があります。代表的なものに決定係数(R2)、平均二乗誤差(MSE)、二乗平均平方根誤差(RMSE)があります。
決定係数R2は、回帰モデルが目的変数の変動をどれだけ説明できているかを測る指標です。言い換えると、予測因子によって目的変数の変動のどれだけが説明されるか(適合度)を定量化します。
これをさらに理解するために、次の式を見てみましょう。
![]()
ここで、yactual は目的変数の実測値、ypredicted はモデルの予測値、ȳ は実測値の平均です。この式により、目的変数の分散のうちどれだけをモデルが説明できているかがわかります。分母はデータ全体の分散、分子は回帰モデル適用後に説明できなかった分散を表します。その比率が、モデルによって説明された分散の割合を示します。
R2はどのように解釈するのでしょうか。
- R2 = 1:モデルが目的変数の分散を完全に説明しています。
- R2 = 0:モデルは分散をまったく説明できておらず、単に平均を使うのと同等です。
- R2 < 0:平均よりも悪い予測で、適合が不十分であることを示します。
留意すべき点:
- 高いR2が常に良いとは限りません。複雑なモデルでは特に、過学習の可能性があります。
- 特徴量を追加すると人工的にR2が上がることがあるため、高ければよいとは限りません。
- 重回帰では、不要な変数による見かけ上の改善を避けるため、予測子数を考慮した調整R2を使います。
scikit-learnを使えば、決定係数による性能評価は簡単です。
# Import metrics.
from sklearn.metrics import mean_squared_error, r2_score
# Calculate and print R^2 score.
r2 = r2_score(y_test, y_pred)
print(f"R-squared: {r2:.4f}")
R-squared: 0.0138
その他によく使われる指標として、平均二乗誤差(MSE)と二乗平均平方根誤差(RMSE)があります。これらは、モデルの予測が実際の値からどれだけ離れているかを測ります。
MSEは、実測値と予測値の差の二乗の平均です。

ここで n は観測数です。誤差は平均化の前に二乗されるため、大きな誤差が小さな誤差よりも強くペナルティ化され、MSEは外れ値に敏感です。MSEが小さいほど、モデルの適合は良好です。
この問題に対処するために、MSEの平方根であるRMSEが用いられます。RMSEは目的変数と同じ単位を持つため、平均的にどの程度予測が外れているかをより解釈しやすく示します。
MSEとRMSEの計算も、scikit-learnで簡単に行えます。
# Calculate and print MSE.
mse = mean_squared_error(y_test, y_pred)
print(f"Mean squared error: {mse:.4f}")
# Calculate and print RMSE.
rmse = mse ** 0.5
print(f"Root mean squared error: {rmse:.4f}")
Mean squared error: 1.2923
Root mean squared error: 1.1368
scikit-learnでの重回帰
今度は平均部屋数だけでなく、利用可能なすべての特徴量を使ってモデルを再実行してみましょう。結果は良くなるでしょうか、悪くなるでしょうか。
# Uses all features.
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.datasets import fetch_california_housing
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error, r2_score
# Load data set.
housing = fetch_california_housing()
# Split into X, y.
X = pd.DataFrame(housing.data, columns=housing.feature_names)
y = housing.target # Median house value in $100,000s
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# Scale the data.
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
# Create model and fit it to the training data.
model = LinearRegression()
model.fit(X_train_scaled, y_train)
# Make predictions.
y_pred = model.predict(X_test_scaled)
# Calculate and print errors.
r2 = r2_score(y_test, y_pred)
print(f"R-squared: {r2:.4f}")
mse = mean_squared_error(y_test, y_pred)
print(f"Mean squared error: {mse:.4f}")
rmse = mse ** 0.5
print(f"Root mean squared error: {rmse:.4f}")
R-squared: 0.5758
Mean squared error: 0.5559
Root mean squared error: 0.7456
単一特徴量のときよりも、かなり良い結果になっていることがわかります。しかし、すべての特徴量が必要かどうかという疑問が生じます。より重要な特徴量はあるのでしょうか。データセットから最も関連性の高い特徴量を選ぶことを特徴量選択と呼びます。
特徴量選択は、次のような理由で重要です。
- 過学習の抑制。特徴量が少ないほどモデルは単純になり、過学習のリスクが下がります。
- 精度の向上。無関係・冗長な特徴量を除去すると、有意なパターンに集中できます。
- 解釈性の向上。重要因子を強調することで、モデルを理解しやすくします。
- 学習の高速化。特徴量数の削減により、計算時間とメモリ使用量が減ります。
複数の特徴量が高い相関を持つ場合、それらは冗長であり、モデルに本質的に同じ情報を与えています。これは多重共線性と呼ばれます。多重共線性は、必ずしも予測精度に影響するわけではありませんが、特に線形回帰や関連モデルにおいて、特徴量選択や解釈を複雑にします。
分散拡大要因(VIF)は、予測因子間の多重共線性を検出するための指標です。各予測因子について、VIFは次の式で計算されます。

ここで Ri2 は、予測因子 Xi を他のすべての予測因子に対して回帰したときに得られる R2 値です。VIFが高いほど、その予測因子は他の変数と強く相関しています。
- VIF = 1:多重共線性なし(理想的)。
- VIF < 5:低〜中程度の多重共線性(概ね許容範囲)。
- VIF > 5:高い多重共線性(相関の高い変数の削除や結合を検討)。
- VIF > 10:深刻な多重共線性(強い冗長性の示唆)。
# Import libraries.
import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
from sklearn.datasets import fetch_california_housing
from statsmodels.stats.outliers_influence import variance_inflation_factor
# Load the dataset.
housing = fetch_california_housing()
X = pd.DataFrame(housing.data, columns=housing.feature_names)
# Compute the correlation matrix.
corr_matrix = X.corr()
# Identify pairs of features with high collinearity (correlation > 0.8 or < -0.8).
high_corr_features = [(col1, col2, corr_matrix.loc[col1, col2])
for col1 in corr_matrix.columns
for col2 in corr_matrix.columns
if col1 != col2 and abs(corr_matrix.loc[col1, col2]) > 0.8]
# Convert to a DataFrame for better visualization.
collinearity_df = pd.DataFrame(high_corr_features, columns=["Feature 1", "Feature 2", "Correlation"])
print("\nHighly Correlated Features:\n", collinearity_df)
# Compute Variance Inflation Factor (VIF) for each feature.
vif_data = pd.DataFrame()
vif_data["Feature"] = X.columns
vif_data["VIF"] = [variance_inflation_factor(X.values, i) for i in range(X.shape[1])]
# Print VIF values.
print("\nVariance Inflation Factor (VIF) for each feature:\n", vif_data)
Highly Correlated Features:
Feature 1 Feature 2 Correlation
0 AveRooms AveBedrms 0.847621
1 AveBedrms AveRooms 0.847621
2 Latitude Longitude -0.924664
3 Longitude Latitude -0.924664
Variance Inflation Factor (VIF) for each feature:
Feature VIF
0 MedInc 11.511140
1 HouseAge 7.195917
2 AveRooms 45.993601
3 AveBedrms 43.590314
4 Population 2.935745
5 AveOccup 1.095243
6 Latitude 559.874071
7 Longitude 633.711654
AveBedrmsをモデルから除外してみましょう。
# Import libraries.
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.datasets import fetch_california_housing
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error, r2_score
# Load California housing dataset.
housing = fetch_california_housing()
# Create DataFrame and remove "AveBedrms" feature.
X = pd.DataFrame(housing.data, columns=housing.feature_names).drop(columns=["AveBedrms"])
y = housing.target # Median house value in $100,000s
# Split data into training and testing sets.
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# Scale the data (Standardization).
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
# Create a linear regression model and train it.
model = LinearRegression()
model.fit(X_train_scaled, y_train)
# Make predictions on the test set.
y_pred = model.predict(X_test_scaled)
# Calculate performance metrics.
r2 = r2_score(y_test, y_pred)
mse = mean_squared_error(y_test, y_pred)
rmse = np.sqrt(mse)
# Print evaluation metrics
print(f"R-squared: {r2:.4f}")
print(f"Mean squared error: {mse:.4f}")
print(f"Root mean squared error: {rmse:.4f}")
R-squared: 0.5823
Mean squared error: 0.5473
Root mean squared error: 0.7398
結果は(わずかに)改善しました。
モデルから洞察を得る
回帰モデルの構築は第一歩に過ぎません。出力を理解することも同じくらい重要です。モデルの係数を分析することで、どの特徴量が予測に最も大きな影響を与えているかを把握できます。
回帰係数を理解する
線形回帰モデルを学習すると、model.coef_ で係数、model.intercept_ で切片にアクセスできます。
LinearRegression() で学習した線形回帰モデルでは、model.coef_ で係数、model.intercept_ で切片にアクセスできます。
print("Intercept:", model.intercept_)
coeff_df = pd.DataFrame({"Feature": X.columns, "Coefficient": model.coef_})
print("\nFeature Coefficients:\n", coeff_df)
Intercept: 2.0719469373788777
Feature Coefficients:
Feature Coefficient
0 MedInc 0.725747
1 HouseAge 0.121519
2 Latitude -0.943105
3 Longitude -0.900735
モデル結果の要約
Scikit-LearnにはStatsmodelsのような組み込みの summary() メソッドがないため、回帰係数を使って各特徴量の重要度を手動で抽出・可視化できます。絶対値の大きな係数を持つ特徴量ほど、目的変数への影響が強いといえます。次のコードを参照してください。
# Sort dataframe by coefficients.
coef_df_sorted = coef_df.sort_values(by="Coefficient", ascending=False)
# Create plot.
plt.figure(figsize=(8,6))
plt.barh(coef_df["Feature"], coef_df_sorted["Coefficient"], color="blue")
plt.xlabel("Coefficient Value")
plt.ylabel("Feature")
plt.title("Feature Importance (Linear Regression Coefficients)")
plt.show()

係数値に基づく特徴量重要度のグラフ
次に、残差と回帰当てはまりを可視化してみましょう。
# Compute residuals.
residuals = y_test - y_pred
# Create plots.
plt.figure(figsize=(12,5))
# Plot 1: Residuals Distribution.
plt.subplot(1,2,1)
sns.histplot(residuals, bins=30, kde=True, color="blue")
plt.axvline(x=0, color='red', linestyle='--')
plt.title("Residuals Distribution")
plt.xlabel("Residuals (y_actual - y_predicted)")
plt.ylabel("Frequency")
# Plot 2: Regression Fit (Actual vs Predicted).
plt.subplot(1,2,2)
sns.scatterplot(x=y_test, y=y_pred, alpha=0.5)
plt.plot([min(y_test), max(y_test)], [min(y_test), max(y_test)], color='red', linestyle='--') # Perfect fit line
plt.title("Regression Fit: Actual vs Predicted")
plt.xlabel("Actual Prices (in $100,000s)")
plt.ylabel("Predicted Prices (in $100,000s)")
# Show plots.
plt.tight_layout()
plt.show()

残差と回帰当てはまりを可視化するプロット
残差の分布(左図)はゼロ付近を中心にしているのが望ましく、誤差がランダムに分布していることを示します。残差が正規分布に従うなら、モデルの当てはまりは良好ですが、歪みや傾向があれば、体系的な誤差の可能性があります。回帰当てはまり(右図)は実測値と予測値を比較し、赤の破線は完全一致の直線を表します。点がこの線に密接に沿っていれば予測は正確ですが、(曲線のような)パターンが見られる場合、関係は真に線形ではないかもしれません。
これらの可視化は、過学習や過小適合の診断、見落としている関係性を示唆する残差のパターンの発見、モデルの有効性の明確な評価に役立ちます。
実世界での応用
線形回帰は、予測や意思決定のためにさまざまな業界で広く使われています。不動産分野では、広さや立地などの要因に基づいて住宅価格を推定します。
営業・マーケティングでは需要予測や予算最適化に、医療では疾患リスク評価に用いられます。金融では株価予測や信用スコアリング、製造では品質管理や故障予測に役立ちます。
線形回帰を使うべき状況
- 特徴量と目的変数の関係が線形である。
- 複雑なモデル化よりも解釈性とシンプルさが重視される。
- 大掛かりな特徴量エンジニアリングを必要としないデータである。
線形回帰を使うべきでない状況
まとめ
線形回帰は、機械学習や統計モデリングにおいて最も基本的かつ広く使われる手法の1つです。シンプルでありながら、変数間の関係を理解し、実世界のさまざまな場面で予測を行うための強力なツールです。
本チュートリアルの主なポイント:
- 幅広い応用。線形回帰は、幅広い業界や課題領域で有益な洞察をもたらします。
- 解釈可能。複雑なブラックボックスモデルと異なり、係数に基づく明確な解釈が可能で、説明しやすい手法です。
- 特徴量選択。適切な特徴量選択と多重共線性への対処により、モデルの正確性・安定性・信頼性を維持できます。
Pythonの文字列補間に関する詳細は、DataCampのリソースをご覧ください。
- 単回帰:知っておくべきすべて - チュートリアル
- Rでの線形回帰の実行方法 - チュートリアル
- Excelでの線形回帰:初心者のための完全ガイド - チュートリアル
- Introduction to Regression in R - コース
- Supervised Learning with scikit-learn - コース
- Scikit-Learn チートシート:Python機械学習 - チートシート
- Pythonで理解するロジスティック回帰 - チュートリアル
Linear Regression Sklearn よくある質問
線形回帰とは何ですか?どのように機能しますか?
線形回帰は、目的変数と1つ以上の予測因子との関係をモデル化する統計手法です。最小二乗法を用いて、実測値と予測値の差を最小化する最適な直線を求めます。
線形回帰の前提条件は何ですか?
線形回帰は次の前提に依存します。
- 線形性:予測因子と目的変数の関係が線形である。
- 独立性:観測が互いに独立である。
- 等分散性:残差の分散が全範囲で一定である。
- 残差の正規性:残差が正規分布に従う。
- 多重共線性なし:独立変数間に強い相関がない。
線形回帰モデルを適合させる前に特徴量をスケーリングすべき理由は?
特徴量のスケーリングは、すべての特徴量がモデルに等しく寄与するようにするためです。線形回帰は特徴量の尺度に敏感なため、数値の大きい変数が小さい変数を支配するのを防ぎます。標準化には StandardScaler() を使用してください。
多重共線性とは何ですか?どのように検出しますか?
多重共線性とは、2つ以上の独立変数が強く相関しており、係数の解釈が不確かになる状態を指します。分散拡大要因(VIF)で検出できます。
線形回帰モデルはどのように評価しますか?
代表的な性能指標は次のとおりです。
- R²(決定係数) → 目的変数の分散をモデルがどれだけ説明できるかを測定。
- MSE(平均二乗誤差) → 実測値と予測値の二乗誤差の平均を測定。
- RMSE(二乗平均平方根誤差) → MSEをより解釈しやすくした指標。