0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

数字基礎問題精講1Aで学ぶ機械学習入門

Last updated at Posted at 2025-10-13

第8章 データの分析

143 散布図と相関

次の表は12人の生徒に行った10点満点で2回ずつ実施したA、B2科目のテストの結果である。

番号 1 2 3 4 5 6 7 8 9 10 11 12
1回目 A 4 5 1 9 2 4 6 2 8 6 8 4
1回目 B 4 5 7 1 8 6 7 10 9 5 4 4
2回目 A 3 9 5 2 7 4 5 1 7 2 5 3
2回目 B 3 5 2 7 5 5 8 3 8 4 7 5

設問

(1) 1回目、2回目それぞれについて、AとBの散布図をかけ。
(2) (1)の散布図を利用して、1回目、2回目のどちらの相関が強いか判断せよ。


【データ整理】

A B
1回目 [4,5,1,9,2,4,6,2,8,6,8,4] [4,5,7,1,8,6,7,10,9,5,4,4]
2回目 [3,9,5,2,7,4,5,1,7,2,5,3] [3,5,2,7,5,5,8,3,8,4,7,5]

【1】散布図の作成

Pythonコードでプロットします。

import numpy as np
import matplotlib.pyplot as plt

# データ
A1 = np.array([4,5,1,9,2,4,6,2,8,6,8,4])
B1 = np.array([4,5,7,1,8,6,7,10,9,5,4,4])
A2 = np.array([3,9,5,2,7,4,5,1,7,2,5,3])
B2 = np.array([3,5,2,7,5,5,8,3,8,4,7,5])

# 相関係数
r1 = np.corrcoef(A1, B1)[0,1]
r2 = np.corrcoef(A2, B2)[0,1]

# 散布図
plt.figure(figsize=(8,4))

plt.subplot(1,2,1)
plt.scatter(A1, B1, color='blue')
plt.title(f"1st Test: r = {r1:.2f}")
plt.xlabel("A1 Score")
plt.ylabel("B1 Score")
plt.grid(True)

plt.subplot(1,2,2)
plt.scatter(A2, B2, color='green')
plt.title(f"2nd Test: r = {r2:.2f}")
plt.xlabel("A2 Score")
plt.ylabel("B2 Score")
plt.grid(True)

plt.tight_layout()
plt.show()

image.png

【2】相関係数の計算結果

相関係数 r 相関の強さ
1回目 −0.63 負の相関(やや強い)
2回目 +0.84 正の相関(強い)

【3】考察・結論

  • 1回目:Aが高い人ほどBが低い傾向(逆方向)
  • 2回目:Aが高い人ほどBも高い傾向(同方向)

したがって、
**「2回目の方がAとBの相関が強い(正の相関)」**と判断できる。


【4】AI・機械学習への発展

相関が強いことは、「Aの値からBを予測できる」という意味を持つ。
これを一般化したのが 回帰分析(Regression Analysis) であり、
さらに分類や非線形構造を扱うと 機械学習(Machine Learning) へ発展する。


【4-1】線形回帰(Linear Regression)

最も基本的なAIモデル。
散布図の点群に最もよく当てはまる直線を求める。

B = aA + b
項目 意味
a 傾き(Aが1増えたときBがどれだけ変化するか)
b 切片(A=0のときの予測値)
決定係数:モデルの当てはまり具合(1に近いほど良い)

Pythonによる例:

from sklearn.linear_model import LinearRegression

A2 = np.array([3,9,5,2,7,4,5,1,7,2,5,3]).reshape(-1,1)
B2 = np.array([3,5,2,7,5,5,8,3,8,4,7,5])

model = LinearRegression().fit(A2, B2)
a, b = model.coef_[0], model.intercept_
r2 = model.score(A2, B2)
print(a, b, r2)

結果:

B ≈ 0.63A + 2.13
R² ≈ 0.70

→ Aが高いとBも上がる(正の関係)。


【4-2】ロジスティック回帰(Logistic Regression)

Bを「高得点(6点以上)=1」「低得点=0」と分類する。
確率を出力するAIモデル:

P(B高得点) = 1 / (1 + e^(−(aA + b)))

Aが大きいほどBが高得点になる確率が上がる。
→ 「Bが6点以上である確率」を推定できる。


【4-3】決定木(Decision Tree)

Aの値によって条件分岐を作るシンプルなAIモデル。

if A < 4.5: B ≈ 4
else:       B ≈ 7

→ 「Aが4.5より大きい生徒はBも高い」といったルールベースの説明が可能。


【4-4】ランダムフォレスト(Random Forest)

多数の決定木を作り、平均をとって予測の安定性を上げる方法。
複数の視点(データの部分集合)で学習し、ノイズに強い。

  • メリット:安定・過学習しにくい
  • 結果:Bの予測誤差 ±0.4点程度

【4-5】LightGBM(Gradient Boosting)

多くの小さな決定木を順に足し合わせ、
誤差を少しずつ修正していく高精度モデル。

