Python3 Scipy(stats.linregress())とscikit-learn(sklearn linear_model.LinearRegression())で単回帰分析。

Python3コード

#!/usr/bin/env python3


"""使用したデータは『マンガでわかる統計学 [回帰分析編]』第2章
"""


#
# 結論から先に書いておくと、Scipyのstats.linregressだけでは、
# 主要な値は出せても、プロットするのが辛い。
# プロットするのに適しているのは、
# scikit-learn sklearn のlinear_model.LinearRegression()。
#
# (いや、わからない、単純にまだ慣れていないだけかもしれない...)
#


import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import scipy as sp
from scipy import stats
from sklearn import linear_model


def main():
    """(docstring)
    """

    # macOSやOS Xで文字化けするなら。
    font = {'family' : 'Osaka'}

    dat = {'最高気温': [29, 28, 34, 31, 25,
                    29, 32, 31, 24, 33,
                    25, 31, 26, 30],
            'アイスティー': [77, 62, 93, 84, 59,
                            64, 80, 75, 58, 91,
                            51, 73, 65, 84]}

    df = pd.DataFrame(dat)
    print('df')
    print('')
    print(df)
    print('')

    # scipy.stats.linregress
    # Calculate a regression line(公式の言葉から借用)
    print('linregress')
    print('一括で出力')
    res = sp.stats.linregress(df.ix[:, '最高気温'], df.ix[:, 'アイスティー'])
    print(res)
    print('')

    print('forで出力')
    for i in res:
        print(i)
    print('')

    print('多重代入して出力')
    slope, intercept, r_value, p_value, std_err = sp.stats.linregress(df.ix[:, '最高気温'], df.ix[:, 'アイスティー'])
    #
    # ベタ書き的print()していく。
    # 回帰係数(傾き)
    print('slope ', slope)
    # y切片
    print('intercept', intercept)
    # r値
    print('r_value', r_value)
    # p値
    print('p_value', p_value)
    # 標準誤差
    print('std_err', std_err)
    # 決定係数
    print('multiple_r_value', r_value**2)
    print('')

    # 上記Scipyの結果からプロットする試みが辛すぎるので、
    # 以下からscikit-learnを使用する。
    #
    # なお、警告(LAPACK bug 0038)が出たら無視していい

    print('ここからscikit-learn')
    lm = linear_model.LinearRegression()
    X = df.ix[:, ['最高気温']]
    Y = df.ix[:, ['アイスティー']]

    # 予測モデル
    print('予測モデル')
    lm.fit(X, Y)
    print('')

    # 回帰係数(傾き)
    print('回帰係数')
    print(lm.coef_)
    print('')

    # 切片
    print('切片')
    print(lm.intercept_)
    print('')

    # 決定係数
    print('決定係数')
    print(lm.score(X, Y))
    print('')

    # matplotlib
    # 散布図
    plt.scatter(X, Y, color='red')
    # 回帰直線
    plt.plot(X, lm.predict(X), color='blue')
    plt.xlabel('最高気温')
    plt.ylabel('アイスティーの注文数')
    plt.show()

if __name__ == '__main__':
    main()

出力

df

    アイスティー  最高気温
0       77    29
1       62    28
2       93    34
3       84    31
4       59    25
5       64    29
6       80    32
7       75    31
8       58    24
9       91    33
10      51    25
11      73    31
12      65    26
13      84    30

linregress
一括で出力
LinregressResult(slope=3.7378854625550657, intercept=-36.361233480176196, rvalue=0.90692297805088962, pvalue=7.6614128044501331e-06, stderr=0.50124814295488607)

forで出力
3.73788546256
-36.3612334802
0.906922978051
7.66141280445e-06
0.501248142955

多重代入して出力
slope  3.73788546256
intercept -36.3612334802
r_value 0.906922978051
p_value 7.66141280445e-06
std_err 0.501248142955
multiple_r_value 0.822509288117

ここからscikit-learn
予測モデル

回帰係数
[[ 3.73788546]]

切片
[-36.36123348]

決定係数
0.822509288117

散布図と回帰直線のスクリーンショット

f:id:my_notes:20170728080400p:plain

参考文献

マンガでわかる統計学 回帰分析編

マンガでわかる統計学 回帰分析編