0
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

機械学習勉強記録 Scikit-learnで重回帰分析を実装

Last updated at Posted at 2021-06-10

Scikit-learnとは

Scikit-learnは、Pythonの機械学習ライブラリです。「サイキット・ラーン」と読みます。
これを使って重回帰分析を行ってみます。

下準備

まず、使うライブラリをインポートする必要があります。

# Scikit-learnを使う時に一緒によく使うライブラリをインポート
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

それぞれが何かは、今までの記事で解説してきました。

データセットのインポート

Scikit-learnの中にデータセットがあらかじめ色々と用意してあります。
今回はボストン近郊の住宅データセットを使います。

from sklearn.datasets import load_boston

これでボストン近郊の住宅データセットを読み込みました。実際にどんなデータが入っているのが、みてみましょう。

print(load_boston())
"""
出力結果 : 
{'data': array([[6.3200e-03, 1.8000e+01, 2.3100e+00, ..., 1.5300e+01, 3.9690e+02,
        4.9800e+00],
       [2.7310e-02, 0.0000e+00, 7.0700e+00, ..., 1.7800e+01, 3.9690e+02,
        9.1400e+00],
       [2.7290e-02, 0.0000e+00, 7.0700e+00, ..., 1.7800e+01, 3.9283e+02,
        4.0300e+00],
       ...,
       [6.0760e-02, 0.0000e+00, 1.1930e+01, ..., 2.1000e+01, 3.9690e+02,
        5.6400e+00],
       [1.0959e-01, 0.0000e+00, 1.1930e+01, ..., 2.1000e+01, 3.9345e+02,
        6.4800e+00],
       [4.7410e-02, 0.0000e+00, 1.1930e+01, ..., 2.1000e+01, 3.9690e+02,
        7.8800e+00]]), 'target': array([24. , 21.6, 34.7, 33.4, 36.2, 28.7, 22.9, 27.1, 16.5, 18.9, 15. ,
       18.9, 21.7, 20.4, 18.2, 19.9, 23.1, 17.5, 20.2, 18.2, 13.6, 19.6,
       15.2, 14.5, 15.6, 13.9, 16.6, 14.8, 18.4, 21. , 12.7, 14.5, 13.2,
       13.1, 13.5, 18.9, 20. , 21. , 24.7, 30.8, 34.9, 26.6, 25.3, 24.7,
       21.2, 19.3, 20. , 16.6, 14.4, 19.4, 19.7, 20.5, 25. , 23.4, 18.9,
       35.4, 24.7, 31.6, 23.3, 19.6, 18.7, 16. , 22.2, 25. , 33. , 23.5,
       19.4, 22. , 17.4, 20.9, 24.2, 21.7, 22.8, 23.4, 24.1, 21.4, 20. ,
       20.8, 21.2, 20.3, 28. , 23.9, 24.8, 22.9, 23.9, 26.6, 22.5, 22.2,
       23.6, 28.7, 22.6, 22. , 22.9, 25. , 20.6, 28.4, 21.4, 38.7, 43.8,
       33.2, 27.5, 26.5, 18.6, 19.3, 20.1, 19.5, 19.5, 20.4, 19.8, 19.4,
       21.7, 22.8, 18.8, 18.7, 18.5, 18.3, 21.2, 19.2, 20.4, 19.3, 22. ,
       20.3, 20.5, 17.3, 18.8, 21.4, 15.7, 16.2, 18. , 14.3, 19.2, 19.6,
       23. , 18.4, 15.6, 18.1, 17.4, 17.1, 13.3, 17.8, 14. , 14.4, 13.4,
       15.6, 11.8, 13.8, 15.6, 14.6, 17.8, 15.4, 21.5, 19.6, 15.3, 19.4,
       17. , 15.6, 13.1, 41.3, 24.3, 23.3, 27. , 50. , 50. , 50. , 22.7,
       25. , 50. , 23.8, 23.8, 22.3, 17.4, 19.1, 23.1, 23.6, 22.6, 29.4,
       23.2, 24.6, 29.9, 37.2, 39.8, 36.2, 37.9, 32.5, 26.4, 29.6, 50. ,
       32. , 29.8, 34.9, 37. , 30.5, 36.4, 31.1, 29.1, 50. , 33.3, 30.3,
       34.6, 34.9, 32.9, 24.1, 42.3, 48.5, 50. , 22.6, 24.4, 22.5, 24.4,
       20. , 21.7, 19.3, 22.4, 28.1, 23.7, 25. , 23.3, 28.7, 21.5, 23. ,
       26.7, 21.7, 27.5, 30.1, 44.8, 50. , 37.6, 31.6, 46.7, 31.5, 24.3,
       31.7, 41.7, 48.3, 29. , 24. , 25.1, 31.5, 23.7, 23.3, 22. , 20.1,
       22.2, 23.7, 17.6, 18.5, 24.3, 20.5, 24.5, 26.2, 24.4, 24.8, 29.6,
       42.8, 21.9, 20.9, 44. , 50. , 36. , 30.1, 33.8, 43.1, 48.8, 31. ,
       36.5, 22.8, 30.7, 50. , 43.5, 20.7, 21.1, 25.2, 24.4, 35.2, 32.4,
       32. , 33.2, 33.1, 29.1, 35.1, 45.4, 35.4, 46. , 50. , 32.2, 22. ,
       20.1, 23.2, 22.3, 24.8, 28.5, 37.3, 27.9, 23.9, 21.7, 28.6, 27.1,
       20.3, 22.5, 29. , 24.8, 22. , 26.4, 33.1, 36.1, 28.4, 33.4, 28.2,
       22.8, 20.3, 16.1, 22.1, 19.4, 21.6, 23.8, 16.2, 17.8, 19.8, 23.1,
       21. , 23.8, 23.1, 20.4, 18.5, 25. , 24.6, 23. , 22.2, 19.3, 22.6,
       19.8, 17.1, 19.4, 22.2, 20.7, 21.1, 19.5, 18.5, 20.6, 19. , 18.7,
       32.7, 16.5, 23.9, 31.2, 17.5, 17.2, 23.1, 24.5, 26.6, 22.9, 24.1,
       18.6, 30.1, 18.2, 20.6, 17.8, 21.7, 22.7, 22.6, 25. , 19.9, 20.8,
       16.8, 21.9, 27.5, 21.9, 23.1, 50. , 50. , 50. , 50. , 50. , 13.8,
       13.8, 15. , 13.9, 13.3, 13.1, 10.2, 10.4, 10.9, 11.3, 12.3,  8.8,
        7.2, 10.5,  7.4, 10.2, 11.5, 15.1, 23.2,  9.7, 13.8, 12.7, 13.1,
       12.5,  8.5,  5. ,  6.3,  5.6,  7.2, 12.1,  8.3,  8.5,  5. , 11.9,
       27.9, 17.2, 27.5, 15. , 17.2, 17.9, 16.3,  7. ,  7.2,  7.5, 10.4,
        8.8,  8.4, 16.7, 14.2, 20.8, 13.4, 11.7,  8.3, 10.2, 10.9, 11. ,
        9.5, 14.5, 14.1, 16.1, 14.3, 11.7, 13.4,  9.6,  8.7,  8.4, 12.8,
       10.5, 17.1, 18.4, 15.4, 10.8, 11.8, 14.9, 12.6, 14.1, 13. , 13.4,
       15.2, 16.1, 17.8, 14.9, 14.1, 12.7, 13.5, 14.9, 20. , 16.4, 17.7,
       19.5, 20.2, 21.4, 19.9, 19. , 19.1, 19.1, 20.1, 19.9, 19.6, 23.2,
       29.8, 13.8, 13.3, 16.7, 12. , 14.6, 21.4, 23. , 23.7, 25. , 21.8,
       20.6, 21.2, 19.1, 20.6, 15.2,  7. ,  8.1, 13.6, 20.1, 21.8, 24.5,
       23.1, 19.7, 18.3, 21.2, 17.5, 16.8, 22.4, 20.6, 23.9, 22. , 11.9]), 'feature_names': array(['CRIM', 'ZN', 'INDUS', 'CHAS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD',
       'TAX', 'PTRATIO', 'B', 'LSTAT'], dtype='<U7'), 'DESCR': ".. _boston_dataset:\n\nBoston house prices dataset\n---------------------------\n\n**Data Set Characteristics:**  \n\n    :Number of Instances: 506 \n\n    :Number of Attributes: 13 numeric/categorical predictive. Median Value (attribute 14) is usually the target.\n\n    :Attribute Information (in order):\n        - CRIM     per capita crime rate by town\n        - ZN       proportion of residential land zoned for lots over 25,000 sq.ft.\n        - INDUS    proportion of non-retail business acres per town\n        - CHAS     Charles River dummy variable (= 1 if tract bounds river; 0 otherwise)\n        - NOX      nitric oxides concentration (parts per 10 million)\n        - RM       average number of rooms per dwelling\n        - AGE      proportion of owner-occupied units built prior to 1940\n        - DIS      weighted distances to five Boston employment centres\n        - RAD      index of accessibility to radial highways\n        - TAX      full-value property-tax rate per $10,000\n        - PTRATIO  pupil-teacher ratio by town\n        - B        1000(Bk - 0.63)^2 where Bk is the proportion of blacks by town\n        - LSTAT    % lower status of the population\n        - MEDV     Median value of owner-occupied homes in $1000's\n\n    :Missing Attribute Values: None\n\n    :Creator: Harrison, D. and Rubinfeld, D.L.\n\nThis is a copy of UCI ML housing dataset.\nhttps://archive.ics.uci.edu/ml/machine-learning-databases/housing/\n\n\nThis dataset was taken from the StatLib library which is maintained at Carnegie Mellon University.\n\nThe Boston house-price data of Harrison, D. and Rubinfeld, D.L. 'Hedonic\nprices and the demand for clean air', J. Environ. Economics & Management,\nvol.5, 81-102, 1978.   Used in Belsley, Kuh & Welsch, 'Regression diagnostics\n...', Wiley, 1980.   N.B. Various transformations are used in the table on\npages 244-261 of the latter.\n\nThe Boston house-price data has been used in many machine learning papers that address regression\nproblems.   \n     \n.. topic:: References\n\n   - Belsley, Kuh & Welsch, 'Regression diagnostics: Identifying Influential Data and Sources of Collinearity', Wiley, 1980. 244-261.\n   - Quinlan,R. (1993). Combining Instance-Based and Model-Based Learning. In Proceedings on the Tenth International Conference of Machine Learning, 236-243, University of Massachusetts, Amherst. Morgan Kaufmann.\n", 'filename': '/usr/local/lib/python3.7/dist-packages/sklearn/datasets/data/boston_house_prices.csv'}
"""

