フリーキーズ | 独学プログラミング

単回帰分析入門!1つの変数から未来を予測する基礎をPythonで学ぼう

リンドくん

リンドくん

先生、データサイエンスって「未来を予測できる」って聞いたんですけど、本当ですか?なんだか魔法みたいで...

たなべ

たなべ

確かに魔法みたいに聞こえるけど、実は統計学の基本的な考え方を使えば、誰でも未来の予測ができるようになるんだ。
その第一歩が「単回帰分析」なんだよ。

リンドくん

リンドくん

たんかいき...分析?難しそうな名前ですね...

たなべ

たなべ

名前は難しそうだけど、考え方はとてもシンプルだよ。
例えば「勉強時間が増えればテストの点数も上がる」みたいな関係を数式で表すイメージなんだ。今日はその仕組みを一緒に学んでいこう!

データサイエンスを学び始めた方にとって、未来の数値を予測するというのは最も魅力的なテーマの一つではないでしょうか。

単回帰分析は、そんな予測の世界への入り口となる、最もシンプルで基本的な手法です。1つの変数(説明変数)から別の変数(目的変数)を予測するという、わかりやすい構造を持っています。

この記事では、統計学やプログラミングの初心者でも理解できるよう、単回帰分析の基本概念から実際のPythonコードでの実装まで、段階的に解説していきます。

オンラインコミュニティ運営しています

HackATAは、IT技術を習得する人のために広く開かれたオンラインコミュニティです。 現在、無料コミュニティとして開放していますので、ご気軽に参加してください。

✓ 再立ち上げ

✓ コミュニティの方向性について意見募集中

HackATA公式Webサイト

単回帰分析とは何か?その本質を理解しよう

リンドくん

リンドくん

そもそも「回帰分析」の「回帰」って、何に回帰するんですか?

たなべ

たなべ

面白い質問だね!
実は「回帰」という言葉の由来には歴史的な背景があるんだけど、現代では「データの傾向に戻る」「平均に戻る」という意味で使われているんだよ。

単回帰分析の基本概念

単回帰分析とは、1つの独立変数(説明変数)と1つの従属変数(目的変数)の間の関係を直線で表現し、その関係性を使って予測を行う統計手法です。

もっと簡単に言えば、「AとBの間にどんな関係があるのか」を見つけ出し、「Aがこの値のとき、Bはどのくらいになりそうか」を予測する方法なのです。

例えば、以下のような関係を調べることができます。

  • 勉強時間と試験の点数 → 勉強時間が増えれば点数も上がる?
  • 広告費と売上 → 広告にお金をかけるほど売上は伸びる?
  • 気温とアイスの売上 → 暑い日ほどアイスは売れる?

これらはすべて、1つの要因(説明変数)が別の結果(目的変数)にどう影響するかを調べる問題です。

直線で関係を表すということ

単回帰分析の特徴は、2つの変数の関係を1本の直線で表現することです。中学校で習った一次関数を思い出してください。

y = ax + b

この式で、単回帰分析では以下のように表現します。

y = β₁x + β₀

ここで、それぞれの記号の意味は以下の通りです。

  • y: 予測したい値(目的変数)
  • x: 予測に使う値(説明変数)
  • β₁: 傾き(回帰係数)
  • β₀: 切片(定数項)

この式が意味するのは、「xが1増えたとき、yはβ₁だけ増える(または減る)」ということです。そして、β₀は「xが0のときのyの値」を表しています。

なぜ直線なのか?

データの関係を表す方法は他にもあるのに、なぜ直線を使うのでしょうか?

その理由は以下の通りです。

  • シンプルで理解しやすい → 複雑な曲線よりも解釈が容易です
  • 計算が比較的簡単 → コンピュータでの処理が高速です
  • 基礎として重要 → より複雑な分析の土台になります
  • 多くの現象で近似できる → 実際のデータで十分な精度が得られることが多いです

もちろん、すべての関係が直線で表せるわけではありません。しかし、まずは単回帰分析で基礎を固めることが、データサイエンスの第一歩となるのです。

