Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dealing with unbalanced datasets in Spark MLlib

I'm working on a particular binary classification problem with a highly unbalanced dataset, and I was wondering if anyone has tried to implement specific techniques for dealing with unbalanced datasets (such as SMOTE) in classification problems using Spark's MLlib.

I'm using MLLib's Random Forest implementation and already tried the simplest approach of randomly undersampling the larger class but it didn't work as well as I expected.

I would appreciate any feedback regarding your experience with similar issues.

Thanks,

like image 526
dbakr Avatar asked Oct 27 '15 16:10

dbakr


People also ask

What is the best technique for dealing with heavily imbalanced datasets?

A widely adopted and perhaps the most straightforward method for dealing with highly imbalanced datasets is called resampling. It consists of removing samples from the majority class (under-sampling) and/or adding more examples from the minority class (over-sampling).

How do you handle an imbalanced Textset?

The simplest way to fix imbalanced dataset is simply balancing them by oversampling instances of the minority class or undersampling instances of the majority class. Using advanced techniques like SMOTE(Synthetic Minority Over-sampling Technique) will help you create new synthetic instances from minority class.

Which algorithm is good for unbalanced data?

Results from the Logistic Regression Algorithm In supervised learning, a common strategy to overcome the class imbalance problem is to resample the original training dataset to decrease the overall level of class imbalance.


1 Answers

Class weight with Spark ML

As of this very moment, the class weighting for the Random Forest algorithm is still under development (see here)

But If you're willing to try other classifiers - this functionality has been already added to the Logistic Regression.

Consider a case where we have 80% positives (label == 1) in the dataset, so theoretically we want to "under-sample" the positive class. The logistic loss objective function should treat the negative class (label == 0) with higher weight.

Here is an example in Scala of generating this weight, we add a new column to the dataframe for each record in the dataset:

def balanceDataset(dataset: DataFrame): DataFrame = {      // Re-balancing (weighting) of records to be used in the logistic loss objective function     val numNegatives = dataset.filter(dataset("label") === 0).count     val datasetSize = dataset.count     val balancingRatio = (datasetSize - numNegatives).toDouble / datasetSize      val calculateWeights = udf { d: Double =>       if (d == 0.0) {         1 * balancingRatio       }       else {         (1 * (1.0 - balancingRatio))       }     }      val weightedDataset = dataset.withColumn("classWeightCol", calculateWeights(dataset("label")))     weightedDataset   } 

Then, we create a classier as follow:

new LogisticRegression().setWeightCol("classWeightCol").setLabelCol("label").setFeaturesCol("features") 

For more details, watch here: https://issues.apache.org/jira/browse/SPARK-9610

- Predictive Power

A different issue you should check - whether your features have a "predictive power" for the label you're trying to predict. In a case where after under-sampling you still have low precision, maybe that has nothing to do with the fact that your dataset is imbalanced by nature.


I would do a exploratory data analysis - If the classifier doesn't do better than a random choice, there is a risk that there simply is no connection between features and class.

  • Perform correlation analysis for every feature with the label.
  • Generating class specific histograms for features (i.e. plotting histograms of the data for each class, for a given feature on the same axis) can also be a good way to show if a feature discriminates well between the two classes.

Overfitting - a low error on your training set and a high error on your test set might be an indication that you overfit using an overly flexible feature set.


Bias variance - Check whether your classifier suffers from a high bias or high variance problem.

  • Training error vs. validation error - graph the validation error and training set error, as a function of training examples (do incremental learning)
    • If the lines seem to converge to the same value and are close at the end, then your classifier has high bias. In such case, adding more data won't help. Change the classifier for a one that has higher variance, or simply lower the regularization parameter of your current one.
    • If on the other hand the lines are quite far apart, and you have a low training set error but high validation error, then your classifier has too high variance. In this case getting more data is very likely to help. If after getting more data the variance will still be too high, you can increase the regularization parameter.
like image 182
Serendipity Avatar answered Oct 01 '22 04:10

Serendipity