title: Why sklearn.linear_model.LogisticRegression with n_jobs = 2 performs so poorly?
body: <p>I am building a model for MNIST database with logistic rergession using scikit-learn package. I noticed that with default parameters it performs very poorly, and after finding <a href="https://towardsdatascience.com/logistic-regression-using-python-sklearn-numpy-mnist-handwriting-recognition-matplotlib-a6b31e2b166a" rel="nofollow noreferrer">this tutorial</a> I changed <code>sklearn.linear_model.LogisticRegression</code> solver to <code>'lbfgs'</code>. Fortunately it worked fine and the training of the model took just under 2 minutes using all 60000 elements from the training set.</p>
  
  <p>I am working on Google Compute Engine, so I wanted to use multiple cores and try to train the model even faster. I set up an instance with 2 cores and put <code>n_jobs = 2</code> in <code>LogisticRegression</code>. However, the algorithm performed worse than with <code>n_jobs = 1</code>. Here is the snippet:</p>
  
  <p>Import data and transform it to <code>np.ndarray</code> objects:</p>
  
  <pre><code>import numpy as np
  import matplotlib.pyplot as plt
  from mnist import MNIST
  mndata = MNIST('./data')
  
  images_train, labels_train = mndata.load_training()
  images_test, labels_test = mndata.load_testing()
  
  labels_train = labels_train.tolist()
  labels_test = labels_test.tolist()
  
  X_train = np.array(images_train)
  y_train = np.array(labels_train)
  X_test = np.array(images_test)
  y_test = np.array(labels_test)
  </code></pre>
  
  <p>Main function:</p>
  
  <pre><code>from sklearn.linear_model import LogisticRegression
  from sklearn.svm import LinearSVC
  import time
  
  def log_test(train_size, c, cores):
      X_train = X_train_all[:train_size]
      y_train = y_train_all[:train_size]
  
      start_time = time.time()
  
      logreg = LogisticRegression(C = c, solver = 'lbfgs', n_jobs = cores).fit(X_train, y_train)
      print("Training set score: {:.3f}".format(logreg.score(X_train, y_train)))
      print("Test set score: {:.3f}".format(logreg.score(X_test_all, y_test_all)))
  
      elapsed_time = time.time() - start_time
      print(elapsed_time)
  </code></pre>
  
  <p>Performance for <code>n_jobs = 1</code> vs <code>n_jobs = 2</code>:</p>
  
  <ul>
  <li><code>log_test(2000, 100, 1)</code>  - 2s</li>
  <li><code>log_test(2000, 100, 2)</code>  - 9s</li>
  <li><code>log_test(5000, 100, 1)</code>  - 8s</li>
  <li><code>log_test(5000, 100, 2)</code>  - 27s</li>
  <li><code>log_test(7000, 100, 1)</code>  - 13s</li>
  <li><code>log_test(7000, 100, 2)</code>  - 55s</li>
  <li><code>log_test(15000, 100, 1)</code> - 27s</li>
  <li><code>log_test(15000, 100, 2)</code> - 115s</li>
  </ul>
  
  <blockquote>
    <p><strong>Question.</strong> How to use multiple cores to boost up the performance of the algorithm?</p>
  </blockquote>