単回帰分析の仕組み - 最小二乗法って何?

リンドくん

リンドくん

でも先生、データって完全に直線上には並んでないですよね?どうやって「最適な直線」を見つけるんですか?

たなべ

たなべ

鋭い質問だね!確かに実際のデータは散らばっているよね。その中で「最も当てはまりの良い直線」を数学的に見つける方法が「最小二乗法」なんだ。

最小二乗法の考え方

最小二乗法とは、実際のデータと予測値の差(誤差)を最小にする直線を見つける方法です。

具体的には、以下のステップで最適な直線を決定します。

  1. すべてのデータ点について、実際の値と予測値の差を計算する
  2. その差を2乗する(プラスとマイナスが打ち消し合わないようにするため)
  3. すべての2乗した差を合計する
  4. この合計が最小になるような傾きと切片を見つける

数式で表すと、以下のようになります。

最小化したい値 = Σ(実際の値 - 予測値)²

この「2乗した誤差の合計」を最小にすることから、「最小二乗法」と呼ばれているのです。

なぜ誤差を2乗するのか?

ここで疑問に思う方もいるかもしれません。なぜ単純に誤差の合計ではなく、2乗した誤差の合計を使うのでしょうか?

理由は以下の通りです。

  • プラスとマイナスの誤差が打ち消し合わない → 上にずれた誤差と下にずれた誤差を同等に扱えます
  • 大きな誤差をより重視できる → 2乗することで、大きく外れた点により大きなペナルティを課せます
  • 数学的に扱いやすい → 微分を使って最適解を求めやすくなります

実際の計算の流れ

最小二乗法を使って最適な直線を見つける具体的な計算式は以下のようになります。

傾き(β₁)の計算

β₁ = Σ[(x - x̄)(y - ȳ)] / Σ(x - x̄)²

切片(β₀)の計算

β₀ = ȳ - β₁x̄

ここで、x̄とȳはそれぞれxとyの平均値を表します。

この計算は手作業でも可能ですが、Pythonのライブラリを使えば一瞬で完了します。次のセクションでは、実際にPythonを使った実装方法を見ていきましょう。

Pythonで単回帰分析を実装してみよう

リンドくん

リンドくん

理論はなんとなくわかったんですけど、実際にコードを書くのは難しいですか?

たなべ

たなべ

安心して!scikit-learnというライブラリを使えば、たった数行のコードで単回帰分析ができるんだよ。一緒にやってみよう!

必要なライブラリのインストール

まず、必要なライブラリをインストールします。ターミナルやコマンドプロンプトで以下を実行してください。

pip install numpy pandas matplotlib scikit-learn

基本的な単回帰分析のコード

それでは、実際のコードを見ていきましょう。ここでは、勉強時間と試験の点数の関係を分析する例を使います。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error, r2_score

# サンプルデータの作成
# 勉強時間(時間)
study_hours = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]).reshape(-1, 1)
# 試験の点数
test_scores = np.array([45, 51, 54, 63, 68, 72, 78, 83, 88, 95])

# 単回帰モデルの作成
model = LinearRegression()

# モデルの学習(データを使って最適な直線を見つける)
model.fit(study_hours, test_scores)

# 予測値の計算
predicted_scores = model.predict(study_hours)

# 結果の表示
print(f"傾き(回帰係数): {model.coef_[0]:.2f}")
print(f"切片: {model.intercept_:.2f}")
print(f"決定係数(R²): {r2_score(test_scores, predicted_scores):.3f}")
print(f"平均二乗誤差(MSE): {mean_squared_error(test_scores, predicted_scores):.2f}")

# グラフの描画
plt.figure(figsize=(10, 6))
plt.scatter(study_hours, test_scores, color='blue', label='実際のデータ')
plt.plot(study_hours, predicted_scores, color='red', linewidth=2, label='回帰直線')
plt.xlabel('勉強時間(時間)', fontsize=12)
plt.ylabel('試験の点数', fontsize=12)
plt.title('勉強時間と試験の点数の関係', fontsize=14)
plt.legend()
plt.grid(True, alpha=0.3)
plt.show()

