機械学習モデルを評価する

完了

予測モデルのトレーニングが完了しました。 それが良いものかどうかは、どうすればわかるでしょうか。

モデルを評価するには、残しておいた検証データを使う必要があります。 教師あり機械学習モデルの場合、この方法を使って、モデルが予測したラベルと、検証データセットの実際のラベルを比較することができます。 予測値と真のラベル値を比較することで、さまざまな評価メトリックを計算し、モデルの予測パフォーマンスを定量化できます。

回帰モデルの評価

回帰モデルは数値を予測するものです。そのため、モデルの予測パフォーマンスを評価するには、予測値と検証データセットの実際のラベル値との差を考慮する必要があります。 検証データセットには複数のケースが含まれており、一部はその他のデータよりも正確に予測できる可能性があるため、その差を集計してパフォーマンスの全体的なメトリックを決定する何らかの方法が必要です。 回帰モデルの評価に使われる一般的なメトリックを次に示します。

  • 平均二乗誤差 (MSE): このメトリックは、各予測値と実際の値の差を二乗し、二乗した差を合計して平均値 (平均値) を計算するものです。 値を二乗することで、差が "絶対値" になり (差分がマイナスかプラスかは無視します)、差が大きい方に重みが付けられます。
  • 二乗平均平方根誤差 (RMSE): MSE メトリックは、モデル予測における誤差のレベルを示すには適したメトリックですが、ラベルの実際の測定単位とは関係がありません。 たとえば、売上 (米ドル単位) を予測するモデルの場合、MSE 値は実際にはドル値の 2 乗を表します。 予測値がドル換算でどれだけずれているかを評価するには、MSE の平方根を計算する必要があります。
  • 決定係数 (R2): R2 メトリックは、2 乗の特徴量と予測値の間の相関関係を測定します。 これにより、モデルで説明できる分散の量を測定する 0 ~ 1 の値が生成されます。 この値が 1 に近いほど、モデルの予測精度は優れています。

ほとんどの機械学習フレームワークには、このようなメトリックを計算するクラスが用意されています。 たとえば、Spark MLlib ライブラリには RegressionEvaluator クラスがあり、次のコード例のように使用できます。

from pyspark.ml.evaluation import RegressionEvaluator

# Inference predicted labels from validation data
predictions_df = model.transform(validation_df)

# Assume predictions_df includes a 'prediction' column with the predicted labels
# and a 'label' column with the actual known label values

# Use an evaluator to get metrics
evaluator = RegressionEvaluator()
evaluator.setPredictionCol("prediction")
mse = evaluator.evaluate(predictions_df, {evaluator.metricName: "mse"})
rmse = evaluator.evaluate(predictions_df, {evaluator.metricName: "rmse"})
r2 = evaluator.evaluate(predictions_df, {evaluator.metricName: "r2"})
print("MSE:", str(mse))
print("RMSE:", str(rmse))
print("R2", str(r2))

分類モデルの評価

分類モデルは、可能性のあるクラスごとに確率値を計算し、最も確率の高いクラス ラベルを選ぶことで、カテゴリ ラベル ("クラス") を予測します。 分類モデルの評価に使われるメトリックは、検証データセットの実際の既知のラベルと比較したときに、これらのクラス予測が正かった頻度を反映しています。 分類モデルの評価に使われる一般的なメトリックを次に示します。

  • 正確性: モデルが行ったクラス予測のうち、正しかった割合を示す単純なメトリック。 分類モデルのパフォーマンスを評価する方法としては当然の方法と思えるかもしれませんが、ある人が車、バス、路面電車のどれで通勤するかを予測するためにモデルを使うシナリオを考えてみましょう。 検証セットの 95% のケースが車、3% がバス、2% が路面電車に乗るとします。 常に車を予測するだけのモデルでも、3 つのクラスを区別する予測能力がないにもかかわらず、正確性は 95% になります。
  • クラスごとのメトリック:
    • 精度: 指定されたクラスの予測のうち、正しかった割合。 これは、"真陽性" (このクラスの正しい予測) の数を、このクラスの予測の合計数 ("擬陽性" を含む) で割った値として測定されます。
    • リコール: このクラスの実際のインスタンスのうち、正しく予測された割合 (モデルが誤って別のクラスを予測したケースを示す "擬陰性" を含め、検証データセット内にこのクラスのインスタンスがある場合は、"真陽性" を合計数で割ったもの)。
    • F1 スコア: 精度とリコールの複合メトリック (精度とリコールの "調和平均" として計算されます)。
  • すべてのクラスの精度リコールF1 の複合 (重み付けされた) メトリック。

