「労働者が自分の仕事をうまくやりたいなら、まず自分の道具を研ぎ澄まさなければなりません。」 - 孔子、「論語。陸霊公」
表紙 > プログラミング > ソフトウェアエンジニアのための機械学習

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

2024 年 8 月 7 日に公開
ブラウズ:556

Machine Learning for Software Engineers

これが貴重だと思ったら知らせてください。続けます!

第 1 章 - 線形モデル

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

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

住宅価格を予測するモデルを構築しましょう。この例では、出力は予想される「住宅価格」で、入力は「sqft」、「num_bedrooms」などになります...

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
  • 大きさは、この重みの変化に対する誤差の感度を示します。

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

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

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

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

これを「数値勾配計算」または「差分法」といいます。勾配を分析的に計算するのではなく、近似しています。

重みを更新しましょう

これで勾配が得られたので、勾配を減算することで、勾配の反対方向にウェイトをプッシュできます。

weights[i] -= gradients[i]

勾配が大きすぎる場合、重みを更新しすぎて最小値を簡単にオーバーシュートしてしまう可能性があります。これを修正するには、グラデーションに小さな数値を掛けます:

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

そして、すべての重みに対してそれを行う方法は次のとおりです:

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

ついに重みが完成しました!

モデルの解釈

トレーニングされた重みを取得したら、それを使用してモデルを解釈できます。

  • 「平方フィート」の重量は、平方フィートあたりの価格の上昇を表します。
  • 「ベッドルーム」のウェイトは、追加のベッドルームごとの価格の増加を表します。
  • 「バス」の重みは、追加のバスルームごとの価格の増加を表します。

たとえば、トレーニングされた重みが [100, 10000, 15000] の場合、次のことを意味します:

  • 平方フィートごとに住宅価格に 100 ドル追加されます。
  • 寝室ごとに住宅価格に 10,000 ドル追加されます。
  • バスルームごとに住宅価格に 15,000 ドル追加されます。

線形モデルは、その単純さにもかかわらず、機械学習における強力なツールです。これらは、より複雑なアルゴリズムを理解するための基盤を提供し、現実世界の問題に対する解釈可能な洞察を提供します。

リリースステートメント この記事は次の場所に転載されています: https://dev.to/akdevelop/machine-learning-for-software-engineers-2hid?1 侵害がある場合は、[email protected] に連絡して削除してください。
最新のチュートリアル もっと>

免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。

Copyright© 2022 湘ICP备2022001581号-3