title: Always get an accuracy and recall of 1.0 before and after oversampling
body: <p>I have the wine dataset, I removed nulls, normalized the dataset. and then created a new column called Quality, if the quality score is over 0.7 then its good, if its below then its a bad wine.  I just wanted to try binary classification.</p>
  <p>I tried Logistic Regression with the unbalanced data set and I get this:</p>
  <pre><code>[[418   0]
   [  0  60]]
                precision    recall  f1-score   support
  
             0       1.00      1.00      1.00       418
             1       1.00      1.00      1.00        60
  
      accuracy                           1.00       478
     macro avg       1.00      1.00      1.00       478
  weighted avg       1.00      1.00      1.00       478
  </code></pre>
  <p>SO I resampled with SMOTE and tried RandomForestClassifier and I get this:</p>
  <pre><code>Accuracy = 1.00
  Recall = 1.00
  </code></pre>
  <p>I really doubt this is possible</p>
  <p>What am I doing wrong?</p>
  <p>Full code below:</p>
  <pre><code>df.dropna(how='any', inplace=True)
  df.isnull().sum()
  
  #normalize
  scaler = preprocessing.MinMaxScaler()
  names = df.columns
  d = scaler.fit_transform(df)
  scaled_df = pd.DataFrame(d, columns=names)
  scaled_df.head()
  
  # Count unique values for the quality score.
  scaled_df['quality'].value_counts()
  
  
  Output menu
  0.4    679
  0.6    636
  0.8    197
  0.2     53
  1.0     18
  0.0     10
  Name: quality, dtype: int64
  
  
  #adding new column
  conditions = [
      (scaled_df['quality'] &lt;= 0.7),
      (scaled_df['quality'] &gt;0.7)
      ]
  
  values = [0, 1]
  
  scaled_df['QualityLabel'] = np.select(conditions, values)
  scaled_df
  
  # We can use value counts
  scaled_df['QualityLabel'].value_counts()
  
  # or we can separate the classes and then print the shape 
  class_0 = scaled_df[scaled_df['QualityLabel'] == 0]
  class_1 = scaled_df[scaled_df['QualityLabel'] == 1]# print the shape of the class
  print('class 0:', class_0.shape)
  print('class 1:', class_1.shape)
  
  class 0: (1378, 13)
  class 1: (215, 13)
  
  from sklearn.model_selection import train_test_split
  import numpy as np
  X_train, X_test, y_train, y_test = train_test_split(scaled_df, scaled_df[&quot;QualityLabel&quot;], test_size=0.3, random_state=0)
  np.bincount(y_train)
  
  # now we have 2 bins, 960 for training and 155 for testing.y_train.head(10)
  
  from sklearn.linear_model import LogisticRegression
  #Initalize the classifier
  clf = LogisticRegression(random_state=0)
  #Fitting the training data
  clf.fit(X_train, y_train)
  #Predicting on test
  y_pred=clf.predict(X_test)
  
  from sklearn.metrics import confusion_matrix
  from sklearn.metrics import classification_report
  print(confusion_matrix(y_test, y_pred))
  print(classification_report(y_test, y_pred))
  
  #lets resample with SMOTE
  
  from imblearn.over_sampling import SMOTE 
  
  sm = SMOTE(random_state=42)
  
  X_sm, y_sm = sm.fit_resample(scaled_df,  scaled_df[&quot;QualityLabel&quot;])
  
  print(f'''Shape of X before SMOTE: {scaled_df.shape}
  Shape of X after SMOTE: {X_sm.shape}''')
  
  print('\nBalance of positive and negative classes (%):')
  y_sm.value_counts(normalize=True) * 100
  
  Output menu
  Shape of X before SMOTE: (1593, 13)
  Shape of X after SMOTE: (2756, 13)
  
  Balance of positive and negative classes (%):
  0    50.0
  1    50.0
  Name: QualityLabel, dtype: float64
  
  from sklearn.ensemble import RandomForestClassifier
  from sklearn.metrics import accuracy_score, recall_score, confusion_matrix
  
  
  X_train, X_test, y_train, y_test = train_test_split(
      X_sm, y_sm, test_size=0.25, random_state=42
  )
  
  model = RandomForestClassifier(random_state=42)
  model.fit(X_train, y_train)
  preds = model.predict(X_test)
  
  print(f'Accuracy = {accuracy_score(y_test, preds):.2f}\nRecall = {recall_score(y_test, preds):.2f}\n')
  cm = confusion_matrix(y_test, preds)
  plt.figure(figsize=(8, 6))
  plt.title('Confusion Matrix (with SMOTE)', size=16)
  sns.heatmap(cm, annot=True, cmap='Blues');
  </code></pre>