日本のチェスをプレむするためのAIの構築における機械孊習の䜿甚将gi





良い䞀日。



かなり長い間、友人のゎルコフず私は将giをするのが奜きでした 。 そしお私たちはあたりにも倢䞭になったので、この玠晎らしいゲヌムのために独自のボットを曞くこずにしたした。 この蚘事は、ボット開発プロセスの詳现な説明です。ボット開発プロセスは、いく぀かの䞭断を䌎いながら、数か月間行われおきたした。







アルファベヌタクリッピングに぀いお、たたは動きを゜ヌトするこずが重芁である理由


チェス䌝統的および日本語、チェッカヌ、䞉目䞊べなどの拮抗ゲヌムでどの動きを行うかを決定するために、アルファ-ベヌタクリッピングず呌ばれる最適化を䌎うミニマックス戊略が䜿甚されたす。

このアルゎリズムは、私の友人の蚘事ず他の蚘事の䞡方で、Habréで繰り返し怜蚎されたした。

次の写真でその本質を簡単に思い出したす。







四角の数字は、察応する䞀連の動きを行った埌の䜍眮の評䟡を瀺したす。



この䟋では、ノヌドがクリップされ、その倀には疑問笊が付けられおいたす。

ノヌドbの倀を蚈算する匏を䜜成するこずにより、このようなカットオフの有効性を怜蚌できたす。



b =最小c、d=最小最倧4,6、最倧7、X



明らかに、匏max7、Xは7以䞊であるため、この匏の倀はXに䟝存したせん。したがっお、 max4,6より倧きく、 bの倀はb = 6に等しくなりたす。



したがっお、アルファ-ベヌタクリッピングアルゎリズムにより、既に取埗されおいるものよりも意図的に悪い結果を䞎えるブランチを考慮しないこずが可胜になりたす。

したがっお、最初のより有望な動きを考慮するず、アルゎリズムが加速されたす。 どの動きがより有望かを刀断するこずが、この蚘事の目的です。



仮説


ゲヌムでは、特定の動きを考慮する必芁がないこずは人にずっおしばしば明らかです。 たずえば、察戊盞手がルヌクを攻撃した瞬間にボヌドの端に立っおいるポヌンを移動するには。

コンピュヌタヌの堎合、「明癜な」ずいう抂念は存圚したせん。すべおの可胜な動きを順番にチェックし、その埌、ボヌトを食べるこずが正しい決定であるず結論付けたす。

䜕らかの方法で、ルヌクのキャプチャが最初に考慮されるように移動の考慮が順序付けされおいる堎合、アルファ-ベヌタカットオフアルゎリズムはすぐに終了し、ルヌクを取るずきよりも明らかに評䟡が悪いブランチをすべお砎棄したす。



この䟋では、移動の考慮の順序のヒュヌリスティックな遞択の特別なケヌスが考慮されおおり、プログラムで個別に䜿甚するこずはほずんどできたせん。 特殊なケヌスのセットを手動で説明するのは非垞に面倒で、さらに、ルヌクが攻撃を受けおいるオプションの䞀郚のサブセットでは、ポヌンの動きが唯䞀の正しいものになる可胜性が垞にありたす。



これは、すでにプレむされたゲヌムから有望な動きに関する情報を自動的に取埗する可胜性のアむデアが出おくるずころです。 この堎合、機械孊習法の䜿甚は、同様のパラメヌタヌ以䞋のパラメヌタヌに぀いおで移動するず同様の結果が埗られるずいう仮説によっお正圓化されたす。



トレヌニングサンプル


機械孊習を䜿甚するずきに解決する必芁がある最初の質問は、トレヌニングサンプルを取埗するこずです。これにより、動䜜の品質が決定されたす。

奇劙なこずに、通垞のチェスず比范しお将giの人気が劣っおいたにもかかわらず、これは最小の問題であるこずが刀明したした。



りェブ䞊にはplayok.comがあり、他のプレむダヌずさたざたなボヌドゲヌムを無料でプレむする機䌚を提䟛しおいたす。 提䟛されるゲヌムの䞭には将areがありたす。 さらに、このサむトでプレむされるすべおのゲヌムはkifu圢匏で保存され、パブリックドメむンにあるため、必芁な数のゲヌムをダりンロヌドする簡単なスクリプトを䜜成できたす。



このサむトに保存されおいるゲヌムの数は非垞に倚い数癟䞇ので、ゲヌムずムヌブのパラメヌタヌのロヌカルストレヌゞ甚のデヌタベヌスを䜜成するこずにしたした。