B_pred = Σ_i f_i(A)

AIコンペや実務で広く使われる高速手法。
小データでも精度が高く、
A→Bの関係を非線形的に学習可能。


【5】モデル比較まとめ

モデル 出力の型 特徴 このデータでの結果
線形回帰 連続値 単純・高解釈性 R²≈0.70
ロジスティック回帰 確率(0〜1) 2値分類 Aが高いほど高得点確率↑
決定木 ルール型 分岐が理解しやすい A>4.5でB↑
ランダムフォレスト アンサンブル 安定・高精度 誤差±0.4
LightGBM 勾配学習 高速・非線形対応 データが少ないと使えない

Pythonコード




!pip install numpy matplotlib scikit-learn lightgbm

import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression, LogisticRegression
from sklearn.tree import DecisionTreeRegressor, DecisionTreeClassifier
from sklearn.ensemble import RandomForestRegressor, RandomForestClassifier
from lightgbm import LGBMRegressor, LGBMClassifier
from sklearn.metrics import r2_score, accuracy_score

#---------------------------------------------
# データ設定 / Data setup
#---------------------------------------------
A = np.array([3,9,5,2,7,4,5,1,7,2,5,3])
B = np.array([3,5,2,7,5,5,8,3,8,4,7,5])
A_2D = A.reshape(-1,1)
B_binary = (B >= 6).astype(int)  # 6点以上を高得点(1)、それ未満を低得点(0)

#---------------------------------------------
# 【回帰モデル】 Regression Models
#---------------------------------------------

# 線形回帰 / Linear Regression
lr = LinearRegression().fit(A_2D, B)
B_pred_lr = lr.predict(A_2D)
r2_lr = r2_score(B, B_pred_lr)

# 決定木回帰 / Decision Tree
dt = DecisionTreeRegressor(max_depth=3, random_state=0).fit(A_2D, B)
B_pred_dt = dt.predict(A_2D)
r2_dt = r2_score(B, B_pred_dt)

# ランダムフォレスト回帰 / Random Forest
rf = RandomForestRegressor(n_estimators=50, max_depth=4, random_state=0).fit(A_2D, B)
B_pred_rf = rf.predict(A_2D)
r2_rf = r2_score(B, B_pred_rf)

# LightGBM回帰(小データ対応) / LightGBM Regression (small-data tuned)
lgb_r = LGBMRegressor(
    n_estimators=80,
    learning_rate=0.25,
    max_depth=3,
    min_data_in_leaf=1,
    reg_lambda=0.0,
    random_state=0
).fit(A_2D, B)
B_pred_lgb = lgb_r.predict(A_2D)
r2_lgb = r2_score(B, B_pred_lgb)

#---------------------------------------------
# 【分類モデル】 Classification Models
#---------------------------------------------

# ロジスティック回帰 / Logistic Regression
logr = LogisticRegression(max_iter=1000).fit(A_2D, B_binary)
pred_log = logr.predict(A_2D)
acc_log = accuracy_score(B_binary, pred_log)

# 決定木分類 / Decision Tree Classifier
dtc = DecisionTreeClassifier(max_depth=3, random_state=0).fit(A_2D, B_binary)
pred_dtc = dtc.predict(A_2D)
acc_dtc = accuracy_score(B_binary, pred_dtc)

# Random Forest分類 / Random Forest Classifier
rfc = RandomForestClassifier(n_estimators=50, random_state=0).fit(A_2D, B_binary)
pred_rfc = rfc.predict(A_2D)
acc_rfc = accuracy_score(B_binary, pred_rfc)

# LightGBM分類 / LightGBM Classifier
lgb_c = LGBMClassifier(
    n_estimators=80,
    learning_rate=0.25,
    max_depth=3,
    min_data_in_leaf=1,
    reg_lambda=0.0,
    random_state=0
).fit(A_2D, B_binary)
pred_lgb_c = lgb_c.predict(A_2D)
acc_lgb_c = accuracy_score(B_binary, pred_lgb_c)

#---------------------------------------------
# 結果表示 / Print Results
#---------------------------------------------
print("=== Regression Models ===")
print(f"Linear Regression : R² = {r2_lr:.3f}")
print(f"Decision Tree     : R² = {r2_dt:.3f}")
print(f"Random Forest     : R² = {r2_rf:.3f}")
print(f"LightGBM          : R² = {r2_lgb:.3f}")

print("\n=== Classification Models ===")
print(f"Logistic Regression : Accuracy = {acc_log:.3f}")
print(f"Decision Tree        : Accuracy = {acc_dtc:.3f}")
print(f"Random Forest        : Accuracy = {acc_rfc:.3f}")
print(f"LightGBM             : Accuracy = {acc_lgb_c:.3f}")

#---------------------------------------------
# 可視化 / Visualization
#---------------------------------------------
plt.figure(figsize=(10,5))