# 新しいデータで予測してみる
new_study_hours = np.array([[12]])
predicted_score = model.predict(new_study_hours)
print(f"\n12時間勉強した場合の予測点数: {predicted_score[0]:.1f}点")

コードの解説

上記のコードを詳しく見ていきましょう。

データの準備

study_hours = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]).reshape(-1, 1)
test_scores = np.array([45, 51, 54, 63, 68, 72, 78, 83, 88, 95])

ここでは、勉強時間と試験の点数のサンプルデータを作成しています。reshape(-1, 1)は、データを2次元配列に変換するために必要な処理です。

モデルの作成と学習

model = LinearRegression()
model.fit(study_hours, test_scores)

LinearRegression()で単回帰モデルを作成し、fit()メソッドでデータを学習させます。この時点で、最小二乗法により最適な傾きと切片が自動的に計算されます。

予測の実行

predicted_scores = model.predict(study_hours)

学習済みのモデルを使って、各勉強時間に対する予測点数を計算します。

モデルの評価

print(f"決定係数(R²): {r2_score(test_scores, predicted_scores):.3f}")
print(f"平均二乗誤差(MSE): {mean_squared_error(test_scores, predicted_scores):.2f}")

ここでは、モデルの性能を評価しています。決定係数(R²)は0から1の値を取り、1に近いほど予測精度が高いことを示します。

結果の読み方

このコードを実行すると、以下のような情報が得られます。

  • 傾き(回帰係数): 勉強時間が1時間増えると、点数が何点上がるかを示します
  • 切片: 勉強時間が0時間のときの予測点数(理論値)です
  • 決定係数(R²): モデルの当てはまりの良さを示す指標です
  • グラフ: 実際のデータと回帰直線が視覚的に確認できます

これらの情報から、勉強時間と試験の点数の間にどのような関係があるのか、数値的にも視覚的にも理解できるようになります。

単回帰分析の評価指標を理解しよう

リンドくん

リンドくん

コードは動いたんですけど、「決定係数」とか「平均二乗誤差」とか、数字がたくさん出てきて混乱します...

たなべ

たなべ

確かに最初は戸惑うよね。でもこれらの指標は、「作ったモデルがどれくらい信頼できるか」を教えてくれる大事な情報なんだ。一つずつ見ていこう!

決定係数(R²スコア)

決定係数は、モデルがデータをどれだけうまく説明できているかを示す指標で、最も重要な評価基準の一つです。

値の範囲と意味

  • 1.0に近い: モデルの予測精度が非常に高い
  • 0.5前後: ある程度の予測能力がある
  • 0に近い: モデルの予測能力が低い
  • マイナスの値: モデルが平均値よりも悪い予測をしている

例えば、R² = 0.95という結果が出た場合、「データのばらつきの95%をこのモデルで説明できている」と解釈できます。

平均二乗誤差(MSE)

MSEは、予測値と実際の値の差を2乗したものの平均を表します。

MSE = Σ(実際の値 - 予測値)² / データ数

特徴

  • 値が小さいほど予測精度が高いことを示します
  • 単位は目的変数の2乗になります
  • 大きな誤差に対してペナルティが大きくなります

平均絶対誤差(MAE)

MAEは、予測値と実際の値の差の絶対値の平均です。

from sklearn.metrics import mean_absolute_error

mae = mean_absolute_error(test_scores, predicted_scores)
print(f"平均絶対誤差(MAE): {mae:.2f}")

MSEとの違い

  • 解釈しやすい: 元のデータと同じ単位で表されます
  • 外れ値に強い: 大きな誤差があっても影響を受けにくいです

単回帰分析を使う際の注意点とよくある間違い

リンドくん

リンドくん

単回帰分析って便利そうですね!どんなデータでも使えるんですか?

たなべ

たなべ