デヌタベヌスを操䜜するプロセスでは、パヌティ番号ごずの移動を取埗するために倚数の操䜜が必芁になるため、このようなデヌタを保存するタスクはそれほど簡単ではありたせん。

぀たり SQLの堎合、数癟䞇行を含むテヌブルから数十行の遞択。

MongoDBなどのNoSQLデヌタベヌスを䜿甚する可胜性を怜蚎したした。 NoSQLの堎合、そのような操䜜は単玔なポむンタヌゞャンプに芁玄されたす。 このNoSQLの利点にもかかわらず、珟圚の実装ではPostgreSQLが䜿甚されおおり、移動テヌブルにはバッチ番号によるむンデックスがありたす。



playok.comからバッチをダりンロヌドしおデヌタベヌスに入力するスクリプト、およびデヌタを準備するスクリプト぀たり、実行時間が重芁ではない関数は、Rubyで蚘述されおいたす。 この蚀語は、高速のコヌド蚘述を提䟛し、デヌタベヌスを操䜜するために必芁なすべおのコンポヌネントも備えおいたす。 ゜ヌスコヌドぞのリンクは、蚘事の最埌に蚘茉されおいたす。



動きの説明に぀いお


機械孊習手法の適甚を可胜にするには、䞀連の機胜を䜿甚しお各動きを蚘述する必芁がありたす。 奇劙に思えるかもしれたせんが、そのような蚘述はオブゞェクトの機胜蚘述ず呌ばれたす。



特性蚘述は倀のベクトルであり、倀のベクトルは属性空間内のポむントの座暙です。

たずえば、ボックスの寞法ず重量は、説明ずしお圹立぀堎合がありたす。 したがっお、2 x 3 x 1メヌトルで重量が10キログラムの箱には、暙識の4次元空間に特城の説明2,3,1,10がありたす。



異なる圓事者の指定による同じ動きe2e4が反察の結果に぀ながる可胜性があるずいう事実のため、動きの特城的な説明にボヌド䞊の他の人物の䜍眮に関する情報を含む暙識を含める必芁がありたす。

暙識の堎合、トレヌニングセットでは黒ず癜の䞡方の動きが良いため、動きをした郚分の色に関する䞍倉性を芳察する必芁がありたす。 たずえば、移動の氎平方向の数は、開始䜍眮たでの氎平線の数に眮き換える方が適切ですこの堎合、黒は氎平9から始たり、癜は氎平1から始たるず考えられおいたす。



䜿甚される特性蚘述のバリアントは、以䞋のパラメヌタヌで構成されおいたす。



長いリスト
  • 動くフィギュアの重さ
  • 食べた人物の䜓重そうでない堎合は0
  • 開始䜍眮から移動が行われる䜍眮たでの氎平の量
  • 移動元の垂盎線の番号
  • 開始䜍眮から移動する䜍眮たでの氎平方向の数
  • 移動が行われる垂盎の番号
  • 図が反転したした1/0
  • 攻撃された砎片の総重量
  • 最匷攻撃フィギュアの重量
  • 攻撃された人物の重みの算術平均
  • 攻撃された最匱の人物の䜓重
  • 移動元の䜍眮を攻撃する盞手のピヌスの総重量
  • 移動元の䜍眮を攻撃しおいる最匷の敵の駒の重量
  • 移動元の䜍眮を攻撃する盞手のピヌスの平均重量
  • 移動元の䜍眮を攻撃しおいる最も匱い盞手の駒の重量
  • 新しい䜍眮を攻撃しおいる敵の駒の総重量
  • 新しい䜍眮を攻撃する最匷の敵の駒の重量
  • 新しい䜍眮を攻撃しおいる敵の駒の平均重量
  • 新しい䜍眮を攻撃しおいる最も匱い敵フィギュアの重量
  • 新しいピヌスを攻撃するピヌスの数
  • 開始䜍眮を保護するフィギュアの総重量
  • 開始䜍眮を守る最匷のピヌスの重量
  • 開始䜍眮を保護するフィギュアの平均重量
  • 開始䜍眮を守るその数字の最も匱いの重量
  • 新しい䜍眮を守る数字の総重量
  • 新しいポゞションを守る最匷のフィギュアの重量
  • 元の新しいを保護する圌らの䜜品の平均重量
  • 新しいポゞションを守る圌の最も匱い人物の䜓重
  • 新しい地䜍を守る数字の数
  • 新しい䜍眮にある敵の王たでの氎平距離
  • 敵の王たでの垂盎距離
  • 圌の王たでの氎平距離
  • 圌の王たでの垂盎距離
  • バッチ番号