このままでは非常に見辛いですね。
なので、これをpandasのデータフレーム型で表示しましょう。
まずは、x(入力変数)とt(目標値)を定義します。

dataset = load_boston()
# dataset の中の data を x, target を t に代入
x,t = dataset.data, dataset.target
# dataset の中の feature_names を columns に代入
columns = dataset.feature_names

feature_namesというのは、CRIM,ZNなどが入っているリストですね。
そしてこれをpandasのデータフレーム型にして表示すると、

df = pd.DataFrame(x, columns=columns)
df.head(3)
"""
出力結果 : 

        CRIM    	ZN	    INDUS	CHAS NOX	RM	    AGE	    DIS	    RAD	 TAX	 PTRATIO B	 
LSTAT
0	    0.00632	    18.0	2.31	0.0	 0.538	6.575	65.2	4.0900	1.0  296.0	 15.3	396.90	4.98
1	    0.02731	    0.0     7.07	0.0	 0.469	6.421	78.9	4.9671	2.0	 242.0	 17.8	396.90	9.14
2	    0.02729	    0.0   	7.07	0.0	 0.469	7.185	61.1	4.9671	2.0	 242.0	 17.8	392.83	4.03
"""

このように見やすくなりました。
columns=columnsというのは、データフレーム内のcolumns(=列の名前)に、先ほど定義したcolumnsを代入するという感じです。名前が同じでややこしいですね。
僕はここを理解するのに時間がかかりましたが、一度load_boston()の中身を見れば、意味がわかりやすいと思います。

