-Python- 重回帰

重回帰は y = ax1 + bx2 + cx3 + d のように複数の変数を使う式を想定して解く回帰問題のことです.まずは,明らかに y = ax1 + bx2 + c の関係になるようなデータを作り,回帰問題を解いて見ます.例として対象とする式を y = 3x1 -2x2 + 1 としてデータ作成してみます.

 
# import modules
import matplotlib.pyplot as plt
import numpy as np
 
# data of y = 3 * x1 - 2 * x2 + 1
x1 = np.random.rand(100, 1)     # Make 100 random numbers up to 0-1
x1 = x1 * 4 - 2                 # Change the value range to -2 - 2
 
x2 = np.random.rand(100, 1)     # Make 100 random numbers up to 0-1
x2 = x2 * 4 -2                  # Change the value range to -2 - 2
 
y = 3 * x1 - 2 * x2 + 1
 
# Graph display
plt.subplot(1, 2, 1)
plt.scatter(x1, y, marker='+')
plt.xlabel('x1')
plt.ylabel('y')
 
plt.subplot(1, 2, 2)
plt.scatter(x2, y, marker='+')
plt.xlabel('x2')
plt.ylabel('y')
 
plt.tight_layout()
plt.show()
 

実行結果は以下のようになります.

f:id:HidehikoMURAO:20181013202209p:plain

 

続いて,sklearn.linear_model.LinearRegressionを使って最小二乗法を使ってx1, x2とyの関係について求めて見ます.

# import modules
import matplotlib.pyplot as plt
import numpy as np
from sklearn import linear_model
 
# data of y = 3 * x1 - 2 * x2 + 1
x1 = np.random.rand(100, 1)     # Make 100 random numbers up to 0-1
x1 = x1 * 4 - 2                 # Change the value range to -2 - 2
 
x2 = np.random.rand(100, 1)     # Make 100 random numbers up to 0-1
x2 = x2 * 4 -2                  # Change the value range to -2 - 2
 
y = 3 * x1 - 2 * x2 + 1
 
x1_x2 = np.c_[x1, x2] # [[x1_1, x2_1], [x1_2, x2_2], ..., x1_100, x2_100]
 
# Learning
model = linear_model.LinearRegression()
model.fit(x1_x2, y)
 
y_ = model.predict(x1_x2) # Forecast by the obtained regression equation
 
# Graph display
plt.subplot(1, 2, 1)
plt.scatter(x1, y, marker='+')
plt.scatter(x1, y_, marker='o')
plt.xlabel('x1')
plt.ylabel('y')
 
plt.subplot(1, 2, 2)
plt.scatter(x2, y, marker='+')
plt.scatter(x2, y_, marker='o')
plt.xlabel('x2')
plt.ylabel('y')
 
plt.tight_layout()
plt.show()
 
実行結果は,以下のようになります.

f:id:HidehikoMURAO:20181013202250p:plain

続いて,求めた回帰式の係数,切片,およびR^2決定係数を求めてみます.そのためには,以下のコードを付近します.
 
# Display
print(model.coef_)          # coefficient
print(model.intercept_)     # intercept
print(model.score(x1_x2, y))
 
実行結果は以下のようになります.
[ 3. -2.]]
[1.]
1.0


上記の結果より,回帰式は y = 3x1 - 2x2 + 1 となり,想定式と同じになっています.回帰式と想定した式が一致しているので,R^2決定係数も 1.0 となっています.

さらに,データにバラつきを与えていきます.

# import modules
import matplotlib.pyplot as plt
import numpy as np
from sklearn import linear_model
 
# data of y = 3 * x1 - 2 * x2 + 1
x1 = np.random.rand(100, 1)     # Make 100 random numbers up to 0-1
x1 = x1 * 4 - 2                 # Change the value range to -2 - 2
 
x2 = np.random.rand(100, 1)     # Make 100 random numbers up to 0-1
x2 = x2 * 4 -2                  # Change the value range to -2 - 2
 
y = 3 * x1 - 2 * x2 + 1
 
# Add a random number \
            with standard normal distribution (average 0, standard deviation 1)
y += np.random.randn(100, 1)
x1_x2 = np.c_[x1, x2]   # [[x1_1, x2_1], [x1_2, x2_2], ..., x1_100, x2_100]
 
# Learning
model = linear_model.LinearRegression()
model.fit(x1_x2, y)
 
y_ = model.predict(x1_x2) # Forecast by the obtained regression equation
 
# Display
print(model.coef_)          # coefficient
print(model.intercept_)     # intercept
print(model.score(x1_x2, y))
 
# Graph display
plt.subplot(1, 2, 1)
plt.scatter(x1, y, marker='+')
plt.scatter(x1, y_, marker='o')
plt.xlabel('x1')
plt.ylabel('y')
 
plt.subplot(1, 2, 2)
plt.scatter(x2, y, marker='+')
plt.scatter(x2, y_, marker='o')
plt.xlabel('x2')
plt.ylabel('y')
 
plt.tight_layout()
plt.show()
 
実行結果は以下のようになります.
[0.97874462]
0.9288163973661103

f:id:HidehikoMURAO:20181013202059p:plain

求めた回帰式の係数は2.96788506,-1.96021763,切片は0.97874462,およびR^2決定係数は0.9288163973661103となっています.よって,回帰式は y = 2.96788506x1 -1.96021763x2 + 0.97874462となります.