はじめに
Google Colabを学びたい Step9です。そろそろ実際のデータを元に解析したいなと思いました!!
いい感じのデータを探してたところ、Kaggleのデータで挑戦してみたいと思います!!
🎓 データセット紹介:Students Performance in Exams
Students Performance in Exams - Kaggle は、教育関連のデータ分析を学ぶ上で非常に適した、シンプルかつ実用的なデータセットです。
✅ 概要
このデータセットは、1,000人の生徒に関する以下の情報を記録しています:
- 生徒の属性(性別・人種・親の学歴・昼食の種類・テスト対策の有無)
- 3つの科目(数学・読解・ライティング)の試験スコア(0〜100点)
📦 データの基本構成
カラム名 | 説明 |
---|---|
gender |
性別(male または female ) |
race/ethnicity |
人種・民族のグループ(Group A〜E) |
parental level of education |
両親の最終学歴(例:bachelor's degree , high school など) |
lunch |
昼食の種類(standard または free/reduced ) |
test preparation course |
テスト対策コースの受講状況(none または completed ) |
math score |
数学のスコア(0〜100点) |
reading score |
読解のスコア(0〜100点) |
writing score |
ライティングのスコア(0〜100点) |
💡 このデータでできる分析の例
- 各科目の平均点や得点分布の可視化(ヒストグラム・箱ひげ図)
- 性別・親の学歴・昼食の種類などによる成績の違い
- 科目間の相関関係(ヒートマップ)
- テスト対策コース受講者と非受講者の成績差
- 機械学習による得点予測モデルの構築(発展)
👍 初心者におすすめな理由
- カラム数が少なくてシンプル
- 欠損値・外れ値がなく、前処理がほとんど不要
- 教育という身近なテーマでイメージが湧きやすい
- 分類・回帰・可視化など、データ分析の基本をひととおり体験できる
本データセットは、PandasやSeabornを使ったデータ可視化の練習や、教師あり学習(回帰・分類)の入門教材として非常に人気があります。
Hands-onスタート!!
まずは、対象のCSVをダウンロードし、GoogleDriveに保存しておきます!
その後、下記コマンドで実行
CSVファイルの読み込み
from google.colab import drive
drive.mount('/content/drive')
import pandas as pd
# パスを明示
file_path = '/content/drive/MyDrive/Colab Notebooks/StudentsPerformance.csv'
# CSV読み込み
df = pd.read_csv(file_path)
# 表示
df.head()
データの分析を開始する
では解析をしていきましょう!!でも、何から分析していいのかがわからないというのが最初の壁です。
とりあえず、いくつかデータの中身を見てみたいと思います!!
データの構造を見てみる
# データ構造の確認(列名・型・nullの有無など)
df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1000 entries, 0 to 999
Data columns (total 8 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 gender 1000 non-null object ← 性別(文字列)、欠損なし
1 race/ethnicity 1000 non-null object ← 人種・民族グループ(文字列)、欠損なし
2 parental level of education 1000 non-null object ← 親の学歴(文字列)、欠損なし
3 lunch 1000 non-null object ← 昼食の種類(標準 or 無料/割引)、欠損なし
4 test preparation course 1000 non-null object ← テスト対策を受けたか(文字列)、欠損なし
5 math score 1000 non-null int64 ← 数学の点数(整数)、欠損なし
6 reading score 1000 non-null int64 ← 読解の点数(整数)、欠損なし
7 writing score 1000 non-null int64 ← ライティングの点数(整数)、欠損なし
dtypes: int64(3), object(5)
memory usage: 62.6+ KB
なるほどね。人種や親の学歴、数学やリーディング、ライティングの成績があるな。
で、なんなの??昼食とか親の学歴も含まれているな。まぁ、いいか。こんなもんだな。
いくつかサンプルデータを見る
# データの内容をざっと見る(先頭5行)
df.head()
index,gender,race/ethnicity,parental level of education,lunch,test preparation course,math score,reading score,writing score
0,female,group B,bachelor's degree,standard,none,72,72,74
1,female,group C,some college,standard,completed,69,90,88
2,female,group B,master's degree,standard,none,90,95,93
3,male,group A,associate's degree,free/reduced,none,47,57,44
4,male,group C,some college,standard,none,76,78,75
数値の分析(平均・中央値・最大値)
# 数値データの基本統計量(平均・中央値・最大値など)
df.describe()
箱ひげ図にしてみよう!!表で読み込むより、図解されている方が読みやすいので!
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
# フォント設定(日本語)
plt.rcParams['font.family'] = 'IPAexGothic'
# 日本語表示にするための変換辞書
subject_labels = {
'math score': '数学',
'reading score': '読解',
'writing score': 'ライティング'
}
# 列を日本語化(コピー)
df_jp = df.rename(columns=subject_labels)
subjects = list(subject_labels.values())
# 平均値の計算
means = [df_jp[col].mean() for col in subjects]
# 箱ひげ図の描画
plt.figure(figsize=(8, 5))
ax = sns.boxplot(data=df_jp[subjects], palette="pastel")
# 平均値を赤丸で重ねる(位置は x=0,1,2...)
for i, mean in enumerate(means):
ax.plot(i, mean, marker="o", color="red", label="平均" if i == 0 else "", markersize=8)
plt.title("教科ごとの点数分布(箱ひげ図+平均)")
plt.ylabel("点数")
plt.grid(True)
# 凡例(最初の1回だけ表示)
plt.legend()
plt.show()
全体的によく似たようなグラフで大きな差はないですね。
ただ、数学は下に外れ値が多く見える。数学の苦手な生徒が読解やライティングに比べると多い印象
性別ごとの得点図の比較
import matplotlib.pyplot as plt
import seaborn as sns
# フォント設定(日本語対応)
plt.rcParams['font.family'] = 'IPAexGothic'
# 教科ごとに箱ひげ図を描画
subjects = ['math score', 'reading score', 'writing score']
titles = ['数学の点数', '読解の点数', 'ライティングの点数']
for subject, title in zip(subjects, titles):
plt.figure(figsize=(8, 5))
ax = sns.boxplot(x='gender', y=subject, data=df, palette='pastel')
# 平均値を赤丸で描く
means = df.groupby('gender')[subject].mean()
for i, gender in enumerate(means.index):
ax.plot(i, means[gender], marker='o', color='red', label='平均' if i == 0 else "", markersize=8)
plt.title(f"{title}(性別比較)")
plt.ylabel("点数")
plt.xlabel("性別")
plt.grid(True)
plt.legend()
plt.show()
🎓 性別ごとの成績分析(箱ひげ図+平均)
3教科(数学・読解・ライティング)の成績を、性別ごとに箱ひげ図と平均値マーカーで比較しました。
その結果、それぞれの教科において性別による明確な傾向が見られました。
🟦 数学(Math)
- 男性の方が平均点・中央値ともに高い
- 女性には極端に低いスコア(外れ値)が多く見られる
- 男性は分布が比較的安定しており、ばらつきも小さい
📌 数学は男性がやや優位で、女性は苦手層が目立つ
🟧 読解(Reading)
- 女性の方が平均点・中央値が高く、点数が安定
- 男性はばらつきがあり、中央値もやや低い
- 女性の外れ値は少なく、高得点層に集中している印象
📌 読解は女性がやや得意な傾向
🟩 ライティング(Writing)
- 女性が圧倒的に優位(平均・中央値が高く、安定している)
- 男性の方がばらつきが大きく、外れ値も多い
📌 ライティングは女性の得意分野。非常に安定感がある
✅ 総合的な考察
教科 | 優位な性別 | 備考 |
---|---|---|
数学 | 男性 | 平均点が高く、外れ値が少ない |
読解 | 女性 | 点数が安定していて高得点傾向 |
ライティング | 女性 | 圧倒的に安定・高得点傾向あり |
💡 教育的示唆
- 女性に対しては数学的支援が有効
- 男性に対しては言語力(読解・ライティング)の強化が課題
- 教科ごとに性別に応じたアプローチを取ることで、全体の底上げが期待できる
親の学歴別 × 教科別の成績分布
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# 日本語フォントを指定(Google Colab用)
plt.rcParams['font.family'] = 'IPAexGothic'
# 🔹 学歴の英語 → 日本語マッピング
edu_mapping = {
"some high school": "高校中退",
"high school": "高校卒業",
"some college": "短大・大学中退",
"associate's degree": "短大卒",
"bachelor's degree": "大学卒",
"master's degree": "大学院卒"
}
# 🔹 日本語順に並べるための順序リスト
edu_order_ja = [
"高校中退",
"高校卒業",
"短大・大学中退",
"短大卒",
"大学卒",
"大学院卒"
]
# 🔹 学歴の日本語ラベル列を作成
df['parent_education_ja'] = df['parental level of education'].map(edu_mapping)
# 🔹 教科と日本語タイトルの辞書
subjects = {
'math score': '数学',
'reading score': '読解',
'writing score': 'ライティング'
}
# 🔹 各教科で箱ひげ図を表示(日本語学歴+平均付き)
for subject, title in subjects.items():
plt.figure(figsize=(10, 6))
# 箱ひげ図(日本語順に並べて表示)
ax = sns.boxplot(
x='parent_education_ja',
y=subject,
data=df,
order=edu_order_ja,
palette='pastel'
)
# 平均値を赤い点でプロット
means = df.groupby('parent_education_ja')[subject].mean()
for i, label in enumerate(edu_order_ja):
ax.plot(i, means[label], marker='o', color='red', label='平均' if i == 0 else "", markersize=8)
plt.title(f"{title}の点数(親の学歴別)")
plt.xlabel("親の学歴")
plt.ylabel("点数")
plt.xticks(rotation=20)
plt.grid(True)
plt.legend()
plt.show()
📊 親の学歴と子どもの成績の関係(箱ひげ図による分析)
📝 分析の目的
この分析では、親の学歴ごとに子どもの点数(数学・読解・ライティング)の分布を箱ひげ図で可視化し、どのような傾向があるかを確認します。平均点も赤丸で重ねて表示しています。
✅ 考察ポイント
1. 親の学歴が高いほど、子どもの成績も高い傾向がある
- 全ての教科において、親の学歴が高いほど、平均点・中央値が高い傾向が見られました。
- 特に大学卒・大学院卒の親を持つ生徒のスコアが高い傾向が一貫しています。
2. 学歴が低い親の子どもは点数のばらつきが大きい
- 高校卒・高校中退の層では点数の分布が広く、ばらつきが大きい傾向が見られます。
- 教育環境やサポートの個人差が大きく影響している可能性があります。
3. 科目ごとの違い
教科 | 特徴 |
---|---|
数学 | 学歴ごとの差が最も顕著。特に大学院卒の親を持つ生徒の得点が高い。 |
読解 | 全体的に得点が高く、親の学歴との相関も比較的明瞭。 |
ライティング | 読解に近い傾向だが、やや個人差(ばらつき)が多め。 |
科目ごとの相関関係を見る
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
# 日本語フォント設定
plt.rcParams['font.family'] = 'IPAexGothic'
# 相関係数を計算(数値データだけ抽出)
score_df = df[['math score', 'reading score', 'writing score']]
corr = score_df.corr()
# 日本語のラベルを定義
score_df.columns = ['数学', '読解', 'ライティング']
corr.columns = ['数学', '読解', 'ライティング']
corr.index = ['数学', '読解', 'ライティング']
# ヒートマップを描画
plt.figure(figsize=(6, 5))
sns.heatmap(corr, annot=True, cmap='coolwarm', vmin=0, vmax=1, fmt='.2f')
plt.title('教科間の相関係数(ヒートマップ)')
plt.tight_layout()
plt.show()
最後に
簡単に分析できていいですね!!Google Colabで実際に分析をするのは初めてだったんですが、こんだけ簡単に分析できると色々夢が広がって楽しいですね!!!