回帰については、ほとんどの機械学習フレームワークに分類メトリックを計算できるクラスがあります。 たとえば、次のコードでは、Spark MLlib ライブラリの MulticlassClassificationEvaluator を使っています。

from pyspark.ml.evaluation import MulticlassClassificationEvaluator

# Inference predicted labels from validation data
predictions_df = model.transform(validation_df)

# Assume predictions_df includes a 'prediction' column with the predicted labels
# and a 'label' column with the actual known label values

# Use an evaluator to get metrics
accuracy = evaluator.evaluate(predictions_df, {evaluator.metricName:"accuracy"})
print("Accuracy:", accuracy)

labels = [0,1,2]
print("\nIndividual class metrics:")
for label in sorted(labels):
    print ("Class %s" % (label))
    precision = evaluator.evaluate(predictions_df, {evaluator.metricLabel:label,
                                                    evaluator.metricName:"precisionByLabel"})
    print("\tPrecision:", precision)
    recall = evaluator.evaluate(predictions_df, {evaluator.metricLabel:label,
                                                 evaluator.metricName:"recallByLabel"})
    print("\tRecall:", recall)
    f1 = evaluator.evaluate(predictions_df, {evaluator.metricLabel:label,
                                             evaluator.metricName:"fMeasureByLabel"})
    print("\tF1 Score:", f1)
    
overallPrecision = evaluator.evaluate(predictions_df, {evaluator.metricName:"weightedPrecision"})
print("Overall Precision:", overallPrecision)
overallRecall = evaluator.evaluate(predictions_df, {evaluator.metricName:"weightedRecall"})
print("Overall Recall:", overallRecall)
overallF1 = evaluator.evaluate(predictions_df, {evaluator.metricName:"weightedFMeasure"})
print("Overall F1 Score:", overallF1)

教師なしクラスタリング モデルの評価

教師なしクラスタリング モデルは、既知の真のラベル値がありません。 クラスタリング モデルの目標は、類似のケースをその特徴量に基づいてクラスターにグループ化することです。 クラスターを評価するには、クラスター間の分離レベルを示すメトリックが必要です。 クラスター化されたケースは、多次元空間にプロットされた点と考えることができます。 同じクラスター内の点は互いに近くにあり、異なるクラスター内の点からは離れているはずです。

このようなメトリックの 1 つがシルエット メジャーです。これはユークリッド距離の二乗を計算し、クラスター内の整合性を示すものです。 シルエット値は 1 から - 1 の間です。1 に近い値は、あるクラスターの点が同じクラスター内の他の点に近く、他のクラスター内の点からは離れていることを示します。

Spark MLlib ライブラリには ClusteringEvaluator クラスがあります。これを使うと、次のようにクラスタリング モデルによる予測のシルエットを計算できます。

from pyspark.ml.evaluation import ClusteringEvaluator
from pyspark.ml.linalg import Vectors

# Inference predicted labels from validation data
predictions_df = model.transform(validation_df)

# Assume predictions_df includes a 'prediction' column with the predicted cluster

# Use an evaluator to get metrics
evaluator = ClusteringEvaluator(predictionCol="prediction")
silhouetteVal  = evaluator.evaluate(predictions_df)
print(silhouetteVal)