LightGBM Unbalanced Data Argument [Issue #3688 Fix] - #3925

Merged
rayankrish merged 12 commits into
dotnet:masterfrom
rayankrish:LightGBM-unbalanced-data
Jul 1, 2019
Merged

LightGBM Unbalanced Data Argument [Issue #3688 Fix]#3925
rayankrish merged 12 commits into
dotnet:masterfrom
rayankrish:LightGBM-unbalanced-data

Conversation

@rayankrish

Copy link
Copy Markdown

Fix for issue #3688. LightGBM Multiclass Trainer can now accept unbalanced data parameter as was previously possible in the Binary Trainer. An additional argument was added to the LightGBMBinaryEstimator test.

@dnfclas

dnfclas commented Jun 27, 2019

Copy link
Copy Markdown

CLA assistant check
All CLA requirements met.

/// Whether training data is unbalanced. Used by <see cref="LightGbmBinaryTrainer"/>.
/// </summary>
[Argument(ArgumentType.AtMostOnce, HelpText = "Use for binary classification when training data is not balanced.", ShortName = "us")]
public bool UnbalancedSets = false;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need two tests for UnbalancedSets=true and UnbalancedSets=false. In addition to simply run a model, we need more restrictive comparison like

[LightGBMFact]publicvoidLightGbmMulticlassEstimatorCompareOva(){floatsigmoidScale=0.5f;// Constant used train LightGBM. See gbmParams["sigmoid"] in the helper function.// Train ML.NET LightGBM and native LightGBM and apply the trained models to the training set.LightGbmHelper(useSoftmax:false,sigmoid:sigmoidScale,outstringmodelString,outList<GbmExample>mlnetPredictions,outdouble[]nativeResult1,outdouble[]nativeResult0);// The i-th predictor returned by LightGBM produces the raw score, denoted by z_i, of the i-th class.// Assume that we have n classes in total. The i-th class probability can be computed via// p_i = sigmoid(sigmoidScale * z_i) / (sigmoid(sigmoidScale * z_1) + ... + sigmoid(sigmoidScale * z_n)).Assert.True(modelString!=null);// Compare native LightGBM's and ML.NET's LightGBM results example by examplefor(inti=0;i<_rowNumber;++i){doublesum=0;for(intj=0;j<_classNumber;++j){Assert.Equal(nativeResult0[j+i*_classNumber],mlnetPredictions[i].Score[j],6);if(float.IsNaN((float)nativeResult1[j+i*_classNumber]))continue;sum+=MathUtils.SigmoidSlow(sigmoidScale*(float)nativeResult1[j+i*_classNumber]);}for(intj=0;j<_classNumber;++j){doubleprob=MathUtils.SigmoidSlow(sigmoidScale*(float)nativeResult1[j+i*_classNumber]);Assert.Equal(prob/sum,mlnetPredictions[i].Score[j],6);}}Done();}

in machinelearning2\test\Microsoft.ML.Tests\TrainerEstimators\TreeEstimators.cs. Note that this test directly checks if ML.NET's LightGBM module and LightGBM's C API produce identical numbers.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you. I will add and run these tests

@rayankrish

rayankrish commented Jun 27, 2019

Copy link
Copy Markdown
Author

Needed to add the unbalanced argument to LightGbmMulticlassTrainer. Ran a test to revise manifest file

Tests Added:

  • Unbalanced binary trainer test
  • Two tests for unbalanced = true and unbalanced = false for multiclass
  • Compare multiclass .NET LightGBM output with multiclass LightGBM C output test

@codemzs
codemzs requested a review from eerhardtJune 28, 2019 17:11
/// <summary>
/// Whether training data is unbalanced.
/// </summary>
[Argument(ArgumentType.AtMostOnce, HelpText = "Use for binary classification when training data is not balanced.", ShortName = "us")]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use for binary classification when training data is not balanced.

It's odd to say "use for binary classification" when this is the multiclass trainer.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it more helpful to just say "Use for multi-class classification when training data is not balanced."

/// <summary>
/// Whether training data is unbalanced. Used by <see cref="LightGbmBinaryTrainer"/>.
/// </summary>
[Argument(ArgumentType.AtMostOnce, HelpText = "Use for binary classification when training data is not balanced.", ShortName = "us")]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use for binary classification when training data is not balanced.

Is putting this option on the OptionsBase class correct if it is only for binary classification?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right. The cause of the problem was this commit which split the trainers in to their classes (binary and multiclass). is it better not to include it as an argument in this file?

/// Whether training data is unbalanced. Used by <see cref="LightGbmBinaryTrainer"/>.
/// </summary>
[Argument(ArgumentType.AtMostOnce, HelpText = "Use for binary classification when training data is not balanced.", ShortName = "us")]
public bool UnbalancedSets = false;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where is this boolean being used? I don't see any code added using it.

@rayankrishrayankrishJun 28, 2019

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's added to the dictionary, NameMapping on line 39:
{nameof(OptionsBase.UnbalancedSets), "is_unbalance"},

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are declaring 2 new boolean fields. I only see 1 being used.

{
var res = base.ToDictionary(host);

res[GetOptionName(nameof(UnbalancedSets))] = UnbalancedSets;

@codemzscodemzsJul 1, 2019

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

res[GetOptionName(nameof(UnbalancedSets))] = UnbalancedSets; [](start = 16, length = 60)

how is getting mapped to is_unbalance 🔗︎, default = false, type = bool, aliases: unbalance, unbalanced_sets #Resolved

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nevermind I see it now:

public static string GetOptionName(string name)
{
// Otherwise convert the name to the light gbm argument
StringBuilder strBuf = new StringBuilder();
bool first = true;
foreach (char c in name)
{
if (char.IsUpper(c))
{
if (first)
first = false;
else
strBuf.Append('_');
strBuf.Append(char.ToLower(c));
}
else
strBuf.Append(c);
}
return strBuf.ToString();
}


In reply to: 299023864 [](ancestors = 299023864)

@codemzscodemzs left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

Sigmoid = sigmoid // Custom sigmoid value.
Sigmoid = sigmoid, // Custom sigmoid value.
UnbalancedSets = unbalancedSets // false by default

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Empty line.

@rayankrish
rayankrish merged commit c5a18ef into dotnet:masterJul 1, 2019
@rayankrish
rayankrish deleted the LightGBM-unbalanced-data branch July 1, 2019 20:04
codemzs added a commit to codemzs/machinelearning that referenced this pull request Jul 3, 2019
…tnet#3925)"
This reverts commit c5a18ef.
# Conflicts:
#	test/Microsoft.ML.Tests/TrainerEstimators/TreeEstimators.cs
Dmitry-A pushed a commit to Dmitry-A/machinelearning that referenced this pull request Jul 24, 2019
* LightGBM unbalanced data arg added
* unbalanced data argument added
* tests for unbalanced LightGbm and added arg for multiclass
* reverted changes on LightGbmArguments
* wording improvement on unbalanced arg help text
* updated manifest
* removed empty line
* added keytype to test
@ghostghost locked as resolved and limited conversation to collaborators Mar 21, 2022
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@rayankrish@dnfclas@codemzs@wschin@eerhardt
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

LightGBM Unbalanced Data Argument [Issue #3688 Fix] - #3925

Merged
rayankrish merged 12 commits into
dotnet:masterfrom
rayankrish:LightGBM-unbalanced-data
Jul 1, 2019
Merged

LightGBM Unbalanced Data Argument [Issue #3688 Fix]#3925
rayankrish merged 12 commits into
dotnet:masterfrom
rayankrish:LightGBM-unbalanced-data

Conversation

@rayankrish

Copy link
Copy Markdown

Fix for issue #3688. LightGBM Multiclass Trainer can now accept unbalanced data parameter as was previously possible in the Binary Trainer. An additional argument was added to the LightGBMBinaryEstimator test.

@dnfclas

dnfclas commented Jun 27, 2019

Copy link
Copy Markdown

CLA assistant check
All CLA requirements met.

/// Whether training data is unbalanced. Used by <see cref="LightGbmBinaryTrainer"/>.
/// </summary>
[Argument(ArgumentType.AtMostOnce, HelpText = "Use for binary classification when training data is not balanced.", ShortName = "us")]
public bool UnbalancedSets = false;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need two tests for UnbalancedSets=true and UnbalancedSets=false. In addition to simply run a model, we need more restrictive comparison like

[LightGBMFact]publicvoidLightGbmMulticlassEstimatorCompareOva(){floatsigmoidScale=0.5f;// Constant used train LightGBM. See gbmParams["sigmoid"] in the helper function.// Train ML.NET LightGBM and native LightGBM and apply the trained models to the training set.LightGbmHelper(useSoftmax:false,sigmoid:sigmoidScale,outstringmodelString,outList<GbmExample>mlnetPredictions,outdouble[]nativeResult1,outdouble[]nativeResult0);// The i-th predictor returned by LightGBM produces the raw score, denoted by z_i, of the i-th class.// Assume that we have n classes in total. The i-th class probability can be computed via// p_i = sigmoid(sigmoidScale * z_i) / (sigmoid(sigmoidScale * z_1) + ... + sigmoid(sigmoidScale * z_n)).Assert.True(modelString!=null);// Compare native LightGBM's and ML.NET's LightGBM results example by examplefor(inti=0;i<_rowNumber;++i){doublesum=0;for(intj=0;j<_classNumber;++j){Assert.Equal(nativeResult0[j+i*_classNumber],mlnetPredictions[i].Score[j],6);if(float.IsNaN((float)nativeResult1[j+i*_classNumber]))continue;sum+=MathUtils.SigmoidSlow(sigmoidScale*(float)nativeResult1[j+i*_classNumber]);}for(intj=0;j<_classNumber;++j){doubleprob=MathUtils.SigmoidSlow(sigmoidScale*(float)nativeResult1[j+i*_classNumber]);Assert.Equal(prob/sum,mlnetPredictions[i].Score[j],6);}}Done();}

in machinelearning2\test\Microsoft.ML.Tests\TrainerEstimators\TreeEstimators.cs. Note that this test directly checks if ML.NET's LightGBM module and LightGBM's C API produce identical numbers.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you. I will add and run these tests

@rayankrish

rayankrish commented Jun 27, 2019

Copy link
Copy Markdown
Author

Needed to add the unbalanced argument to LightGbmMulticlassTrainer. Ran a test to revise manifest file

Tests Added:

  • Unbalanced binary trainer test
  • Two tests for unbalanced = true and unbalanced = false for multiclass
  • Compare multiclass .NET LightGBM output with multiclass LightGBM C output test

@codemzs
codemzs requested a review from eerhardtJune 28, 2019 17:11
/// <summary>
/// Whether training data is unbalanced.
/// </summary>
[Argument(ArgumentType.AtMostOnce, HelpText = "Use for binary classification when training data is not balanced.", ShortName = "us")]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use for binary classification when training data is not balanced.

It's odd to say "use for binary classification" when this is the multiclass trainer.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it more helpful to just say "Use for multi-class classification when training data is not balanced."

/// <summary>
/// Whether training data is unbalanced. Used by <see cref="LightGbmBinaryTrainer"/>.
/// </summary>
[Argument(ArgumentType.AtMostOnce, HelpText = "Use for binary classification when training data is not balanced.", ShortName = "us")]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use for binary classification when training data is not balanced.

Is putting this option on the OptionsBase class correct if it is only for binary classification?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right. The cause of the problem was this commit which split the trainers in to their classes (binary and multiclass). is it better not to include it as an argument in this file?

/// Whether training data is unbalanced. Used by <see cref="LightGbmBinaryTrainer"/>.
/// </summary>
[Argument(ArgumentType.AtMostOnce, HelpText = "Use for binary classification when training data is not balanced.", ShortName = "us")]
public bool UnbalancedSets = false;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where is this boolean being used? I don't see any code added using it.

@rayankrishrayankrishJun 28, 2019

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's added to the dictionary, NameMapping on line 39:
{nameof(OptionsBase.UnbalancedSets), "is_unbalance"},

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are declaring 2 new boolean fields. I only see 1 being used.

{
var res = base.ToDictionary(host);

res[GetOptionName(nameof(UnbalancedSets))] = UnbalancedSets;

@codemzscodemzsJul 1, 2019

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

res[GetOptionName(nameof(UnbalancedSets))] = UnbalancedSets; [](start = 16, length = 60)

how is getting mapped to is_unbalance 🔗︎, default = false, type = bool, aliases: unbalance, unbalanced_sets #Resolved

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nevermind I see it now:

public static string GetOptionName(string name)
{
// Otherwise convert the name to the light gbm argument
StringBuilder strBuf = new StringBuilder();
bool first = true;
foreach (char c in name)
{
if (char.IsUpper(c))
{
if (first)
first = false;
else
strBuf.Append('_');
strBuf.Append(char.ToLower(c));
}
else
strBuf.Append(c);
}
return strBuf.ToString();
}


In reply to: 299023864 [](ancestors = 299023864)

@codemzscodemzs left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

Sigmoid = sigmoid // Custom sigmoid value.
Sigmoid = sigmoid, // Custom sigmoid value.
UnbalancedSets = unbalancedSets // false by default

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Empty line.

@rayankrish
rayankrish merged commit c5a18ef into dotnet:masterJul 1, 2019
@rayankrish
rayankrish deleted the LightGBM-unbalanced-data branch July 1, 2019 20:04
codemzs added a commit to codemzs/machinelearning that referenced this pull request Jul 3, 2019
…tnet#3925)"
This reverts commit c5a18ef.
# Conflicts:
#	test/Microsoft.ML.Tests/TrainerEstimators/TreeEstimators.cs
Dmitry-A pushed a commit to Dmitry-A/machinelearning that referenced this pull request Jul 24, 2019
* LightGBM unbalanced data arg added
* unbalanced data argument added
* tests for unbalanced LightGbm and added arg for multiclass
* reverted changes on LightGbmArguments
* wording improvement on unbalanced arg help text
* updated manifest
* removed empty line
* added keytype to test
@ghostghost locked as resolved and limited conversation to collaborators Mar 21, 2022
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@rayankrish@dnfclas@codemzs@wschin@eerhardt
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

LightGBM Unbalanced Data Argument [Issue #3688 Fix] - #3925

Merged
rayankrish merged 12 commits into
dotnet:masterfrom
rayankrish:LightGBM-unbalanced-data
Jul 1, 2019
Merged

LightGBM Unbalanced Data Argument [Issue #3688 Fix]#3925
rayankrish merged 12 commits into
dotnet:masterfrom
rayankrish:LightGBM-unbalanced-data

Conversation

@rayankrish

Copy link
Copy Markdown

Fix for issue #3688. LightGBM Multiclass Trainer can now accept unbalanced data parameter as was previously possible in the Binary Trainer. An additional argument was added to the LightGBMBinaryEstimator test.

@dnfclas

dnfclas commented Jun 27, 2019

Copy link
Copy Markdown

CLA assistant check
All CLA requirements met.

/// Whether training data is unbalanced. Used by <see cref="LightGbmBinaryTrainer"/>.
/// </summary>
[Argument(ArgumentType.AtMostOnce, HelpText = "Use for binary classification when training data is not balanced.", ShortName = "us")]
public bool UnbalancedSets = false;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need two tests for UnbalancedSets=true and UnbalancedSets=false. In addition to simply run a model, we need more restrictive comparison like

[LightGBMFact]publicvoidLightGbmMulticlassEstimatorCompareOva(){floatsigmoidScale=0.5f;// Constant used train LightGBM. See gbmParams["sigmoid"] in the helper function.// Train ML.NET LightGBM and native LightGBM and apply the trained models to the training set.LightGbmHelper(useSoftmax:false,sigmoid:sigmoidScale,outstringmodelString,outList<GbmExample>mlnetPredictions,outdouble[]nativeResult1,outdouble[]nativeResult0);// The i-th predictor returned by LightGBM produces the raw score, denoted by z_i, of the i-th class.// Assume that we have n classes in total. The i-th class probability can be computed via// p_i = sigmoid(sigmoidScale * z_i) / (sigmoid(sigmoidScale * z_1) + ... + sigmoid(sigmoidScale * z_n)).Assert.True(modelString!=null);// Compare native LightGBM's and ML.NET's LightGBM results example by examplefor(inti=0;i<_rowNumber;++i){doublesum=0;for(intj=0;j<_classNumber;++j){Assert.Equal(nativeResult0[j+i*_classNumber],mlnetPredictions[i].Score[j],6);if(float.IsNaN((float)nativeResult1[j+i*_classNumber]))continue;sum+=MathUtils.SigmoidSlow(sigmoidScale*(float)nativeResult1[j+i*_classNumber]);}for(intj=0;j<_classNumber;++j){doubleprob=MathUtils.SigmoidSlow(sigmoidScale*(float)nativeResult1[j+i*_classNumber]);Assert.Equal(prob/sum,mlnetPredictions[i].Score[j],6);}}Done();}

in machinelearning2\test\Microsoft.ML.Tests\TrainerEstimators\TreeEstimators.cs. Note that this test directly checks if ML.NET's LightGBM module and LightGBM's C API produce identical numbers.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you. I will add and run these tests

@rayankrish

rayankrish commented Jun 27, 2019

Copy link
Copy Markdown
Author

Needed to add the unbalanced argument to LightGbmMulticlassTrainer. Ran a test to revise manifest file

Tests Added:

  • Unbalanced binary trainer test
  • Two tests for unbalanced = true and unbalanced = false for multiclass
  • Compare multiclass .NET LightGBM output with multiclass LightGBM C output test

@codemzs
codemzs requested a review from eerhardtJune 28, 2019 17:11
/// <summary>
/// Whether training data is unbalanced.
/// </summary>
[Argument(ArgumentType.AtMostOnce, HelpText = "Use for binary classification when training data is not balanced.", ShortName = "us")]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use for binary classification when training data is not balanced.

It's odd to say "use for binary classification" when this is the multiclass trainer.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it more helpful to just say "Use for multi-class classification when training data is not balanced."

/// <summary>
/// Whether training data is unbalanced. Used by <see cref="LightGbmBinaryTrainer"/>.
/// </summary>
[Argument(ArgumentType.AtMostOnce, HelpText = "Use for binary classification when training data is not balanced.", ShortName = "us")]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use for binary classification when training data is not balanced.

Is putting this option on the OptionsBase class correct if it is only for binary classification?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right. The cause of the problem was this commit which split the trainers in to their classes (binary and multiclass). is it better not to include it as an argument in this file?

/// Whether training data is unbalanced. Used by <see cref="LightGbmBinaryTrainer"/>.
/// </summary>
[Argument(ArgumentType.AtMostOnce, HelpText = "Use for binary classification when training data is not balanced.", ShortName = "us")]
public bool UnbalancedSets = false;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where is this boolean being used? I don't see any code added using it.

@rayankrishrayankrishJun 28, 2019

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's added to the dictionary, NameMapping on line 39:
{nameof(OptionsBase.UnbalancedSets), "is_unbalance"},

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are declaring 2 new boolean fields. I only see 1 being used.

{
var res = base.ToDictionary(host);

res[GetOptionName(nameof(UnbalancedSets))] = UnbalancedSets;

@codemzscodemzsJul 1, 2019

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

res[GetOptionName(nameof(UnbalancedSets))] = UnbalancedSets; [](start = 16, length = 60)

how is getting mapped to is_unbalance 🔗︎, default = false, type = bool, aliases: unbalance, unbalanced_sets #Resolved

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nevermind I see it now:

public static string GetOptionName(string name)
{
// Otherwise convert the name to the light gbm argument
StringBuilder strBuf = new StringBuilder();
bool first = true;
foreach (char c in name)
{
if (char.IsUpper(c))
{
if (first)
first = false;
else
strBuf.Append('_');
strBuf.Append(char.ToLower(c));
}
else
strBuf.Append(c);
}
return strBuf.ToString();
}


In reply to: 299023864 [](ancestors = 299023864)

@codemzscodemzs left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

Sigmoid = sigmoid // Custom sigmoid value.
Sigmoid = sigmoid, // Custom sigmoid value.
UnbalancedSets = unbalancedSets // false by default

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Empty line.

@rayankrish
rayankrish merged commit c5a18ef into dotnet:masterJul 1, 2019
@rayankrish
rayankrish deleted the LightGBM-unbalanced-data branch July 1, 2019 20:04
codemzs added a commit to codemzs/machinelearning that referenced this pull request Jul 3, 2019
…tnet#3925)"
This reverts commit c5a18ef.
# Conflicts:
#	test/Microsoft.ML.Tests/TrainerEstimators/TreeEstimators.cs
Dmitry-A pushed a commit to Dmitry-A/machinelearning that referenced this pull request Jul 24, 2019
* LightGBM unbalanced data arg added
* unbalanced data argument added
* tests for unbalanced LightGbm and added arg for multiclass
* reverted changes on LightGbmArguments
* wording improvement on unbalanced arg help text
* updated manifest
* removed empty line
* added keytype to test
@ghostghost locked as resolved and limited conversation to collaborators Mar 21, 2022
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@rayankrish@dnfclas@codemzs@wschin@eerhardt
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

LightGBM Unbalanced Data Argument [Issue #3688 Fix] - #3925

Merged
rayankrish merged 12 commits into
dotnet:masterfrom
rayankrish:LightGBM-unbalanced-data
Jul 1, 2019
Merged

LightGBM Unbalanced Data Argument [Issue #3688 Fix]#3925
rayankrish merged 12 commits into
dotnet:masterfrom
rayankrish:LightGBM-unbalanced-data

Conversation

@rayankrish

Copy link
Copy Markdown

Fix for issue #3688. LightGBM Multiclass Trainer can now accept unbalanced data parameter as was previously possible in the Binary Trainer. An additional argument was added to the LightGBMBinaryEstimator test.

@dnfclas

dnfclas commented Jun 27, 2019

Copy link
Copy Markdown

CLA assistant check
All CLA requirements met.

/// Whether training data is unbalanced. Used by <see cref="LightGbmBinaryTrainer"/>.
/// </summary>
[Argument(ArgumentType.AtMostOnce, HelpText = "Use for binary classification when training data is not balanced.", ShortName = "us")]
public bool UnbalancedSets = false;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need two tests for UnbalancedSets=true and UnbalancedSets=false. In addition to simply run a model, we need more restrictive comparison like

[LightGBMFact]publicvoidLightGbmMulticlassEstimatorCompareOva(){floatsigmoidScale=0.5f;// Constant used train LightGBM. See gbmParams["sigmoid"] in the helper function.// Train ML.NET LightGBM and native LightGBM and apply the trained models to the training set.LightGbmHelper(useSoftmax:false,sigmoid:sigmoidScale,outstringmodelString,outList<GbmExample>mlnetPredictions,outdouble[]nativeResult1,outdouble[]nativeResult0);// The i-th predictor returned by LightGBM produces the raw score, denoted by z_i, of the i-th class.// Assume that we have n classes in total. The i-th class probability can be computed via// p_i = sigmoid(sigmoidScale * z_i) / (sigmoid(sigmoidScale * z_1) + ... + sigmoid(sigmoidScale * z_n)).Assert.True(modelString!=null);// Compare native LightGBM's and ML.NET's LightGBM results example by examplefor(inti=0;i<_rowNumber;++i){doublesum=0;for(intj=0;j<_classNumber;++j){Assert.Equal(nativeResult0[j+i*_classNumber],mlnetPredictions[i].Score[j],6);if(float.IsNaN((float)nativeResult1[j+i*_classNumber]))continue;sum+=MathUtils.SigmoidSlow(sigmoidScale*(float)nativeResult1[j+i*_classNumber]);}for(intj=0;j<_classNumber;++j){doubleprob=MathUtils.SigmoidSlow(sigmoidScale*(float)nativeResult1[j+i*_classNumber]);Assert.Equal(prob/sum,mlnetPredictions[i].Score[j],6);}}Done();}

in machinelearning2\test\Microsoft.ML.Tests\TrainerEstimators\TreeEstimators.cs. Note that this test directly checks if ML.NET's LightGBM module and LightGBM's C API produce identical numbers.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you. I will add and run these tests

@rayankrish

rayankrish commented Jun 27, 2019

Copy link
Copy Markdown
Author

Needed to add the unbalanced argument to LightGbmMulticlassTrainer. Ran a test to revise manifest file

Tests Added:

  • Unbalanced binary trainer test
  • Two tests for unbalanced = true and unbalanced = false for multiclass
  • Compare multiclass .NET LightGBM output with multiclass LightGBM C output test

@codemzs
codemzs requested a review from eerhardtJune 28, 2019 17:11
/// <summary>
/// Whether training data is unbalanced.
/// </summary>
[Argument(ArgumentType.AtMostOnce, HelpText = "Use for binary classification when training data is not balanced.", ShortName = "us")]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use for binary classification when training data is not balanced.

It's odd to say "use for binary classification" when this is the multiclass trainer.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it more helpful to just say "Use for multi-class classification when training data is not balanced."

/// <summary>
/// Whether training data is unbalanced. Used by <see cref="LightGbmBinaryTrainer"/>.
/// </summary>
[Argument(ArgumentType.AtMostOnce, HelpText = "Use for binary classification when training data is not balanced.", ShortName = "us")]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use for binary classification when training data is not balanced.

Is putting this option on the OptionsBase class correct if it is only for binary classification?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right. The cause of the problem was this commit which split the trainers in to their classes (binary and multiclass). is it better not to include it as an argument in this file?

/// Whether training data is unbalanced. Used by <see cref="LightGbmBinaryTrainer"/>.
/// </summary>
[Argument(ArgumentType.AtMostOnce, HelpText = "Use for binary classification when training data is not balanced.", ShortName = "us")]
public bool UnbalancedSets = false;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where is this boolean being used? I don't see any code added using it.

@rayankrishrayankrishJun 28, 2019

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's added to the dictionary, NameMapping on line 39:
{nameof(OptionsBase.UnbalancedSets), "is_unbalance"},

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are declaring 2 new boolean fields. I only see 1 being used.

{
var res = base.ToDictionary(host);

res[GetOptionName(nameof(UnbalancedSets))] = UnbalancedSets;

@codemzscodemzsJul 1, 2019

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

res[GetOptionName(nameof(UnbalancedSets))] = UnbalancedSets; [](start = 16, length = 60)

how is getting mapped to is_unbalance 🔗︎, default = false, type = bool, aliases: unbalance, unbalanced_sets #Resolved

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nevermind I see it now:

public static string GetOptionName(string name)
{
// Otherwise convert the name to the light gbm argument
StringBuilder strBuf = new StringBuilder();
bool first = true;
foreach (char c in name)
{
if (char.IsUpper(c))
{
if (first)
first = false;
else
strBuf.Append('_');
strBuf.Append(char.ToLower(c));
}
else
strBuf.Append(c);
}
return strBuf.ToString();
}


In reply to: 299023864 [](ancestors = 299023864)

@codemzscodemzs left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

Sigmoid = sigmoid // Custom sigmoid value.
Sigmoid = sigmoid, // Custom sigmoid value.
UnbalancedSets = unbalancedSets // false by default

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Empty line.

@rayankrish
rayankrish merged commit c5a18ef into dotnet:masterJul 1, 2019
@rayankrish
rayankrish deleted the LightGBM-unbalanced-data branch July 1, 2019 20:04
codemzs added a commit to codemzs/machinelearning that referenced this pull request Jul 3, 2019
…tnet#3925)"
This reverts commit c5a18ef.
# Conflicts:
#	test/Microsoft.ML.Tests/TrainerEstimators/TreeEstimators.cs
Dmitry-A pushed a commit to Dmitry-A/machinelearning that referenced this pull request Jul 24, 2019
* LightGBM unbalanced data arg added
* unbalanced data argument added
* tests for unbalanced LightGbm and added arg for multiclass
* reverted changes on LightGbmArguments
* wording improvement on unbalanced arg help text
* updated manifest
* removed empty line
* added keytype to test
@ghostghost locked as resolved and limited conversation to collaborators Mar 21, 2022
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@rayankrish@dnfclas@codemzs@wschin@eerhardt
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

LightGBM Unbalanced Data Argument [Issue #3688 Fix] - #3925

Merged
rayankrish merged 12 commits into
dotnet:masterfrom
rayankrish:LightGBM-unbalanced-data
Jul 1, 2019
Merged

LightGBM Unbalanced Data Argument [Issue #3688 Fix]#3925
rayankrish merged 12 commits into
dotnet:masterfrom
rayankrish:LightGBM-unbalanced-data

Conversation

@rayankrish

Copy link
Copy Markdown

Fix for issue #3688. LightGBM Multiclass Trainer can now accept unbalanced data parameter as was previously possible in the Binary Trainer. An additional argument was added to the LightGBMBinaryEstimator test.

@dnfclas

dnfclas commented Jun 27, 2019

Copy link
Copy Markdown

CLA assistant check
All CLA requirements met.

/// Whether training data is unbalanced. Used by <see cref="LightGbmBinaryTrainer"/>.
/// </summary>
[Argument(ArgumentType.AtMostOnce, HelpText = "Use for binary classification when training data is not balanced.", ShortName = "us")]
public bool UnbalancedSets = false;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need two tests for UnbalancedSets=true and UnbalancedSets=false. In addition to simply run a model, we need more restrictive comparison like

[LightGBMFact]publicvoidLightGbmMulticlassEstimatorCompareOva(){floatsigmoidScale=0.5f;// Constant used train LightGBM. See gbmParams["sigmoid"] in the helper function.// Train ML.NET LightGBM and native LightGBM and apply the trained models to the training set.LightGbmHelper(useSoftmax:false,sigmoid:sigmoidScale,outstringmodelString,outList<GbmExample>mlnetPredictions,outdouble[]nativeResult1,outdouble[]nativeResult0);// The i-th predictor returned by LightGBM produces the raw score, denoted by z_i, of the i-th class.// Assume that we have n classes in total. The i-th class probability can be computed via// p_i = sigmoid(sigmoidScale * z_i) / (sigmoid(sigmoidScale * z_1) + ... + sigmoid(sigmoidScale * z_n)).Assert.True(modelString!=null);// Compare native LightGBM's and ML.NET's LightGBM results example by examplefor(inti=0;i<_rowNumber;++i){doublesum=0;for(intj=0;j<_classNumber;++j){Assert.Equal(nativeResult0[j+i*_classNumber],mlnetPredictions[i].Score[j],6);if(float.IsNaN((float)nativeResult1[j+i*_classNumber]))continue;sum+=MathUtils.SigmoidSlow(sigmoidScale*(float)nativeResult1[j+i*_classNumber]);}for(intj=0;j<_classNumber;++j){doubleprob=MathUtils.SigmoidSlow(sigmoidScale*(float)nativeResult1[j+i*_classNumber]);Assert.Equal(prob/sum,mlnetPredictions[i].Score[j],6);}}Done();}

in machinelearning2\test\Microsoft.ML.Tests\TrainerEstimators\TreeEstimators.cs. Note that this test directly checks if ML.NET's LightGBM module and LightGBM's C API produce identical numbers.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you. I will add and run these tests

@rayankrish

rayankrish commented Jun 27, 2019

Copy link
Copy Markdown
Author

Needed to add the unbalanced argument to LightGbmMulticlassTrainer. Ran a test to revise manifest file

Tests Added:

  • Unbalanced binary trainer test
  • Two tests for unbalanced = true and unbalanced = false for multiclass
  • Compare multiclass .NET LightGBM output with multiclass LightGBM C output test

@codemzs
codemzs requested a review from eerhardtJune 28, 2019 17:11
/// <summary>
/// Whether training data is unbalanced.
/// </summary>
[Argument(ArgumentType.AtMostOnce, HelpText = "Use for binary classification when training data is not balanced.", ShortName = "us")]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use for binary classification when training data is not balanced.

It's odd to say "use for binary classification" when this is the multiclass trainer.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it more helpful to just say "Use for multi-class classification when training data is not balanced."

/// <summary>
/// Whether training data is unbalanced. Used by <see cref="LightGbmBinaryTrainer"/>.
/// </summary>
[Argument(ArgumentType.AtMostOnce, HelpText = "Use for binary classification when training data is not balanced.", ShortName = "us")]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use for binary classification when training data is not balanced.

Is putting this option on the OptionsBase class correct if it is only for binary classification?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right. The cause of the problem was this commit which split the trainers in to their classes (binary and multiclass). is it better not to include it as an argument in this file?

/// Whether training data is unbalanced. Used by <see cref="LightGbmBinaryTrainer"/>.
/// </summary>
[Argument(ArgumentType.AtMostOnce, HelpText = "Use for binary classification when training data is not balanced.", ShortName = "us")]
public bool UnbalancedSets = false;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where is this boolean being used? I don't see any code added using it.

@rayankrishrayankrishJun 28, 2019

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's added to the dictionary, NameMapping on line 39:
{nameof(OptionsBase.UnbalancedSets), "is_unbalance"},

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are declaring 2 new boolean fields. I only see 1 being used.

{
var res = base.ToDictionary(host);

res[GetOptionName(nameof(UnbalancedSets))] = UnbalancedSets;

@codemzscodemzsJul 1, 2019

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

res[GetOptionName(nameof(UnbalancedSets))] = UnbalancedSets; [](start = 16, length = 60)

how is getting mapped to is_unbalance 🔗︎, default = false, type = bool, aliases: unbalance, unbalanced_sets #Resolved

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nevermind I see it now:

public static string GetOptionName(string name)
{
// Otherwise convert the name to the light gbm argument
StringBuilder strBuf = new StringBuilder();
bool first = true;
foreach (char c in name)
{
if (char.IsUpper(c))
{
if (first)
first = false;
else
strBuf.Append('_');
strBuf.Append(char.ToLower(c));
}
else
strBuf.Append(c);
}
return strBuf.ToString();
}


In reply to: 299023864 [](ancestors = 299023864)

@codemzscodemzs left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

Sigmoid = sigmoid // Custom sigmoid value.
Sigmoid = sigmoid, // Custom sigmoid value.
UnbalancedSets = unbalancedSets // false by default

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Empty line.

@rayankrish
rayankrish merged commit c5a18ef into dotnet:masterJul 1, 2019
@rayankrish
rayankrish deleted the LightGBM-unbalanced-data branch July 1, 2019 20:04
codemzs added a commit to codemzs/machinelearning that referenced this pull request Jul 3, 2019
…tnet#3925)"
This reverts commit c5a18ef.
# Conflicts:
#	test/Microsoft.ML.Tests/TrainerEstimators/TreeEstimators.cs
Dmitry-A pushed a commit to Dmitry-A/machinelearning that referenced this pull request Jul 24, 2019
* LightGBM unbalanced data arg added
* unbalanced data argument added
* tests for unbalanced LightGbm and added arg for multiclass
* reverted changes on LightGbmArguments
* wording improvement on unbalanced arg help text
* updated manifest
* removed empty line
* added keytype to test
@ghostghost locked as resolved and limited conversation to collaborators Mar 21, 2022
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@rayankrish@dnfclas@codemzs@wschin@eerhardt
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

LightGBM Unbalanced Data Argument [Issue #3688 Fix] - #3925

Merged
rayankrish merged 12 commits into
dotnet:masterfrom
rayankrish:LightGBM-unbalanced-data
Jul 1, 2019
Merged

LightGBM Unbalanced Data Argument [Issue #3688 Fix]#3925
rayankrish merged 12 commits into
dotnet:masterfrom
rayankrish:LightGBM-unbalanced-data

Conversation

@rayankrish

Copy link
Copy Markdown

Fix for issue #3688. LightGBM Multiclass Trainer can now accept unbalanced data parameter as was previously possible in the Binary Trainer. An additional argument was added to the LightGBMBinaryEstimator test.

@dnfclas

dnfclas commented Jun 27, 2019

Copy link
Copy Markdown

CLA assistant check
All CLA requirements met.

/// Whether training data is unbalanced. Used by <see cref="LightGbmBinaryTrainer"/>.
/// </summary>
[Argument(ArgumentType.AtMostOnce, HelpText = "Use for binary classification when training data is not balanced.", ShortName = "us")]
public bool UnbalancedSets = false;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need two tests for UnbalancedSets=true and UnbalancedSets=false. In addition to simply run a model, we need more restrictive comparison like

[LightGBMFact]publicvoidLightGbmMulticlassEstimatorCompareOva(){floatsigmoidScale=0.5f;// Constant used train LightGBM. See gbmParams["sigmoid"] in the helper function.// Train ML.NET LightGBM and native LightGBM and apply the trained models to the training set.LightGbmHelper(useSoftmax:false,sigmoid:sigmoidScale,outstringmodelString,outList<GbmExample>mlnetPredictions,outdouble[]nativeResult1,outdouble[]nativeResult0);// The i-th predictor returned by LightGBM produces the raw score, denoted by z_i, of the i-th class.// Assume that we have n classes in total. The i-th class probability can be computed via// p_i = sigmoid(sigmoidScale * z_i) / (sigmoid(sigmoidScale * z_1) + ... + sigmoid(sigmoidScale * z_n)).Assert.True(modelString!=null);// Compare native LightGBM's and ML.NET's LightGBM results example by examplefor(inti=0;i<_rowNumber;++i){doublesum=0;for(intj=0;j<_classNumber;++j){Assert.Equal(nativeResult0[j+i*_classNumber],mlnetPredictions[i].Score[j],6);if(float.IsNaN((float)nativeResult1[j+i*_classNumber]))continue;sum+=MathUtils.SigmoidSlow(sigmoidScale*(float)nativeResult1[j+i*_classNumber]);}for(intj=0;j<_classNumber;++j){doubleprob=MathUtils.SigmoidSlow(sigmoidScale*(float)nativeResult1[j+i*_classNumber]);Assert.Equal(prob/sum,mlnetPredictions[i].Score[j],6);}}Done();}

in machinelearning2\test\Microsoft.ML.Tests\TrainerEstimators\TreeEstimators.cs. Note that this test directly checks if ML.NET's LightGBM module and LightGBM's C API produce identical numbers.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you. I will add and run these tests

@rayankrish

rayankrish commented Jun 27, 2019

Copy link
Copy Markdown
Author

Needed to add the unbalanced argument to LightGbmMulticlassTrainer. Ran a test to revise manifest file

Tests Added:

  • Unbalanced binary trainer test
  • Two tests for unbalanced = true and unbalanced = false for multiclass
  • Compare multiclass .NET LightGBM output with multiclass LightGBM C output test

@codemzs
codemzs requested a review from eerhardtJune 28, 2019 17:11
/// <summary>
/// Whether training data is unbalanced.
/// </summary>
[Argument(ArgumentType.AtMostOnce, HelpText = "Use for binary classification when training data is not balanced.", ShortName = "us")]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use for binary classification when training data is not balanced.

It's odd to say "use for binary classification" when this is the multiclass trainer.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it more helpful to just say "Use for multi-class classification when training data is not balanced."

/// <summary>
/// Whether training data is unbalanced. Used by <see cref="LightGbmBinaryTrainer"/>.
/// </summary>
[Argument(ArgumentType.AtMostOnce, HelpText = "Use for binary classification when training data is not balanced.", ShortName = "us")]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use for binary classification when training data is not balanced.

Is putting this option on the OptionsBase class correct if it is only for binary classification?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right. The cause of the problem was this commit which split the trainers in to their classes (binary and multiclass). is it better not to include it as an argument in this file?

/// Whether training data is unbalanced. Used by <see cref="LightGbmBinaryTrainer"/>.
/// </summary>
[Argument(ArgumentType.AtMostOnce, HelpText = "Use for binary classification when training data is not balanced.", ShortName = "us")]
public bool UnbalancedSets = false;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where is this boolean being used? I don't see any code added using it.

@rayankrishrayankrishJun 28, 2019

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's added to the dictionary, NameMapping on line 39:
{nameof(OptionsBase.UnbalancedSets), "is_unbalance"},

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are declaring 2 new boolean fields. I only see 1 being used.

{
var res = base.ToDictionary(host);

res[GetOptionName(nameof(UnbalancedSets))] = UnbalancedSets;

@codemzscodemzsJul 1, 2019

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

res[GetOptionName(nameof(UnbalancedSets))] = UnbalancedSets; [](start = 16, length = 60)

how is getting mapped to is_unbalance 🔗︎, default = false, type = bool, aliases: unbalance, unbalanced_sets #Resolved

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nevermind I see it now:

public static string GetOptionName(string name)
{
// Otherwise convert the name to the light gbm argument
StringBuilder strBuf = new StringBuilder();
bool first = true;
foreach (char c in name)
{
if (char.IsUpper(c))
{
if (first)
first = false;
else
strBuf.Append('_');
strBuf.Append(char.ToLower(c));
}
else
strBuf.Append(c);
}
return strBuf.ToString();
}


In reply to: 299023864 [](ancestors = 299023864)

@codemzscodemzs left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

Sigmoid = sigmoid // Custom sigmoid value.
Sigmoid = sigmoid, // Custom sigmoid value.
UnbalancedSets = unbalancedSets // false by default

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Empty line.

@rayankrish
rayankrish merged commit c5a18ef into dotnet:masterJul 1, 2019
@rayankrish
rayankrish deleted the LightGBM-unbalanced-data branch July 1, 2019 20:04
codemzs added a commit to codemzs/machinelearning that referenced this pull request Jul 3, 2019
…tnet#3925)"
This reverts commit c5a18ef.
# Conflicts:
#	test/Microsoft.ML.Tests/TrainerEstimators/TreeEstimators.cs
Dmitry-A pushed a commit to Dmitry-A/machinelearning that referenced this pull request Jul 24, 2019
* LightGBM unbalanced data arg added
* unbalanced data argument added
* tests for unbalanced LightGbm and added arg for multiclass
* reverted changes on LightGbmArguments
* wording improvement on unbalanced arg help text
* updated manifest
* removed empty line
* added keytype to test
@ghostghost locked as resolved and limited conversation to collaborators Mar 21, 2022
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@rayankrish@dnfclas@codemzs@wschin@eerhardt
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

LightGBM Unbalanced Data Argument [Issue #3688 Fix] - #3925

Merged
rayankrish merged 12 commits into
dotnet:masterfrom
rayankrish:LightGBM-unbalanced-data
Jul 1, 2019
Merged

LightGBM Unbalanced Data Argument [Issue #3688 Fix]#3925
rayankrish merged 12 commits into
dotnet:masterfrom
rayankrish:LightGBM-unbalanced-data

Conversation

@rayankrish

Copy link
Copy Markdown

Fix for issue #3688. LightGBM Multiclass Trainer can now accept unbalanced data parameter as was previously possible in the Binary Trainer. An additional argument was added to the LightGBMBinaryEstimator test.

@dnfclas

dnfclas commented Jun 27, 2019

Copy link
Copy Markdown

CLA assistant check
All CLA requirements met.

/// Whether training data is unbalanced. Used by <see cref="LightGbmBinaryTrainer"/>.
/// </summary>
[Argument(ArgumentType.AtMostOnce, HelpText = "Use for binary classification when training data is not balanced.", ShortName = "us")]
public bool UnbalancedSets = false;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need two tests for UnbalancedSets=true and UnbalancedSets=false. In addition to simply run a model, we need more restrictive comparison like

[LightGBMFact]publicvoidLightGbmMulticlassEstimatorCompareOva(){floatsigmoidScale=0.5f;// Constant used train LightGBM. See gbmParams["sigmoid"] in the helper function.// Train ML.NET LightGBM and native LightGBM and apply the trained models to the training set.LightGbmHelper(useSoftmax:false,sigmoid:sigmoidScale,outstringmodelString,outList<GbmExample>mlnetPredictions,outdouble[]nativeResult1,outdouble[]nativeResult0);// The i-th predictor returned by LightGBM produces the raw score, denoted by z_i, of the i-th class.// Assume that we have n classes in total. The i-th class probability can be computed via// p_i = sigmoid(sigmoidScale * z_i) / (sigmoid(sigmoidScale * z_1) + ... + sigmoid(sigmoidScale * z_n)).Assert.True(modelString!=null);// Compare native LightGBM's and ML.NET's LightGBM results example by examplefor(inti=0;i<_rowNumber;++i){doublesum=0;for(intj=0;j<_classNumber;++j){Assert.Equal(nativeResult0[j+i*_classNumber],mlnetPredictions[i].Score[j],6);if(float.IsNaN((float)nativeResult1[j+i*_classNumber]))continue;sum+=MathUtils.SigmoidSlow(sigmoidScale*(float)nativeResult1[j+i*_classNumber]);}for(intj=0;j<_classNumber;++j){doubleprob=MathUtils.SigmoidSlow(sigmoidScale*(float)nativeResult1[j+i*_classNumber]);Assert.Equal(prob/sum,mlnetPredictions[i].Score[j],6);}}Done();}

in machinelearning2\test\Microsoft.ML.Tests\TrainerEstimators\TreeEstimators.cs. Note that this test directly checks if ML.NET's LightGBM module and LightGBM's C API produce identical numbers.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you. I will add and run these tests

@rayankrish

rayankrish commented Jun 27, 2019

Copy link
Copy Markdown
Author

Needed to add the unbalanced argument to LightGbmMulticlassTrainer. Ran a test to revise manifest file

Tests Added:

  • Unbalanced binary trainer test
  • Two tests for unbalanced = true and unbalanced = false for multiclass
  • Compare multiclass .NET LightGBM output with multiclass LightGBM C output test

@codemzs
codemzs requested a review from eerhardtJune 28, 2019 17:11
/// <summary>
/// Whether training data is unbalanced.
/// </summary>
[Argument(ArgumentType.AtMostOnce, HelpText = "Use for binary classification when training data is not balanced.", ShortName = "us")]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use for binary classification when training data is not balanced.

It's odd to say "use for binary classification" when this is the multiclass trainer.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it more helpful to just say "Use for multi-class classification when training data is not balanced."

/// <summary>
/// Whether training data is unbalanced. Used by <see cref="LightGbmBinaryTrainer"/>.
/// </summary>
[Argument(ArgumentType.AtMostOnce, HelpText = "Use for binary classification when training data is not balanced.", ShortName = "us")]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use for binary classification when training data is not balanced.

Is putting this option on the OptionsBase class correct if it is only for binary classification?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right. The cause of the problem was this commit which split the trainers in to their classes (binary and multiclass). is it better not to include it as an argument in this file?

/// Whether training data is unbalanced. Used by <see cref="LightGbmBinaryTrainer"/>.
/// </summary>
[Argument(ArgumentType.AtMostOnce, HelpText = "Use for binary classification when training data is not balanced.", ShortName = "us")]
public bool UnbalancedSets = false;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where is this boolean being used? I don't see any code added using it.

@rayankrishrayankrishJun 28, 2019

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's added to the dictionary, NameMapping on line 39:
{nameof(OptionsBase.UnbalancedSets), "is_unbalance"},

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are declaring 2 new boolean fields. I only see 1 being used.

{
var res = base.ToDictionary(host);

res[GetOptionName(nameof(UnbalancedSets))] = UnbalancedSets;

@codemzscodemzsJul 1, 2019

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

res[GetOptionName(nameof(UnbalancedSets))] = UnbalancedSets; [](start = 16, length = 60)

how is getting mapped to is_unbalance 🔗︎, default = false, type = bool, aliases: unbalance, unbalanced_sets #Resolved

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nevermind I see it now:

public static string GetOptionName(string name)
{
// Otherwise convert the name to the light gbm argument
StringBuilder strBuf = new StringBuilder();
bool first = true;
foreach (char c in name)
{
if (char.IsUpper(c))
{
if (first)
first = false;
else
strBuf.Append('_');
strBuf.Append(char.ToLower(c));
}
else
strBuf.Append(c);
}
return strBuf.ToString();
}


In reply to: 299023864 [](ancestors = 299023864)

@codemzscodemzs left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

Sigmoid = sigmoid // Custom sigmoid value.
Sigmoid = sigmoid, // Custom sigmoid value.
UnbalancedSets = unbalancedSets // false by default

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Empty line.

@rayankrish
rayankrish merged commit c5a18ef into dotnet:masterJul 1, 2019
@rayankrish
rayankrish deleted the LightGBM-unbalanced-data branch July 1, 2019 20:04
codemzs added a commit to codemzs/machinelearning that referenced this pull request Jul 3, 2019
…tnet#3925)"
This reverts commit c5a18ef.
# Conflicts:
#	test/Microsoft.ML.Tests/TrainerEstimators/TreeEstimators.cs
Dmitry-A pushed a commit to Dmitry-A/machinelearning that referenced this pull request Jul 24, 2019
* LightGBM unbalanced data arg added
* unbalanced data argument added
* tests for unbalanced LightGbm and added arg for multiclass
* reverted changes on LightGbmArguments
* wording improvement on unbalanced arg help text
* updated manifest
* removed empty line
* added keytype to test
@ghostghost locked as resolved and limited conversation to collaborators Mar 21, 2022
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@rayankrish@dnfclas@codemzs@wschin@eerhardt
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

LightGBM Unbalanced Data Argument [Issue #3688 Fix] - #3925

Merged
rayankrish merged 12 commits into
dotnet:masterfrom
rayankrish:LightGBM-unbalanced-data
Jul 1, 2019
Merged

LightGBM Unbalanced Data Argument [Issue #3688 Fix]#3925
rayankrish merged 12 commits into
dotnet:masterfrom
rayankrish:LightGBM-unbalanced-data

Conversation

@rayankrish

Copy link
Copy Markdown

Fix for issue #3688. LightGBM Multiclass Trainer can now accept unbalanced data parameter as was previously possible in the Binary Trainer. An additional argument was added to the LightGBMBinaryEstimator test.

@dnfclas

dnfclas commented Jun 27, 2019

Copy link
Copy Markdown

CLA assistant check
All CLA requirements met.

/// Whether training data is unbalanced. Used by <see cref="LightGbmBinaryTrainer"/>.
/// </summary>
[Argument(ArgumentType.AtMostOnce, HelpText = "Use for binary classification when training data is not balanced.", ShortName = "us")]
public bool UnbalancedSets = false;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need two tests for UnbalancedSets=true and UnbalancedSets=false. In addition to simply run a model, we need more restrictive comparison like

[LightGBMFact]publicvoidLightGbmMulticlassEstimatorCompareOva(){floatsigmoidScale=0.5f;// Constant used train LightGBM. See gbmParams["sigmoid"] in the helper function.// Train ML.NET LightGBM and native LightGBM and apply the trained models to the training set.LightGbmHelper(useSoftmax:false,sigmoid:sigmoidScale,outstringmodelString,outList<GbmExample>mlnetPredictions,outdouble[]nativeResult1,outdouble[]nativeResult0);// The i-th predictor returned by LightGBM produces the raw score, denoted by z_i, of the i-th class.// Assume that we have n classes in total. The i-th class probability can be computed via// p_i = sigmoid(sigmoidScale * z_i) / (sigmoid(sigmoidScale * z_1) + ... + sigmoid(sigmoidScale * z_n)).Assert.True(modelString!=null);// Compare native LightGBM's and ML.NET's LightGBM results example by examplefor(inti=0;i<_rowNumber;++i){doublesum=0;for(intj=0;j<_classNumber;++j){Assert.Equal(nativeResult0[j+i*_classNumber],mlnetPredictions[i].Score[j],6);if(float.IsNaN((float)nativeResult1[j+i*_classNumber]))continue;sum+=MathUtils.SigmoidSlow(sigmoidScale*(float)nativeResult1[j+i*_classNumber]);}for(intj=0;j<_classNumber;++j){doubleprob=MathUtils.SigmoidSlow(sigmoidScale*(float)nativeResult1[j+i*_classNumber]);Assert.Equal(prob/sum,mlnetPredictions[i].Score[j],6);}}Done();}

in machinelearning2\test\Microsoft.ML.Tests\TrainerEstimators\TreeEstimators.cs. Note that this test directly checks if ML.NET's LightGBM module and LightGBM's C API produce identical numbers.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you. I will add and run these tests

@rayankrish

rayankrish commented Jun 27, 2019

Copy link
Copy Markdown
Author

Needed to add the unbalanced argument to LightGbmMulticlassTrainer. Ran a test to revise manifest file

Tests Added:

  • Unbalanced binary trainer test
  • Two tests for unbalanced = true and unbalanced = false for multiclass
  • Compare multiclass .NET LightGBM output with multiclass LightGBM C output test

@codemzs
codemzs requested a review from eerhardtJune 28, 2019 17:11
/// <summary>
/// Whether training data is unbalanced.
/// </summary>
[Argument(ArgumentType.AtMostOnce, HelpText = "Use for binary classification when training data is not balanced.", ShortName = "us")]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use for binary classification when training data is not balanced.

It's odd to say "use for binary classification" when this is the multiclass trainer.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it more helpful to just say "Use for multi-class classification when training data is not balanced."

/// <summary>
/// Whether training data is unbalanced. Used by <see cref="LightGbmBinaryTrainer"/>.
/// </summary>
[Argument(ArgumentType.AtMostOnce, HelpText = "Use for binary classification when training data is not balanced.", ShortName = "us")]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use for binary classification when training data is not balanced.

Is putting this option on the OptionsBase class correct if it is only for binary classification?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right. The cause of the problem was this commit which split the trainers in to their classes (binary and multiclass). is it better not to include it as an argument in this file?

/// Whether training data is unbalanced. Used by <see cref="LightGbmBinaryTrainer"/>.
/// </summary>
[Argument(ArgumentType.AtMostOnce, HelpText = "Use for binary classification when training data is not balanced.", ShortName = "us")]
public bool UnbalancedSets = false;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where is this boolean being used? I don't see any code added using it.

@rayankrishrayankrishJun 28, 2019

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's added to the dictionary, NameMapping on line 39:
{nameof(OptionsBase.UnbalancedSets), "is_unbalance"},

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are declaring 2 new boolean fields. I only see 1 being used.

{
var res = base.ToDictionary(host);

res[GetOptionName(nameof(UnbalancedSets))] = UnbalancedSets;

@codemzscodemzsJul 1, 2019

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

res[GetOptionName(nameof(UnbalancedSets))] = UnbalancedSets; [](start = 16, length = 60)

how is getting mapped to is_unbalance 🔗︎, default = false, type = bool, aliases: unbalance, unbalanced_sets #Resolved

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nevermind I see it now:

public static string GetOptionName(string name)
{
// Otherwise convert the name to the light gbm argument
StringBuilder strBuf = new StringBuilder();
bool first = true;
foreach (char c in name)
{
if (char.IsUpper(c))
{
if (first)
first = false;
else
strBuf.Append('_');
strBuf.Append(char.ToLower(c));
}
else
strBuf.Append(c);
}
return strBuf.ToString();
}


In reply to: 299023864 [](ancestors = 299023864)

@codemzscodemzs left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

Sigmoid = sigmoid // Custom sigmoid value.
Sigmoid = sigmoid, // Custom sigmoid value.
UnbalancedSets = unbalancedSets // false by default

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Empty line.

@rayankrish
rayankrish merged commit c5a18ef into dotnet:masterJul 1, 2019
@rayankrish
rayankrish deleted the LightGBM-unbalanced-data branch July 1, 2019 20:04
codemzs added a commit to codemzs/machinelearning that referenced this pull request Jul 3, 2019
…tnet#3925)"
This reverts commit c5a18ef.
# Conflicts:
#	test/Microsoft.ML.Tests/TrainerEstimators/TreeEstimators.cs
Dmitry-A pushed a commit to Dmitry-A/machinelearning that referenced this pull request Jul 24, 2019
* LightGBM unbalanced data arg added
* unbalanced data argument added
* tests for unbalanced LightGbm and added arg for multiclass
* reverted changes on LightGbmArguments
* wording improvement on unbalanced arg help text
* updated manifest
* removed empty line
* added keytype to test
@ghostghost locked as resolved and limited conversation to collaborators Mar 21, 2022
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@rayankrish@dnfclas@codemzs@wschin@eerhardt