Answers.Body: <p>I am not sure about risk preferences, but here is an example that you can play around.</p>
  <p>The features are the engine's best score, the human move score, etc. And the result could be your target.</p>
  <p>There are only two positions as your dataset in this example. But you can extend this.</p>
  <p>I use python chess library to create this system and use stockfish engine to analyze the positions.</p>
  <pre><code>import chess
  import chess.engine
  import pandas as pd
  
  
  pd.set_option('display.max_colwidth', 1000)
  
  
  # Positions and human move in the actual game.
  FENS = [
      ['8/3b2pk/4qp1p/p2r4/1r1B1Q2/4P1P1/PP1R3P/K1R5 w - - 4 34', 'c1c7', '0-1'],
      ['r2q1rk1/ppp1nppp/1b6/3np3/6b1/1BPP1N1P/PP1N1PP1/R1BQ1RK1 b - - 0 12', 'g4h5', '1-0']
  ]
  
  
  # Engine's path
  STOCKFISH_PATH = r'F:\Chess\Engines\stockfish\sf16/sf16pop.exe'
  
  
  def analyze_fen(fen, timesec=1.0, rootmoves=None):
      &quot;&quot;&quot;Analyze the given fen position.&quot;&quot;&quot;
      engine_hash_size = 128  # in MB
      engine_threads = 1      # number of threads
      board = chess.Board(fen)
  
      engine = chess.engine.SimpleEngine.popen_uci(STOCKFISH_PATH)
      engine.configure({&quot;Hash&quot;: engine_hash_size, &quot;Threads&quot;: engine_threads})
      info = engine.analyse(board, chess.engine.Limit(time=timesec), root_moves=rootmoves)
      engine.quit()
  
      best_move = info['pv'][0]
      score = info['score'].white().score(mate_score=32000)
  
      return best_move, score
      
  
  def main():
      data = []
      analysis_timesec = 2.0
  
      for fen, human_move, result in FENS:
          # Get the best engine move and its score.
          engine_best_move, engine_best_score = analyze_fen(fen, timesec=analysis_timesec)
  
          # Get the score of the move by human.
          human_chess_move = chess.Move.from_uci(human_move)
          _, human_move_score = analyze_fen(fen, timesec=analysis_timesec, rootmoves=[human_chess_move])
  
          # Calculate the error.
          if engine_best_move == human_chess_move:
              error = 0
          else:
              error = abs(engine_best_score - human_move_score)
          data.append([fen, str(engine_best_move), engine_best_score, str(human_chess_move), human_move_score, result, error])
  
      df = pd.DataFrame(data, columns=['FEN', 'EMove', 'EScore', 'HMove', 'HScore', 'Result', 'Error'])
      print(df)
  
  
  if __name__ == '__main__':
      main()
  </code></pre>
  <h2>Output</h2>
  <p>The scores are in WPOV (White Point of View), meaning if score is positive, the position assessment is better for white. If score is negative, it is better for black.</p>
  <p>At index 0, the engine's best score is -24. It favors slightly for black. But the human move or the actual move played in the game is c1c7 and it is a blunder. The position assessment of that move is -504 CP or centipawn which put black in a winning position. The error is 480 which is just the absolute score difference.</p>
  <pre><code>                                                                   FEN EMove  EScore HMove  HScore Result  Error
  0              8/3b2pk/4qp1p/p2r4/1r1B1Q2/4P1P1/PP1R3P/K1R5 w - - 4 34  f4c7     -24  c1c7    -504    0-1    480
  1  r2q1rk1/ppp1nppp/1b6/3np3/6b1/1BPP1N1P/PP1N1PP1/R1BQ1RK1 b - - 0 12  g4f3      44  g4h5     128    1-0     84
  </code></pre>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2024-01-17T07:47:11.897Z
Answers.LastActivityDate: 2024-01-17T08:03:36.777Z
Answers.LastEditDate: 2024-01-17T08:03:36.777Z
Answers.UserDisplayName: ferdy
Body: <p>How do I extract data such as board configuration, engine evaluation, time spent per move etc from an engine into a statistical software package like stata? I am currently trying to investigate the effects of risk preferences on deviations from optimal play and know how to run statistical regression analysis but have no experience with chess datasets.</p>
  