分類アルゎリズムの遞択に぀いお




問題の蚘述は、動きを有望なものずそうでないもの良いものず悪いものに分類するこずを意味したすが、アルゎリズムにはいく぀かの远加条件も課されたす。







分類アルゎリズムの䞭では、 最近傍法がタスクに適しおいたす。

この方法は、属性空間で分類されたオブゞェクトに最も近いクラスのオブゞェクトが誰であるかを刀断するこずで構成されたす。

この方法は、怜蚎䞭の2぀の動きのうちどちらが良いかを自然に決定するため、優れおいたす。 これを行うには、距離を最も近い隣人ず比范するだけで十分です。

ただし、この方法には重倧な欠点もありたす。最も近いオブゞェクトが芋぀かったず䞻匵する前に、倚数のオブゞェクトをチェックする必芁がありたす。



この問題を解決する1぀の方法は、クラスタリングを䜿甚するこずです。

開始点のセットをクラスタヌの䞭心である点のセットで眮き換えるず、オブゞェクトの分類に必芁な操䜜の数が倧幅に削枛されたす。 このような眮換は明らかに分類の品質を䜎䞋させ、出力セットにあるクラスタヌが少ないほど品質が䜎䞋したす。 したがっお、クラスタヌの数は、粟床ず速床の間の劥協を反映する倀です。



動きの遞択に぀いお


圓事者の凊理に進む前に、どの動きが良いず芋なされ、どの動きが私たちのベヌスずしお悪いず刀断する必芁がありたす。 いく぀かのオプションがすぐに思い浮かびたす





少し考えおみるず、最初ず2番目のオプションが良いこずを保蚌されおいないこずが明らかになりたす。

第䞀に、匷い人物の犠牲者がその埌犠牲者を受け入れたプレヌダヌの損倱に぀ながるプレヌダヌがいる状況があるからです。

第二に、負けおいるプレむダヌの䞍泚意のためにチェックメむトを眮くこずができたす。これは非垞に頻繁に起こりたす。

レヌティングが高いプレヌダヌがゲヌムに勝った堎合、圌は明癜に愚かな動きをしなかったず蚀うこずができたすあくびは十分なレベルで敗北に぀ながるこずが保蚌されおいたす、私たちのタスクは、特定の状況で絶察に正確な動きを確立しないこずです、゜ヌトは平均しお品質で移動したす。

䞊蚘の議論に基づいお、私たちは問題を解決するために圓局を信頌する必芁があるず考えおいたす。



珟圚の実装では、移動は次のように遞択されたす。





最初の動きのスクリヌニングは、パヌティヌのデビュヌには他のより効果的なアルゎリズムがあり、その考慮は蚘事の範囲を超えおいるずいう事実によっお正圓化されたす。



クラスタリングに぀いお


ゲヌムツリヌを衚瀺する各ステップで実行する必芁のある分類ずは察照的に、この堎合、クラスタリングに察する芁件はそれほど厳しくありたせん。

たず、クラスタリングは1回だけ行う必芁がありたす。これにより、ゲヌムの時点で必芁な時間よりも倚くの時間を必芁ずするアルゎリズムを䜿甚する暩利が䞎えられたす。



クラスタリングタスク自䜓は明確に定匏化されおいないため、解釈の倚くのオプションが提䟛されたす。 次の定矩を䜿甚したす。



クラスタリングずは、クラスタヌ内のオブゞェクト間の距離を最小化し、クラスタヌ間の距離を最倧化するような方法で、オブゞェクトのセットを互いに玠なセットクラスタヌに分割するこずです。



正匏には、この定矩は次のように蚘述できたす。





ここで、 K y-番号yのクラスタヌ

px、yは、指定されたメトリックで距離を決定する関数です

ÎŒyは、番号yのクラスタヌの䞭心です。

x i-番号iのオブゞェクト



私の実装では、k-meansクラスタリングアルゎリズムを䜿甚したした;詳现な説明は、たずえばWikipediaにありたす。

アルゎリズムの特城は、クラスタヌぞの初期パヌティションずしおランダムな倀を䜿甚するこずです。その遞択は、さらにパヌティション化の結果に匷く圱響したす。これにより、より良い結果を達成するためにクラスタリングを繰り返し実行するこずが可胜になり、この段階での実行時間に制限されたせん。



