ホームページ  >  記事  >  バックエンド開発  >  ソフトウェアエンジニアのための機械学習

ソフトウェアエンジニアのための機械学習

WBOY
WBOYオリジナル
2024-08-06 20:14:151187ブラウズ

Machine Learning for Software Engineers

これに価値があると思われた場合はお知らせください。続けます。

第 1 章 - 線形モデル

最もシンプルでありながら強力な概念の 1 つは線形モデルです。

ML における主な目標の 1 つは、データに基づいて予測を行うことです。 線形モデルは機械学習の「Hello World」に似ており、単純ですが、より複雑なモデルを理解するための基礎を形成します。

住宅価格を予測するモデルを構築してみましょう。この例では、出力は予想される「住宅価格」であり、入力は「平方フィート」、「寝室数」などです...

def prediction(sqft, num_bedrooms, num_baths):
    weight_1, weight_2, weight_3 = .0, .0, .0  
    home_price = weight_1*sqft, weight_2*num_bedrooms, weight_3*num_baths
    return home_price

各入力の「重み」に気づくでしょう。これらの重みは、予測の背後にある魔法を生み出すものです。この例は、重みがゼロなので常にゼロを出力するので退屈です。

それでは、これらの重みを見つける方法を見てみましょう。

重みを見つける

重みを見つけるプロセスは、モデルの「トレーニング」と呼ばれます。

  • まず、既知の特徴 (入力) と価格 (出力) を持つ住宅のデータセットが必要です。例えば:
data = [
    {"sqft": 1000, "bedrooms": 2, "baths": 1, "price": 200000},
    {"sqft": 1500, "bedrooms": 3, "baths": 2, "price": 300000},
    # ... more data points ...
]
  • 重みを更新する方法を作成する前に、予測がどの程度外れているかを知る必要があります。予測と実際の値の差を計算できます。
home_price = prediction(1000, 2, 1) # our weights are currently zero, so this is zero
actual_value = 200000

error = home_price - actual_value # 0 - 200000 we are way off. 
# let's square this value so we aren't dealing with negatives
error = home_price**2

1 つのデータ ポイントについてどれだけずれているか (誤差) を知る方法ができたので、すべてのデータ ポイントの平均誤差を計算できます。これは一般に平均二乗誤差と呼ばれます。

  • 最後に、平均二乗誤差を減らす方法で重みを更新します。

もちろん、乱数を選択して、最適な値を保存し続けることもできますが、それは非効率です。そこで、別の方法である勾配降下法を検討してみましょう。

勾配降下法

勾配降下法は、モデルに最適な重みを見つけるために使用される最適化アルゴリズムです。

勾配は、各重みに小さな変更を加えたときに誤差がどのように変化するかを示すベクトルです。

サイドバーの直感
丘陵地に立っているところを想像してください。あなたの目標は、最低点 (最小誤差) に到達することです。勾配は常に最も急な上り坂を指すコンパスのようなものです。勾配の方向に逆らって、最下点に向かって進んでいきます。

その仕組みは次のとおりです:

  1. ランダムな重み (またはゼロ) から始めます。
  2. 現在の重みの誤差を計算します。
  3. 各重みの誤差の勾配 (傾き) を計算します。
  4. 誤差を減らす方向に少しずつ移動して重みを更新します。
  5. 誤差が大幅に減少しなくなるまで、手順 2 ~ 4 を繰り返します。

各誤差の勾配をどのように計算しますか?

勾配を計算する 1 つの方法は、重みを少し変更し、それが誤差にどのような影響を与えたかを確認し、そこからどこに移動する必要があるかを確認することです。

def calculate_gradient(weight, data, feature_index, step_size=1e-5):
    original_error = calculate_mean_squared_error(weight, data)

    # Slightly increase the weight
    weight[feature_index] += step_size
    new_error = calculate_mean_squared_error(weight, data)

    # Calculate the slope
    gradient = (new_error - original_error) / step_size

    # Reset the weight
    weight[feature_index] -= step_size

    return gradient

段階的な内訳

  • 入力パラメータ:

    • Weight: モデルの現在の重みセット。
    • データ: 住宅の特徴と価格のデータセット。
    • feature_index: 勾配を計算する重み (平方フィートの場合は 0、寝室の場合は 1、浴室の場合は 2)。
    • step_size: 重みをわずかに変更するために使用する小さな値 (デフォルトは 1e-5 または 0.00001)。
  • 元のエラーを計算:

   original_error = calculate_mean_squared_error(weight, data)

まず、現在の重みを使用して平均二乗誤差を計算します。これが出発点となります。

  • 重量をわずかに増加させます:
   weight[feature_index] += step_size

ウェイトをわずかな量 (step_size) だけ増やします。これにより、重量のわずかな変化が誤差にどのような影響を与えるかを確認できます。

  • 新しいエラーを計算:
   new_error = calculate_mean_squared_error(weight, data)

わずかに増加した重みで平均二乗誤差を再度計算します。

  • 傾き (勾配) を計算します:
   gradient = (new_error - original_error) / step_size

これが重要なステップです。 「重量を少し増やしたときに誤差はどのくらい変化しましたか?」という質問です。

  • new_error の場合 > original_error の場合、勾配は正です。つまり、この重みを増やすと誤差が増加します。
  • new_error の場合 < original_error、勾配は負です。つまり、この重みを増やすと誤差が減少します。
  • 大きさは、この重みの変化に対する誤差の感度を示します。

    • 体重をリセット:
   weight[feature_index] -= step_size

ウェイトを変更するとどうなるかをテストしていたので、ウェイトを元の値に戻しました。

  • グラデーションを返します:
   return gradient

この重みに対して計算された勾配を返します。

This is called "numerical gradient calculation" or "finite difference method". We're approximating the gradient instead of calculating it analytically.

Let's update the weights

Now that we have our gradients, we can push our weights in the opposite direction of the gradient by subtracting the gradient.

weights[i] -= gradients[i]

If our gradient is too large, we could easily overshoot our minimum by updating our weight too much. To fix this, we can multiply the gradient by some small number:

learning_rate = 0.00001
weights[i] -= learning_rate*gradients[i]

And so here is how we do it for all of the weights:

def gradient_descent(data, learning_rate=0.00001, num_iterations=1000):
    weights = [0, 0, 0]  # Start with zero weights

    for _ in range(num_iterations):
        gradients = [
            calculate_gradient(weights, data, 0), # sqft
            calculate_gradient(weights, data, 1), # bedrooms
            calculate_gradient(weights, data, 2)  # bathrooms
        ]

        # Update each weight
        for i in range(3):
            weights[i] -= learning_rate * gradients[i]

        if _ % 100 == 0:
            error = calculate_mean_squared_error(weights, data)
            print(f"Iteration {_}, Error: {error}, Weights: {weights}")

    return weights

Finally, we have our weights!

Interpreting the Model

Once we have our trained weights, we can use them to interpret our model:

  • The weight for 'sqft' represents the price increase per square foot.
  • The weight for 'bedrooms' represents the price increase per additional bedroom.
  • The weight for 'baths' represents the price increase per additional bathroom.

For example, if our trained weights are [100, 10000, 15000], it means:

  • Each square foot adds $100 to the home price.
  • Each bedroom adds $10,000 to the home price.
  • Each bathroom adds $15,000 to the home price.

Linear models, despite their simplicity, are powerful tools in machine learning. They provide a foundation for understanding more complex algorithms and offer interpretable insights into real-world problems.

以上がソフトウェアエンジニアのための機械学習の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。