Pythonで単回帰分析のプログラムを実行します。
プログラムの実行はGoogle Colabで行います。下記のリンクからGoogle Colabを開きましょう。
新しくノートブック「ip0405」を作成してください。
Pythonで単回帰分析のプログラムを実行します。
プログラムの実行はGoogle Colabで行います。下記のリンクからGoogle Colabを開きましょう。
新しくノートブック「ip0405」を作成してください。
まずは、pandasというライブラリを使用し、必要なデータを読み込みます。
pandasとは、Pythonでデータを表(データフレーム)として扱えるライブラリです。
データの読み込み、整理、集計、分析などを簡単に行うことができます。
データは、Webサーバ上においてあり、そのURLを指定して読み込みます。
セルに以下のコードを入力し、実行してください。
import pandas as pd
df = pd.read_csv("https://starjuku-contents.s3.ap-northeast-1.amazonaws.com/ip/04-05/data1.csv")
df.head()
1行目
使用するライブラリ、pandasのインポートを行います。
2行目
指定したURLから、CSVファイルを読み込みます。
読み込んだデータを「データフレーム」と呼ばれる表形式のデータに自動で変換します。
3行目
head()メソッドは、データフレームの先頭から5行を表示します。
headは「先頭」という意味で、引数を指定しない場合は標準で5行が表示されるように設計されています。
データが多い場合、すべてを表示すると画面が見づらくなるため、内容を確認するのにちょうどよい行数として5行だけ表示する仕組みになっています。
(実際のデータは50行ありますが、表示を見やすくするために先頭5行のみを表示しています。)
なお、head(10)のように数字を指定すれば、表示する行数を変更することもできます。
実行結果
では、これから回帰分析を行う前に、どんなデータが入っているのかを確認しましょう。
head()で表示されているのは先頭の一部ですが、各列(カラム)が何を意味するかをここで整理しておくと、このあとの分析がスムーズになります。
データの各列の説明
student_id:学生番号
study_hours:平均勉強時間
sleep_hours:平均睡眠時間
attendance_pct:出席率
smartphone_hours:スマホ使用時間
test_score:テストの得点 ← 目的変数
このデータを使用し、テストの得点を回帰分析で予測できるモデル(データを予測する回帰式)を作成します。
Pythonで、機械学習と呼ばれる手法で、既存のデータから計算式を作成します。
この中に、目的変数の得点と明らかに無相関のデータがあります。
どれかわかりますか?
学生番号の「student_id」ですね。
だな。学生番号でテストの得点は決められないよ。
その通りですね。
それでは、学生番号の列を削除しましょう。
新しいセルに以下のコードを入力し、実行してください。
df = df.drop("student_id",axis=1)
df.head()
1行目
データフレームから、必要のない列を削除し、上書きします。
dropメソッドの第一引数に、削除したいカラム名を書きます。
axis引数は、行を削除するなら0、列を削除するなら1を指定します。
実行結果
単回帰分析に使用する説明変数を選びます。
まずは、散布図を使って、目的変数である「test_score」との関係性をみてみましょう。
新しいセルに以下のコードを入力し、実行してください。
df.plot.scatter(x='study_hours', y='test_score')
df.plot.scatter(x='sleep_hours', y='test_score')
df.plot.scatter(x='attendance_pct', y='test_score')
df.plot.scatter(x='smartphone_hours', y='test_score')
1行目〜4行目
df.plot.scatter()で、データフレームの内のデータから、散布図を表示します。
引数xに、x軸の項目、引数yに、y軸の項目の列名を設定します。
1行目:x軸→勉強時間、y軸→テストの得点
2行目:x軸→睡眠時間、y軸→テストの得点
3行目:x軸→出席率、y軸→テストの得点
4行目:x軸→スマホ使用時間、y軸→テストの得点
実行結果
目的変数と、それ以外の列全てのデータで、散布図を作成してみました。
もっとも相関関係が強いのは、どの項目でしょうか?
なんとなく、study_hoursが関係が強い気がしますけど。
でも、確証は持てないなぁ。
それでは、実際に相関係数を見てみましょう。
目的変数「test_score」と、それ以外の列の相関係数を見てみます。
新しいセルに以下のコードを入力し、実行してください。
df.corr()["test_score"]
1行目
df.corr()で、データフレーム内の相関係数を取得するメソッドです。
後ろに[]で列名を指定することで、指定した列と、それ以外の列との相関関係を見ることができます。
実行結果
もっとも相関関係が強いデータはどれでしょうか?
相関係数が1.0のデータがあるけど、これは同じ列同士だから無視していいよな。
それを除いたら、study_hoursが0.7で一番高くて、2番目がsmartphone_hoursの-0.5ですね。
マイナスだけど、相関関係が強いの?
マイナスは負の相関になりますが、-1に近いほど関係性が強いと思ってください。
なので、マイナスは無視した状態の数値の大きさ(絶対値)で決めてください。
なるほどな!
それでは、study_hoursを説明変数として、回帰分析のモデル(回帰式)を作成します。
新しいセルに、以下のプログラムを打って実行してください。
from sklearn.linear_model import LinearRegression
model = LinearRegression()
model.fit(df[["study_hours"]], df["test_score"])
1行目
回帰分析の学習を行う関数「LinerRegression」をインポートします。
2行目
回帰分析を行う土台づくりをします。その土台をmodelという変数に代入します。
3行目
fit()メソッドで、分析を行います。第一引数に説明変数を、第二引数に目的変数を設定します。
その際、データフレーム["列名"]で指定します。
説明変数の[]が2重になっていますが、いいんですか?
はい、これは、重回帰分析もできることを前提に作られています。
重回帰分析は2次元のデータを渡すので、[]を2重にする必要があります。
それじゃあ、これから最小二乗法のプログラムだな!
いえ、その必要はありません。
え、なんでですか?
fitメソッドの中で、最小二乗法を自動でやってくれるプログラムが動いているんです。
これで回帰式の完成です。
実際に計算していたらとっても大変だったよね。プログラムってすごいな。
では、実行結果をみてみましょう。
求めた回帰直線の、回帰係数と切片を確認しましょう。
新しいセルに、以下のプログラムを打って実行してください。
print("回帰係数:",model.coef_[0])
print("切片:",model.intercept_)
1行目
回帰係数を表示します。
2行目
切片を表示します。
実行結果
とっても細かい数値が出てきたね。
そうですね。これは、説明変数の値に約7.6をかけて、それに約45.2を加算した値が、目的変数の値になります。
なるほど。「y = ax + b」のaとbの値ってことですね。
ところで、回帰係数のmodel.coef_[0]の[0]って何ですか?
重回帰分析の場合、説明変数の数だけ回帰係数ができるんです。
そのため、リストでデータが作成されるんですよ。
なるほどなぁ。Pythonのプログラムで、できちゃうことにもびっくりだよ。
それでは、散布図に回帰直線を重ねてみてみましょう。
import matplotlib.pyplot as plt
y_pred = model.predict(df[["study_hours"]])
plt.scatter(df[["study_hours"]], df["test_score"])
plt.plot(df[["study_hours"]], y_pred , color="red")
plt.show()
1行目
グラフを描画するためのライブラリ「matplotlib.pyplot」をインポートします。
pltという名前で使えるようにしています。
3行目
学習済みの回帰モデルを使って、予測値を計算します。
study_hours(勉強時間)を説明変数として、対応する予測得点を求めています。
この予測結果をy_predに保存しています。
4行目
実際のデータを散布図として表示します。
横軸にstudy_hours(勉強時間)、縦軸にtest_score(テスト得点)を設定しています。
点の一つ一つが、生徒一人分のデータを表しています。
5行目
回帰直線を描画します。
横軸はstudy_hours、縦軸は予測値y_predです。
color="red"は、回帰直線を赤色で表示する指定です。
散布図と区別しやすくするために色を変えています。
6行目
作成したグラフを画面に表示します。
show()を実行しないと、グラフは表示されません。
実行結果
matplotlibとは?
matplotlibは、Pythonでグラフを描くための代表的なライブラリです。
折れ線グラフ、散布図、棒グラフなど、さまざまな種類のグラフを自由に作成できます。
細かい色や線の設定などもできるため、分析結果を分かりやすく表現できます。
なぜここではmatplotlibを使うのか?
これまではpandasの機能を使って簡単にグラフを表示していました。
pandasのグラフ機能は手軽ですが、実は内部ではmatplotlibを利用しています。
回帰直線を重ねたり、色を指定したりする場合は、matplotlibを直接使った方が柔軟に設定できます。
そのため、今回はmatplotlibを使って散布図と回帰直線を同時に描画しています。
実測値と予測値の違い
散布図の点は実際に観測されたテスト得点です。
赤い線は、勉強時間から計算された「予測得点」です。
点と線のズレが「誤差」を表しており、回帰分析ではこの誤差をできるだけ小さくする直線を求めています。
回帰直線はかけましたか?
今後の予測では、この赤い線の上の値を予測値として出すようになります。
それでは、何か数値を当てはめて予測してみましょう。
もし勉強時間が、5時間だったら、何点くらい取れるでしょうか?
5時間勉強した時の得点の予測を求めましょう。
新しいセルに、以下のプログラムを打って実行してください。
pred_score = model.predict([[5]])
print("5時間勉強したときの予測得点:", pred_score)
1行目
作成したモデルのpredictメソッドに数値を渡し、予測結果を求めます。
2行目
printで予測結果を表示します。
実行結果
このプログラムを実行すると、実行結果に合わせて、以下のような警告文が出ます。
/usr/local/lib/python3.12/dist-packages/sklearn/utils/validation.py:2739: UserWarning: X does not have valid feature names, but LinearRegression was fitted with feature names warnings.warn(
これは、学習の時に「列名」を指定していたのに、予測時には列名が無いことを警告しています。
予測時のデータもデータフレームで渡すことで回避できますが、今回は無視してください。
おぉ〜!83.26156452って、こんな点数ある!?
回帰分析は、整数だけの予測はできません。
予測なので、目安としてください。
正確に計算で求めなくても、散布図と回帰直線から、ある程度の推測はできますね。
問題
勉強時間を6.5時間にした時の予測した得点を答えてください。
小数点以下の数値も全て答えましょう。
※この再現版では提出は行いません(送信先は未接続です)