Sınırlı Bilgiyle Satranç Analizi


19

Bu meydan okumada, belirli bir satranç oyunu hakkında sınırlı miktarda bilgi verilir ve oyunu kimin kazandığını tahmin etmeniz gerekir .

Size iki veri kümesi verilir:

  1. Parça sayısı (Hangi parçalar hala hayatta)
  2. Tahta renkleri (Tahtadaki parçaların rengi)

Daha da önemlisi, sen yok parçalar nerede bulunduğunu bilmek . Kimin kazanacağını düşündüğünü belirlemelisin.

Oyunlar 2010'dan bu yana PGNMentor'da listelenen tüm etkinliklerden seçilmektedir . Kazanılan veya kaybıyla sonuçlanan her oyundan tüm tahta pozisyonlarının% 10'unu seçtim. Kurul pozisyonları her zaman oyuna en az 30 hamle olacaktır. Test senaryolarını burada bulabilirsiniz . (Önce beyaz kazançlar, ardından siyah kazançlar listelenir)

Giriş

Parça sayısı, her parça için bir karakterden oluşan bir dize olacaktır: king, queen, rook n, bkght, ishop veya tente p. Küçük harf siyah, büyük harf beyaz demektir. Kart 64 karakterlik bir dize olacaktır (8 satır x 8 sütun). Bsiyah bir parçayı Wtemsil eder, beyaz bir parçayı .temsil eder ve boş bir noktayı temsil eder. Örneklem:

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

aşağıdaki kurulu temsil eder

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

ve her iki rengin de 2 Piskopos, 1 Kral, 7 Piyon, 1 Kraliçe, 2 Kale olduğu yerlerde

Çıktı

Beyazın kazanma olasılığını belirlemek için 0 ile 1 (dahil) arasında bir kayan nokta sayısı döndürmeniz gerekir. Örneklem:

0.3     (30% chance that white wins)

Daha fazla detay:

  • Her test senaryosu 1 puan değerindedir. Puanınız 1 - (1-Output)^2beyaz kazanırsa veya 1 - (Output)^2siyah kazanırsa olur.
  • Nihai puanınız tüm test senaryolarının toplamı olacaktır.
  • Eğer gönderimlerin girdiyi kodladığını düşünürsem, test senaryolarını değiştirme hakkını saklı tutarım. (Onları değiştirirsem, SHA-256 karmasına sahip olacaklar893be4425529f40bb9a0a7632f7a268a087ea00b0eb68293d6c599c6c671cdee )
  • Programınız test senaryolarını bağımsız olarak çalıştırmalıdır. Bir test durumundan diğerine kayıt bilgisi yok.
  • Makine öğrenimi kullanıyorsanız, verilerin ilk% 80'i üzerinde eğitim ve kalan% 20'yi kullanarak test yapmanızı önemle tavsiye ederim . (Ya da kullandığınız yüzdeler). Oyunları verilerde birden çok kez kullanıyorum ama aynı oyunları sırayla bir araya getirdim.
  • GÜNCELLEME: Test ve öğrenme amacıyla bir milyondan fazla test vakası ekledim . Github repo boyut sınırları nedeniyle siyah beyaz parçalara ayrılırlar.

İyi şanslar ve iyi eğlenceler!


Bu sohbet sohbete taşındı .
Dennis

Yeni test senaryoları eskilerini içeriyor mu yoksa iki set ayrık mı?
17'de

Hiç bir fikrim yok. Onları farklı sitelerden aldım, bu yüzden her ikisi de aynı oyun setini içeriyor olabilir.
Nathan Merrill

Yanıtlar:


8

Java 8 + Weka, 6413 puan, 94.5%

Bu cevap bir makine öğrenimi yaklaşımı kullanır. Sen almak gerekir Weka önemlisi, kütüphane weka.jarve PackageManager.jar.

Burada, sınıflandırıcı olarak çok katmanlı bir algılayıcı kullanıyorum; mlpherhangi biriyle değiştirebilirsinizClassifiersonuçları karşılaştırmak için Weka sınıfıyla .

MLP'nin parametreleriyle pek uğraşmadım ve sadece gözlerini salladım (50 nöronun bir gizli katmanı, 100 dönem, 0.2 öğrenme oranı, 0.1 momentum).

