10の古典的な機械学習アルゴリズムの線形回帰

 

線形回帰は、次の式で表すことができます。

線形回帰は連続値予測の問題です。つまり、与えられたxとモデルパラメータθの計算の下で、対応する方程式を真の値yに無限に近似することができます。

連続値予測の簡単な例を次に示します。

y = w * x + b

2組のパラメータがわかっている場合、パラメータwとbは消去法で取得でき、方程式の正確な解を取得できます。つまり、w = 1.477、b = 0.089

1.567 = w * 1 + b

3.043 = w * 2 + b

しかし、実生活では正確に解くことができない場合が多く、第一に、モデル自体の方程式が不明であるため、収集されたデータはすべて一定の偏差があり、第二に、観察されるデータはノイズが多いことがよくあります。したがって、ノイズ係数εを上記の式に追加する必要があります。

y = w * x + b +ε、ε〜N(0,1)と仮定します。つまり、εは平均0、分散1のガウス分布に従います。上記の分布を次の図に示します。

つまり、ほとんどの値は0の近くに分布し、0から遠い値はあまり分布していません。

ガウス分布を介して、上記のソリューションプロセスを次のように変更できます。

1.567 = w * 1 + b + eps

3.043 = w * 2 + b + eps

4.519 = w * 3 + b + eps

wとbの適切な値を取得したい場合は、さらにいくつかのデータセットを観察する必要があり、複数の観察データセットを繰り返すことで、wとbの全体的なパフォーマンスを最大限に高めることができます。

では、2つのパラメーターwとbをどのように解決するのでしょうか。

ここでは、損失関数の概念、つまり真の値と予測値の間の誤差を導入する必要があります。損失関数の式は次のとおりです。

損失関数が最小値に達した状態で最高の性能wとb、つまりwとbを得るために、ここでの損失関数は各観測グループの誤差の合計です。

したがって、モデルパラメータwおよびbを推定する問題を、損失関数を最小化する問題に変換しました。

次に、勾配降下アルゴリズムを使用して、モデルパラメータwおよびbを決定します。ここでは、勾配降下アルゴリズムとは何かについてはあまり説明しません。勾配は関数の導関数として簡単に理解でき、勾配の方向は関数の値が増加する方向です。例えば:

たとえば、目的関数はf(x)であり、上記の3点での関数の導関数の方向は、関数の値が増加する方向を指します。これは、関数の最大値の方向としても理解できます。損失関数を最小化する場合は、損失関数を解きます。そして、対応するポイントのwとb、つまり取得したいモデルパラメータを取得します。上の図では、損失関数の最小値は約5です。モデルパラメータで、勾配が反対方向に変更されていることを確認します。各変更には、固定のステップサイズ、つまり学習率があります。繰り返し繰り返して、最適なモデルパラメータを見つけます。 。

したがって、目的関数の部分導関数を見つける必要があります。つまり、それぞれw 'とb'を計算する必要があります。

そして、次のように勾配を更新します

Pythonコードの推論:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
__author__ = 'Seven'

import numpy as np


# y = wx + b
def calculate_loss_function(w, b, points):
    total_error = 0
    for i in range(len(points)):
        x = points[i, 0]
        y = points[i, 1]
        total_error += ((w * x + b) - y) ** 2
    return total_error / float(len(points))


def step_gradient(w_current, b_current, points, learning_rate):
    w_gradient = 0
    b_gradient = 0
    N = float(len(points))
    for i in range(len(points)):
        x = points[i, 0]
        y = points[i, 1]
        # w_gradient = 2x(wx+b-y)
        w_gradient += 2 / N * x * ((w_current * x + b_current) - y)
        # b_gradient = 2(wx+b-y)
        b_gradient += 2 / N * ((w_current * x + b_current) - y)

    new_w = w_current - learning_rate * w_gradient
    new_b = b_current - learning_rate * b_gradient
    return [new_w, new_b]


def gradient_descent_runner(starting_w, starting_b, learning_rate, num_iterations, points):
    w = starting_w
    b = starting_b
    for i in range(num_iterations):
        w, b = step_gradient(w, b, points, learning_rate)
    return [w, b]


def run():
    # 构建模拟数据并添加噪声,并拟合y = 1.477x + 0.089
    x = np.random.uniform(0, 100, 100)
    y = 1.477 * x + 0.089 + np.random.normal(0, 1, 1)
    points = np.array([[i, j] for i, j in zip(x, y)])
    learning_rate = 0.0001
    initial_b = 0
    initial_w = 0
    num_iterations = 1000
    print(f'原始损失函数值为:{calculate_loss_function(initial_w, initial_b, points)}, w={initial_w}, b={initial_b}')
    w, b = gradient_descent_runner(initial_w, initial_b, learning_rate, num_iterations, points)
    print(f'经过{num_iterations}次迭代, 损失函数的值为:{calculate_loss_function(w, b, points)}, w={w}, b={b}')


if __name__ == '__main__':
    run()

 

動作効果は以下のとおりです。

上の図からわかるように、1000回の繰り返しの後、wの値は約1.49、bの値は約0.08、実際のwは1.477、bは0.089です。実行効果は実際の値に非常に近くなります。

おすすめ

転載: blog.csdn.net/gf19960103/article/details/104655278