上のデータフレームには、targetの列がありませんので、追加します。

# tのデータを、'Target'という名前の列を追加してそこに代入
df['Target'] = t

これで、Targetという列がデータフレームに追加されます。

データをndarray型に変換

機械学習アルゴリズムの実装を行う際には、numpyのndarray型にする必要があります。
それは、.valuesの属性で取り出すことができます。
そして、同時にデータフレーム内の入力変数と出力変数の切り分けを行います。
データフレーム内の'Target'が出力変数、それ以外が入力変数にあたります。
切り分ける時は、.dropメソッドを使います。

# 'Target'という列名の列の値をtに代入
t = df['Target'].values
# dfの中の'Target'という列名の列の値以外の値をxに代入
x = df.drop(labels=['Target'], axis=1).values

学習用データセットとテスト用データセットへ分割

ボストン近郊の住宅データセットを学習用データセットとテスト用データセットに分けます。
学習用データセットで、適切な重みなどを求めて、それが本当に使えるかどうかをテスト用データセットでテストするためです。

from sklearn.model_selection import train_test_split
x_train, x_test, t_train, t_test = train_test_split(x, t, test_size=0.3, random_state=0)

train_test_splitを使うことで、データセットを
x_train学習用入力変数
x_testテスト用入力変数
t_train学習用出力変数
t_testテスト用出力変数
と、ランダムに抽出して4つに分けます。
test_size=0.3というのは、データ全体の3割をテスト用データセットにするという意味です。
random_state=0は、ランダムに抽出する際のランダム性を指定することができます。同じ数字にすることで再現性を確保できます。

