PyTorchを使った線形回帰の実装方法を徹底解説
線形回帰とは
単純線形回帰の基礎
2つの連続変数の間にある関係性を把握するために用いられる手法です。
具体例:
x = 独立変数
(例:体重)y = 従属変数
(例:身長)
関係式は y = αx + β という形式で表されます。
それでは、実際にプログラムを通して単純線形回帰の仕組みを見ていきましょう。
#単純線形回帰 import numpy as np import matplotlib.pyplot as plt np.random.seed(1) n = 70 x = np.random.randn(n) y = x * np.random.randn(n) colors = np.random.rand(n) plt.plot(np.unique(x), np.poly1d(np.polyfit(x, y, 1))(np.unique(x))) plt.scatter(x, y, c = colors, alpha = 0.5) plt.show()
出力結果

散布図に対して回帰直線が引かれ、xとyの間に正の相関関係があることが視覚的に確認できます。
線形回帰の目的
各データポイントと直線(y = αx + β)との距離を最小化すること
そのために、以下の2つのパラメータを調整します
係数:α
切片/バイアス:β
PyTorchによる線形回帰モデルの構築
ここでは、係数(α)を2、切片(β)を1と仮定します。すると、モデルが学習すべき方程式は次のようになります。
y = 2x + 1 #線形モデル
データセットの作成
まず、入力データとなるxの値を用意します。
x_values = [i for i in range(11)] x_values
出力結果
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
続いて、このリストをNumPy配列に変換します。
#numpy配列へ変換 x_train = np.array(x_values, dtype = np.float32) x_train.shape
出力結果
(11,)
PyTorchのモデルに入力するには2次元配列が必要なため、reshapeで形状を変更します。
#重要:2次元配列が必要 x_train = x_train.reshape(-1, 1) x_train.shape
出力結果
(11, 1)
次に、y = 2x + 1 に従って目的変数yの値を作成します。リスト内包表記でもforループでも同じ結果が得られます。
y_values = [2*i + 1 for i in x_values] y_values
出力結果
[1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21]
#リストの反復処理を使う場合
y_values = []
for i in x_values:
result = 2*i + 1
y_values.append(result)
y_values
出力結果
[1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21]
同様に、yの値もNumPy配列に変換し、2次元形式に整えます。
y_train = np.array(y_values, dtype = np.float32) y_train.shape
出力結果
(11,)
#2次元配列が必要 y_train = y_train.reshape(-1, 1) y_train.shape
出力結果
(11, 1)
モデルの構築
準備が整ったら、PyTorchで線形回帰モデルを定義し、学習を行います。損失関数にはMSE(平均二乗誤差)、最適化アルゴリズムにはSGD(確率的勾配降下法)を使用します。
#ライブラリのインポート
import torch
import torch.nn as nn
from torch.autograd import Variable
#モデルクラスの作成
class LinearRegModel(nn.Module):
def __init__(self, input_size, output_size):
super(LinearRegModel, self).__init__()
self.linear = nn.Linear(input_dim, output_dim)
def forward(self, x):
out = self.linear(x)
return out
input_dim = 1
output_dim = 1
model = LinearRegModel(input_dim, output_dim)
criterion = nn.MSELoss()
learning_rate = 0.01
optimizer = torch.optim.SGD(model.parameters(), lr = learning_rate)
epochs = 100
for epoch in range(epochs):
epoch += 1
#numpy配列をtorchのVariableに変換
inputs = Variable(torch.from_numpy(x_train))
labels = Variable(torch.from_numpy(y_train))
#パラメータに関する勾配をクリア
optimizer.zero_grad()
#順伝播で出力を取得
outputs = model.forward(inputs)
#損失を計算
loss = criterion(outputs, labels)
#パラメータに関する勾配を取得
loss.backward()
#パラメータを更新
optimizer.step()
print('epoch {}, loss {}'.format(epoch, loss.item()))
補足: 新しいバージョンのPyTorchでは、loss.data[0]は非推奨となっているため、上記のコードではloss.item()を使用しています。
出力結果
epoch 1, loss 276.7417907714844 epoch 2, loss 22.601360321044922 epoch 3, loss 1.8716105222702026 epoch 4, loss 0.18043726682662964 epoch 5, loss 0.04218350350856781 epoch 6, loss 0.03060017339885235 epoch 7, loss 0.02935197949409485 epoch 8, loss 0.02895027957856655 epoch 9, loss 0.028620922937989235 epoch 10, loss 0.02830091118812561 ...... ...... epoch 94, loss 0.011018744669854641 epoch 95, loss 0.010895680636167526 epoch 96, loss 0.010774039663374424 epoch 97, loss 0.010653747245669365 epoch 98, loss 0.010534750297665596 epoch 99, loss 0.010417098179459572 epoch 100, loss 0.010300817899405956
この結果から、エポック1からエポック100にかけて損失が大幅に減少していることが分かります。初期の損失は約276でしたが、学習の進行とともに約0.01まで下がり、モデルがデータの傾向を正しく学習できていることが確認できます。
グラフのプロット
最後に、学習済みモデルによる予測値と実際の値をグラフ上で比較してみましょう。
#推論のみを実行 predicted = model(Variable(torch.from_numpy(x_train))).data.numpy() predicted y_train #グラフのプロット #図をクリア plt.clf() #予測値を取得 predicted = model(Variable(torch.from_numpy(x_train))).data.numpy() #実際のデータをプロット plt.plot(x_train, y_train, 'go', label ='True data', alpha = 0.5) #予測値をプロット plt.plot(x_train, predicted, '--', label='Predictions', alpha = 0.5) #凡例と表示 plt.legend(loc = 'best') plt.show()
出力結果

グラフを見ると、緑色の点で示された実際のデータと破線で示された予測値がほぼ一致していることが分かります。これにより、PyTorchで構築した線形回帰モデルが y = 2x + 1 の関係を正確に学習できたことが確認できました。
-
PythonでのCX_Freezeの使い方:スクリプトを実行ファイル(EXE)に変換する方法
はじめに 何か面白いものを作りたいという欲求は人間の本能であり、完成したものは誰かに共有したくなるものです。Pythonでもその願いを叶えられます。ただし、作成したPythonスクリプトをそのまま共有するには、相手のマシンにも同じバージョンのPythonと、プログラムで使用しているすべてのモジュールがインストールされている必要があります。 そこで役立つのがCX_Freezeです。このツールを使えば、Pythonがインストールされていない環境でも動作するスタンドアロンの実行ファイル(.exe)を作成できます。 CX_Freezeのインストール まず、コマンドプロンプトで以下のコマンドを実行し、c
-
Rubyの線形回帰で未来を予測する方法
私たちが日々行う選択の多くは、実は数値的な関係に基づいています。科学者がコレステロールを下げると言うから、特定の食品を食べる収入が増えやすいから、学歴を積む最も資産価値が上がりそうだと考えた地域に、家を買うこれらの結論には、どうやって到達するのでしょうか?おそらく、誰かが大量のデータを収集し、それを分析して結論を導き出したのでしょう。よく使われる手法のひとつが「線形回帰」で、これは教師あり学習の一種です。教師あり学習の詳細や活用例については、このシリーズの第1回をご覧ください。線形関係とは2つの値(xとyとします)の間に「線形関係」があるとは、xが1変化すると、yも必ず一定の量だけ変化すること