たずえば、2次元空間でのランダムポむントのクラスタリングは次のようになりたす。







Rubyの実装
def midle(cluster) # "" res = [0]*cluster[0].size(); cluster.each do |e| i = 0; e.each do |x| res[i] += x; i+=1; end end res.map! {|x| x/cluster.size.to_f} return res; end def dist(x1,x2) if(x1.size != x2.size) raise "WrongSizeException"; end mode = 1 if mode ==1 then #     dist = 0; for i in 0..x1.size-1 dist += (x1[i]-x2[i])**2 end return dist; end if mode == 2 then #   dist = 0; x1_s = 0; x2_s = 0; for i in 0..x1.size-1 dist += x1[i]*x2[i] x1_s += x1[i]**2; x2_s += x2[i]**2; end dist =1 - dist / Math.sqrt(x1_s) / Math.sqrt(x2_s) end end def quality1 (clusters) #    ( ,    - ) sum = 0; clusters.each do |cluster| center = midle(cluster) local_sum = 0 cluster.each do |vector| local_sum += dist(vector, center); end sum += local_sum / cluster.size.to_f; end return sum; end def quality2 (clusters) #    centers = []; clusters.each do |cl| centers += [midle(cl)]; end sum = 0 centers.each do |c1| centers.each do |c2| sum += dist(c1,c2) end end return sum; end def quality (clusters) #    return quality1(clusters)/quality2(clusters); end def find_nearest(vectors, point) min = Float::INFINITY imin = 0 i = 0 vectors.each do |vector| d = dist(vector, point) if(d < min) then min = d; imin = i; end i += 1; end return imin end def k_means(vectors, k) len = vectors.size; clusters = []; centers_index = []; if len < k then raise "count of clusters more than objects"; end while centers_index.size != k do #    k   centers_index = (1..k).map { Random.rand(len)}; #  k   centers_index.uniq! end centers = centers_index.map{ |e| vectors[e] } clusters_new = [] begin #       clusters = clusters_new; clusters_new = k.times.map {[]}; vectors.each do |vector| clusters_new[find_nearest(centers, vector)] += [vector]; end #    centers = []; clusters_new.each do |cluster| return nil if cluster == nil; #  ,  -    return nil if cluster.size == 0; centers += [midle(cluster)] end end until clusters_new == clusters return clusters_new end
      
      









クラスタリングの結果ずしお、特城空間での良い動きず悪い動きのクラスタヌの䞭心であるN 私はN = 20を遞択したしたポむントを取埗したす。

これらのポむントたでの距離は、衚瀺の動きの順序を䞊べ替えるずきに䜿甚されたす。



分類に぀いお




元のベヌスに比べおポむントの数が倧幅に少なくなったので、これらのポむントぞの近接床に基づいお䞊べ替えを適甚できたす。



前の段階ず同様に、遞択の䜙地がありたす。 ぀たり、クラスタヌたでの距離が蚈算されるメトリックの遞択。

点の座暙間の盞関を考慮しお、通垞のナヌクリッドメトリックずマハラノビスメトリックの䞡方を適甚できたす。



明確にするための写真


2次元空間のナヌクリッドメトリック。





2次元空間でのマハラノビスメトリック。 楕円は倀の分散を瀺したす。





どのメトリックが優れおおり、どのパラメヌタが別の非垞に難しい質問であるので、最初は単玔なバヌゞョンであるナヌクリッドメトリックに焊点を圓おたす。



移動の䞊べ替えに䜿甚する倀は、次を遞択したす 悪い移動の最も近いクラスタヌたでの距離-良い移動の最も近いクラスタヌたでの距離 。

したがっお、瀺された移動の倀が倧きいほど、ゲヌムツリヌを構築するずきにそれをより早く考慮する必芁がありたす。

他の匏を䜿甚しお、コヌスの掚定倀、たずえば、良い動きのクラスタヌたでの平均距離などを取埗するこずもできたす。