MLP'nin çıkış değerini eşleştiriyorum, bu nedenle çıkış gerçekten zorlukta tanımlandığı gibi 1 veya 0'dır. Bu şekilde Weka tarafından basılan doğru sınıflandırılmış örnek sayısı doğrudan bizim puanımızdır.

Özellik vektör yapısı

Her örneği bir dizeden 76 öğeden oluşan bir vektöre çeviririm:

  • İlk 64 element, 1beyaz bir parça olan ipte olduğu gibi tahtadaki hücreleri temsil eder, -1siyah bir parçadır ve 0boş bir hücredir.
  • Son 12 eleman her bir parçayı temsil eder (oyuncu başına 6); bu öğelerin değeri tahtadaki o türün parça sayısıdır ( 0"bu türden bir parça değildir"). Bu değerleri -1 ile 1 arasında değiştirmek için normalizasyon uygulanabilir, ancak bu muhtemelen çok yararlı değildir.

Eğitim örneği sayısı

Sınıflandırıcımı eğitmek için verilen tüm test senaryolarını kullanırsam, 6694 (yani% 98.6588) doğru sınıflandırılmış örnek almayı başardım . Bu, şaşırtıcı bir şekilde şaşırtıcı değildir, çünkü bir modeli eğitmek için kullandığınız aynı veriler üzerinde test etmek çok kolaydır (çünkü bu durumda modelin fazla uyması iyidir).

Eğitim verisi olarak örneklerin% 80'inin rastgele bir alt kümesini kullanarak , başlıkta bildirilen 6413 (yani% 94.5173) doğru sınıflandırılmış örnek figürünü elde ederiz (elbette alt küme rastgele olduğundan biraz farklı sonuçlar alabilirsiniz). Modelin yeni veriler üzerinde iyi çalışacağından eminim, çünkü örneklerin (eğitim için kullanılmayan) kalan% 20'sini test etmek% 77.0818 yapılması, modellerin iyi bir şekilde genelleştirildiğini gösteren ( Burada verilen örnekler, bize verilecek yeni test örneklerini temsil etmektedir).

Yarım eğitim örneklerini ve test için diğer yarısı kullanarak, olsun 86,7502% eğitim ve test verileri ve hem de 74,4988% sadece deney verilerine.

uygulama

Dediğim gibi, bu kod Weka gerektirir weka.jarve PackageManager.jar.

Eğitim setinde kullanılan veri yüzdesi ile kontrol edilebilir TRAIN_PERCENTAGE.

MLP'nin parametreleri hemen aşağıda değiştirilebilir TRAIN_PERCENTAGE. Başka bir sınıflandırıcıyla SMOdeğiştirerek Weka'nın diğer sınıflandırıcılarını (örneğin , SVM'ler için) deneyebilirsiniz mlp.

Bu program sonuç kümesine yazdırır, ilki tüm sette (eğitim için kullanılan veriler dahil), bu zorlukta tanımlanan puandır ve ikincisi sadece eğitim için kullanılmayan verilerdedir.

Birisi, onu argüman olarak içeren dosyanın yolunu programa aktararak veri girer.

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;
    }
}

Girişi nasıl kodlarsınız?
Nathan Merrill

@NathanMerrill Sorunuzu anladığımdan emin değilim
17'de Fatalize

Sinir ağına girdi olarak test senaryosunu nasıl geçiriyorsunuz? Sadece ham ipi mi geçiyorsun?
Nathan Merrill

@NathanMerrill Özellik vektörü yapısıyla ilgili bir paragrafla düzenlendi.
Fatalize

Weka kazananı tahmin etmeye çalıştığınızı nasıl biliyor?
user1502040

8

GNU sed + bc, 4336 5074.5 puan, 64 75%

Güncelleme: OP, bireysel bir test vakası için tahmin puanını hesaplamak için yeni bir yol verdi. Wolfram Alpha'yı kullanarak farklılıkları görmek için her iki formül setini de çizdim.

Mevcut yol, yeni formüllerin eskisi gibi aynı maksimum puanı verdiği sadece 0 ve 1 uçlarını değil, gerçek olasılıkları çıkarmak için güçlü bir teşvik getiriyor. Bu nedenle aşağıdaki değişmemiş algoritmanın daha iyi bir tahmin oranı var, aslında basitliği göz önüne alındığında büyük bir oran.