Tags: <engines><software><stockfish><statistics>
Title: Transferring data from chess engine to statistical software
ThreadText: # Transferring data from chess engine to statistical software
  
  (Asked by: username_0 on 2024-01-13)
  
  How do I extract data such as board configuration, engine evaluation, time spent per move etc from an engine into a statistical software package like stata? I am currently trying to investigate the effects of risk preferences on deviations from optimal play and know how to run statistical regression analysis but have no experience with chess datasets.
  
  **Tags:** engines, software, stockfish, statistics
  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_1 on 2024-01-17. Score: 1
  
  I am not sure about risk preferences, but here is an example that you can play around.
  The features are the engine's best score, the human move score, etc. And the result could be your target.
  There are only two positions as your dataset in this example. But you can extend this.
  I use python chess library to create this system and use stockfish engine to analyze the positions.
  import chess
  import chess.engine
  import pandas as pd
  
  
  pd.set_option('display.max_colwidth', 1000)
  
  
  # Positions and human move in the actual game.
  FENS = [
      ['8/3b2pk/4qp1p/p2r4/1r1B1Q2/4P1P1/PP1R3P/K1R5 w - - 4 34', 'c1c7', '0-1'],
      ['r2q1rk1/ppp1nppp/1b6/3np3/6b1/1BPP1N1P/PP1N1PP1/R1BQ1RK1 b - - 0 12', 'g4h5', '1-0']
  ]
  
  
  # Engine's path
  STOCKFISH_PATH = r'F:\Chess\Engines\stockfish\sf16/sf16pop.exe'
  
  
  def analyze_fen(fen, timesec=1.0, rootmoves=None):
      """Analyze the given fen position."""
      engine_hash_size = 128  # in MB
      engine_threads = 1      # number of threads
      board = chess.Board(fen)
  
      engine = chess.engine.SimpleEngine.popen_uci(STOCKFISH_PATH)
      engine.configure({"Hash": engine_hash_size, "Threads": engine_threads})
      info = engine.analyse(board, chess.engine.Limit(time=timesec), root_moves=rootmoves)
      engine.quit()
  
      best_move = info['pv'][0]
      score = info['score'].white().score(mate_score=32000)
  
      return best_move, score
      
  
  def main():
      data = []
      analysis_timesec = 2.0
  
      for fen, human_move, result in FENS:
          # Get the best engine move and its score.
          engine_best_move, engine_best_score = analyze_fen(fen, timesec=analysis_timesec)
  
          # Get the score of the move by human.
          human_chess_move = chess.Move.from_uci(human_move)
          _, human_move_score = analyze_fen(fen, timesec=analysis_timesec, rootmoves=[human_chess_move])
  
          # Calculate the error.
          if engine_best_move == human_chess_move:
              error = 0
          else:
              error = abs(engine_best_score - human_move_score)
          data.append([fen, str(engine_best_move), engine_best_score, str(human_chess_move), human_move_score, result, error])
  
      df = pd.DataFrame(data, columns=['FEN', 'EMove', 'EScore', 'HMove', 'HScore', 'Result', 'Error'])
      print(df)
  
  
  if __name__ == '__main__':
      main()
  
  Output
  The scores are in WPOV (White Point of View), meaning if score is positive, the position assessment is better for white. If score is negative, it is better for black.
  At index 0, the engine's best score is -24. It favors slightly for black. But the human move or the actual move played in the game is c1c7 and it is a blunder. The position assessment of that move is -504 CP or centipawn which put black in a winning position. The error is 480 which is just the absolute score difference.
                                                                     FEN EMove  EScore HMove  HScore Result  Error
  0              8/3b2pk/4qp1p/p2r4/1r1B1Q2/4P1P1/PP1R3P/K1R5 w - - 4 34  f4c7     -24  c1c7    -504    0-1    480
  1  r2q1rk1/ppp1nppp/1b6/3np3/6b1/1BPP1N1P/PP1N1PP1/R1BQ1RK1 b - - 0 12  g4f3      44  g4h5     128    1-0     84
  
  
  ---
  
  