Python 3 で数学を。

Python 3 とライブラリで数学の問題を解いていきます。統計学や機械学習はときどき。

単回帰分析 (線形回帰、要約統計量、散布図、相関係数、p値、回帰直線) (Python 3, StatsModels: statsmodels.formula.api, ols())

以前、自分が書いていたブログから加筆・修正してこちらで公開。

(以前のブログは、自分自身のためのノート化が強くなったので現在非公開モードにしている)。

使用するライブラリ

matplotlib

Pandas

SciPy

StatsModels

Python 3 コード

linear_regression1.py

#!/usr/bin/env python3


"""(docstring)
"""


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


import matplotlib.pyplot as plt
import pandas as pd
from scipy.stats import pearsonr
import statsmodels.formula.api as smf


def linear_regression1():
    """(docstring)
    """
    # matplotlib の日本語設定
    # 直下は、環境によるから、ここではコメントアウトしておく。
    # font = {'family': 'IPAexGothic'}
    # plt.rc('font', **font)

    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, columns=['最高気温', 'アイスティー'])
    print('df')
    print('')
    print(df)
    print('')

    # 要約統計量 (pandas)
    print(df.describe())
    print('')

    highest_temperatures = df.ix[:, '最高気温']
    iced_teas = df.ix[:, 'アイスティー']

    # matplotlib
    # 散布図。
    plt.scatter(highest_temperatures, iced_teas)
    plt.grid()
    plt.xlabel('最高気温')
    plt.ylabel('アイスティー')
    plt.show()

    # 相関係数(ピアソン)と p 値。
    r, p = pearsonr(highest_temperatures, iced_teas)
    print('相関係数 r: {0},    p 値: {1}'.format(r, p))
    print('')

    # statsmodels.formula.api.ols()
    # statsmodels.formula.api as smf
    # smf.ols() として使用。
    #
    # (UserWarning: kurtosistest ... とりあえずこの警告は無視してもいいと思う)。
    #
    # R (R言語) の記法で書ける。
    mod = smf.ols(formula="iced_teas ~ highest_temperatures", data=df)
    res = mod.fit()
    print(res)
    print('')

    print(res.summary())
    print('')

    print(res.params)
    print('')

    print(res.predict())
    print('')

    # 散布図と回帰直線
    plt.scatter(highest_temperatures, iced_teas)
    # res.predict() には引数不要。
    plt.plot(highest_temperatures, res.predict(), color='red')
    # 回帰直線は自分で計算式を書いても描ける。
    # b, a = res.params # 切片と回帰係数
    # print(b, a)
    # 第 1 引数に x (ここでは、'最高気温'),
    # 第 2 引数に y = a*x+b の計算式部分。
    # plt.plot(x, a*x+b, color='red')
    # y = a*x+b で代入して、y を第 2 引数にしてもいい。
    # plt.plot(x, y, color='red')
    plt.grid()
    plt.xlabel('最高気温')
    plt.ylabel('アイスティーの注文数')
    plt.show()


if __name__ == '__main__':
    linear_regression1()

出力

$ python3 linear_regression1.py
df

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

            最高気温     アイスティー
count  14.000000  14.000000
mean   29.142857  72.571429
std     3.158801  13.019006
min    24.000000  51.000000
25%    26.500000  62.500000
50%    29.500000  74.000000
75%    31.000000  83.000000
max    34.000000  93.000000

相関係数 r: 0.9069229780508896,    p 値: 7.66141280445014e-06

<statsmodels.regression.linear_model.RegressionResultsWrapper object at 0x1125c6dd8>

                            OLS Regression Results                            
==============================================================================
Dep. Variable:              iced_teas   R-squared:                       0.823
Model:                            OLS   Adj. R-squared:                  0.808
Method:                 Least Squares   F-statistic:                     55.61
Date:                Sat, 21 Apr 2018   Prob (F-statistic):           7.66e-06
Time:                        11:58:15   Log-Likelihood:                -43.174
No. Observations:                  14   AIC:                             90.35
Df Residuals:                      12   BIC:                             91.63
Df Model:                           1                                         
Covariance Type:            nonrobust                                         
========================================================================================
                           coef    std err          t      P>|t|      [0.025      0.975]
----------------------------------------------------------------------------------------
Intercept              -36.3612     14.687     -2.476      0.029     -68.362      -4.360
highest_temperatures     3.7379      0.501      7.457      0.000       2.646       4.830
==============================================================================
Omnibus:                        5.158   Durbin-Watson:                   1.669
Prob(Omnibus):                  0.076   Jarque-Bera (JB):                1.433
Skew:                          -0.180   Prob(JB):                        0.488
Kurtosis:                       1.474   Cond. No.                         282.
==============================================================================

Warnings:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.

Intercept              -36.361233
highest_temperatures     3.737885
dtype: float64

[72.03744493 68.29955947 90.72687225 79.51321586 57.08590308 72.03744493
 83.25110132 79.51321586 53.34801762 86.98898678 57.08590308 79.51321586
 60.82378855 75.7753304 ]

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

f:id:my_notes:20180421120820p:plain

f:id:my_notes:20180421120833p:plain

参考文献 (数式とデータを参考)

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

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