Bununla birlikte, 'Düzenle 1'de açıklandığı gibi yeni formüllerle ilişkili bir dezavantaj vardır.


Bu, sadece malzeme avantajına / dezavantajına dayanan, parçaların gerçek yerleşimini göz ardı eden basit bir tahmindir. Bunun nasıl performans göstereceğini merak ettim. Sed'i kullanmamın nedeni, bunu bir satırda yapabilecek bir dil değil, en sevdiğim ezoterik dilim.

/:/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

Kullanılan standart parça değerleri:

  • 9 - Kraliçe
  • 5 - Kale
  • 3 - Şövalye
  • 3 - Piskopos
  • 1 - Piyon
  • 0 - Kral

Malzemeyi her iki taraf için de hesaplıyorum ve siyahın malzemesini beyazdan çıkarıyorum. Her test senaryosunun çıktısı, aşağıdaki farklılığa dayanmaktadır:

  • fark> 0 ise, çıktı = 1 (potansiyel beyaz kazanç)
  • fark = 0 ise, çıkış = 0.5 (potansiyel çekme).

Bu benim tek kesirli çıktım, dolayısıyla yukarıda açıklandığı gibi iyileşmenin nedeni.

  • fark <0 ise, çıktı = 0 (potansiyel siyah kazanç)

Bu yöntem için tahmin oranı% 64 idi. Şimdi yeni formüllerle% 75.

Başlangıçta daha yüksek olmasını bekledim, diyelim% 70, ama bir satranç oyuncusu olarak sonucu anlayabiliyorum, çünkü +1 / +2 iken çok fazla oyun kaybettim ve düştüğümde çok fazla kazandım malzeme. Her şey gerçek konumla ilgili. (Eh, şimdi dileğimi aldım!)

Düzenleme 1: dezavantaj

Önemsiz çözüm, her test senaryosu için 0,5 çıktı almaktır, çünkü bu şekilde kimin kazandığından bağımsız olarak yarım puan aldınız. Test vakalarımız için bu toplam 3392.5 puan (% 50) anlamına geliyordu.

Ancak yeni formüllerle 0,5 (kimin kazanacağına kararsızsanız vereceğiniz bir çıktıdır) 0,75 puana dönüştürülür. Bir test vakası için alabileceğiniz maksimum puanın, kazanana% 100 güven için 1 olduğunu unutmayın. Bu nedenle, sabit bir 0,5 çıktı için yeni toplam puan 5088,75 puan veya% 75'tir! Bence bu dava için teşvik çok güçlü.

Bu puan, marjinal olarak olsa da, malzeme avantajına dayalı algoritmamdan daha iyidir. Bunun nedeni, algoritmanın 1 (0) (teşvik yok), varsayılan kazanç veya kayıp olasılığı, (3831) 0,5 (teşvik), varsayılan çekilişe (2954) göre daha fazla olasılık vermesidir. Yöntem sonunda basittir ve bu nedenle yüksek oranda doğru cevaplara sahip değildir. Yeni formülden 0,5'e yükselme, bu yüzdeye yapay olarak ulaşmayı başarır.

Düzenleme 2:

Satranç kitaplarında bahsedilen, piskopos çiftine bir şövalye çiftinden daha iyi olduğu bilinen bir gerçektir. Bu, özellikle test senaryolarının olduğu oyunun orta-uç aşamasında doğrudur, çünkü bir piskoposun menzilinin arttığı açık bir pozisyona sahip olma olasılığı daha yüksektir.

Bu nedenle ikinci bir test yaptım, ancak bu kez piskoposların değerini 3'ten 3,5'e değiştirdim. Şövalyenin değeri 3'te kaldı. Bu kişisel bir tercihtir, bu yüzden varsayılan gönderimi yapmadım. Bu vakadaki toplam puan 4411 puan (% 65) idi. Sadece yüzde 1'lik bir artış gözlendi.

Yeni formüllerle toplam puan 4835 puan (% 71). Şimdi ağırlıklı fil düşük performans gösteriyor. Ancak, etki açıklanmıştır, çünkü ağırlıklı yöntem artık varsayılan kazanım veya kayıpları (5089) varsayılan çekilişlerden (1696) daha fazla vermektedir.


