糖尿病と血圧の関係

ゆうき( @BASEBALLY15 )です^^

Pythonで『最小二乗法』を使って,傾きと切片を求めたいんだけれど・・・

出来ますよ!
それでは,今回は,Pythonで『最小二乗法』を使う方法についてご紹介します^^

お願いします・・・

(Udemy 『実践Pythonデータサイエンス』を参考,Jupiternotebookを使用)

最小二乗法とは?

データから得られた結果をグラフにプロットし,

すべてのプロットから最も近い直線を求めることを最小二乗法と言います.

今回は,一次関数 (y = ax+b)を使います.

最小二乗法とは?

学習内容

データ分析で使うデータ

今回は,機械学習でよく使われている, scikit-learn(サイキットラーン) の中から,

「糖尿病疾患の診断データ」を使います.それでは,コードを見ていきましょう^^

ライブラリ

import numpy as np

import pandas as pd

from pandas import Series, DataFrame

import matplotlib.pyplot as plt

import seaborn as sns

sns.set_style("whitegrid")

%matplotlib inline

上のライブラリに加えて, scikit-learn(サイキットラーン) もインポートしたいと思います.

#データをロードする.
from sklearn.datasets import load_diabetes

コード

まず, scikit-learn からロードしたデータに名前を付けたいと思います.

#ロードしたデータをdiabetesと名付ける
diabetes = load_diabetes()

どのようなデータなのかを調べるために,一度書き出してみましょう^^

#diabetesの詳細を表示
print(diabetes.DESCR)

実行すると,長文が表示されるのですが,その中から,

  • Target: Column 11 is a quantitative measure of disease progression one year after baseline
  • Attribute Information:- Average blood pressure

を分析では使いたいとます.

Target は1年後の疾患進行状況を表し, Average blood pressure は血圧を表しています.

この2つの関係性について,最小二乗法を用いて分析を行いたいと思います.

データフレームを表示

まずは, scikit-learn からロードしたデータ がどのようなデータなのかを調べるために,

以下のコードで,データフレーム化したいと思います.

#データフレーム化する
diabetes_df = DataFrame(diabetes.data)


#項目ごとに名前を表示
diabetes_df.columns = diabetes.feature_names


#実行
diabetes_df.head()

すると,以下の表が表示されます.

agesexbmibps1s2s3s4s5s6
00.0380760.0506800.0616960.021872-0.044223-0.034821-0.043401-0.0025920.019908-0.017646
1-0.001882-0.044642-0.051474-0.026328-0.008449-0.0191630.074412-0.039493-0.068330-0.092204
20.0852990.0506800.044451-0.005671-0.045599-0.034194-0.032356-0.0025920.002864-0.025930
3-0.089063-0.044642-0.011595-0.0366560.0121910.024991-0.0360380.0343090.022692-0.009362
40.005383-0.044642-0.0363850.0218720.0039350.0155960.008142-0.002592-0.031991-0.046641

この表には,上で説明した『 Target (1年後の疾患状況)』が無いので,

以下のコードを記述し,追加したいと思います.

#データフレームにTargetを追加("progression"と名付ける)
diabetes_df["progression"] = diabetes.target

すると,以下の通り, Target のデータ が追加されています.

agesexbmibps1s2s3s4s5s6progression
00.0380760.0506800.0616960.021872-0.044223-0.034821-0.043401-0.0025920.019908-0.017646151.0
1-0.001882-0.044642-0.051474-0.026328-0.008449-0.0191630.074412-0.039493-0.068330-0.09220475.0
20.0852990.0506800.044451-0.005671-0.045599-0.034194-0.032356-0.0025920.002864-0.025930141.0
3-0.089063-0.044642-0.011595-0.0366560.0121910.024991-0.0360380.0343090.022692-0.009362206.0
40.005383-0.044642-0.0363850.0218720.0039350.0155960.008142-0.002592-0.031991-0.046641135.0

最小二乗法(y=ax+b)を使って,回帰分析を行う

最終的には,このようなグラフが完成します!

最小二乗法を用いた回帰分析

それでは,コードを見ていきましょう^^

まず,Yの値を決めておきます. Target をYの値とします.

上で, Target のデータをprogressionと名付けてるので,以下のコードを記述します.

Y = diabetes_df.progression

次に,Xの値を決めたいと思います.

#Xをdiabetes_dfのbpの列とする
X = diabetes_df.bp

#Xの形を見てみる
X.shape

すると,このような結果となります.

(442,)

Pythonで最小二乗法を使う場合,下の図のような形にする必要があります.

Pythonで最小二乗法を使う場合

つまり, (442,) という形ではなく, (442,1)という形に変換する必要があるのです.

以下のコードを記述し,変換します.

#Xを2次元配列に変換する
X = np.vstack(diabetes_df.bp)

#変換したXの形を見てみる
X.shape

すると,

(442, 1)

という形に変換されています.

これを,リスト内包表記で表したいと思います.

#Xをリスト内法表記に変換する(X,1)の形にする
X = np.array([[value[0], 1] for value in X])

#実行(データフレーム化しています)
DataFrame(X)

すると,このように(X,1)の形にする事が出来ます.

01
00.0218721.0
1-0.0263281.0
2-0.0056711.0
3-0.0366561.0
40.0218721.0

最後に,y=ax+bのaとbの値を求め,グラフを完成させたいと思います.

#linalg.lstsqで傾きと切片を求めることができる
a, b = np.linalg.lstsq(X, Y)[0]


#血圧と糖尿病進行状況の関係をプロットする
plt.plot(diabetes_df.bp, diabetes_df.progression, "o")


#最小二乗法で求めた近似曲線をプロットする
x = diabetes_df.bp
plt.plot(x, a*x+b, "r", linewidth=3)


#傾きaと切片bの値を表示する
print("a={}\nb={}".format(a, b))

すると,以下の様に表示されます.

最小二乗法を用いた回帰分析

a=714.741643704288

b=152.13348416289583

終わりに

今回は,Pythonを使って最小二乗法について,まとめてみました.

義務教育でプログラミングが必修化されたので,

この記事を参考に勉強してみてください^^

それでは・・・

Q &A

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA