title: How to prevent overfitting in Random Forest
body: <p>I have a random forest model I built to predict if NFL teams will score more combined points than the line Vegas has set. The features I use are <code>Total</code> - the total number of combined points Vegas thinks both teams will score, <code>over_percentage</code> - the percentage of public bets on the over, and <code>under_percentage</code> - the percentage of public bets on the under. The over means people are betting that both team's combined scores will be greater than the number Vegas sets and under means the combined score will go under the Vegas number. When I run my model I'm getting a confusion_matrix like this</p>
  <p><a href="https://i.stack.imgur.com/VfFRO.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/VfFRO.png" alt="enter image description here" /></a></p>
  <p>and an accuracy_score of 76%. However, the predictions do not perform well. Right now I have it giving me the probability the classification will be 0. I'm wondering if there are parameters I can tune or solutions to prevent my model from overfitting. I have over 30K games in the training data set so I don't think lack of data is causing the issue.</p>
  <p>Here is the code:</p>
  <pre><code>import pandas as pd
  from sklearn.ensemble import RandomForestClassifier
  from sklearn.model_selection import train_test_split, StratifiedKFold, GridSearchCV
  from sklearn.metrics import classification_report, confusion_matrix, accuracy_score
  
  training_data = pd.read_csv(
      '/Users/aus10/NFL/Data/Betting_Data/Training_Data_Betting.csv')
  test_data = pd.read_csv(
      '/Users/aus10/NFL/Data/Betting_Data/Test_Data_Betting.csv')
  
  df_model = training_data.dropna()
  
  X = df_model.loc[:, [&quot;Total&quot;, &quot;Over_Percentage&quot;,
                       &quot;Under_Percentage&quot;]]  # independent columns
  y = df_model[&quot;Over_Under&quot;]  # target column
  
  results = []
  
  model = RandomForestClassifier(
      random_state=1, n_estimators=500, min_samples_split=2, max_depth=30, min_samples_leaf=1)
  
  n_estimators = [100, 300, 500, 800, 1200]
  max_depth = [5, 8, 15, 25, 30]
  min_samples_split = [2, 5, 10, 15, 100]
  min_samples_leaf = [1, 2, 5, 10]
  
  hyperF = dict(n_estimators=n_estimators, max_depth=max_depth,
                min_samples_split=min_samples_split, min_samples_leaf=min_samples_leaf)
  
  gridF = GridSearchCV(model, hyperF, cv=3, verbose=1, n_jobs=-1)
  
  model.fit(X, y)
  
  skf = StratifiedKFold(n_splits=2)
  
  skf.get_n_splits(X, y)
  
  StratifiedKFold(n_splits=2, random_state=None, shuffle=False)
  
  for train_index, test_index in skf.split(X, y):
      print(&quot;TRAIN:&quot;, train_index, &quot;TEST:&quot;, test_index)
      X_train, X_test = X, X
      y_train, y_test = y, y
  
  bestF = gridF.fit(X_train, y_train)
  
  print(bestF.best_params_)
  
  y_train_pred = model.predict(X_train)
  y_test_pred = model.predict(X_test)
  
  model.fit(X_train, y_train)
  
  y_pred = model.predict(X_test)
  
  print(confusion_matrix(y_test, y_pred))
  print(classification_report(y_test, y_pred))
  print(round(accuracy_score(y_test, y_pred), 2))
  
  index = 0
  count = 0
  
  while count &lt; len(test_data):
      team = test_data.loc[index].at['Team']
      total = test_data.loc[index].at['Total']
      over_perc = test_data.loc[index].at['Over_Percentage']
      under_perc = test_data.loc[index].at['Under_Percentage']
  
      Xnew = [[total, over_perc, under_perc]]
      # make a prediction
      ynew = model.predict_proba(Xnew)
      # show the inputs and predicted outputs
      results.append(
          {
              'Team': team,
              'Over': ynew[0][0]
          })
      index += 1
      count += 1
  
  sorted_results = sorted(results, key=lambda k: k['Over'], reverse=True)
  
  df = pd.DataFrame(sorted_results, columns=[
      'Team', 'Over'])
  writer = pd.ExcelWriter('/Users/aus10/NFL/Data/ML_Results/Over_Probability.xlsx',  # pylint: disable=abstract-class-instantiated
                          engine='xlsxwriter')
  df.to_excel(writer, sheet_name='Sheet1', index=False)
  df.style.set_properties(**{'text-align': 'center'})
  pd.set_option('display.max_colwidth', 100)
  pd.set_option('display.width', 1000)
  writer.save()
  </code></pre>
  <p>And here are links the the google docs with the test and training data.</p>
  <p><a href="https://docs.google.com/spreadsheets/d/1IWZ6UPDd8ZZXsON_3kQCVynb2XDu4l1zza2lDL5vBbA/edit?usp=sharing" rel="nofollow noreferrer">Test Data</a></p>
  <p><a href="https://docs.google.com/spreadsheets/d/1Z36dIrin7Xtup6qbAKfQycWD4cChX4g7nneaAzL1UdQ/edit?usp=sharing" rel="nofollow noreferrer">Training Data</a></p>