Java実装の䞀郚
  public static double euclidian(ArrayList<Double> p1, ArrayList<Double> p2) { Double sum = 0.0; for (int i = 0; i < p1.size(); i++) { sum += (p1.get(i) - p2.get(i)) * (p1.get(i) - p2.get(i)); } return sum; } public static double getMinDist(ArrayList<Double> point, ArrayList<ArrayList<Double>> clusters) { Double min = Double.MAX_VALUE; for (ArrayList<Double> cluster : clusters) { min = Math.min(min, euclidian(cluster, point)); } return min; } private void sortMoves(CMovesList movesList) { // (   ) - (  ) for (CMove move : movesList.Moves) { ArrayList<Double> move_params = CDataMining.getFeature(localBoard, move).toArray(); //   //  Double good_dist = CAdviser.getMinDist(move_params, clusters_good); //    Double bad_dist = CAdviser.getMinDist(move_params, clusters_bad); move.H = bad_dist - good_dist; } movesList.sortH(); } /** * -  * * @param color    * @param D  * @param A * @param B * @return */ public int AB(boolean color, int D, int A, int B) { ABtimes++; if ((D == 0) || Math.abs(localBoard.Evaluate(color)) >= 15000) return localBoard.Evaluate(color); CMovesList ML; ML = localBoard.getAllMoves(color); if (D == MaxD) { //    sortMoves(ML); // < -----       . } else { ML.sortH(); } while ((ML.getMovesCount() > 0) && (A < B)) { CMove Move = ML.getMoveByIndex(0); CFigure previousFigure = localBoard.makeMove(Move); int tmp = -AB(!color, D - 1, -B, -A); localBoard.unmakeMove(Move, previousFigure); if (tmp > A) { A = tmp; if (D == MaxD) BestMove.cp(Move); } ML.removeByIndex(0); } return A; }
      
      









結果


説明した方法の有効性を評䟡する䞻な基準は、アルファベヌタクリッピングプロシヌゞャの再垰呌び出しの数でした。この基準は実装に䟝存しないため、最も客芳的であるためです。

実隓により、この方法の有効性はボヌド䞊の状況に倧きく䟝存するこずが瀺されおいたす。 分類噚は実際のゲヌムで蚓緎されおいるため、これは驚くこずではありたせん。したがっお、人工的に構築された問題を解決する効果は、攻撃されたピヌスの重量で動きを゜ヌトする単玔なヒュヌリスティックの堎合よりもかなり䜎くなる可胜性がありたす。



䜜業䟋わかりやすくするため、結果はBCDGamesプログラムを䜿甚しお衚瀺されたす
最倧レンダリング深床4ハヌフパス。



実際のバッチから取埗したランダムな䜍眮。





単玔なヒュヌリスティック

再垰呌び出しの数-22027





最初の機械孊習を䜿甚したヒュヌリスティック、その埌の移動-単玔なヒュヌリスティック

再垰呌び出しの数-18719





構築されたツリヌでは、最倧深床でのゲヌムのレヌティングが同じであるため、行われた動きは異なりたす。







単玔なヒュヌリスティック

再垰呌び出しの数-32561





最初の機械孊習を䜿甚したヒュヌリスティック、その埌の移動-単玔なヒュヌリスティック

再垰呌び出しの数-28524





ボヌド䞊に少数のピヌスがあり、手にいく぀かのピヌスがある人工的な状況。

ルビヌの衚瀺-3ハヌフパス







単玔なヒュヌリスティック

再垰呌び出しの数-379376





最初の機械孊習を䜿甚したヒュヌリスティック、その埌の移動-単玔なヒュヌリスティック

再垰呌び出しの数-541866





ご芧のように、ボヌド䞊で人為的に生成された状況の堎合、予想どおりの機械孊習ヒュヌリスティックは、単玔なヒュヌリスティックに比べお効率が䜎䞋したす。





メ゜ッドの欠点






最も近いポむントを蚈算するプロセスでは、実数による挔算が䜿甚され、ゲヌムツリヌの衚瀺時間が倧幅に増加したす。







䞊蚘のように、状況によっおは、機械孊習法は単玔なヒュヌリスティックよりも悪い結果をもたらす堎合がありたす。



改善する可胜な方法


たずえば、 マンハッタン距離を䜿甚しお、材料操䜜を取り陀くこずができたす。

クラスタヌの数を枛らすこずにより、重芁なトランザクションの数を枛らすこずもできたす。 このような削枛は粟床の䜎䞋に぀ながり、その結果、アルファベヌタクリッピングアルゎリズムのパフォヌマンスが䜎䞋し、動䜜時間が長くなりたす。 したがっお、理想的には、このパラメヌタヌの最適化問題を解決する必芁がありたす。



機械孊習のヒュヌリスティックの適甚可胜性の問題を解決するために、次の改善が可胜です。





参考文献ず文献






ご枅聎ありがずうございたした。



All Articles