情報が限られたチェス分析


19

この課題では、チェスの特定のゲームに関する限られた量の情報が提供され、ゲームに勝った人を予測する必要があります

次の2つのデータセットが提供されます。

  1. 個数(ま​​だ残っている個数)
  2. ボードの色(ボード上のピースの色)

さらに重要なことは、あなたはしていない部分が配置されている場所を知っています。誰が勝つと思うかを決める必要があります。

ゲームは、2010年から現在までのPGNMentorにリストされているすべてのイベントから選択されます。私は勝ち負けで終わる各ゲームからすべてのボードポジションの10%を選択しました。ボードの位置は、常にゲーム内で少なくとも30の動きになります。テストケースはこちらにあります。(白の勝利が最初にリストされ、その後に黒の勝利が続きます)

入力

ピースカウントは、king、queen、ook r、k night、bishop、またはpawnの各ピースの文字で構成される文字列になります。小文字は黒、大文字は白を意味します。ボードは、64文字(8行8列)の文字列です。Bは黒い部分をW表し、白い部分を.表し、空のスポットを表します。サンプル:

W..WB......W.BB....W..B..W.WWBBB..W...B....W..BBWWW...BB.W....B.,BBKPPPPPPPQRRbbkpppppppqrr

次のボードを表します

...B.BB.
.BBBBBBB
.B.B....
B..W....
WWWW.W..
....W.W.
...W..WW
W.....W.

そして両方の色が2人の司教、1人の王、7人のポーン、1人の女王、2人のルークを持っているところ

出力

白が勝つ可能性を判断するには、0〜1(両端を含む)の浮動小数点数を返す必要があります。サンプル:

0.3     (30% chance that white wins)

詳細:

  • 各テストケースには1ポイントの価値があります。あなたのスコアは1 - (1-Output)^2、白が勝った1 - (Output)^2場合、または黒が勝った場合になります。
  • 最終スコアは、すべてのテストケースの合計になります。
  • 提出物が入力をハードコーディングしていると感じた場合、テストケースを変更する権利を留保します。(変更した場合、SHA-256ハッシュが使用されます893be4425529f40bb9a0a7632f7a268a087ea00b0eb68293d6c599c6c671cdee
  • プログラムは、テストケースを個別に実行する必要があります。あるテストケースから次のテストケースに情報を保存しません。
  • 機械学習を使用している場合は、データの最初の80%でトレーニングし、残りの20%を使用してテストすることを強くお勧めします。(または、使用するパーセンテージ)。データでゲームを複数回使用していますが、同じゲームを順番に組み合わせています。
  • 更新:テストと学習の目的で、100万を超えるテストケースを追加しました。githubリポジトリのサイズ制限により、これらは黒と白の部分に分割されます。

頑張って楽しんでね!



新しいテストケースに古いテストケースが含まれていますか、それとも2つのセットがばらばらですか?
致命的

何も思いつきません。別のサイトから入手したので、両方に同じゲームのセットが含まれている可能性があります。
ネイサンメリル

回答:


8

Java 8 + Weka、6413ポイント、94.5%

この答えは機械学習のアプローチを使用しています。Wekaライブラリ、特にweka.jarとを取得する必要がありますPackageManager.jar

ここでは、分類器として多層パーセプトロンを使用しています。Wekaのmlp任意のClassifierクラスに置き換えて、結果を比較できます。

私はMLPのパラメーターをあまりいじっておらず、単純にそれらを目で見てみました(50ニューロン、100エポック、0.2学習率、0.1運動量の1つの隠れ層)。

MLPの出力値にしきい値を設定するため、チャレンジで定義されているように、出力は実際に1または0のいずれかになります。このようにして、Wekaが印刷した正しく分類されたインスタンスの数が直接スコアになります。

特徴ベクトルの構築

各インスタンスを文字列から76要素のベクトルに変換します。ここで、

  • 最初の64個の要素は、文字列と同じ順序でボードのセルを表します。1白の部分、-1黒の部分0、空のセルです。
  • 最後の12個の要素は、各タイプのピースを表します(プレーヤーごとに6個)。これらの要素の値は、ボード上のそのタイプのピースの数です(0「そのタイプのピースはありません」)。-1から1の間の値を再調整するために正規化を適用できますが、これはおそらくここではあまり役に立ちません。

トレーニングインスタンスの数

与えられたすべてのテストケースを使用して分類子をトレーニングすると、6694(つまり98.6588%)の正しく分類されたインスタンスを取得できました。トレーニングに使用したのと同じデータを使用してモデルをテストするのは簡単すぎるため(この場合、モデルがオーバーフィットするのは実際には良いため)、これは明らかに驚くことではありません。

インスタンスの80%のランダムなサブセットをトレーニングデータとして使用して、6413(つまり94.5173%)の正しく分類されたインスタンスを取得します。と、ヘッダーで報告された図が得られ(もちろんサブセットはランダムであるため、結果が若干異なる場合があります)。インスタンスの残りの20%(トレーニングに使用されなかった)でテストすると77.0818%の正しい分類が得られるため、モデルが適切に一般化されていることを示すため、モデルは新しいデータで適切に機能すると確信していますここで与えられるインスタンスは、与えられる新しいテストケースの代表です)。

