R 線形回帰:lm() の完全ガイド
これまでの3回のレッスンでは、記述統計、確率分布、仮説検定について学びました。これらはすべて「データを分析する」ことに関わっています。今回のレッスンでは、「データを使って未来を予測する」こと、つまり線形回帰へと進みます。これがRの真の「見どころ」です。「1,000,000の投資で5,000,000の売上を生み出す」という広告の主張は、信頼できるものでしょうか?
lm()を使って、たった1行で計算してみましょう。
このレッスンを修了すると、R を使用して線形回帰の分析、予測、係数の解釈、有意性検定、モデルの診断を行うことができるようになります。これらは、データサイエンス業務の 80% を占めています。
1. 学習内容
- 線形回帰の原理(Y = β0 + β1X + ε)
- lm() の数式構文:y ~ x
- summary() の係数の解釈(推定値/標準誤差/p値)
- predict predict()
- 残差診断:plot.lm
- 多重回帰
- カテゴリ変数の取り扱い
- 実践的な応用:売上予測モデル
2. 売上予測に関する話
(1) 課題:広告と営業
ボブは、「広告費」が「売上」に与える影響を予測したいと考えています:
Advertising expenses(0K) Sales(0K)
1 3
2 5
3 7
4 9
5 12
「広告に10,000を費やせば、20,000の売り上げが見込める」というのは「単なる直感」でしょうか? LMを使って正確に計算してみましょう――
(2) Rを用いた解決策
# 1. Model Building in One Line
model <- lm(sales ~ ad, data = df)
# 2. View the results in one line
summary(model)
# Coefficients:
# Estimate Std. Error t value Pr(>|t|)
# (Intercept) 1.0000 0.3536 2.828 0.0474 *
# ad 2.0000 0.1054 18.975 0.0001 ***
# ---
# Residual standard error: 0.3651
# Multiple R-squared: 0.9923
# 3. One-Line Forecast
predict(model, data.frame(ad = 10))
# [1] 21 ← invest $10,000Advertising Sales Forecast 210,000
3行のコード → モデル + 予測。
3. 線形回帰の原理
(1) 数式
Y = β₀ + β₁X + ε
│ │ │
│ │ └─ Error term (Residual)
│ └────── Slope (X increases by 1, Y changes by how much?)
└────────── Intercept (Y value when X=0)
graph LR
A[Actual data points] --> B[Linear Model Fitting]
B --> C[Find the Best Straight Line]
C --> D[Minimize the sum of squared residuals]
D --> E[Least Squares Method OLS]
style A fill:#cce5ff
style B fill:#d4edda
style C fill:#fff3cd
style D fill:#f8d7da
style E fill:#e1d4ff
(2) 核心となる考え方
すべての点からその直線までの「距離の二乗和」が最小となる直線を求める(普通最小二乗法、OLS)。
4. lm() の基本的な使い方
(1) 数式の構文の4つの種類
# 1. y ~ x (Most Commonly Used)
lm(sales ~ ad, data = df)
# 2. y ~ x1 + x2 (Multiple)
lm(sales ~ ad + price, data = df)
# 3. y ~ x1 * x2 (Interaction)
lm(sales ~ ad * price, data = df)
# 4. y ~ . (All other variables)
lm(sales ~ ., data = df)
(2) 最初の回帰分析
# Data
df <- data.frame(
ad = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10),
sales = c(3, 5, 7, 9, 12, 13, 15, 17, 19, 21)
)
# Build a model
model <- lm(sales ~ ad, data = df)
# Abstract
summary(model)
出力の詳細な説明:
Call:
lm(formula = sales ~ ad, data = df)
Residuals:
Min 1Q Median 3Q Max
-0.4 -0.3 0.0 0.3 0.4
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 1.0000 0.2041 4.899 0.00106 **
ad 2.0000 0.0340 58.787 1.01e-12 ***
---
Signif. codes: 0 ‘*’ 0.001 ‘’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 0.3651 on 8 degrees of freedom
Multiple R-squared: 0.9977, Adjusted R-squared: 0.9974
F-statistic: 3456 on 1 and 8 DF, p-value: 1.008e-12
(3) 6つの主要指標の分析
| 項目 | 意味 | 説明 |
|---|---|---|
| 推定値 | 係数の推定値 | ad=2.0 は、広告費が 10,000 増加すると、売上が 20,000 増加することを示す |
| 標準誤差 | 係数の標準誤差 | 係数推定値の精度(数値が小さいほど良い) |
| t値 | t統計量 | 推定値/標準誤差 |
| Pr(>|t|) | p値 | 係数が 有意でない(0) である確率 |
| R² | 決定係数 | モデルによって説明される分散の割合(0~1) |
| F統計量 | F統計量 | 全体モデルの有意性 |
5. predict() の予測
(1) 基本予測
# Single-Point Forecast
predict(model, data.frame(ad = 10))
# [1] 21 ← invest $10,000Advertising Sales Forecast 210,000
# Multi-point Forecasting
new_data <- data.frame(ad = c(11, 12, 13, 14, 15))
predict(model, new_data)
# [1] 23 25 27 29 31
# Confidence Interval
predict(model, data.frame(ad = 10), interval = "confidence")
# fit lwr upr
# 1 21.000 20.751 21.249
(2) 予測区間
# Prediction Range (Includes uncertainty in individual predictions)
predict(model, data.frame(ad = 10), interval = "prediction")
# fit lwr upr
# 1 21.000 20.064 21.936 <- wider than confidence
6. 残差の診断:plot.lm
(1) 4つの主要な診断チャート
par(mfrow = c(2, 2))
plot(model)
| 画像 | 意味 | どうあるべきか |
|---|---|---|
| 1. 残差と推定値 | 残差と推定値 | ランダムに散らばっている(パターンなし) |
| 2. QQプロット | 残差の正規性 | 直線に近い点 |
| 3. スケール・位置 | 等分散性 | 水平線付近 |
| 4. 残差とレバレッジ | レバレッジとその影響 | ほとんどのデータ点は境界から遠く離れている |
(2) 主要な診断
# Residual
residuals(model)
# Standardized Residuals
rstandard(model)
# Leverage Ratio
hatvalues(model)
# Cook's Distance (Impact Metrics)
cooks.distance(model)
7. 多重線形回帰
(1) 多重回帰
# Sales ~ Advertising expenses + Price + Season
df <- data.frame(
sales = c(100, 120, 130, 110, 140, 150, 130, 160, 170, 180),
ad = c(10, 12, 14, 11, 15, 16, 13, 17, 18, 19),
price = c(50, 48, 45, 49, 44, 43, 47, 42, 41, 40),
season = c("Spring", "Summer", "Autumn", "Winter", "Spring", "Summer", "Autumn", "Winter", "Spring", "Summer")
)
model <- lm(sales ~ ad + price + season, data = df)
summary(model)
(2) インタラクティブ項目
# Includes interaction terms (ad:price)
model <- lm(sales ~ ad * price, data = df)
# Equivalent to sales ~ ad + price + ad:price
(3) カテゴリ変数の自動エンコーディング
R character 変数を自動的に ダミー変数 に変換する:
# season is a character vector, R automatically creates:
# seasonSummer, seasonAutumn, seasonWinter (Spring as the Baseline)
as.factor() 明示的な因子変換は、デフォルトの文字よりも安全です。
8. モデルの選択
(1) 調整済みR²
# The more variables you add, R-squared gets bigger (even if the variables are irrelevant)
# Adjusted R-squared corrects this bias
summary(model)$adj.r.squared
(2) AIC(情報量基準)
# AIC The smaller the model, the better
model1 <- lm(sales ~ ad, data = df)
model2 <- lm(sales ~ ad + price, data = df)
model3 <- lm(sales ~ ad + price + season, data = df)
AIC(model1, model2, model3)
# df AIC
# 1 3 85.32
# 2 4 78.45
# 3 6 72.18 ← Best
(3) 段階的な復帰
# Forward
step(lm(sales ~ 1, data = df),
scope = list(lower = ~ 1, upper = ~ ad + price + season),
direction = "forward")
# Back
step(model3, direction = "backward")
# Two-way
step(model1, scope = ~ ad + price + season, direction = "both")
9. 実践的な応用:包括的な売上予測モデル
以下は、このレッスンで取り上げた線形回帰の概念をすべて結びつけた完全なワークフローの例です。
▶ サンプル:統合型販売予測モデル
# ============================================
# Comprehensive Sales Forecasting Model
# Features: The Complete Linear Regression Process (Data Exploration -> Model -> Diagnosis -> Forecast)
# ============================================
library(ggplot2)
library(dplyr)
library(broom)
# 1. Prepare data
set.seed(42)
df <- tibble(
month = 1:24,
sales = round(50 + 5 * (1:24) + rnorm(24, 0, 8)),
ad = round(10 + 2 * (1:24) + rnorm(24, 0, 3)),
price = round(50 - 0.5 * (1:24) + rnorm(24, 0, 2)),
season = rep(c("Spring", "Summer", "Autumn", "Winter"), 6),
region = rep(c("Northern China", "East China", "South China", "Central China"), 6)
)
cat("=== Data Preview ===\n")
print(head(df, 3))
# 2. Data Exploration: Scatter Plot Matrix
cat("\n=== Correlation Analysis ===\n")
cor(df |> select(month, sales, ad, price))
cat("\n")
# 3. Simple Linear Regression
cat("=== Simple Regression: sales ~ ad ===\n")
model1 <- lm(sales ~ ad, data = df)
summary(model1)
# 4. Multiple Regression
cat("\n=== Multiple Regression: sales ~ ad + price + season ===\n")
model2 <- lm(sales ~ ad + price + season, data = df)
summary(model2)
# 5. Full Return
cat("\n=== Full Model: sales ~ ad + price + season + region ===\n")
model3 <- lm(sales ~ ad + price + season + region, data = df)
summary(model3)
# 6. Model Comparison
cat("\n=== Model Comparison ===\n")
cat("Model 1 (Advertisement Only): R-squared =", round(summary(model1)$r.squared, 3),
"Adjusted R-squared =", round(summary(model1)$adj.r.squared, 3), "\n")
cat("Model 2 (+Price+Season): R-squared =", round(summary(model2)$r.squared, 3),
"Adjusted R-squared =", round(summary(model2)$adj.r.squared, 3), "\n")
cat("Model 3 (+Region): R-squared =", round(summary(model3)$r.squared, 3),
"Adjusted R-squared =", round(summary(model3)$adj.r.squared, 3), "\n")
cat("AIC:\n")
print(AIC(model1, model2, model3))
# 7. Model Diagnostics
cat("\n=== Model 3 Residual Diagnosis ===\n")
par(mfrow = c(2, 2))
plot(model3)
par(mfrow = c(1, 1))
# 8. Forecast
cat("\n=== Forecast for Next Month ===\n")
future <- data.frame(
ad = 60,
price = 38,
season = "Autumn",
region = "Northern China"
)
prediction <- predict(model3, future, interval = "confidence")
print(prediction)
cat("\nAnalysis: Sales Forecast for Next Month:", round(prediction[1, "fit"], 1), "10,000 yuan\n")
cat("95% Confidence Interval: [", round(prediction[1, "lwr"], 1), ", ",
round(prediction[1, "upr"], 1), "]\n")
# 9. Residual Analysis
cat("\n=== Residual Analysis ===\n")
df <- df |>
mutate(
fitted = fitted(model3),
residual = resid(model3),
std_residual = rstandard(model3)
)
cat("Maximum Positive Residual:", round(max(df$residual), 2),
" (Sales were higher than expected)\n")
cat("Maximum Negative Residual:", round(min(df$residual), 2),
" (Sales were lower than expected)\n")
cat("Standard Deviation of Residuals:", round(sd(df$residual), 2), "\n\n")
# 10. Coefficient Visualization
coef_df <- tidy(model3, conf.int = TRUE)
print(coef_df |> select(term, estimate, std.error, p.value, conf.low, conf.high))
# 11. Actual vs Fitting a Scatter Plot
ggplot(df, aes(x = fitted, y = sales)) +
geom_point(size = 3, color = "blue") +
geom_abline(slope = 1, intercept = 0, color = "red", linetype = "dashed") +
labs(title = "Actual vs Fitting", x = "Fitted values", y = "Actual value") +
theme_minimal()
# 12. Save Model
saveRDS(model3, "sales_model.rds")
cat("\n=== The model has been saved: sales_model.rds ===\n")
期待される出力(抜粋):
=== Full Model: sales ~ ad + price + season + region ===
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 55.234 8.123 6.801 0.00001 ***
ad 4.876 0.234 20.838 < 2e-16 ***
price -0.432 0.123 -3.512 0.00245 **
seasonSummer 5.234 1.876 2.789 0.01234 *
seasonAutumn 2.123 1.876 1.132 0.27456
seasonWinter -3.456 1.876 -1.842 0.08345 .
regionEast China 8.234 1.876 4.389 0.00045 ***
regionSouth China 3.456 1.876 1.842 0.08345 .
regionCentral China 1.234 1.876 0.658 0.51894
---
Signif. codes: 0 ‘*’ 0.001 ‘’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 4.234 on 15 degrees of freedom
Multiple R-squared: 0.9823, Adjusted R-squared: 0.9734
=== Forecast for Next Month ===
fit lwr upr
1 168.452 162.345 174.559
Analysis: Sales Forecast for Next Month: 168.5 10,000 yuan
95% Confidence Interval: [162.3, 174.6]
❓ よくある質問
step() ③ 情報基準 AIC / BIC を用いて、最も単純なモデルを選択します。📖 まとめ
- 線形回帰:Y = β₀ + β₁X + ε。普通最小二乗法(OLS)を用いて推定される。
lm(y ~ x, data)数式の構文:y ~ x1 + x2多変量 /y ~ x1 * x2交互作用を含む /y ~ .すべてsummary(model)6つの出力項目:推定値(係数)/標準誤差/t値/Pr(>|t|)/R²/F値predict(model, new, interval = "confidence" | "prediction")予報- 4つの診断プロット:残差対推定値/QQ/スケール・ロケーション/レバレッジ
- 多重回帰:複数の独立変数。カテゴリ変数は自動的にダミー変数に変換されます。
- モデル選択:R² / AIC /
step()の調整、ステップワイズ回帰 - 係数:βは、Xが1単位増加すると、他の変数を一定と仮定した場合、Yが平均でβだけ増加することを示している。
- p < 0.05 は係数が有意であることを示す。R² の値が高いほど、モデルの精度が高い(ただし、過学習には注意が必要)。
📝 練習問題
-
基本演習:Rの組み込みデータセット
mtcarsを使用してmpg ~ wt単純線形回帰を行い、summary()を用いてすべての出力を解釈し、wt = 3についてmpgを予測する。 -
基本的な問題:前の問題(
par(mfrow = c(2, 2)); plot(model))のモデルについて、4つの診断プロットを描き、残差が正規分布に従い、等分散であるかどうかを確認しなさい。 -
基本的な問題:多重回帰モデル
mpg ~ wt + cyl + hpを構築し、そのR²値と調整済みR²値を単純回帰のそれと比較してください。どちらが優れていますか? -
応用演習:売上データ(売上対広告費+価格+季節)を100行分シミュレートします。以下の全プロセスを完了させてください:①探索 ②モデリング ③要約 ④診断 ⑤予測 ⑥可視化。モデルをRDSファイルとして保存してください。
-
課題問題:
mtcarsを使用して、完全なモデル選択を行ってください: ① 4つのモデル(wtのみ / wt+cyl / wt+cyl+hp / wt+cyl+hp+disp)を実行する ② AICを用いて比較する ③step()を使用して段階的回帰分析を行う ④anova()を使用してネスト比較を行う ⑤ 最適なモデルを選択し、予測を行う。プロセスを記録するためにスクリーンショットを撮影すること。