実は、そこが大事なポイントなんだ。単回帰分析には「使える条件」と「使えない条件」があるんだよ。間違った使い方をすると、とんでもない結論を導いてしまうこともあるから注意が必要なんだ。

相関と因果の違い

単回帰分析を学ぶ上で最も重要な注意点は、相関関係と因果関係は別物だということです。

相関関係: 2つの変数が一緒に変動する関係 因果関係: 1つの変数が原因で、もう1つの変数が結果として変化する関係

例えば、以下のような例を考えてみましょう。

# 間違った解釈の例
# アイスクリームの売上と熱中症の発生件数には強い相関がある
# → でも、アイスを食べると熱中症になるわけではない!
# → 実際は「気温」という共通の原因がある

このように、相関があっても因果関係があるとは限らないのです。単回帰分析は相関を見つける手法であって、因果関係を証明する手法ではありません。

外れ値の影響

単回帰分析は外れ値(極端に大きい、または小さい値)の影響を受けやすいという特徴があります。

# 外れ値の影響を確認するコード
import numpy as np
from sklearn.linear_model import LinearRegression

# 通常のデータ
x_normal = np.array([1, 2, 3, 4, 5]).reshape(-1, 1)
y_normal = np.array([2, 4, 6, 8, 10])

# 外れ値を追加
x_with_outlier = np.array([1, 2, 3, 4, 5, 6]).reshape(-1, 1)
y_with_outlier = np.array([2, 4, 6, 8, 10, 50])  # 50が外れ値

# それぞれでモデルを作成
model_normal = LinearRegression().fit(x_normal, y_normal)
model_outlier = LinearRegression().fit(x_with_outlier, y_with_outlier)

print(f"通常データの傾き: {model_normal.coef_[0]:.2f}")
print(f"外れ値を含むデータの傾き: {model_outlier.coef_[0]:.2f}")

外れ値が1つあるだけで、回帰直線の傾きが大きく変わってしまうことがあります。データを分析する前に、必ず散布図を描いて外れ値の有無を確認しましょう。

線形関係の前提

単回帰分析は、データが直線的な関係にあることを前提としています。

以下のような関係には適していません。

  • 二次曲線的な関係: y = x²のような関係
  • 指数関数的な関係: y = e^xのような関係
  • 対数的な関係: y = log(x)のような関係

これらの関係を無理やり直線で近似しようとすると、予測精度が著しく低下します。

データ数の問題

単回帰分析を行う際は、十分なデータ数が必要です。

一般的な目安として、以下のような基準があります。

  • 最低限: 10〜20個のデータ点
  • 推奨: 30個以上のデータ点
  • 理想: 100個以上のデータ点

データが少なすぎると、偶然の関係を見つけてしまう可能性が高くなります。

まとめ

リンドくん

リンドくん

なるほど!単回帰分析って、思っていたよりシンプルで、でも奥が深いんですね。

たなべ

たなべ

その通り!単回帰分析はデータサイエンスの基礎中の基礎だけど、だからこそしっかり理解することが大切なんだ。
ここで学んだことは、今後の学習すべての土台になるよ。

この記事では、単回帰分析の基本から実践的な使い方まで、段階的に解説してきました。重要なポイントを振り返ってみましょう。

基本概念の理解

  • 1つの説明変数から目的変数を予測する手法
  • 最小二乗法により最適な直線を見つける
  • 数式とコードの両面から理解を深める

Pythonでの実装

  • scikit-learnを使えば数行で実装可能
  • データの準備からモデルの評価まで一貫して実行
  • 視覚化により直感的に理解できる

評価と注意点

  • R²スコアやMSEでモデルの性能を評価
  • 相関と因果の違いを理解する
  • 外れ値や線形性の前提に注意する

データサイエンスは、実践を通じて学ぶことが最も効果的です。今日学んだ単回帰分析を、ぜひ自分の手で実際に試してみてください。
身近なデータから始めてみましょう。

小さな成功体験を積み重ねることで、データサイエンスのスキルは確実に向上していきます。

この記事をシェア

関連するコンテンツ