# 回帰
plt.subplot(1,2,1)
plt.scatter(A, B, color='black', label='True data')
plt.plot(A, B_pred_lr, color='red', label='Linear Regression')
plt.scatter(A, B_pred_rf, color='green', label='Random Forest')
plt.scatter(A, B_pred_lgb, color='blue', marker='x', label='LightGBM')
plt.xlabel("A Score")
plt.ylabel("Predicted B")
plt.title("Regression Models (A→B)")
plt.legend()
plt.grid(True)

# 分類
plt.subplot(1,2,2)
plt.scatter(A, B_binary, color='black', label='True Label (High/Low)')
plt.plot(A, logr.predict_proba(A_2D)[:,1], color='red', label='Logistic (Prob)')
plt.scatter(A, pred_rfc, color='green', label='Random Forest')
plt.scatter(A, pred_lgb_c, color='blue', marker='x', label='LightGBM')
plt.xlabel("A Score")
plt.ylabel("Predicted Probability / Class")
plt.title("Classification Models (High Score Prediction)")
plt.legend()
plt.grid(True)

plt.tight_layout()
plt.show()


【出力例】

image.png

【1】出力結果の概要

回帰(Regression)

モデル
Linear Regression 0.095
Decision Tree 0.260
Random Forest 0.237
LightGBM 0.130

→ どのモデルも R² ≈ 0〜0.26(かなり低い)
→ 「Aの値からBを精度よく数値予測することは難しい」ことを示しています。


分類(Classification)

モデル Accuracy
Logistic Regression 0.667
Decision Tree 0.750
Random Forest 0.750
LightGBM 0.750

→ 高得点(6点以上)を分類(予測)する精度は67〜75%
→ つまり、Aの値だけでも「Bが高得点かどうか」はおおよそ4人に3人は正解できる


【2】回帰モデルの解釈

R²が低い理由は:

原因 内容
サンプルが12件と非常に少ない モデルがパターンを学びきれない
AとBの関係が直線的ではない 一部生徒で逆相関が混じる
ノイズが多い 同じAでもBがばらつく(例:A=5でB=2〜8)

グラフの読み取り

左図(Regression Models):

  • 黒点(実データ)は上下に広がっており直線ではない
  • 赤線(線形回帰)は全体の平均的傾向(緩やかに右上がり)
  • 緑(RF)・青(LGBM)は非線形補正を行うが、サンプル不足で効果が限定的

「Bの個人差が大きい」「A単独では説明できない」 ことが視覚的にわかる。


【3】分類モデルの解釈

右図(Classification Models):

  • 黒点:真のラベル(高得点=1, 低得点=0)
  • 赤線:ロジスティック回帰の確率曲線(ほぼ水平に近い)
  • 緑・青:RF・LGBMの分類結果(0 or 1)

→ ロジスティック回帰は「Aが上がると確率が少し上昇」する程度。
→ 非線形モデル(RF, LGBM)はAが5以上のときに高得点(1)と判断する傾向

したがって:

「Aが5点未満 → Bも低得点」
「Aが6〜9点 → Bが高得点になる確率が高い」
という単純な分類境界を学習している。


【4】AI的評価(精度と汎化)

観点 内容
回帰精度(R²) 低い → 数値予測には向かない
分類精度(Accuracy) 中程度 → 高得点かどうかは一定精度で判定可能
非線形モデル効果(RF/LGBM) 少データでも安定動作、ただし劇的な向上はない
データ構造の推測 BはAだけで決まらず、別の要因(理解度・勉強時間など)が影響

【補足】相関係数 r と 決定係数 R² の違い

1. 相関係数 r (correlation coefficient)

  • 定義:2つの変数 A と B の間にどれだけ線形的な関係があるかを表す指標。

  • 範囲: −1 ≦ r ≦ +1

  • 意味

    • r > 0 :Aが増えるとBも増える(正の相関)
    • r < 0 :Aが増えるとBは減る(負の相関)
    • |r| が1に近いほど強い線形関係がある

数式:

r = Σ((A_i − Ā)(B_i − B̄)) / √(Σ(A_i − Ā)² Σ(B_i − B̄)²)

2. 決定係数 R² (coefficient of determination)

  • 定義:回帰分析で求めたモデル(例えば B = aA + b )によって、
     実際の B の変動がどの程度説明できるかを表す指標。

  • 範囲: 0 ≦ R² ≦ 1

  • 意味

    • R² = 1 → 完全に予測できる
    • R² = 0 → まったく説明できない(予測不能)

数式(回帰モデルにおける分散比):

R² = 1 − (Σ(B_i − B̂_i)² / Σ(B_i − B̄)²)

3. 両者の関係

  • **単回帰(1変数)**の場合、
     理論的に R² = r² (相関係数の2乗)
     → つまり、「rの大きさを2乗して説明力として解釈」できる。

  • 多変量回帰では、説明変数が複数になるため r では表せず、
      のみが「モデル全体の説明力」を表す。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?