R EDA:探索的データ分析――包括的な方法論
これまでの6回のレッスンでは、記述統計、確率分布、仮説検定、回帰分析について学びましたが、これらはすべて「分析」ツールです。しかし、データ分析の第一歩はモデリングではありません。むしろ、EDA(探索的データ分析)、つまりデータが「どのような様子か」を探ることなのです。このレッスンでは、Rを用いたEDAの手法を包括的に学びます。
このレッスンを修了すると、R を使用して、あらゆるデータセットを徹底的に分析できるようになります。これには、データの形状、分布、外れ値、欠損値、相関関係などが含まれ、今後のモデリングに向けた基礎を築くことができます。
1. 学習内容
- EDAプロセスの全容(5つのステップ)
- データの形状:str / dim / nrow / ncol
- 分布:概要 / skimr
- 欠損値: md.pattern / naniar
- 分布の可視化:ヒストグラム/箱ひげ図/密度プロット
- 関係性:散布図/相関行列
- 外れ値:箱ひげ図+四分位範囲(IQR)
- 自動化EDA(DataExplorer / SmartEDA)
2. 馴染みのないデータセットに伴う課題
(1) 課題:100列のCSVファイルの処理は、どこから手をつければよいでしょうか?
ボブは、100列、10,000行からなる顧客データのデータセットを受け取り、上司から「まずはこのデータを見てみて」と言われた。彼は5分間、Excelファイルを見つめ続けたが、どこから手をつければいいのかわからなかった。
(2) Rを用いた解決策
library(DataExplorer)
# One line EDA Report
create_report(df, output_file = "eda_report.html")
1行のコード → EDA HTMLレポートの完成(30ページ以上のグラフや統計データ)。
3. EDAプロセスの全容(5つのステップ)
(1) 5ステップ法
graph TB
A[1. Data Shape] --> B[2. Data Types]
B --> C[3. Missing Value Analysis]
C --> D[4. Distribution Exploration]
D --> E[5. Exploring Relationships]
A --> A1[dim/str/head]
B --> B1[summary/skimr]
C --> C1[md.pattern/naniar]
D --> D1[Histogram/Box plot]
E --> E1[Scatter/Correlation Matrix]
style A fill:#fff3cd
style B fill:#cce5ff
style C fill:#d4edda
style D fill:#f8d7da
style E fill:#e1d4ff
(2) 5ステップのクイックリファレンス
| ステップ | 目的 | 主な機能 |
|---|---|---|
| 1. 形状 | データの規模はどのくらいか? | dim() nrow() ncol() str() |
| 2. データ型 | 列のデータ型は何か? | sapply(df, class) summary() |
| 3. 欠落 | いくつ欠落しているか? | colSums(is.na()) skimr naniar |
| 4. 分布 | 数値範囲? | hist() boxplot() geom_density() |
| 5. 関係性 | 列間に関連性はあるか? | pairs() cor() corrplot |
4. ステップ1:データの整形
# Prepare the data
df <- iris # Use iris as demo
# Basic Information
dim(df) # [1] 150 5 ← 150 row 5 col
nrow(df) # [1] 150
ncol(df) # [1] 5
names(df) # Listed
str(df) # Structure
# 'data.frame': 150 obs. of 5 variables:
# $ Sepal.Length: num 5.1 4.9 4.7 4.6 5 ...
# $ Sepal.Width : num 3.5 3 3.2 3.1 3.6 ...
# $ Petal.Length: num 1.4 1.4 1.3 1.5 1.4 ...
# $ Petal.Width : num 0.2 0.2 0.2 0.2 0.2 ...
# $ Species : Factor w/ 3 levels "setosa",...
# Data Preview
head(df, 3) # First 3 rows
tail(df, 3) # Last 3 rows
5. ステップ2:論文の種類と要旨
(1) 数値型列とカテゴリ型列
# Column Types
sapply(df, class)
# Sepal.Length Sepal.Width Petal.Length Petal.Width Species
# "numeric" "numeric" "numeric" "numeric" "factor"
# Automatic Recognition
library(dplyr)
df |> summarise(across(everything(), class))
(2) summary()—1行の要約
summary(iris)
# Sepal.Length Sepal.Width Petal.Length Petal.Width
# Min. :4.30 Min. :2.00 Min. :1.00 Min. :0.1
# 1st Qu.:5.10 1st Qu.:2.80 1st Qu.:1.60 1st Qu.:0.3
# Median :5.80 Median :3.00 Median :4.35 Median :1.3
# Mean :5.84 Mean :3.05 Mean :3.76 Mean :1.2
# 3rd Qu.:6.40 3rd Qu.:3.30 3rd Qu.:5.10 3rd Qu.:1.8
# Max. :7.90 Max. :4.40 Max. :6.90 Max. :2.5
# Species
# setosa :50
# versicolor:50
# virginica :50
(3) skimr 詳細概要
install.packages("skimr")
library(skimr)
skim(iris)
# ── Data Summary ────────────────────────
# Values
# Number of rows 150
# Number of columns 5
# ── Variable type: factor ──
# Species: 1 unique, 50 each
# ── Variable type: numeric ──
# Sepal.Length: mean=5.84, sd=0.83, p0=4.3, p25=5.1, p50=5.8, p75=6.4, p100=7.9
# ... (Each variable 20+ metrics)
6. ステップ3:欠損値の分析
(1) 欠損値に関する統計
# Simulating Data with Missing Values
df <- data.frame(
a = c(1, 2, NA, 4),
b = c("x", NA, "z", "w"),
c = c(NA, 2, 3, NA)
)
# Number of missing values
colSums(is.na(df))
# a b c
# 1 1 2
# Proportion of Missing Values
colMeans(is.na(df)) * 100
# a b c
# 25 25 50
# Entire rows with NA
sum(!complete.cases(df)) # [1] 3
(2) naniar:欠損値の高度な可視化
install.packages("naniar")
library(naniar)
# Missing Value Patterns
vis_miss(iris) # iris has no missing values, can draw empty chart
# Simulation with Missing Values
df_with_na <- iris
df_with_na[sample(150, 20), 1] <- NA
df_with_na[sample(150, 10), 3] <- NA
vis_miss(df_with_na)
# Missing Correlation
gg_miss_upset(df_with_na)
# Missing vs Variable Relationships
ggplot(df_with_na, aes(x = Sepal.Length, y = Petal.Length)) +
geom_miss_point() # The red dot indicates a missing item.
7. ステップ4:分布の可視化
(1) 単変量分布
library(ggplot2)
# Histogram
ggplot(iris, aes(x = Sepal.Length)) +
geom_histogram(bins = 30, fill = "skyblue", color = "white") +
labs(title = "Sepal.Length Distribution")
# Density Plot
ggplot(iris, aes(x = Sepal.Length, fill = Species)) +
geom_density(alpha = 0.5) +
labs(title = "Sepal.Length Distribution by Species")
# Box-and-Whisker Plot (Identifying Outliers)
ggplot(iris, aes(y = Sepal.Length)) +
geom_boxplot(fill = "lightblue", outlier.color = "red") +
labs(title = "Sepal.Length Box-and-Whisker Plot")
# Box-and-Whisker Plot by Species
ggplot(iris, aes(x = Species, y = Sepal.Length, fill = Species)) +
geom_boxplot() +
labs(title = "Sepal.Length Distribution by Species")
(2) 多変量分布
# Scatter Plot + Return
ggplot(iris, aes(x = Sepal.Length, y = Petal.Length, color = Species)) +
geom_point(size = 3) +
geom_smooth(method = "lm", se = FALSE) +
labs(title = "Sepal vs Petal Length")
# Pair Graphs (Scatter Plot Matrix)
library(GGally)
ggpairs(iris, aes(color = Species))
(3) 相関行列
# CalculateCorrelation Coefficient
cor_matrix <- cor(iris |> select(-Species))
print(round(cor_matrix, 2))
# Visualization of Related Matrices
library(corrplot)
corrplot(cor_matrix, method = "circle", type = "upper")
# ggplot2 Version
library(reshape2)
melted <- melt(cor_matrix)
ggplot(melted, aes(Var1, Var2, fill = value)) +
geom_tile() +
scale_fill_gradient2(low = "blue", high = "red", mid = "white",
midpoint = 0) +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
8. ステップ5:外れ値の検出
(1) IQR法(最もロバストな手法)
detect_outliers <- function(x) {
q1 <- quantile(x, 0.25, na.rm = TRUE)
q3 <- quantile(x, 0.75, na.rm = TRUE)
iqr <- q3 - q1
lower <- q1 - 1.5 * iqr
upper <- q3 + 1.5 * iqr
x < lower | x > upper
}
# Applications
iris |>
mutate(across(where(is.numeric), detect_outliers, .names = "{.col}_out")) |>
select(ends_with("_out")) |>
summarise(across(everything(), sum))
# Sepal.Length_out Sepal.Width_out Petal.Length_out Petal.Width_out
# 0 4 0 0
(2) 3σ法(正規分布するデータにのみ適用可能)
detect_outliers_z <- function(x, threshold = 3) {
z <- (x - mean(x, na.rm = TRUE)) / sd(x, na.rm = TRUE)
abs(z) > threshold
}
9. 自動化されたEDA
(1) DataExplorer
install.packages("DataExplorer")
library(DataExplorer)
# 1. One-Line Report
create_report(iris, output_file = "eda_report.html")
# 2. Report Contents
plot_intro(iris) # Data Overview
plot_missing(iris) # Missing values
plot_histogram(iris) # Histogram of All Numeric Columns
plot_density(iris) # Density Plot
plot_bar(iris) # Bar Chart by Category
plot_boxplot(iris) # Box-and-Whisker Plot
plot_scatterplot(iris) # Scatter Plot Matrix
plot_correlation(iris) # Related Matrices
(2) SmartEDA
install.packages("SmartEDA")
library(SmartEDA)
ExpReport(iris, op_file = "smarteda_report.html")
ExpNumStat(iris) # Statistical Data
ExpCatStat(iris) # Categorical Statistics
10. 完全な例:アイリスおよびMPGデータセットを用いたEDA
以下は、このレッスンで取り上げたすべてのEDAの概念を結びつけた完全なワークフローの例です。
▶ サンプル:Iris データセットおよび MPG データセットの EDA を完了する
# ============================================
# iris + mpg Both Datasets Complete EDA
# Features: 5-step EDA Complete Process
# ============================================
library(ggplot2)
library(dplyr)
library(skimr)
library(naniar)
library(GGally)
# 1. Step 1: Data Shape
cat("=== Step 1: Data Shape ===\n")
cat("iris:", nrow(iris), "rows x", ncol(iris), "cols\n")
cat("mpg:", nrow(mpg), "rows x", ncol(mpg), "cols\n\n")
# 2. Step 2: Type + Abstract
cat("=== Step 2: Type and Abstract ===\n")
cat("iris Column Types:\n")
print(sapply(iris, class))
cat("\nmpg Column Types:\n")
print(sapply(mpg, class))
cat("\niris Summary:\n")
print(summary(iris))
cat("\nmpg Summary:\n")
print(summary(mpg |> select(displ, year, cyl, cty, hwy)))
# 3. Step 3: Missing Value Analysis
cat("\n=== Step 3: Missing values ===\n")
cat("iris Missing values:", sum(is.na(iris)), "\n")
cat("mpg Missing values:", sum(is.na(mpg)), "\n\n")
# Simulation with Missing Data
set.seed(42)
iris_na <- iris
iris_na[sample(150, 20), 1] <- NA
iris_na[sample(150, 10), 3] <- NA
vis_miss(iris_na, cluster = TRUE)
gg_miss_upset(iris_na)
# 4. Step 4: Distribution Visualization
cat("\n=== Step 4: Distribution Visualization ===\n")
# 4.1 Distribution of Numeric Variables
iris |>
select(-Species) |>
pivot_longer(everything(), names_to = "variable", values_to = "value") |>
ggplot(aes(x = value)) +
geom_histogram(bins = 20, fill = "skyblue", color = "white") +
facet_wrap(~ variable, scales = "free") +
labs(title = "iris 4 Distribution of a Numeric Variable")
# 4.2 By Component
ggplot(iris, aes(x = Species, y = Sepal.Length, fill = Species)) +
geom_boxplot() +
labs(title = "Sepal.Length Box-and-Whisker Plot by Species")
# 4.3 Scatter Plot Matrix
ggpairs(iris, aes(color = Species))
# 5. Step 5: Correlation Matrix
cat("\n=== Step 5: Correlation Matrix ===\n")
cor_matrix <- cor(iris |> select(-Species))
print(round(cor_matrix, 2))
library(corrplot)
corrplot(cor_matrix, method = "circle", type = "upper",
addCoef.col = "black", number.cex = 0.8)
# 6. Outlier Detection
cat("\n=== Step 6: Outlier Detection ===\n")
detect_outliers <- function(x) {
q1 <- quantile(x, 0.25, na.rm = TRUE)
q3 <- quantile(x, 0.75, na.rm = TRUE)
iqr <- q3 - q1
lower <- q1 - 1.5 * iqr
upper <- q3 + 1.5 * iqr
sum(x < lower | x > upper, na.rm = TRUE)
}
iris |>
summarise(across(where(is.numeric), detect_outliers)) |>
print()
# 7. Automated Reports
cat("\n=== Step 7: Automated Reports ===\n")
library(DataExplorer)
create_report(iris, output_file = "iris_eda_report.html")
cat("iris_eda_report.html Generated\n")
create_report(mpg, output_file = "mpg_eda_report.html")
cat("mpg_eda_report.html Generated\n")
# 8. Summary of Business Insights
cat("\n=== Business Insights ===\n")
cat("1. iris 4 None of the numerical variables have missing values.\n")
cat("2. Setosa Species' Petal.Length Significantly smaller than the other two\n")
cat("3. Petal.Length and Petal.Width Highly correlated (0.96)\n")
cat("4. Sepal.Width The distribution is approximately normal\n")
cat("5. mpg 11 Numeric variables, 38 Vehicle models\n")
期待される成果物:30ページ以上のEDA HTMLレポートおよび複数の統計グラフ。
❓ よくある質問
📖 まとめ
- 5段階のEDA手法:形状 → タイプ → 欠損 → 分布 → 関係性
- 形状:
dimnrowncolstrデータサイズに応じて - タイプ:
summaryskimr各変数の統計情報を表示 - 欠落:
colSums(is.na)カウント +naniar::vis_miss視覚化 - 分布:
hist/boxplot/density(単変量)+pairs/ggpairs(多変量) - 関連:
cor()+corrplot相関行列の可視化 - 外れ値:IQR法(ロバスト) < Q1 - 1.5×IQR または > Q3 + 1.5×IQR
- 自動化:
DataExplorer::create_report()1行で完全なHTMLレポートを生成する - モデリングを行う前には、EDAが不可欠です。EDAなしではモデリングはできません
- 相関関係 ≠ 因果関係—因果関係を証明できるのは実験だけである
📝 練習問題
-
基本演習:Rに組み込まれている
mtcarsデータセットに対して、EDAを完全に実施してください:① データ形状 ② 概要 ③ 欠損値 ④ 4つの数値変数のヒストグラム ⑤ 相関行列。スクリーンショットを保存してください。 -
基本演習:欠損値が20%含まれるデータフレーム(1,000行、5列)をシミュレートします。
naniar::vis_miss()を使用して欠損値のパターンを可視化し、3つの処理方法(削除、平均値による補完、中央値による補完)の結果を比較してください。 -
基本演習:
irisを使用して、4つの数値変数の相関行列(corrplot)をプロットし、相関が最も高い2組の変数を特定し、散布図を用いてその結果を検証してください。 -
応用演習:
mpgデータセットを使用して、EDA の全手順を実行してください:① 形状分析 ② 要約 ③classによるグループ分けをした箱ひげ図 ④classによる散布図マトリックス ⑤ 相関行列 ⑥ 自動レポート。スクリーンショットを保存してください。 -
課題:10,000行、20列からなる混合データセット(数値型、カテゴリ型、欠損値、外れ値を含む)を作成し、
DataExplorer::create_report()を使用して包括的な EDA レポート(HTML 形式、30 ページ以上)を生成し、そのレポートに基づいて ビジネスインサイトの要約(500 文字)を作成してください。



