「パフォーマンス評価」タスクmlbootcamp.ruのソリューション

「パフォーマンスアセスメント」コンテストの終了まであと3日未満です。 おそらくこの記事は、誰かが決断を改善するのに役立つでしょう。 問題の本質は、異なるコンピューティングシステムでの2つの行列の乗算時間を予測することです。 予測の品質の推定として、最小の平均相対誤差MAPEが採用されます。



現時点では、1位は4.68%です。 以下では、6.69%へのパスを説明します(これはすでに70以上の場所です)。



そのため、951列の表形式のトレーニング用データがあります。 このような膨大な数の兆候は、「手動で」分析を開始する意味さえありません。 したがって、いくつかの標準的なアルゴリズムを「見ずに」適用しようとしますが、少しデータを準備します。



試行番号1





これらの操作により、mape = 11.22%が得られます。 そして、これは362箇所のうち154箇所です。 つまり 半分以上の参加者。



試行番号2



線形アルゴリズムを使用するには、機能をスケーリングする必要があります。 さらに、既存の機能に基づいた新しい機能の追加が役立つ場合があります。 たとえば、 PolynomialFeaturesを使用します。 すべての951文字について多項式を計算することは非常にリソースを消費するため、すべての文字を2つの部分に分割します。



そして、行列の特徴についてのみ多項式を計算します。 さらに、応答ベクトル(y)はトレーニング前の対数であり、答えを計算するとき、前のスケールを返します。



いくつかの簡単な操作により、すでにmape = 6.91%(362の80番地)が得られます。 RidgeCV()モデルが標準パラメーターで呼び出されることは注目に値します。 理論的には、まだ調整可能です。



試行番号3



最良の結果のmape = 6.69%(72/362)は、属性の「手動」追加によって得られました。 3つの記号m * n、m * k、k * nを追加しました。

また、両方のマトリックスの最小寸法に対するマトリックスの最大寸法の比率を追加しました。



結果を再現するためのコード
import numpy as np import pandas as pd from sklearn import linear_model def write_answer(data, str_add=''): with open("answer"+str(str_add)+".txt", "w") as fout: fout.write('\n'.join(map(str, data))) def convert_cat(inf,inf_data): return inf_data[inf_data == inf].index[0] X = pd.read_csv('x_train.csv') y = pd.read_csv('y_train.csv') X_check = pd.read_csv('x_test.csv') # memFreq  .     X.memFreq = pd.to_numeric(X.memFreq, errors = 'coerce') mean_memFreq = 525.576 X.fillna(value = mean_memFreq, inplace=True) X_check.memFreq = pd.to_numeric(X_check.memFreq, errors = 'coerce') X_check.fillna(value = mean_memFreq, inplace=True) #    for c in X.columns: if len(np.unique(X_check[c])) == 1: X.drop(c, axis=1, inplace=True) X_check.drop(c, axis=1, inplace=True) #    cpuArch_ = pd.Series(np.unique(X.cpuArch)) X.cpuArch = X.cpuArch.apply(lambda x: convert_cat(x,cpuArch_)) X_check.cpuArch = X_check.cpuArch.apply(lambda x: convert_cat(x,cpuArch_)) memType_ = pd.Series(np.unique(X.memType)) X.memType = X.memType.apply(lambda x: convert_cat(x,memType_)) X_check.memType = X_check.memType.apply(lambda x: convert_cat(x,memType_)) memtRFC_ = pd.Series(np.unique(X.memtRFC)) X.memtRFC = X.memtRFC.apply(lambda x: convert_cat(x,memtRFC_)) X_check.memtRFC = X_check.memtRFC.apply(lambda x: convert_cat(x,memtRFC_)) os_ = pd.Series(np.unique(X.os)) X.os = X.os.apply(lambda x: convert_cat(x,os_)) X_check.os = X_check.os.apply(lambda x: convert_cat(x,os_)) cpuFull_ = pd.Series(np.unique(X.cpuFull)) X.cpuFull = X.cpuFull.apply(lambda x: convert_cat(x,cpuFull_)) X_check.cpuFull = X_check.cpuFull.apply(lambda x: convert_cat(x,cpuFull_)) #     perf_features = X.columns[3:] #   X['log_mn'] = np.log(Xm * Xn) X['log_mk'] = np.log(np.int64(Xm*Xk)) X['log_kn'] = np.log(np.int64(Xk*Xn)) X['min_max_a'] = np.float64(X.loc[:, ['m', 'k']].max(axis=1)) / X.loc[:, ['m', 'k']].min(axis=1) X['min_max_b'] = np.float64(X.loc[:, ['n', 'k']].max(axis=1)) / X.loc[:, ['n', 'k']].min(axis=1) X_check['log_mn'] = np.log(X_check.m * X_check.n) X_check['log_mk'] = np.log(np.int64(X_check.m*X_check.k)) X_check['log_kn'] = np.log(np.int64(X_check.k*X_check.n)) X_check['min_max_a'] = np.float64(X_check.loc[:, ['m', 'k']].max(axis=1)) / X_check.loc[:, ['m', 'k']].min(axis=1) X_check['min_max_b'] = np.float64(X_check.loc[:, ['n', 'k']].max(axis=1)) / X_check.loc[:, ['n', 'k']].min(axis=1) model = linear_model.RidgeCV(cv=5) model.fit(X, np.log(y)) y_answer = np.exp(model.predict(X_check)) write_answer(y_answer.reshape(4947), '_habr_RidgeCV')
      
      









あとがき



ウィキペディアを使用してのみ行列を乗算できることを認めます。 そして、割り当ての説明に示されているStrassenの方法とVinogradovのアルゴリズムは、習得するのが非現実的です。 機械学習のコンテストに参加するのはこれが初めてです。 そして、競争の作者によって引用された研究の背景に対して結果が良く見えるという事実によって、プライドの感覚が高められます-A. A.シドネフ、V。P.ゲルゲル「アルゴリズムの最も効果的な実装の自動選択」



All Articles