モデルの学習・検証

機械学習において、入力値を受け取り、何かしらの評価・判定をして出力値を出すものをモデルと言います。
例えば家賃を予測するモデルであれば、賃貸物件の面積と駅からの距離という入力値を受け取り、重回帰分析をして家賃という出力値を出すという働きをします。

モデルを定義し、学習させ、検証する。
この3ステップで、モデルを作っていきます。

1.モデルの定義

Scikit-learnで重回帰分析を行う時は、LinearRegressionを使います。

from sklearn.linear_model import LinearRegression
# モデルの定義
model = LinearRegression()

これで、modelは、重回帰分析をするモデルだと定義します。

2.モデルの学習

今回学習で使用するのは、先ほど分割したデータセットのうち、学習用のデータセットです。

# モデルの学習
model.fit(x_train, t_train)

この.fitを使うだけで、モデルの学習が完了します。簡単ですね。
ここでパラメータ(重みwとバイアスbのこと)を確かめてみましょう。

# 重み
print(model.coef_)
"""
出力結果 : 
[-1.21310401e-01  4.44664254e-02  1.13416945e-02  2.51124642e+00
 -1.62312529e+01  3.85906801e+00 -9.98516565e-03 -1.50026956e+00
  2.42143466e-01 -1.10716124e-02 -1.01775264e+00  6.81446545e-03
 -4.86738066e-01]
"""

# バイアス
print(model.intercept_)
# 出力結果 : 37.93710774183309

重みについて、棒グラフで可視化することもできます。(出力結果は割愛)

plt.figure(figsize=(10, 7))
plt.bar(x=columns, height=model.coef_)

3.モデルの検証

モデルの検証は以下で行えます。

# 学習済みモデルを用いて、学習用データセットで計算した係数
print('train score : ', model.score(x_train, t_train))
# 出力結果 : train score :  0.7645451026942549


# 学習済みモデルを用いて、テスト用データセットで計算した係数
print('test score : ', model.score(x_test, t_test))
# 出力結果 : test score :  0.6733825506400171

出力された係数が、1に近ければ近いほど良いモデルです。

学習用データに対してのみ数値が高く、テスト用データに対して数値が低い状態のことを「過学習」といいます。
同じことばっかり勉強しちゃって、他の問題への応用がききにくくなってしまった、違う傾向を持つ問題について対応しにくくなった、そんな状態です。
過学習を防いで、テスト用データで計算した係数を1に近づけるようにしましょう。

推論

学習が終わったモデルに新たな入力値を加えて、予測値を計算させることもできます。それを「推論」と言います。
テスト用データからサンプルを一つ取り出し、推論してみます。

# x_testに対して、モデルで推論する
y = model.predict(x_test)

# 推論結果の1番目の予測値を表示
print('予測値 : ', y[0])
# 目標値の1番目はどうだったか確認
print('目標値 : ', t_test[0])
'''
出力結果 : 
予測値 :  24.935707898576915
目標値 :  22.6
'''

まぁまぁ近い数字が推論されていることがわかりました。

0
3
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?