インスタンスの半分をトレーニングに使用し、残りの半分をテストに使用すると、トレーニングデータとテストデータの両方で86.7502%を取得し、 74.4988パーセントのみ試験データに。

実装

私が言ったように、このコードが必要ですweka.jarし、PackageManager.jarウェカから。

トレーニングセットで使用されるデータの割合を次のように制御できます。 TRAIN_PERCENTAGEます。

MLPのパラメータは、すぐ下で変更できますTRAIN_PERCENTAGE。Wekaの他の分類子(SMOSVMなど)を試すには、単にmlp、別の分類子にです。

このプログラムは結果のセットに出力します。最初のセットはこのチャレンジで定義されたスコアであるセット全体(トレーニングに使用されるデータを含む)にあり、2番目のセットはトレーニングに使用されなかったデータのみにあります。

データを含むファイルのパスを引数としてプログラムに渡すことにより、データを入力します。

import weka.classifiers.Classifier;
import weka.classifiers.Evaluation;
import weka.classifiers.functions.MultilayerPerceptron;
import weka.core.Attribute;
import weka.core.DenseInstance;
import weka.core.Instance;
import weka.core.Instances;

import java.io.BufferedReader;
import java.io.FileReader;
import java.util.ArrayList;

public class Test {

    public static void main(String[] arg) {

        final double TRAIN_PERCENTAGE = 0.5;

        final String HIDDEN_LAYERS = "50";
        final int NB_EPOCHS = 100;
        final double LEARNING_RATE = 0.2;
        final double MOMENTUM = 0.1;

        Instances instances = parseInstances(arg[0]);
        instances.randomize(new java.util.Random(0));
        Instances trainingSet = new Instances(instances, 0, (int) Math.floor(instances.size() * TRAIN_PERCENTAGE));
        Instances testingSet = new Instances(instances, (int) Math.ceil(instances.size() * TRAIN_PERCENTAGE), (instances.size() - (int) Math.ceil(instances.size() * TRAIN_PERCENTAGE)));

        Classifier mlp = new MultilayerPerceptron();
        ((MultilayerPerceptron) mlp).setHiddenLayers(HIDDEN_LAYERS);
        ((MultilayerPerceptron) mlp).setTrainingTime(NB_EPOCHS);
        ((MultilayerPerceptron) mlp).setLearningRate(LEARNING_RATE);
        ((MultilayerPerceptron) mlp).setMomentum(MOMENTUM);


        try {
            // Training phase
            mlp.buildClassifier(trainingSet);
            // Test phase
            System.out.println("### CHALLENGE SCORE ###");
            Evaluation test = new Evaluation(trainingSet);
            test.evaluateModel(mlp, instances);
            System.out.println(test.toSummaryString());
            System.out.println();
            System.out.println("### TEST SET SCORE ###");
            Evaluation test2 = new Evaluation(trainingSet);
            test2.evaluateModel(mlp, testingSet);
            System.out.println(test2.toSummaryString());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static Instances parseInstances(String filePath) {
        ArrayList<Attribute> attrs = new ArrayList<>(); // Instances constructor only accepts ArrayList
        for(int i = 0 ; i < 76 ; i++) {
            attrs.add(new Attribute("a" + String.valueOf(i)));
        }
        attrs.add(new Attribute("winner", new ArrayList<String>(){{this.add("white");this.add("black");}}));
        Instances instances = new Instances("Rel", attrs, 10);
        instances.setClassIndex(76);

        try {
            BufferedReader r = new BufferedReader(new FileReader(filePath));
            String line;
            String winner = "white";
            while((line = r.readLine()) != null) {
                if(line.equals("White:")) {
                    winner = "white";
                } else if(line.equals("Black:")) {
                    winner = "black";
                } else {
                    Instance instance = new DenseInstance(77);
                    instance.setValue(attrs.get(76), winner);
                    String[] values = line.split(",");
                    for(int i = 0 ; i < values[0].length() ; i++) {
                        if(values[0].charAt(i) == 'B') {
                            instance.setValue(attrs.get(i), -1);
                        } else if(values[0].charAt(i) == 'W') {
                            instance.setValue(attrs.get(i), 1);
                        } else {
                            instance.setValue(attrs.get(i), 0);
                        }
                    }
                    // Ugly as hell
                    instance.setValue(attrs.get(64), values[1].length() - values[1].replace("k", "").length());
                    instance.setValue(attrs.get(65), values[1].length() - values[1].replace("q", "").length());
                    instance.setValue(attrs.get(66), values[1].length() - values[1].replace("r", "").length());
                    instance.setValue(attrs.get(67), values[1].length() - values[1].replace("n", "").length());
                    instance.setValue(attrs.get(68), values[1].length() - values[1].replace("b", "").length());
                    instance.setValue(attrs.get(69), values[1].length() - values[1].replace("p", "").length());
                    instance.setValue(attrs.get(70), values[1].length() - values[1].replace("K", "").length());
                    instance.setValue(attrs.get(71), values[1].length() - values[1].replace("Q", "").length());
                    instance.setValue(attrs.get(72), values[1].length() - values[1].replace("R", "").length());
                    instance.setValue(attrs.get(73), values[1].length() - values[1].replace("N", "").length());
                    instance.setValue(attrs.get(74), values[1].length() - values[1].replace("B", "").length());
                    instance.setValue(attrs.get(75), values[1].length() - values[1].replace("P", "").length());

                    instances.add(instance);
                }
            }
        } catch (Exception e) { // who cares
            e.printStackTrace();
        }
        return instances;
    }
}

入力をどのようにエンコードしますか?
ネイサンメリル

@NathanMerrillあなたの質問を理解しているかわかりません
致命的

テストケースをニューラルネットワークへの入力としてどのように渡しますか?生の文字列を渡すだけですか?
ネイサンメリル

@NathanMerrill特徴ベクトルの構築に関するパラグラフで編集。
致命的

wekaは、勝者を予測しようとしていることをどのように知っていますか?
user1502040

8

GNU sed + bc、4336 5074.5ポイント、64 75%

更新: OPは、個々のテストケースの予測のスコアを計算する新しい方法を提供しました。Wolfram Alphaを使用して、両方の式のセットをプロットして、違いを確認しました。

現在の方法では、新しい式が以前と同じ最大スコアを与える極端な0と1だけでなく、実際の確率を出力する強いインセンティブをもたらします。これが、以下の変更されていないアルゴリズムの予測率が向上した理由です。実際、その単純さを考えると非常に高い率です。

ただし、「編集1」で説明されているように、新しい数式に関連する欠点もあります。


これは、材料の実際の配置を無視して、材料の利点/欠点のみに基づいた単純な推定です。これがどのように機能するか興味がありました。私がsedを使用している理由は、1行でこれを実行できる言語ではなく、それが私のお気に入りの難解な言語だからです。

/:/d                                             # delete the two headers
s:.*,::                                          # delete board positions
s:$:;Q9,R5,B3,N3,P1,K0,q-9,r-5,b-3,n-3,p-1,k-0:  # add relative piece value table
:r                                               # begin replacement loop
s:([a-Z])((.*)\1([^,]+)):\4+\2:                  # table lookup: letter-value repl.
tr                                               # repeat till last piece
s:;.*::                                          # delete value table
s:.*:echo '&0'|bc:e                              # get material difference: bc call
/^0$/c0.5                                        # print potential draw score
/-/c0                                            # print potential black win score
c1                                               # print potential white win score

使用される標準ピース値:

  • 9-クイーン
  • 5-ルーク
  • 3-ナイト
  • 3-ビショップ
  • 1-ポーン
  • 0-キング

両側のマテリアルを計算し、白のマテリアルから黒のマテリアルを減算します。各テストケースの出力は、次のようにその違いに基づいています。

  • 差> 0の場合、出力= 1(潜在的な白勝)
  • 差= 0の場合、出力= 0.5(電位差)。

これが私の唯一の分数出力であるため、上で説明した改善の理由です。

  • 差<0の場合、出力= 0(潜在的な黒勝)

この方法の予測率は64%でした。現在、新しい数式では75%です。

当初は70%程度と高くなると予想していましたが、チェスプレーヤーとしては結果を理解できます。材料。それはすべて実際の位置に関するものです。(まあ、今私は私の願いを得た!)

編集1:欠点

簡単な解決策は、テストケースごとに0.5を出力することです。この方法では、誰が勝ったかに関係なく、半分のポイントを獲得しました。テストケースでは、これは3392.5ポイント(50%)の合計スコアを意味しました。

しかし、新しい数式では、0.5(勝者が決まっていない場合に得られる出力)が0.75ポイントに変換されます。テストケースで受け取ることができる最大スコアは1であり、勝者を100%信頼できることに注意してください。したがって、一定の0.5出力の新しい合計スコアは5088.75ポイント、つまり75%です!私の意見では、この場合のインセンティブは強すぎます。

そのスコアは、わずかではありますが、私の材料の利点に基づくアルゴリズムよりも優れています。その理由は、アルゴリズムが1または0の確率(インセンティブなし)、想定される勝敗を、0.5(インセンティブ)、想定される引き分け(2954)を与えるよりも多く(3831)与えるためです。この方法は、最終的には単純であり、正解の割合が高くありません。新しいフォーミュラから定数0.5へのブーストにより、人為的にその割合に到達することができます。

編集2:

チェスの本で言及されているように、騎士のペアよりも司教のペアを持っている方が通常は良いということは既知の事実です。これは、ビショップの範囲が拡大するオープンポジションを持っている可能性が高いため、テストケースが存在するゲームの中間から終了段階で特に当てはまります。

したがって、2回目のテストを行いましたが、今回は司教の価値を3から3.5に置き換えました。騎士の価値は3のままでした。これは個人的な好みなので、私はそれをデフォルトの提出にしませんでした。この場合の合計スコアは4411ポイント(65%)でした。1パーセントポイントの増加のみが観察されました。

新しい数式では、合計スコアは4835ポイント(71%)です。現在、加重ビショップはパフォーマンスを下回っています。しかし、重み付き方法では、想定されるドロー(1696)よりも想定される勝ちまたは負け(5089)の回数が多くなるため、効果は説明されています。


1
合理的なベースラインソリューションを提供するための+1。また、これがどれだけうまく機能するのか疑問に思っていました。
マーティンエンダー

@MartinEnderありがとう 前回述べた司教の価値を高めるという私の考えでは、成功率は1%しか向上しませんでした(更新2を参照)。結局、標準値にはその効果が含まれていたと思います。
seshoumara

ちょっと、xnorのコメントによると、スコアを絶対差の2乗に変更してもかまいませんか?
ネイサンメリル

1
驚くばかり。また、答えてくれてありがとう!難しい質問では答えが出ないのではないかといつも心配しています。
ネイサンメリル

@NathanMerrill質問に答えて、新しいスコアを使用するように回答を更新しました。長い分析で申し訳ありませんが、私は確かに本当に興味がありました。
seshoumara

4

Python 3-84.6%、検証セットで5275ポイント

すべてのデータをチートして使用すると、達成できます と、99.3%の精度と6408のスコアを達成できます。

Kerasを使用したドロップアウト付きの単純な大規模MLP

import collections
import numpy as np
import random

import keras
from keras.models import Sequential
from keras.layers import Dense, Dropout
from keras.layers.noise import GaussianDropout
from keras.optimizers import Adam

np.random.seed(0)
random.seed(0)

def load_data():
    with open('test_cases.txt', 'r') as f:
        for line in f:
            yield line.split(',')

def parse_data(rows):
    black_pieces = "kpbkrq"
    white_pieces = black_pieces.upper()
    for i, row in enumerate(rows):
        if len(row) >= 2:
            board = row[0]
            board = np.array([1 if c == 'W' else -1 if c == 'B' else 0 for c in board], dtype=np.float32)
            pieces = row[1]
            counts = collections.Counter(pieces)
            white_counts = np.array([counts[c] for c in white_pieces], dtype=np.float32)
            black_counts = np.array([counts[c] for c in black_pieces], dtype=np.float32)
            yield (outcome, white_counts, black_counts, board)
        else:
            if 'White' in row[0]:
                outcome = 1
            else:
                outcome = 0

data = list(parse_data(load_data()))
random.shuffle(data)
data = list(zip(*data))
y = np.array(data[0])
x = list(zip(*data[1:]))
x = np.array([np.concatenate(xi) for xi in x])

i = len(y) // 10

x_test, x_train = x[:i], x[i:]
y_test, y_train = y[:i], y[i:]

model = Sequential()
model.add(Dense(512, activation='relu', input_shape=(76,)))
model.add(GaussianDropout(0.5))
model.add(Dense(512, activation='relu'))
model.add(GaussianDropout(0.5))
model.add(Dense(512, activation='relu'))
model.add(GaussianDropout(0.5))
model.add(Dense(1, activation='sigmoid'))

model.compile(loss='mean_squared_error', optimizer=Adam())

use_all_data = False

x_valid, y_valid = x_test, y_test

if use_all_data:
    x_train, y_train = x_test, y_test = x, y
    validation_data=None
else:
    validation_data=(x_test, y_test)

batch_size = 128

history = model.fit(x_train, y_train, batch_size=batch_size, epochs=50, verbose=1, validation_data=validation_data)

y_pred = model.predict_on_batch(x_test).flatten()
y_class = np.round(y_pred)
print("accuracy: ", np.sum(y_class == y_test) / len(y_test))

score = np.sum((y_pred - (1 - y_test)) ** 2) * (len(y) / len(y_test))
print("score: ", score)

84.6%の数値を得るためのトレーニングにはどのくらいのデータを使用しますか?
致命的

コードに示すように、私は90-10分割を用い
user1502040

ねえ、私が追加したトンあなたが興味を持っている場合はより多くのテストケースを。
ネイサンメリル

2

Python 3-94.3%の精度、20%のデータの検証セットで6447ポイント

3つのニューラルネットワーク、最近傍回帰、ランダムフォレスト、および勾配ブースティングを使用します。これらの予測は、データにもアクセスできるランダムフォレストと組み合わされます。

import collections
import numpy as np
import numpy.ma as ma
import random

import keras
from keras.models import Sequential
from keras.layers import Dense, Dropout, BatchNormalization, Activation, Conv2D, Flatten
from keras.layers.noise import GaussianDropout
from keras.callbacks import EarlyStopping
from keras.optimizers import Adam
from sklearn.neighbors import KNeighborsRegressor
from sklearn.ensemble import RandomForestRegressor
from sklearn.ensemble import GradientBoostingRegressor
import tensorflow

tensorflow.set_random_seed(1)
np.random.seed(1)
random.seed(1)

def load_data():
    with open('test_cases.txt', 'r') as f:
        for line in f:
            yield line.split(',')

def parse_data(rows):
    black_pieces = "kqrnbp"
    white_pieces = black_pieces.upper()
    for i, row in enumerate(rows):
        if len(row) >= 2:
            board = row[0]
            board = np.array([1 if c == 'W' else -1 if c == 'B' else 0 for c in board], dtype=np.float32)
            pieces = row[1]
            counts = collections.Counter(pieces)
            white_counts = np.array([counts[c] for c in white_pieces], dtype=np.float32)
            black_counts = np.array([counts[c] for c in black_pieces], dtype=np.float32)
            yield (outcome, white_counts, black_counts, board)
        else:
            if 'White' in row[0]:
                outcome = 1
            else:
                outcome = 0

data = list(parse_data(load_data()))
random.shuffle(data)
data = list(zip(*data))
y = np.array(data[0])
x = list(zip(*data[1:]))
conv_x = []
for white_counts, black_counts, board in x:
    board = board.reshape((1, 8, 8))
    white_board = board > 0
    black_board = board < 0
    counts = [white_counts, black_counts]
    for i, c in enumerate(counts):
        n = c.shape[0]
        counts[i] = np.tile(c, 64).reshape(n, 8, 8)
    features = np.concatenate([white_board, black_board] + counts, axis=0)
    conv_x.append(features)
conv_x = np.array(conv_x)
x = np.array([np.concatenate(xi) for xi in x])
s = x.std(axis=0)
u = x.mean(axis=0)
nz = s != 0
x = x[:,nz]
u = u[nz]
s = s[nz]
x = (x - u) / s

i = 2 * len(y) // 10

x_test, x_train = x[:i], x[i:]
conv_x_test, conv_x_train = conv_x[:i], conv_x[i:]
y_test, y_train = y[:i], y[i:]

model = Sequential()

def conv(n, w=3, shape=None):
    if shape is None:
        model.add(Conv2D(n, w, padding="same"))
    else:
        model.add(Conv2D(n, w, padding="same", input_shape=shape))
    model.add(BatchNormalization())
    model.add(Activation('relu'))

conv(128, shape=conv_x[0].shape) 
conv(128)
conv(128)
conv(128)
conv(128)
conv(128)
conv(128)
conv(128)
conv(128)
conv(128)
conv(2, w=1)
model.add(Flatten())
model.add(GaussianDropout(0.5))
model.add(Dense(256))
model.add(BatchNormalization())
model.add(Activation('relu'))
model.add(GaussianDropout(0.5))
model.add(Dense(1))
model.add(BatchNormalization())
model.add(Activation('sigmoid'))

model.compile(loss='mse', optimizer=Adam())

model5 = model

model = Sequential()
model.add(Dense(50, input_shape=(x.shape[1],)))
model.add(Activation('sigmoid'))
model.add(Dense(1))
model.add(Activation('sigmoid'))

model.compile(loss='mse', optimizer=Adam())

model0 = model

model = Sequential()
model.add(Dense(1024, input_shape=(x.shape[1],)))
model.add(BatchNormalization())
model.add(Activation('relu'))
model.add(GaussianDropout(0.5))
model.add(Dense(1024))
model.add(BatchNormalization())
model.add(Activation('relu'))
model.add(GaussianDropout(0.5))
model.add(Dense(1024))
model.add(BatchNormalization())
model.add(Activation('relu'))
model.add(GaussianDropout(0.5))
model.add(Dense(1))
model.add(Activation('sigmoid'))

model.compile(loss='mse', optimizer=Adam())

model4 = model

use_all_data = False

x_valid, y_valid = x_test, y_test

if use_all_data:
    x_train, y_train = x_test, y_test = x, y
    validation_data=None
else:
    validation_data=(x_test, y_test)

def subsample(x, y, p=0.9, keep_rest=False):
    m = np.random.binomial(1, p, size=len(y)).astype(np.bool)
    r = (x[m,:], y[m])
    if not keep_rest:
        return r
    m = ~m
    return r + (x[m,:], y[m])

epochs=100

x0, y0, x_valid, y_valid = subsample(conv_x_train, y_train, keep_rest=True)
model5.fit(x0, y0, epochs=epochs, verbose=1, validation_data=(x_valid, y_valid), callbacks=[EarlyStopping(patience=1)])

x0, y0, x_valid, y_valid = subsample(x_train, y_train, keep_rest=True)
model0.fit(x0, y0, epochs=epochs, verbose=1, validation_data=(x_valid, y_valid), callbacks=[EarlyStopping(patience=1)])

x0, y0, x_valid, y_valid = subsample(x_train, y_train, keep_rest=True)
model4.fit(x0, y0, epochs=epochs, verbose=1, validation_data=(x_valid, y_valid), callbacks=[EarlyStopping(patience=1)])

model1 = RandomForestRegressor(n_estimators=400, n_jobs=-1, verbose=1)
model1.fit(*subsample(x_train, y_train))

model2 = GradientBoostingRegressor(learning_rate=0.2, n_estimators=5000, verbose=1)
model2.fit(*subsample(x_train, y_train))

model3 = KNeighborsRegressor(n_neighbors=2, weights='distance', p=1)
model3.fit(*subsample(x_train, y_train))

models = (model0, model1, model2, model3, model4, model5)

model_names = [
    "shallow neural net",
    "random forest",
    "gradient boosting",
    "k-nearest neighbors",
    "deep neural net",
    "conv-net",
    "ensemble"
]

def combine(predictions):
    clip = lambda x: np.clip(x, 0, 1)
    return clip(np.array([y.flatten() for y in predictions]).T)

def augment(x, conv_x):
    p = combine([m.predict(x) for m in models[:-1]] + [models[-1].predict(conv_x)])
    return np.concatenate((x, p), axis=1)

model = RandomForestRegressor(n_estimators=200, n_jobs=-1, verbose=1)
model.fit(augment(x_train, conv_x_train), y_train)

def accuracy(prediction):
    class_prediction = np.where(prediction > 0.5, 1, 0)
    return np.sum(class_prediction == y_test) / len(y_test)

predictions = [m.predict(x_test).flatten() for m in models[:-1]] + [models[-1].predict(conv_x_test).flatten()]+ [model.predict(augment(x_test, conv_x_test))]

for s, p in zip(model_names, predictions):
    print(s + " accuracy: ", accuracy(p))

def evaluate(prediction):
    return np.sum(1 - (prediction - y_test) ** 2) * (len(y) / len(y_test))

for s, p in zip(model_names, predictions):
    print(s + " score: ", evaluate(p))

ねえ、私が追加したトンあなたが興味を持っている場合はより多くのテストケースを。
ネイサンメリル

うわー、あなたはこれに出かけました。
ロバートフレイザー

ここでのJavaの回答に注意してください。「ビート」はデータセット全体の%を報告し、トレーニングしていないデータの77%しか取得しないようです。
ロバートフレイザー

0

Python 3-4353.25 / 6785ポイント-64%

だから私は昨日ほとんどこれに取り組んだ。ゴルフの最初の投稿で、Pythonを使用してから1週間ほどしか経っていないので、すべてが最適化されているわけではないにしても許してください。

def GetWhiteWinPercent(a):
finalWhiteWinPercent=0
i=a.index(',')

#position
board=a[:i]
blackBoardScore=0
whiteBoardScore=0
for r in range(i):
    if board[r] == 'B': blackBoardScore += abs(7 - (r % 8))
    if board[r] == 'W': whiteBoardScore += r % 8
if   whiteBoardScore > blackBoardScore: finalWhiteWinPercent += .5
elif whiteBoardScore < blackBoardScore: finalWhiteWinPercent += .0
else: finalWhiteWinPercent+=.25

#pieces
pieces=a[i:]
s = {'q':-9,'r':-5,'n':-3,'b':-3,'p':-1,'Q':9,'R':5,'N':3,'B':3,'P':1}
pieceScore = sum([s.get(z) for z in pieces if s.get(z) != None])
if   pieceScore < 0: finalWhiteWinPercent += 0
elif pieceScore > 0: finalWhiteWinPercent += .5
else: finalWhiteWinPercent += .25

return finalWhiteWinPercent

私は、最初にセショウマラの答えと同じ道をたどりました。しかし、数え切れないほどの数のテストケースがあったため、不満が残りました。

だから私はチェスで誰が勝っているのかを決める特性をグーグルで調べ(私は自分でゲームをプレイしていません)、ボードの位置、特にセンターコントロールが大きいことに気付きました。それがこのビットの出番です。

for r in range(i):
    if board[r] == 'B': blackBoardScore += abs(7 - (r % 8))
    if board[r] == 'W': whiteBoardScore += r % 8
if   whiteBoardScore > blackBoardScore: finalWhiteWinPercent += .5
elif whiteBoardScore < blackBoardScore: finalWhiteWinPercent += .0
else: finalWhiteWinPercent+=.25

これらの半分を組み合わせて、スコア(0.0、0.25、0.50、0.75、1.0)を見つけます。

このボードポジションの追加が勝者を推測する機会をまったく増やしていないように見えることは非常に興味深い。

テストケースをいくつかのファイルにドロップすると、次のテストが実行されます。

whiteWins=0
blackWins=0
totalWins=0
for line in open('testcases2.txt','r'):
    totalWins += 1
    blackWins += 1 - GetWhiteWinPercent(line)
for line in open('testcases.txt','r'):
    totalWins += 1
    whiteWins += GetWhiteWinPercent(line)

print(str(whiteWins+blackWins) +'/'+str(totalWins))

私はこれがゴルフの挑戦ではないことを知っていますが、その点に関するヒントやアドバイスは大歓迎です!


私の答え?セショウマラの答えですか?また、これをゴルフする必要はありません(そうしない限り)。これはコードゴルフの挑戦ではありません。
ネイサンメリル

1文字の変数名を使用するだけで、多くのバイトを節約できます。(これはコードのゴルフではありませんので、それは本当に問題ではありませんが)
HyperNeutrino

わあ!今すぐ編集します。職場では、これがスキミングで得られるものです!
ストリーム

2
ゴルフしないでください。コードゴルフではない場合は、コードを読みやすくすることをお勧めします。
mbomb007

ボードの中央をコントロールするということは、ボードの中央を占めることではなく、ボードの中央を攻撃することを意味します。複雑さを追加したい場合は、スコアが改善される可能性があります。
チャールズ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.