1
+1 makul bir temel çözüm sağlamak için. Bunun ne kadar iyi performans göstereceğini merak ediyordum.
Martin Ender

@MartinEnder Teşekkür ederim. Son kez bahsedilen piskoposun değerini artırma fikrim sadece% 1'lik bir başarı artışı sağladı (bkz. Güncelleme 2). Sonuçta standart değerlerin bu etkiyi içerdiğini düşünüyorum.
seshoumara

Hey, xnor'ın yorumuna göre, puanlamayı kare mutlak fark olarak değiştirirsem sakıncası olur mu?
Nathan Merrill

1
Muhteşem. Ayrıca, cevap verdiğiniz için teşekkürler! Her zaman daha zor sorularımın bir cevap alamayacağından endişeleniyorum.
Nathan Merrill

@NathanMerrill Yeni skorlamayı istendiği gibi kullanmak için cevabımı güncelledim. Uzun analiz için özür dilerim, ama gerçekten çok merak ettim.
seshoumara

4

Python 3 -% 84.6, bir doğrulama kümesinde 5275 puan

Tüm verileri aldatır ve kullanırsak, % 99,3'lük bir doğruluk ve 6408'lik bir puan elde edebiliriz.

Sadece Keras kullanarak bırakma ile basit bir büyük 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 rakamını almak için eğitim için ne kadar veri kullanıyorsunuz?
Fatalize


Hey, eğer ilgilenirsen bir ton daha test vakası ekledim .
Nathan Merrill

2

Python 3 -% 94,3 doğruluk, verilerin% 20'si bir doğrulama kümesinde 6447 puan

3 sinir ağı, en yakın komşu regresörü, rastgele bir orman ve gradyan güçlendirme kullanır. Bu tahminler, verilere erişimi olan rastgele bir ormanla birleştirilir.

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))

Hey, eğer ilgilenirsen bir ton daha test vakası ekledim .
Nathan Merrill

Woah, bunun üzerine çıktın.
Robert Fraser

Burada "sizin atıyor" ifadesinin, tüm veri kümesinde% olarak rapor verdiğini ve eğitim vermediği verilerde yalnızca% 77 aldığını belirten java cevabına dikkat edin.
Robert Fraser

0

Python 3 - 4353,25 / 6785 puan -% 64

Bu yüzden çoğunlukla dün üzerinde çalıştım. İlk yazım golf ve ben sadece bir hafta kadar python kullanıyorum, bu yüzden her şey optimize değilse beni affet.

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

Seshoumara'nın yanıtı ile aynı yol boyunca devam ettim. Ancak, çok sayıda parçaya sahip olan çok sayıda test vakası beni tatmin etmedi.

Bu yüzden satrançta kimin kazanacağını belirleyen özellikleri oynadım (oyunu kendim oynamıyorum) ve tahta pozisyonunun, özellikle merkez kontrolün büyük olduğunu fark ettim. Bu bit devreye giriyor.

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

Bu yarımların her ikisi de skoru bulmak için kullanılır (0.0, 0.25, 0.50, 0.75, 1.0)

Çok ilginç bu tahta pozisyonu ekstra kazanan hiç tahmin şansını artırmak gibi görünmüyor.

Test senaryolarını bazı dosyalara bırakırsanız, test burada.

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))

Bu bir golf meydan okuma değil biliyorum, ama bu konuda herhangi bir ipucu veya tavsiye takdir!


Cevabım? Seshoumara'nın cevabı mı demek istiyorsun? Ayrıca, bu golf (gerekmez sürece) gerekmez. Bu bir kod golf zorluğu değil.
Nathan Merrill

Yalnızca tek karakterlik değişken adlarını kullanarak birçok bayt kaydedebilirsiniz. (Bu kod golf olmadığı için gerçekten önemli olmasa da)
HyperNeutrino

Woops! Şimdi düzenleniyor. İş yerinde, kaymağını aldığım şey bu!
Datastream

2
Lütfen golf oynama. Kod-golf olmadığında kodu okunabilir tutmak daha iyidir.
mbomb007

Tahtanın ortasının kontrolü, tahtanın ortasını işgal etmek değil, tahtanın ortasına saldırmak anlamına gelir. Eğer buna biraz karmaşıklık katmak istiyorsanız puanınızı yükseltebilirsiniz.
Charles
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.