Samples for FeatureSelection transform estimators - #3184

Merged
abgoswam merged 6 commits into
dotnet:masterfrom
abgoswam:abgoswam/featureselection_samples
Apr 5, 2019
Merged

Samples for FeatureSelection transform estimators#3184
abgoswam merged 6 commits into
dotnet:masterfrom
abgoswam:abgoswam/featureselection_samples

Conversation

@abgoswam

Copy link
Copy Markdown
Member

Towards #1209

The PR makes the following changes

  • Adds sample for the SelectFeaturesBasedOnCount transform estimator.
  • Adds sample for the SelectFeaturesBasedOnMutualInformation transform estimator.
  • Delete old sample.

@codecov

codecovBot commented Apr 3, 2019

Copy link
Copy Markdown

Codecov Report

Merging #3184 into master will increase coverage by 0.06%.
The diff coverage is n/a.

@@ Coverage Diff @@## master #3184 +/- ##
==========================================
+ Coverage 72.54% 72.6% +0.06% 
==========================================
Files 807 807 Lines 144774 145077 +303 Branches 16208 16213 +5 ==========================================
+ Hits 105021 105332 +311 + Misses 35339 35326 -13 - Partials 4414 4419 +5
FlagCoverage Δ
#Debug72.6% <ø> (+0.06%)⬆️
#production68.14% <ø> (+0.01%)⬆️
#test88.92% <ø> (+0.09%)⬆️
Impacted FilesCoverage Δ
...Microsoft.ML.Transforms/FeatureSelectionCatalog.cs60% <ø> (ø)⬆️
...c/Microsoft.ML.FastTree/Utils/ThreadTaskManager.cs79.48% <0%> (-20.52%)⬇️
src/Microsoft.ML.DataView/KeyDataViewType.cs74.57% <0%> (-3.76%)⬇️
src/Microsoft.ML.Maml/MAML.cs24.75% <0%> (-1.46%)⬇️
src/Microsoft.ML.Transforms/Text/LdaTransform.cs89.26% <0%> (-0.63%)⬇️
src/Microsoft.ML.Data/Transforms/ValueMapping.cs84.26% <0%> (-0.14%)⬇️
test/Microsoft.ML.Tests/ImagesTests.cs98.69% <0%> (-0.13%)⬇️
src/Microsoft.ML.Transforms/CategoricalCatalog.cs68.42% <0%> (ø)⬆️
...Microsoft.ML.Tests/Transformers/NormalizerTests.cs100% <0%> (ø)⬆️
...crosoft.ML.Tests/Transformers/ValueMappingTests.cs100% <0%> (ø)⬆️
... and 7 more

/// <format type="text/markdown">
/// <![CDATA[
/// [!code-csharp[SelectFeaturesBasedOnMutualInformation](~/../docs/samples/docs/samples/Microsoft.ML.Samples/Dynamic/FeatureSelectionTransform.cs?range=1-4,10-121)]
/// [!code-csharp[SelectFeaturesBasedOnMutualInformation](~/../docs/samples/docs/samples/Microsoft.ML.Samples/Dynamic/SelectFeaturesBasedOnMutualInformation.cs)]

@sfilipisfilipiApr 3, 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.

Dynamic/S [](start = 118, length = 9)

Dynamic/Transforms/ #Resolved

/// <example>
/// <format type="text/markdown">
/// <![CDATA[
/// [!code-csharp[SelectFeaturesBasedOnMutualInformation](~/../docs/samples/docs/samples/Microsoft.ML.Samples/Dynamic/SelectFeaturesBasedOnMutualInformation.cs)]

@sfilipisfilipiApr 3, 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.

Dynamic [](start = 118, length = 7)

Dynamic/Transforms/ #Resolved

{
// Downloading a classification dataset from github.com/dotnet/machinelearning.
// It will be stored in the same path as the executable
string dataFilePath = SamplesUtils.DatasetUtils.DownloadBreastCancerDataset();

@sfilipisfilipiApr 3, 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.

string dataFilePath = SamplesUtils.DatasetUtils.DownloadBreastCancerDataset(); [](start = 9, length = 81)

can it be done with a small in memory dataset? #Resolved

pipeline = mlContext.Transforms.FeatureSelection.SelectFeaturesBasedOnMutualInformation(
new InputOutputColumnPair[] { new InputOutputColumnPair("GroupB"), new InputOutputColumnPair("GroupC") },
labelColumnName: "Label",
slotsInOutput:4);

@sfilipisfilipiApr 3, 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.

slotsInOutput:4 [](start = 16, length = 15)

one line comment about what this does. #Resolved

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

comment in line 28 should clarify this


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

// 3 7 1
// 3 1 1

// Second, we define the transformations that we apply on the data. Remember that an Estimator does not transform data

@sfilipisfilipiApr 3, 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.

Remember [](start = 80, length = 8)

remove #Resolved

{
public float[] GroupB { get; set; }

public float[] GroupC { get; set; }

@sfilipisfilipiApr 3, 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.

space #Resolved

string dataFilePath = SamplesUtils.DatasetUtils.DownloadBreastCancerDataset();

// Data Preview
// 1. Label 0=benign, 1=malignant

@Ivanidzo4kaIvanidzo4kaApr 3, 2019

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.

 [](start = 26, length = 7)

He use tabs! Where is my pitchfork! #Resolved

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

:) lol


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

// In this example we define a CountFeatureSelectingEstimator, that selects slots in a feature vector that have more non-default
// values than the specified count. This transformation can be used to remove slots with too many missing values.
var pipeline = mlContext.Transforms.FeatureSelection.SelectFeaturesBasedOnCount(
outputColumnName: "FeaturesSelectedGroupB", inputColumnName: "GroupB", count: 695);

@Ivanidzo4kaIvanidzo4kaApr 3, 2019

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.

695 [](start = 94, length = 3)

Where this number coming from?
#Resolved

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

comment in line 29 should clarify this now, also the in-memory example should make it more intuitive


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

// 5 7
// 1 2
// 1 3
// 3 2

@Ivanidzo4kaIvanidzo4kaApr 3, 2019

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.

with current data it's not obvious at all. Can we switch to some small in memory sample rather than unknown dataset? #Resolved

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

true. moved over to use a small in-memory dataset instead


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

// We will use the SelectFeaturesBasedOnCount transform estimator, to retain only those slots which have
// at least 'count' non-default values per slot.

// Multi column example : This pipeline uses two columns for transformation

@shmoradimsshmoradimsApr 4, 2019

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This pipeline uses two columns for transformation [](start = 38, length = 49)

i think this is clearer: this pipeline transform two columns using the same options.

just want to make sure it's clear that columns are transformed independently and are not mixed #Resolved

@shmoradimsshmoradims left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

:shipit:

@abgoswam
abgoswam requested a review from rogancarrApril 4, 2019 21:27
// We define a MutualInformationFeatureSelectingEstimator that selects the top k slots in a feature
// vector based on highest mutual information between that slot and a specified label.

var pipeline = mlContext.Transforms.FeatureSelection.SelectFeaturesBasedOnMutualInformation(

@abgoswamabgoswamApr 4, 2019

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

SelectFeaturesBasedOnMutualInformation [](start = 65, length = 38)

this sample is only for API reference, so small in-memory dataset suffices for this example.

we should have a "tutorial" to show the computation of MI..something along the lines of

https://www.researchgate.net/post/How_can_i_calculate_Mutual_Information_theory_from_a_simple_dataset

@sfilipisfilipiApr 4, 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.

+1 @natke was looking into how this transform works.


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

foreach (var item in convertedData)
Console.WriteLine("{0}\t\t\t{1}", string.Join("\t", item.NumericVector), string.Join("\t", item.StringVector));
// 4 NaN 6 A WA Male
// 4 5 6 A Female

@sfilipisfilipiApr 4, 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.

 [](start = 63, length = 5)

align for just here.. no need to make it match exactly to the output and have it looked tabbing off. #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.

or is it a separate column?

It helps to print the headers.


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

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

the alignment here seems good to me... for text this slot is empty or null ..

not sure if u meant something else


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


// We will use the SelectFeaturesBasedOnCount to retain only those slots which have at least 'count' non-default values per slot.

// Usage on numeric column.

@sfilipisfilipiApr 4, 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.

remove space #Resolved

// The pipeline can then be trained, using .Fit(), and the resulting transformer can be used to transform data.
var transformedData = pipeline.Fit(data).Transform(data);

Console.WriteLine("Contents of column 'NumericVector'");

@sfilipisfilipiApr 4, 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.

Console.WriteLine("Contents of column 'NumericVector'"); [](start = 11, length = 57)

convert to just comment. #Resolved

Console.Write($"{row[i]}\t");
Console.WriteLine();
}
// 4 6

@sfilipisfilipiApr 4, 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.

// 4 6 [](start = 12, length = 12)

headers #Resolved

for (var i = 0; i < row.Length; i++)
Console.Write($"{row[i]}\t");
Console.WriteLine();
}

@sfilipisfilipiApr 4, 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.

would it polish it a bit if you made a little helper for this, since it is being used twice? #Resolved

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

one of then is a float[] while the other is string[] .. did not want to over-engineer this...

is there anything specific you had in mind, or can we keep it as is ?


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

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.

object :)


In reply to: 272394600 [](ancestors = 272394600,272392068)


Console.WriteLine("Contents of two columns 'NumericVector' and 'StringVector'.");
foreach (var item in convertedData)
Console.WriteLine("{0}\t\t\t{1}", string.Join("\t", item.NumericVector), string.Join("\t", item.StringVector));

@sfilipisfilipiApr 4, 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.

\t [](start = 63, length = 2)

think for vectors we are using comma ',' as the separator. #Resolved


// Usage on text column.
pipeline = mlContext.Transforms.FeatureSelection.SelectFeaturesBasedOnCount(
outputColumnName: "StringVector", count: 3);

@sfilipisfilipiApr 4, 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.

I'd probably append to the previous pipeline, and show the prints once. Compacts the sample. #Resolved

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

sounds good. will do.


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


Console.WriteLine("Contents of two columns 'NumericVector' and 'StringVector'.");
foreach (var item in rawData)
Console.WriteLine("{0}\t\t\t{1}", string.Join("\t", item.NumericVector), string.Join("\t", item.StringVector));

@sfilipisfilipiApr 4, 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.

\t [](start = 63, length = 2)

same comment, ',' #Resolved


Console.WriteLine("Contents of column 'NumericVector'");
PrintDataColumn(transformedData, "NumericVector");
// 4 0

@sfilipisfilipiApr 4, 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.

4 [](start = 15, length = 1)

Curious, why is it dropping 6, but keeping 4? It is not obvious to me. Is it because slotsInOutput is 2? A comment about that might help. #Pending

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

we need to improve this once we have found a better sample. i have noted this in the issue #1209


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

@sfilipisfilipi 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:


Console.WriteLine("Contents of columns 'Label', 'NumericVectorA' and 'NumericVectorB'.");
foreach (var item in rawData)
Console.WriteLine("{0}\t\t{1}\t\t{2}", item.Label, string.Join(" ", item.NumericVectorA), string.Join(" ", item.NumericVectorB));

@sfilipisfilipiApr 4, 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.

[](start = 80, length = 1)

',' #Resolved

var rawData = GetData();
var data = mlContext.Data.LoadFromEnumerable(rawData);

var convertedData = mlContext.Data.CreateEnumerable<InputData>(data, true);

@zeahmedzeahmedApr 4, 2019

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.

convertedData [](start = 16, length = 13)

Why do you convert that back to Enumerable? rawData is already there. #Resolved

foreach (var item in convertedData)
Console.WriteLine("{0}\t\t{1}", string.Join(" ", item.NumericVectorA), string.Join(" ", item.NumericVectorB));

// Here, we see SelectFeaturesBasedOnMutualInformation selected 4 slots.

@sfilipisfilipiApr 4, 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.

4 slot [](start = 76, length = 6)

the 4 slots that had most in common with the respective value in the Label column, maybe? #Resolved

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

yes, these 4 slots carried the most MI with Label.... we should have a better tutorial for this though


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

@sfilipisfilipi 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:

@rogancarrrogancarr left a comment

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.

:shipit:

@abgoswam
abgoswam merged commit 8130567 into dotnet:masterApr 5, 2019
abgoswam added a commit to abgoswam/machinelearning that referenced this pull request Apr 5, 2019
* samples for FeatureSelection transform estimators
* fix review comments
* fix review comments
* review comments
* take care of review comments
* fix copy paste output error
@ghostghost locked as resolved and limited conversation to collaborators Mar 23, 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.

6 participants

@abgoswam@Ivanidzo4ka@shmoradims@sfilipi@rogancarr@zeahmed
, '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

Samples for FeatureSelection transform estimators - #3184

Merged
abgoswam merged 6 commits into
dotnet:masterfrom
abgoswam:abgoswam/featureselection_samples
Apr 5, 2019
Merged

Samples for FeatureSelection transform estimators#3184
abgoswam merged 6 commits into
dotnet:masterfrom
abgoswam:abgoswam/featureselection_samples

Conversation

@abgoswam

Copy link
Copy Markdown
Member

Towards #1209

The PR makes the following changes

  • Adds sample for the SelectFeaturesBasedOnCount transform estimator.
  • Adds sample for the SelectFeaturesBasedOnMutualInformation transform estimator.
  • Delete old sample.

@codecov

codecovBot commented Apr 3, 2019

Copy link
Copy Markdown

Codecov Report

Merging #3184 into master will increase coverage by 0.06%.
The diff coverage is n/a.

@@ Coverage Diff @@## master #3184 +/- ##
==========================================
+ Coverage 72.54% 72.6% +0.06% 
==========================================
Files 807 807 Lines 144774 145077 +303 Branches 16208 16213 +5 ==========================================
+ Hits 105021 105332 +311 + Misses 35339 35326 -13 - Partials 4414 4419 +5
FlagCoverage Δ
#Debug72.6% <ø> (+0.06%)⬆️
#production68.14% <ø> (+0.01%)⬆️
#test88.92% <ø> (+0.09%)⬆️
Impacted FilesCoverage Δ
...Microsoft.ML.Transforms/FeatureSelectionCatalog.cs60% <ø> (ø)⬆️
...c/Microsoft.ML.FastTree/Utils/ThreadTaskManager.cs79.48% <0%> (-20.52%)⬇️
src/Microsoft.ML.DataView/KeyDataViewType.cs74.57% <0%> (-3.76%)⬇️
src/Microsoft.ML.Maml/MAML.cs24.75% <0%> (-1.46%)⬇️
src/Microsoft.ML.Transforms/Text/LdaTransform.cs89.26% <0%> (-0.63%)⬇️
src/Microsoft.ML.Data/Transforms/ValueMapping.cs84.26% <0%> (-0.14%)⬇️
test/Microsoft.ML.Tests/ImagesTests.cs98.69% <0%> (-0.13%)⬇️
src/Microsoft.ML.Transforms/CategoricalCatalog.cs68.42% <0%> (ø)⬆️
...Microsoft.ML.Tests/Transformers/NormalizerTests.cs100% <0%> (ø)⬆️
...crosoft.ML.Tests/Transformers/ValueMappingTests.cs100% <0%> (ø)⬆️
... and 7 more

/// <format type="text/markdown">
/// <![CDATA[
/// [!code-csharp[SelectFeaturesBasedOnMutualInformation](~/../docs/samples/docs/samples/Microsoft.ML.Samples/Dynamic/FeatureSelectionTransform.cs?range=1-4,10-121)]
/// [!code-csharp[SelectFeaturesBasedOnMutualInformation](~/../docs/samples/docs/samples/Microsoft.ML.Samples/Dynamic/SelectFeaturesBasedOnMutualInformation.cs)]

@sfilipisfilipiApr 3, 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.

Dynamic/S [](start = 118, length = 9)

Dynamic/Transforms/ #Resolved

/// <example>
/// <format type="text/markdown">
/// <![CDATA[
/// [!code-csharp[SelectFeaturesBasedOnMutualInformation](~/../docs/samples/docs/samples/Microsoft.ML.Samples/Dynamic/SelectFeaturesBasedOnMutualInformation.cs)]

@sfilipisfilipiApr 3, 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.

Dynamic [](start = 118, length = 7)

Dynamic/Transforms/ #Resolved

{
// Downloading a classification dataset from github.com/dotnet/machinelearning.
// It will be stored in the same path as the executable
string dataFilePath = SamplesUtils.DatasetUtils.DownloadBreastCancerDataset();

@sfilipisfilipiApr 3, 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.

string dataFilePath = SamplesUtils.DatasetUtils.DownloadBreastCancerDataset(); [](start = 9, length = 81)

can it be done with a small in memory dataset? #Resolved

pipeline = mlContext.Transforms.FeatureSelection.SelectFeaturesBasedOnMutualInformation(
new InputOutputColumnPair[] { new InputOutputColumnPair("GroupB"), new InputOutputColumnPair("GroupC") },
labelColumnName: "Label",
slotsInOutput:4);

@sfilipisfilipiApr 3, 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.

slotsInOutput:4 [](start = 16, length = 15)

one line comment about what this does. #Resolved

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

comment in line 28 should clarify this


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

// 3 7 1
// 3 1 1

// Second, we define the transformations that we apply on the data. Remember that an Estimator does not transform data

@sfilipisfilipiApr 3, 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.

Remember [](start = 80, length = 8)

remove #Resolved

{
public float[] GroupB { get; set; }

public float[] GroupC { get; set; }

@sfilipisfilipiApr 3, 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.

space #Resolved

string dataFilePath = SamplesUtils.DatasetUtils.DownloadBreastCancerDataset();

// Data Preview
// 1. Label 0=benign, 1=malignant

@Ivanidzo4kaIvanidzo4kaApr 3, 2019

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.

 [](start = 26, length = 7)

He use tabs! Where is my pitchfork! #Resolved

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

:) lol


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

// In this example we define a CountFeatureSelectingEstimator, that selects slots in a feature vector that have more non-default
// values than the specified count. This transformation can be used to remove slots with too many missing values.
var pipeline = mlContext.Transforms.FeatureSelection.SelectFeaturesBasedOnCount(
outputColumnName: "FeaturesSelectedGroupB", inputColumnName: "GroupB", count: 695);

@Ivanidzo4kaIvanidzo4kaApr 3, 2019

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.

695 [](start = 94, length = 3)

Where this number coming from?
#Resolved

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

comment in line 29 should clarify this now, also the in-memory example should make it more intuitive


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

// 5 7
// 1 2
// 1 3
// 3 2

@Ivanidzo4kaIvanidzo4kaApr 3, 2019

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.

with current data it's not obvious at all. Can we switch to some small in memory sample rather than unknown dataset? #Resolved

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

true. moved over to use a small in-memory dataset instead


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

// We will use the SelectFeaturesBasedOnCount transform estimator, to retain only those slots which have
// at least 'count' non-default values per slot.

// Multi column example : This pipeline uses two columns for transformation

@shmoradimsshmoradimsApr 4, 2019

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This pipeline uses two columns for transformation [](start = 38, length = 49)

i think this is clearer: this pipeline transform two columns using the same options.

just want to make sure it's clear that columns are transformed independently and are not mixed #Resolved

@shmoradimsshmoradims left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

:shipit:

@abgoswam
abgoswam requested a review from rogancarrApril 4, 2019 21:27
// We define a MutualInformationFeatureSelectingEstimator that selects the top k slots in a feature
// vector based on highest mutual information between that slot and a specified label.

var pipeline = mlContext.Transforms.FeatureSelection.SelectFeaturesBasedOnMutualInformation(

@abgoswamabgoswamApr 4, 2019

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

SelectFeaturesBasedOnMutualInformation [](start = 65, length = 38)

this sample is only for API reference, so small in-memory dataset suffices for this example.

we should have a "tutorial" to show the computation of MI..something along the lines of

https://www.researchgate.net/post/How_can_i_calculate_Mutual_Information_theory_from_a_simple_dataset

@sfilipisfilipiApr 4, 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.

+1 @natke was looking into how this transform works.


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

foreach (var item in convertedData)
Console.WriteLine("{0}\t\t\t{1}", string.Join("\t", item.NumericVector), string.Join("\t", item.StringVector));
// 4 NaN 6 A WA Male
// 4 5 6 A Female

@sfilipisfilipiApr 4, 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.

 [](start = 63, length = 5)

align for just here.. no need to make it match exactly to the output and have it looked tabbing off. #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.

or is it a separate column?

It helps to print the headers.


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

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

the alignment here seems good to me... for text this slot is empty or null ..

not sure if u meant something else


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


// We will use the SelectFeaturesBasedOnCount to retain only those slots which have at least 'count' non-default values per slot.

// Usage on numeric column.

@sfilipisfilipiApr 4, 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.

remove space #Resolved

// The pipeline can then be trained, using .Fit(), and the resulting transformer can be used to transform data.
var transformedData = pipeline.Fit(data).Transform(data);

Console.WriteLine("Contents of column 'NumericVector'");

@sfilipisfilipiApr 4, 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.

Console.WriteLine("Contents of column 'NumericVector'"); [](start = 11, length = 57)

convert to just comment. #Resolved

Console.Write($"{row[i]}\t");
Console.WriteLine();
}
// 4 6

@sfilipisfilipiApr 4, 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.

// 4 6 [](start = 12, length = 12)

headers #Resolved

for (var i = 0; i < row.Length; i++)
Console.Write($"{row[i]}\t");
Console.WriteLine();
}

@sfilipisfilipiApr 4, 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.

would it polish it a bit if you made a little helper for this, since it is being used twice? #Resolved

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

one of then is a float[] while the other is string[] .. did not want to over-engineer this...

is there anything specific you had in mind, or can we keep it as is ?


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

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.

object :)


In reply to: 272394600 [](ancestors = 272394600,272392068)


Console.WriteLine("Contents of two columns 'NumericVector' and 'StringVector'.");
foreach (var item in convertedData)
Console.WriteLine("{0}\t\t\t{1}", string.Join("\t", item.NumericVector), string.Join("\t", item.StringVector));

@sfilipisfilipiApr 4, 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.

\t [](start = 63, length = 2)

think for vectors we are using comma ',' as the separator. #Resolved


// Usage on text column.
pipeline = mlContext.Transforms.FeatureSelection.SelectFeaturesBasedOnCount(
outputColumnName: "StringVector", count: 3);

@sfilipisfilipiApr 4, 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.

I'd probably append to the previous pipeline, and show the prints once. Compacts the sample. #Resolved

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

sounds good. will do.


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


Console.WriteLine("Contents of two columns 'NumericVector' and 'StringVector'.");
foreach (var item in rawData)
Console.WriteLine("{0}\t\t\t{1}", string.Join("\t", item.NumericVector), string.Join("\t", item.StringVector));

@sfilipisfilipiApr 4, 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.

\t [](start = 63, length = 2)

same comment, ',' #Resolved


Console.WriteLine("Contents of column 'NumericVector'");
PrintDataColumn(transformedData, "NumericVector");
// 4 0

@sfilipisfilipiApr 4, 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.

4 [](start = 15, length = 1)

Curious, why is it dropping 6, but keeping 4? It is not obvious to me. Is it because slotsInOutput is 2? A comment about that might help. #Pending

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

we need to improve this once we have found a better sample. i have noted this in the issue #1209


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

@sfilipisfilipi 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:


Console.WriteLine("Contents of columns 'Label', 'NumericVectorA' and 'NumericVectorB'.");
foreach (var item in rawData)
Console.WriteLine("{0}\t\t{1}\t\t{2}", item.Label, string.Join(" ", item.NumericVectorA), string.Join(" ", item.NumericVectorB));

@sfilipisfilipiApr 4, 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.

[](start = 80, length = 1)

',' #Resolved

var rawData = GetData();
var data = mlContext.Data.LoadFromEnumerable(rawData);

var convertedData = mlContext.Data.CreateEnumerable<InputData>(data, true);

@zeahmedzeahmedApr 4, 2019

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.

convertedData [](start = 16, length = 13)

Why do you convert that back to Enumerable? rawData is already there. #Resolved

foreach (var item in convertedData)
Console.WriteLine("{0}\t\t{1}", string.Join(" ", item.NumericVectorA), string.Join(" ", item.NumericVectorB));

// Here, we see SelectFeaturesBasedOnMutualInformation selected 4 slots.

@sfilipisfilipiApr 4, 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.

4 slot [](start = 76, length = 6)

the 4 slots that had most in common with the respective value in the Label column, maybe? #Resolved

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

yes, these 4 slots carried the most MI with Label.... we should have a better tutorial for this though


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

@sfilipisfilipi 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:

@rogancarrrogancarr left a comment

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.

:shipit:

@abgoswam
abgoswam merged commit 8130567 into dotnet:masterApr 5, 2019
abgoswam added a commit to abgoswam/machinelearning that referenced this pull request Apr 5, 2019
* samples for FeatureSelection transform estimators
* fix review comments
* fix review comments
* review comments
* take care of review comments
* fix copy paste output error
@ghostghost locked as resolved and limited conversation to collaborators Mar 23, 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.

6 participants

@abgoswam@Ivanidzo4ka@shmoradims@sfilipi@rogancarr@zeahmed
, '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

Samples for FeatureSelection transform estimators - #3184

Merged
abgoswam merged 6 commits into
dotnet:masterfrom
abgoswam:abgoswam/featureselection_samples
Apr 5, 2019
Merged

Samples for FeatureSelection transform estimators#3184
abgoswam merged 6 commits into
dotnet:masterfrom
abgoswam:abgoswam/featureselection_samples

Conversation

@abgoswam

Copy link
Copy Markdown
Member

Towards #1209

The PR makes the following changes

  • Adds sample for the SelectFeaturesBasedOnCount transform estimator.
  • Adds sample for the SelectFeaturesBasedOnMutualInformation transform estimator.
  • Delete old sample.

@codecov

codecovBot commented Apr 3, 2019

Copy link
Copy Markdown

Codecov Report

Merging #3184 into master will increase coverage by 0.06%.
The diff coverage is n/a.

@@ Coverage Diff @@## master #3184 +/- ##
==========================================
+ Coverage 72.54% 72.6% +0.06% 
==========================================
Files 807 807 Lines 144774 145077 +303 Branches 16208 16213 +5 ==========================================
+ Hits 105021 105332 +311 + Misses 35339 35326 -13 - Partials 4414 4419 +5
FlagCoverage Δ
#Debug72.6% <ø> (+0.06%)⬆️
#production68.14% <ø> (+0.01%)⬆️
#test88.92% <ø> (+0.09%)⬆️
Impacted FilesCoverage Δ
...Microsoft.ML.Transforms/FeatureSelectionCatalog.cs60% <ø> (ø)⬆️
...c/Microsoft.ML.FastTree/Utils/ThreadTaskManager.cs79.48% <0%> (-20.52%)⬇️
src/Microsoft.ML.DataView/KeyDataViewType.cs74.57% <0%> (-3.76%)⬇️
src/Microsoft.ML.Maml/MAML.cs24.75% <0%> (-1.46%)⬇️
src/Microsoft.ML.Transforms/Text/LdaTransform.cs89.26% <0%> (-0.63%)⬇️
src/Microsoft.ML.Data/Transforms/ValueMapping.cs84.26% <0%> (-0.14%)⬇️
test/Microsoft.ML.Tests/ImagesTests.cs98.69% <0%> (-0.13%)⬇️
src/Microsoft.ML.Transforms/CategoricalCatalog.cs68.42% <0%> (ø)⬆️
...Microsoft.ML.Tests/Transformers/NormalizerTests.cs100% <0%> (ø)⬆️
...crosoft.ML.Tests/Transformers/ValueMappingTests.cs100% <0%> (ø)⬆️
... and 7 more

/// <format type="text/markdown">
/// <![CDATA[
/// [!code-csharp[SelectFeaturesBasedOnMutualInformation](~/../docs/samples/docs/samples/Microsoft.ML.Samples/Dynamic/FeatureSelectionTransform.cs?range=1-4,10-121)]
/// [!code-csharp[SelectFeaturesBasedOnMutualInformation](~/../docs/samples/docs/samples/Microsoft.ML.Samples/Dynamic/SelectFeaturesBasedOnMutualInformation.cs)]

@sfilipisfilipiApr 3, 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.

Dynamic/S [](start = 118, length = 9)

Dynamic/Transforms/ #Resolved

/// <example>
/// <format type="text/markdown">
/// <![CDATA[
/// [!code-csharp[SelectFeaturesBasedOnMutualInformation](~/../docs/samples/docs/samples/Microsoft.ML.Samples/Dynamic/SelectFeaturesBasedOnMutualInformation.cs)]

@sfilipisfilipiApr 3, 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.

Dynamic [](start = 118, length = 7)

Dynamic/Transforms/ #Resolved

{
// Downloading a classification dataset from github.com/dotnet/machinelearning.
// It will be stored in the same path as the executable
string dataFilePath = SamplesUtils.DatasetUtils.DownloadBreastCancerDataset();

@sfilipisfilipiApr 3, 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.

string dataFilePath = SamplesUtils.DatasetUtils.DownloadBreastCancerDataset(); [](start = 9, length = 81)

can it be done with a small in memory dataset? #Resolved

pipeline = mlContext.Transforms.FeatureSelection.SelectFeaturesBasedOnMutualInformation(
new InputOutputColumnPair[] { new InputOutputColumnPair("GroupB"), new InputOutputColumnPair("GroupC") },
labelColumnName: "Label",
slotsInOutput:4);

@sfilipisfilipiApr 3, 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.

slotsInOutput:4 [](start = 16, length = 15)

one line comment about what this does. #Resolved

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

comment in line 28 should clarify this


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

// 3 7 1
// 3 1 1

// Second, we define the transformations that we apply on the data. Remember that an Estimator does not transform data

@sfilipisfilipiApr 3, 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.

Remember [](start = 80, length = 8)

remove #Resolved

{
public float[] GroupB { get; set; }

public float[] GroupC { get; set; }

@sfilipisfilipiApr 3, 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.

space #Resolved

string dataFilePath = SamplesUtils.DatasetUtils.DownloadBreastCancerDataset();

// Data Preview
// 1. Label 0=benign, 1=malignant

@Ivanidzo4kaIvanidzo4kaApr 3, 2019

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.

 [](start = 26, length = 7)

He use tabs! Where is my pitchfork! #Resolved

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

:) lol


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

// In this example we define a CountFeatureSelectingEstimator, that selects slots in a feature vector that have more non-default
// values than the specified count. This transformation can be used to remove slots with too many missing values.
var pipeline = mlContext.Transforms.FeatureSelection.SelectFeaturesBasedOnCount(
outputColumnName: "FeaturesSelectedGroupB", inputColumnName: "GroupB", count: 695);

@Ivanidzo4kaIvanidzo4kaApr 3, 2019

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.

695 [](start = 94, length = 3)

Where this number coming from?
#Resolved

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

comment in line 29 should clarify this now, also the in-memory example should make it more intuitive


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

// 5 7
// 1 2
// 1 3
// 3 2

@Ivanidzo4kaIvanidzo4kaApr 3, 2019

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.

with current data it's not obvious at all. Can we switch to some small in memory sample rather than unknown dataset? #Resolved

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

true. moved over to use a small in-memory dataset instead


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

// We will use the SelectFeaturesBasedOnCount transform estimator, to retain only those slots which have
// at least 'count' non-default values per slot.

// Multi column example : This pipeline uses two columns for transformation

@shmoradimsshmoradimsApr 4, 2019

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This pipeline uses two columns for transformation [](start = 38, length = 49)

i think this is clearer: this pipeline transform two columns using the same options.

just want to make sure it's clear that columns are transformed independently and are not mixed #Resolved

@shmoradimsshmoradims left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

:shipit:

@abgoswam
abgoswam requested a review from rogancarrApril 4, 2019 21:27
// We define a MutualInformationFeatureSelectingEstimator that selects the top k slots in a feature
// vector based on highest mutual information between that slot and a specified label.

var pipeline = mlContext.Transforms.FeatureSelection.SelectFeaturesBasedOnMutualInformation(

@abgoswamabgoswamApr 4, 2019

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

SelectFeaturesBasedOnMutualInformation [](start = 65, length = 38)

this sample is only for API reference, so small in-memory dataset suffices for this example.

we should have a "tutorial" to show the computation of MI..something along the lines of

https://www.researchgate.net/post/How_can_i_calculate_Mutual_Information_theory_from_a_simple_dataset

@sfilipisfilipiApr 4, 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.

+1 @natke was looking into how this transform works.


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

foreach (var item in convertedData)
Console.WriteLine("{0}\t\t\t{1}", string.Join("\t", item.NumericVector), string.Join("\t", item.StringVector));
// 4 NaN 6 A WA Male
// 4 5 6 A Female

@sfilipisfilipiApr 4, 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.

 [](start = 63, length = 5)

align for just here.. no need to make it match exactly to the output and have it looked tabbing off. #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.

or is it a separate column?

It helps to print the headers.


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

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

the alignment here seems good to me... for text this slot is empty or null ..

not sure if u meant something else


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


// We will use the SelectFeaturesBasedOnCount to retain only those slots which have at least 'count' non-default values per slot.

// Usage on numeric column.

@sfilipisfilipiApr 4, 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.

remove space #Resolved

// The pipeline can then be trained, using .Fit(), and the resulting transformer can be used to transform data.
var transformedData = pipeline.Fit(data).Transform(data);

Console.WriteLine("Contents of column 'NumericVector'");

@sfilipisfilipiApr 4, 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.

Console.WriteLine("Contents of column 'NumericVector'"); [](start = 11, length = 57)

convert to just comment. #Resolved

Console.Write($"{row[i]}\t");
Console.WriteLine();
}
// 4 6

@sfilipisfilipiApr 4, 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.

// 4 6 [](start = 12, length = 12)

headers #Resolved

for (var i = 0; i < row.Length; i++)
Console.Write($"{row[i]}\t");
Console.WriteLine();
}

@sfilipisfilipiApr 4, 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.

would it polish it a bit if you made a little helper for this, since it is being used twice? #Resolved

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

one of then is a float[] while the other is string[] .. did not want to over-engineer this...

is there anything specific you had in mind, or can we keep it as is ?


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

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.

object :)


In reply to: 272394600 [](ancestors = 272394600,272392068)


Console.WriteLine("Contents of two columns 'NumericVector' and 'StringVector'.");
foreach (var item in convertedData)
Console.WriteLine("{0}\t\t\t{1}", string.Join("\t", item.NumericVector), string.Join("\t", item.StringVector));

@sfilipisfilipiApr 4, 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.

\t [](start = 63, length = 2)

think for vectors we are using comma ',' as the separator. #Resolved


// Usage on text column.
pipeline = mlContext.Transforms.FeatureSelection.SelectFeaturesBasedOnCount(
outputColumnName: "StringVector", count: 3);

@sfilipisfilipiApr 4, 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.

I'd probably append to the previous pipeline, and show the prints once. Compacts the sample. #Resolved

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

sounds good. will do.


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


Console.WriteLine("Contents of two columns 'NumericVector' and 'StringVector'.");
foreach (var item in rawData)
Console.WriteLine("{0}\t\t\t{1}", string.Join("\t", item.NumericVector), string.Join("\t", item.StringVector));

@sfilipisfilipiApr 4, 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.

\t [](start = 63, length = 2)

same comment, ',' #Resolved


Console.WriteLine("Contents of column 'NumericVector'");
PrintDataColumn(transformedData, "NumericVector");
// 4 0

@sfilipisfilipiApr 4, 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.

4 [](start = 15, length = 1)

Curious, why is it dropping 6, but keeping 4? It is not obvious to me. Is it because slotsInOutput is 2? A comment about that might help. #Pending

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

we need to improve this once we have found a better sample. i have noted this in the issue #1209


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

@sfilipisfilipi 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:


Console.WriteLine("Contents of columns 'Label', 'NumericVectorA' and 'NumericVectorB'.");
foreach (var item in rawData)
Console.WriteLine("{0}\t\t{1}\t\t{2}", item.Label, string.Join(" ", item.NumericVectorA), string.Join(" ", item.NumericVectorB));

@sfilipisfilipiApr 4, 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.

[](start = 80, length = 1)

',' #Resolved

var rawData = GetData();
var data = mlContext.Data.LoadFromEnumerable(rawData);

var convertedData = mlContext.Data.CreateEnumerable<InputData>(data, true);

@zeahmedzeahmedApr 4, 2019

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.

convertedData [](start = 16, length = 13)

Why do you convert that back to Enumerable? rawData is already there. #Resolved

foreach (var item in convertedData)
Console.WriteLine("{0}\t\t{1}", string.Join(" ", item.NumericVectorA), string.Join(" ", item.NumericVectorB));

// Here, we see SelectFeaturesBasedOnMutualInformation selected 4 slots.

@sfilipisfilipiApr 4, 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.

4 slot [](start = 76, length = 6)

the 4 slots that had most in common with the respective value in the Label column, maybe? #Resolved

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

yes, these 4 slots carried the most MI with Label.... we should have a better tutorial for this though


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

@sfilipisfilipi 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:

@rogancarrrogancarr left a comment

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.

:shipit:

@abgoswam
abgoswam merged commit 8130567 into dotnet:masterApr 5, 2019
abgoswam added a commit to abgoswam/machinelearning that referenced this pull request Apr 5, 2019
* samples for FeatureSelection transform estimators
* fix review comments
* fix review comments
* review comments
* take care of review comments
* fix copy paste output error
@ghostghost locked as resolved and limited conversation to collaborators Mar 23, 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.

6 participants

@abgoswam@Ivanidzo4ka@shmoradims@sfilipi@rogancarr@zeahmed
, '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

Samples for FeatureSelection transform estimators - #3184

Merged
abgoswam merged 6 commits into
dotnet:masterfrom
abgoswam:abgoswam/featureselection_samples
Apr 5, 2019
Merged

Samples for FeatureSelection transform estimators#3184
abgoswam merged 6 commits into
dotnet:masterfrom
abgoswam:abgoswam/featureselection_samples

Conversation

@abgoswam

Copy link
Copy Markdown
Member

Towards #1209

The PR makes the following changes

  • Adds sample for the SelectFeaturesBasedOnCount transform estimator.
  • Adds sample for the SelectFeaturesBasedOnMutualInformation transform estimator.
  • Delete old sample.

@codecov

codecovBot commented Apr 3, 2019

Copy link
Copy Markdown

Codecov Report

Merging #3184 into master will increase coverage by 0.06%.
The diff coverage is n/a.

@@ Coverage Diff @@## master #3184 +/- ##
==========================================
+ Coverage 72.54% 72.6% +0.06% 
==========================================
Files 807 807 Lines 144774 145077 +303 Branches 16208 16213 +5 ==========================================
+ Hits 105021 105332 +311 + Misses 35339 35326 -13 - Partials 4414 4419 +5
FlagCoverage Δ
#Debug72.6% <ø> (+0.06%)⬆️
#production68.14% <ø> (+0.01%)⬆️
#test88.92% <ø> (+0.09%)⬆️
Impacted FilesCoverage Δ
...Microsoft.ML.Transforms/FeatureSelectionCatalog.cs60% <ø> (ø)⬆️
...c/Microsoft.ML.FastTree/Utils/ThreadTaskManager.cs79.48% <0%> (-20.52%)⬇️
src/Microsoft.ML.DataView/KeyDataViewType.cs74.57% <0%> (-3.76%)⬇️
src/Microsoft.ML.Maml/MAML.cs24.75% <0%> (-1.46%)⬇️
src/Microsoft.ML.Transforms/Text/LdaTransform.cs89.26% <0%> (-0.63%)⬇️
src/Microsoft.ML.Data/Transforms/ValueMapping.cs84.26% <0%> (-0.14%)⬇️
test/Microsoft.ML.Tests/ImagesTests.cs98.69% <0%> (-0.13%)⬇️
src/Microsoft.ML.Transforms/CategoricalCatalog.cs68.42% <0%> (ø)⬆️
...Microsoft.ML.Tests/Transformers/NormalizerTests.cs100% <0%> (ø)⬆️
...crosoft.ML.Tests/Transformers/ValueMappingTests.cs100% <0%> (ø)⬆️
... and 7 more

/// <format type="text/markdown">
/// <![CDATA[
/// [!code-csharp[SelectFeaturesBasedOnMutualInformation](~/../docs/samples/docs/samples/Microsoft.ML.Samples/Dynamic/FeatureSelectionTransform.cs?range=1-4,10-121)]
/// [!code-csharp[SelectFeaturesBasedOnMutualInformation](~/../docs/samples/docs/samples/Microsoft.ML.Samples/Dynamic/SelectFeaturesBasedOnMutualInformation.cs)]

@sfilipisfilipiApr 3, 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.

Dynamic/S [](start = 118, length = 9)

Dynamic/Transforms/ #Resolved

/// <example>
/// <format type="text/markdown">
/// <![CDATA[
/// [!code-csharp[SelectFeaturesBasedOnMutualInformation](~/../docs/samples/docs/samples/Microsoft.ML.Samples/Dynamic/SelectFeaturesBasedOnMutualInformation.cs)]

@sfilipisfilipiApr 3, 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.

Dynamic [](start = 118, length = 7)

Dynamic/Transforms/ #Resolved

{
// Downloading a classification dataset from github.com/dotnet/machinelearning.
// It will be stored in the same path as the executable
string dataFilePath = SamplesUtils.DatasetUtils.DownloadBreastCancerDataset();

@sfilipisfilipiApr 3, 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.

string dataFilePath = SamplesUtils.DatasetUtils.DownloadBreastCancerDataset(); [](start = 9, length = 81)

can it be done with a small in memory dataset? #Resolved

pipeline = mlContext.Transforms.FeatureSelection.SelectFeaturesBasedOnMutualInformation(
new InputOutputColumnPair[] { new InputOutputColumnPair("GroupB"), new InputOutputColumnPair("GroupC") },
labelColumnName: "Label",
slotsInOutput:4);

@sfilipisfilipiApr 3, 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.

slotsInOutput:4 [](start = 16, length = 15)

one line comment about what this does. #Resolved

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

comment in line 28 should clarify this


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

// 3 7 1
// 3 1 1

// Second, we define the transformations that we apply on the data. Remember that an Estimator does not transform data

@sfilipisfilipiApr 3, 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.

Remember [](start = 80, length = 8)

remove #Resolved

{
public float[] GroupB { get; set; }

public float[] GroupC { get; set; }

@sfilipisfilipiApr 3, 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.

space #Resolved

string dataFilePath = SamplesUtils.DatasetUtils.DownloadBreastCancerDataset();

// Data Preview
// 1. Label 0=benign, 1=malignant

@Ivanidzo4kaIvanidzo4kaApr 3, 2019

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.

 [](start = 26, length = 7)

He use tabs! Where is my pitchfork! #Resolved

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

:) lol


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

// In this example we define a CountFeatureSelectingEstimator, that selects slots in a feature vector that have more non-default
// values than the specified count. This transformation can be used to remove slots with too many missing values.
var pipeline = mlContext.Transforms.FeatureSelection.SelectFeaturesBasedOnCount(
outputColumnName: "FeaturesSelectedGroupB", inputColumnName: "GroupB", count: 695);

@Ivanidzo4kaIvanidzo4kaApr 3, 2019

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.

695 [](start = 94, length = 3)

Where this number coming from?
#Resolved

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

comment in line 29 should clarify this now, also the in-memory example should make it more intuitive


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

// 5 7
// 1 2
// 1 3
// 3 2

@Ivanidzo4kaIvanidzo4kaApr 3, 2019

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.

with current data it's not obvious at all. Can we switch to some small in memory sample rather than unknown dataset? #Resolved

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

true. moved over to use a small in-memory dataset instead


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

// We will use the SelectFeaturesBasedOnCount transform estimator, to retain only those slots which have
// at least 'count' non-default values per slot.

// Multi column example : This pipeline uses two columns for transformation

@shmoradimsshmoradimsApr 4, 2019

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This pipeline uses two columns for transformation [](start = 38, length = 49)

i think this is clearer: this pipeline transform two columns using the same options.

just want to make sure it's clear that columns are transformed independently and are not mixed #Resolved

@shmoradimsshmoradims left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

:shipit:

@abgoswam
abgoswam requested a review from rogancarrApril 4, 2019 21:27
// We define a MutualInformationFeatureSelectingEstimator that selects the top k slots in a feature
// vector based on highest mutual information between that slot and a specified label.

var pipeline = mlContext.Transforms.FeatureSelection.SelectFeaturesBasedOnMutualInformation(

@abgoswamabgoswamApr 4, 2019

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

SelectFeaturesBasedOnMutualInformation [](start = 65, length = 38)

this sample is only for API reference, so small in-memory dataset suffices for this example.

we should have a "tutorial" to show the computation of MI..something along the lines of

https://www.researchgate.net/post/How_can_i_calculate_Mutual_Information_theory_from_a_simple_dataset

@sfilipisfilipiApr 4, 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.

+1 @natke was looking into how this transform works.


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

foreach (var item in convertedData)
Console.WriteLine("{0}\t\t\t{1}", string.Join("\t", item.NumericVector), string.Join("\t", item.StringVector));
// 4 NaN 6 A WA Male
// 4 5 6 A Female

@sfilipisfilipiApr 4, 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.

 [](start = 63, length = 5)

align for just here.. no need to make it match exactly to the output and have it looked tabbing off. #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.

or is it a separate column?

It helps to print the headers.


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

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

the alignment here seems good to me... for text this slot is empty or null ..

not sure if u meant something else


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


// We will use the SelectFeaturesBasedOnCount to retain only those slots which have at least 'count' non-default values per slot.

// Usage on numeric column.

@sfilipisfilipiApr 4, 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.

remove space #Resolved

// The pipeline can then be trained, using .Fit(), and the resulting transformer can be used to transform data.
var transformedData = pipeline.Fit(data).Transform(data);

Console.WriteLine("Contents of column 'NumericVector'");

@sfilipisfilipiApr 4, 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.

Console.WriteLine("Contents of column 'NumericVector'"); [](start = 11, length = 57)

convert to just comment. #Resolved

Console.Write($"{row[i]}\t");
Console.WriteLine();
}
// 4 6

@sfilipisfilipiApr 4, 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.

// 4 6 [](start = 12, length = 12)

headers #Resolved

for (var i = 0; i < row.Length; i++)
Console.Write($"{row[i]}\t");
Console.WriteLine();
}

@sfilipisfilipiApr 4, 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.

would it polish it a bit if you made a little helper for this, since it is being used twice? #Resolved

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

one of then is a float[] while the other is string[] .. did not want to over-engineer this...

is there anything specific you had in mind, or can we keep it as is ?


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

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.

object :)


In reply to: 272394600 [](ancestors = 272394600,272392068)


Console.WriteLine("Contents of two columns 'NumericVector' and 'StringVector'.");
foreach (var item in convertedData)
Console.WriteLine("{0}\t\t\t{1}", string.Join("\t", item.NumericVector), string.Join("\t", item.StringVector));

@sfilipisfilipiApr 4, 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.

\t [](start = 63, length = 2)

think for vectors we are using comma ',' as the separator. #Resolved


// Usage on text column.
pipeline = mlContext.Transforms.FeatureSelection.SelectFeaturesBasedOnCount(
outputColumnName: "StringVector", count: 3);

@sfilipisfilipiApr 4, 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.

I'd probably append to the previous pipeline, and show the prints once. Compacts the sample. #Resolved

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

sounds good. will do.


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


Console.WriteLine("Contents of two columns 'NumericVector' and 'StringVector'.");
foreach (var item in rawData)
Console.WriteLine("{0}\t\t\t{1}", string.Join("\t", item.NumericVector), string.Join("\t", item.StringVector));

@sfilipisfilipiApr 4, 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.

\t [](start = 63, length = 2)

same comment, ',' #Resolved


Console.WriteLine("Contents of column 'NumericVector'");
PrintDataColumn(transformedData, "NumericVector");
// 4 0

@sfilipisfilipiApr 4, 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.

4 [](start = 15, length = 1)

Curious, why is it dropping 6, but keeping 4? It is not obvious to me. Is it because slotsInOutput is 2? A comment about that might help. #Pending

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

we need to improve this once we have found a better sample. i have noted this in the issue #1209


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

@sfilipisfilipi 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:


Console.WriteLine("Contents of columns 'Label', 'NumericVectorA' and 'NumericVectorB'.");
foreach (var item in rawData)
Console.WriteLine("{0}\t\t{1}\t\t{2}", item.Label, string.Join(" ", item.NumericVectorA), string.Join(" ", item.NumericVectorB));

@sfilipisfilipiApr 4, 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.

[](start = 80, length = 1)

',' #Resolved

var rawData = GetData();
var data = mlContext.Data.LoadFromEnumerable(rawData);

var convertedData = mlContext.Data.CreateEnumerable<InputData>(data, true);

@zeahmedzeahmedApr 4, 2019

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.

convertedData [](start = 16, length = 13)

Why do you convert that back to Enumerable? rawData is already there. #Resolved

foreach (var item in convertedData)
Console.WriteLine("{0}\t\t{1}", string.Join(" ", item.NumericVectorA), string.Join(" ", item.NumericVectorB));

// Here, we see SelectFeaturesBasedOnMutualInformation selected 4 slots.

@sfilipisfilipiApr 4, 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.

4 slot [](start = 76, length = 6)

the 4 slots that had most in common with the respective value in the Label column, maybe? #Resolved

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

yes, these 4 slots carried the most MI with Label.... we should have a better tutorial for this though


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

@sfilipisfilipi 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:

@rogancarrrogancarr left a comment

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.

:shipit:

@abgoswam
abgoswam merged commit 8130567 into dotnet:masterApr 5, 2019
abgoswam added a commit to abgoswam/machinelearning that referenced this pull request Apr 5, 2019
* samples for FeatureSelection transform estimators
* fix review comments
* fix review comments
* review comments
* take care of review comments
* fix copy paste output error
@ghostghost locked as resolved and limited conversation to collaborators Mar 23, 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.

6 participants

@abgoswam@Ivanidzo4ka@shmoradims@sfilipi@rogancarr@zeahmed
, '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

Samples for FeatureSelection transform estimators - #3184

Merged
abgoswam merged 6 commits into
dotnet:masterfrom
abgoswam:abgoswam/featureselection_samples
Apr 5, 2019
Merged

Samples for FeatureSelection transform estimators#3184
abgoswam merged 6 commits into
dotnet:masterfrom
abgoswam:abgoswam/featureselection_samples

Conversation

@abgoswam

Copy link
Copy Markdown
Member

Towards #1209

The PR makes the following changes

  • Adds sample for the SelectFeaturesBasedOnCount transform estimator.
  • Adds sample for the SelectFeaturesBasedOnMutualInformation transform estimator.
  • Delete old sample.

@codecov

codecovBot commented Apr 3, 2019

Copy link
Copy Markdown

Codecov Report

Merging #3184 into master will increase coverage by 0.06%.
The diff coverage is n/a.

@@ Coverage Diff @@## master #3184 +/- ##
==========================================
+ Coverage 72.54% 72.6% +0.06% 
==========================================
Files 807 807 Lines 144774 145077 +303 Branches 16208 16213 +5 ==========================================
+ Hits 105021 105332 +311 + Misses 35339 35326 -13 - Partials 4414 4419 +5
FlagCoverage Δ
#Debug72.6% <ø> (+0.06%)⬆️
#production68.14% <ø> (+0.01%)⬆️
#test88.92% <ø> (+0.09%)⬆️
Impacted FilesCoverage Δ
...Microsoft.ML.Transforms/FeatureSelectionCatalog.cs60% <ø> (ø)⬆️
...c/Microsoft.ML.FastTree/Utils/ThreadTaskManager.cs79.48% <0%> (-20.52%)⬇️
src/Microsoft.ML.DataView/KeyDataViewType.cs74.57% <0%> (-3.76%)⬇️
src/Microsoft.ML.Maml/MAML.cs24.75% <0%> (-1.46%)⬇️
src/Microsoft.ML.Transforms/Text/LdaTransform.cs89.26% <0%> (-0.63%)⬇️
src/Microsoft.ML.Data/Transforms/ValueMapping.cs84.26% <0%> (-0.14%)⬇️
test/Microsoft.ML.Tests/ImagesTests.cs98.69% <0%> (-0.13%)⬇️
src/Microsoft.ML.Transforms/CategoricalCatalog.cs68.42% <0%> (ø)⬆️
...Microsoft.ML.Tests/Transformers/NormalizerTests.cs100% <0%> (ø)⬆️
...crosoft.ML.Tests/Transformers/ValueMappingTests.cs100% <0%> (ø)⬆️
... and 7 more

/// <format type="text/markdown">
/// <![CDATA[
/// [!code-csharp[SelectFeaturesBasedOnMutualInformation](~/../docs/samples/docs/samples/Microsoft.ML.Samples/Dynamic/FeatureSelectionTransform.cs?range=1-4,10-121)]
/// [!code-csharp[SelectFeaturesBasedOnMutualInformation](~/../docs/samples/docs/samples/Microsoft.ML.Samples/Dynamic/SelectFeaturesBasedOnMutualInformation.cs)]

@sfilipisfilipiApr 3, 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.

Dynamic/S [](start = 118, length = 9)

Dynamic/Transforms/ #Resolved

/// <example>
/// <format type="text/markdown">
/// <![CDATA[
/// [!code-csharp[SelectFeaturesBasedOnMutualInformation](~/../docs/samples/docs/samples/Microsoft.ML.Samples/Dynamic/SelectFeaturesBasedOnMutualInformation.cs)]

@sfilipisfilipiApr 3, 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.

Dynamic [](start = 118, length = 7)

Dynamic/Transforms/ #Resolved

{
// Downloading a classification dataset from github.com/dotnet/machinelearning.
// It will be stored in the same path as the executable
string dataFilePath = SamplesUtils.DatasetUtils.DownloadBreastCancerDataset();

@sfilipisfilipiApr 3, 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.

string dataFilePath = SamplesUtils.DatasetUtils.DownloadBreastCancerDataset(); [](start = 9, length = 81)

can it be done with a small in memory dataset? #Resolved

pipeline = mlContext.Transforms.FeatureSelection.SelectFeaturesBasedOnMutualInformation(
new InputOutputColumnPair[] { new InputOutputColumnPair("GroupB"), new InputOutputColumnPair("GroupC") },
labelColumnName: "Label",
slotsInOutput:4);

@sfilipisfilipiApr 3, 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.

slotsInOutput:4 [](start = 16, length = 15)

one line comment about what this does. #Resolved

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

comment in line 28 should clarify this


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

// 3 7 1
// 3 1 1

// Second, we define the transformations that we apply on the data. Remember that an Estimator does not transform data

@sfilipisfilipiApr 3, 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.

Remember [](start = 80, length = 8)

remove #Resolved

{
public float[] GroupB { get; set; }

public float[] GroupC { get; set; }

@sfilipisfilipiApr 3, 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.

space #Resolved

string dataFilePath = SamplesUtils.DatasetUtils.DownloadBreastCancerDataset();

// Data Preview
// 1. Label 0=benign, 1=malignant

@Ivanidzo4kaIvanidzo4kaApr 3, 2019

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.

 [](start = 26, length = 7)

He use tabs! Where is my pitchfork! #Resolved

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

:) lol


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

// In this example we define a CountFeatureSelectingEstimator, that selects slots in a feature vector that have more non-default
// values than the specified count. This transformation can be used to remove slots with too many missing values.
var pipeline = mlContext.Transforms.FeatureSelection.SelectFeaturesBasedOnCount(
outputColumnName: "FeaturesSelectedGroupB", inputColumnName: "GroupB", count: 695);

@Ivanidzo4kaIvanidzo4kaApr 3, 2019

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.

695 [](start = 94, length = 3)

Where this number coming from?
#Resolved

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

comment in line 29 should clarify this now, also the in-memory example should make it more intuitive


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

// 5 7
// 1 2
// 1 3
// 3 2

@Ivanidzo4kaIvanidzo4kaApr 3, 2019

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.

with current data it's not obvious at all. Can we switch to some small in memory sample rather than unknown dataset? #Resolved

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

true. moved over to use a small in-memory dataset instead


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

// We will use the SelectFeaturesBasedOnCount transform estimator, to retain only those slots which have
// at least 'count' non-default values per slot.

// Multi column example : This pipeline uses two columns for transformation

@shmoradimsshmoradimsApr 4, 2019

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This pipeline uses two columns for transformation [](start = 38, length = 49)

i think this is clearer: this pipeline transform two columns using the same options.

just want to make sure it's clear that columns are transformed independently and are not mixed #Resolved

@shmoradimsshmoradims left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

:shipit:

@abgoswam
abgoswam requested a review from rogancarrApril 4, 2019 21:27
// We define a MutualInformationFeatureSelectingEstimator that selects the top k slots in a feature
// vector based on highest mutual information between that slot and a specified label.

var pipeline = mlContext.Transforms.FeatureSelection.SelectFeaturesBasedOnMutualInformation(

@abgoswamabgoswamApr 4, 2019

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

SelectFeaturesBasedOnMutualInformation [](start = 65, length = 38)

this sample is only for API reference, so small in-memory dataset suffices for this example.

we should have a "tutorial" to show the computation of MI..something along the lines of

https://www.researchgate.net/post/How_can_i_calculate_Mutual_Information_theory_from_a_simple_dataset

@sfilipisfilipiApr 4, 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.

+1 @natke was looking into how this transform works.


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

foreach (var item in convertedData)
Console.WriteLine("{0}\t\t\t{1}", string.Join("\t", item.NumericVector), string.Join("\t", item.StringVector));
// 4 NaN 6 A WA Male
// 4 5 6 A Female

@sfilipisfilipiApr 4, 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.

 [](start = 63, length = 5)

align for just here.. no need to make it match exactly to the output and have it looked tabbing off. #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.

or is it a separate column?

It helps to print the headers.


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

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

the alignment here seems good to me... for text this slot is empty or null ..

not sure if u meant something else


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


// We will use the SelectFeaturesBasedOnCount to retain only those slots which have at least 'count' non-default values per slot.

// Usage on numeric column.

@sfilipisfilipiApr 4, 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.

remove space #Resolved

// The pipeline can then be trained, using .Fit(), and the resulting transformer can be used to transform data.
var transformedData = pipeline.Fit(data).Transform(data);

Console.WriteLine("Contents of column 'NumericVector'");

@sfilipisfilipiApr 4, 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.

Console.WriteLine("Contents of column 'NumericVector'"); [](start = 11, length = 57)

convert to just comment. #Resolved

Console.Write($"{row[i]}\t");
Console.WriteLine();
}
// 4 6

@sfilipisfilipiApr 4, 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.

// 4 6 [](start = 12, length = 12)

headers #Resolved

for (var i = 0; i < row.Length; i++)
Console.Write($"{row[i]}\t");
Console.WriteLine();
}

@sfilipisfilipiApr 4, 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.

would it polish it a bit if you made a little helper for this, since it is being used twice? #Resolved

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

one of then is a float[] while the other is string[] .. did not want to over-engineer this...

is there anything specific you had in mind, or can we keep it as is ?


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

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.

object :)


In reply to: 272394600 [](ancestors = 272394600,272392068)


Console.WriteLine("Contents of two columns 'NumericVector' and 'StringVector'.");
foreach (var item in convertedData)
Console.WriteLine("{0}\t\t\t{1}", string.Join("\t", item.NumericVector), string.Join("\t", item.StringVector));

@sfilipisfilipiApr 4, 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.

\t [](start = 63, length = 2)

think for vectors we are using comma ',' as the separator. #Resolved


// Usage on text column.
pipeline = mlContext.Transforms.FeatureSelection.SelectFeaturesBasedOnCount(
outputColumnName: "StringVector", count: 3);

@sfilipisfilipiApr 4, 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.

I'd probably append to the previous pipeline, and show the prints once. Compacts the sample. #Resolved

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

sounds good. will do.


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


Console.WriteLine("Contents of two columns 'NumericVector' and 'StringVector'.");
foreach (var item in rawData)
Console.WriteLine("{0}\t\t\t{1}", string.Join("\t", item.NumericVector), string.Join("\t", item.StringVector));

@sfilipisfilipiApr 4, 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.

\t [](start = 63, length = 2)

same comment, ',' #Resolved


Console.WriteLine("Contents of column 'NumericVector'");
PrintDataColumn(transformedData, "NumericVector");
// 4 0

@sfilipisfilipiApr 4, 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.

4 [](start = 15, length = 1)

Curious, why is it dropping 6, but keeping 4? It is not obvious to me. Is it because slotsInOutput is 2? A comment about that might help. #Pending

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

we need to improve this once we have found a better sample. i have noted this in the issue #1209


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

@sfilipisfilipi 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:


Console.WriteLine("Contents of columns 'Label', 'NumericVectorA' and 'NumericVectorB'.");
foreach (var item in rawData)
Console.WriteLine("{0}\t\t{1}\t\t{2}", item.Label, string.Join(" ", item.NumericVectorA), string.Join(" ", item.NumericVectorB));

@sfilipisfilipiApr 4, 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.

[](start = 80, length = 1)

',' #Resolved

var rawData = GetData();
var data = mlContext.Data.LoadFromEnumerable(rawData);

var convertedData = mlContext.Data.CreateEnumerable<InputData>(data, true);

@zeahmedzeahmedApr 4, 2019

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.

convertedData [](start = 16, length = 13)

Why do you convert that back to Enumerable? rawData is already there. #Resolved

foreach (var item in convertedData)
Console.WriteLine("{0}\t\t{1}", string.Join(" ", item.NumericVectorA), string.Join(" ", item.NumericVectorB));

// Here, we see SelectFeaturesBasedOnMutualInformation selected 4 slots.

@sfilipisfilipiApr 4, 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.

4 slot [](start = 76, length = 6)

the 4 slots that had most in common with the respective value in the Label column, maybe? #Resolved

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

yes, these 4 slots carried the most MI with Label.... we should have a better tutorial for this though


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

@sfilipisfilipi 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:

@rogancarrrogancarr left a comment

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.

:shipit:

@abgoswam
abgoswam merged commit 8130567 into dotnet:masterApr 5, 2019
abgoswam added a commit to abgoswam/machinelearning that referenced this pull request Apr 5, 2019
* samples for FeatureSelection transform estimators
* fix review comments
* fix review comments
* review comments
* take care of review comments
* fix copy paste output error
@ghostghost locked as resolved and limited conversation to collaborators Mar 23, 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.

6 participants

@abgoswam@Ivanidzo4ka@shmoradims@sfilipi@rogancarr@zeahmed
, '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

Samples for FeatureSelection transform estimators - #3184

Merged
abgoswam merged 6 commits into
dotnet:masterfrom
abgoswam:abgoswam/featureselection_samples
Apr 5, 2019
Merged

Samples for FeatureSelection transform estimators#3184
abgoswam merged 6 commits into
dotnet:masterfrom
abgoswam:abgoswam/featureselection_samples

Conversation

@abgoswam

Copy link
Copy Markdown
Member

Towards #1209

The PR makes the following changes

  • Adds sample for the SelectFeaturesBasedOnCount transform estimator.
  • Adds sample for the SelectFeaturesBasedOnMutualInformation transform estimator.
  • Delete old sample.

@codecov

codecovBot commented Apr 3, 2019

Copy link
Copy Markdown

Codecov Report

Merging #3184 into master will increase coverage by 0.06%.
The diff coverage is n/a.

@@ Coverage Diff @@## master #3184 +/- ##
==========================================
+ Coverage 72.54% 72.6% +0.06% 
==========================================
Files 807 807 Lines 144774 145077 +303 Branches 16208 16213 +5 ==========================================
+ Hits 105021 105332 +311 + Misses 35339 35326 -13 - Partials 4414 4419 +5
FlagCoverage Δ
#Debug72.6% <ø> (+0.06%)⬆️
#production68.14% <ø> (+0.01%)⬆️
#test88.92% <ø> (+0.09%)⬆️
Impacted FilesCoverage Δ
...Microsoft.ML.Transforms/FeatureSelectionCatalog.cs60% <ø> (ø)⬆️
...c/Microsoft.ML.FastTree/Utils/ThreadTaskManager.cs79.48% <0%> (-20.52%)⬇️
src/Microsoft.ML.DataView/KeyDataViewType.cs74.57% <0%> (-3.76%)⬇️
src/Microsoft.ML.Maml/MAML.cs24.75% <0%> (-1.46%)⬇️
src/Microsoft.ML.Transforms/Text/LdaTransform.cs89.26% <0%> (-0.63%)⬇️
src/Microsoft.ML.Data/Transforms/ValueMapping.cs84.26% <0%> (-0.14%)⬇️
test/Microsoft.ML.Tests/ImagesTests.cs98.69% <0%> (-0.13%)⬇️
src/Microsoft.ML.Transforms/CategoricalCatalog.cs68.42% <0%> (ø)⬆️
...Microsoft.ML.Tests/Transformers/NormalizerTests.cs100% <0%> (ø)⬆️
...crosoft.ML.Tests/Transformers/ValueMappingTests.cs100% <0%> (ø)⬆️
... and 7 more

/// <format type="text/markdown">
/// <![CDATA[
/// [!code-csharp[SelectFeaturesBasedOnMutualInformation](~/../docs/samples/docs/samples/Microsoft.ML.Samples/Dynamic/FeatureSelectionTransform.cs?range=1-4,10-121)]
/// [!code-csharp[SelectFeaturesBasedOnMutualInformation](~/../docs/samples/docs/samples/Microsoft.ML.Samples/Dynamic/SelectFeaturesBasedOnMutualInformation.cs)]

@sfilipisfilipiApr 3, 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.

Dynamic/S [](start = 118, length = 9)

Dynamic/Transforms/ #Resolved

/// <example>
/// <format type="text/markdown">
/// <![CDATA[
/// [!code-csharp[SelectFeaturesBasedOnMutualInformation](~/../docs/samples/docs/samples/Microsoft.ML.Samples/Dynamic/SelectFeaturesBasedOnMutualInformation.cs)]

@sfilipisfilipiApr 3, 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.

Dynamic [](start = 118, length = 7)

Dynamic/Transforms/ #Resolved

{
// Downloading a classification dataset from github.com/dotnet/machinelearning.
// It will be stored in the same path as the executable
string dataFilePath = SamplesUtils.DatasetUtils.DownloadBreastCancerDataset();

@sfilipisfilipiApr 3, 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.

string dataFilePath = SamplesUtils.DatasetUtils.DownloadBreastCancerDataset(); [](start = 9, length = 81)

can it be done with a small in memory dataset? #Resolved

pipeline = mlContext.Transforms.FeatureSelection.SelectFeaturesBasedOnMutualInformation(
new InputOutputColumnPair[] { new InputOutputColumnPair("GroupB"), new InputOutputColumnPair("GroupC") },
labelColumnName: "Label",
slotsInOutput:4);

@sfilipisfilipiApr 3, 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.

slotsInOutput:4 [](start = 16, length = 15)

one line comment about what this does. #Resolved

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

comment in line 28 should clarify this


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

// 3 7 1
// 3 1 1

// Second, we define the transformations that we apply on the data. Remember that an Estimator does not transform data

@sfilipisfilipiApr 3, 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.

Remember [](start = 80, length = 8)

remove #Resolved

{
public float[] GroupB { get; set; }

public float[] GroupC { get; set; }

@sfilipisfilipiApr 3, 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.

space #Resolved

string dataFilePath = SamplesUtils.DatasetUtils.DownloadBreastCancerDataset();

// Data Preview
// 1. Label 0=benign, 1=malignant

@Ivanidzo4kaIvanidzo4kaApr 3, 2019

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.

 [](start = 26, length = 7)

He use tabs! Where is my pitchfork! #Resolved

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

:) lol


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

// In this example we define a CountFeatureSelectingEstimator, that selects slots in a feature vector that have more non-default
// values than the specified count. This transformation can be used to remove slots with too many missing values.
var pipeline = mlContext.Transforms.FeatureSelection.SelectFeaturesBasedOnCount(
outputColumnName: "FeaturesSelectedGroupB", inputColumnName: "GroupB", count: 695);

@Ivanidzo4kaIvanidzo4kaApr 3, 2019

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.

695 [](start = 94, length = 3)

Where this number coming from?
#Resolved

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

comment in line 29 should clarify this now, also the in-memory example should make it more intuitive


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

// 5 7
// 1 2
// 1 3
// 3 2

@Ivanidzo4kaIvanidzo4kaApr 3, 2019

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.

with current data it's not obvious at all. Can we switch to some small in memory sample rather than unknown dataset? #Resolved

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

true. moved over to use a small in-memory dataset instead


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

// We will use the SelectFeaturesBasedOnCount transform estimator, to retain only those slots which have
// at least 'count' non-default values per slot.

// Multi column example : This pipeline uses two columns for transformation

@shmoradimsshmoradimsApr 4, 2019

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This pipeline uses two columns for transformation [](start = 38, length = 49)

i think this is clearer: this pipeline transform two columns using the same options.

just want to make sure it's clear that columns are transformed independently and are not mixed #Resolved

@shmoradimsshmoradims left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

:shipit:

@abgoswam
abgoswam requested a review from rogancarrApril 4, 2019 21:27
// We define a MutualInformationFeatureSelectingEstimator that selects the top k slots in a feature
// vector based on highest mutual information between that slot and a specified label.

var pipeline = mlContext.Transforms.FeatureSelection.SelectFeaturesBasedOnMutualInformation(

@abgoswamabgoswamApr 4, 2019

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

SelectFeaturesBasedOnMutualInformation [](start = 65, length = 38)

this sample is only for API reference, so small in-memory dataset suffices for this example.

we should have a "tutorial" to show the computation of MI..something along the lines of

https://www.researchgate.net/post/How_can_i_calculate_Mutual_Information_theory_from_a_simple_dataset

@sfilipisfilipiApr 4, 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.

+1 @natke was looking into how this transform works.


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

foreach (var item in convertedData)
Console.WriteLine("{0}\t\t\t{1}", string.Join("\t", item.NumericVector), string.Join("\t", item.StringVector));
// 4 NaN 6 A WA Male
// 4 5 6 A Female

@sfilipisfilipiApr 4, 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.

 [](start = 63, length = 5)

align for just here.. no need to make it match exactly to the output and have it looked tabbing off. #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.

or is it a separate column?

It helps to print the headers.


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

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

the alignment here seems good to me... for text this slot is empty or null ..

not sure if u meant something else


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


// We will use the SelectFeaturesBasedOnCount to retain only those slots which have at least 'count' non-default values per slot.

// Usage on numeric column.

@sfilipisfilipiApr 4, 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.

remove space #Resolved

// The pipeline can then be trained, using .Fit(), and the resulting transformer can be used to transform data.
var transformedData = pipeline.Fit(data).Transform(data);

Console.WriteLine("Contents of column 'NumericVector'");

@sfilipisfilipiApr 4, 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.

Console.WriteLine("Contents of column 'NumericVector'"); [](start = 11, length = 57)

convert to just comment. #Resolved

Console.Write($"{row[i]}\t");
Console.WriteLine();
}
// 4 6

@sfilipisfilipiApr 4, 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.

// 4 6 [](start = 12, length = 12)

headers #Resolved

for (var i = 0; i < row.Length; i++)
Console.Write($"{row[i]}\t");
Console.WriteLine();
}

@sfilipisfilipiApr 4, 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.

would it polish it a bit if you made a little helper for this, since it is being used twice? #Resolved

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

one of then is a float[] while the other is string[] .. did not want to over-engineer this...

is there anything specific you had in mind, or can we keep it as is ?


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

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.

object :)


In reply to: 272394600 [](ancestors = 272394600,272392068)


Console.WriteLine("Contents of two columns 'NumericVector' and 'StringVector'.");
foreach (var item in convertedData)
Console.WriteLine("{0}\t\t\t{1}", string.Join("\t", item.NumericVector), string.Join("\t", item.StringVector));

@sfilipisfilipiApr 4, 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.

\t [](start = 63, length = 2)

think for vectors we are using comma ',' as the separator. #Resolved


// Usage on text column.
pipeline = mlContext.Transforms.FeatureSelection.SelectFeaturesBasedOnCount(
outputColumnName: "StringVector", count: 3);

@sfilipisfilipiApr 4, 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.

I'd probably append to the previous pipeline, and show the prints once. Compacts the sample. #Resolved

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

sounds good. will do.


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


Console.WriteLine("Contents of two columns 'NumericVector' and 'StringVector'.");
foreach (var item in rawData)
Console.WriteLine("{0}\t\t\t{1}", string.Join("\t", item.NumericVector), string.Join("\t", item.StringVector));

@sfilipisfilipiApr 4, 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.

\t [](start = 63, length = 2)

same comment, ',' #Resolved


Console.WriteLine("Contents of column 'NumericVector'");
PrintDataColumn(transformedData, "NumericVector");
// 4 0

@sfilipisfilipiApr 4, 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.

4 [](start = 15, length = 1)

Curious, why is it dropping 6, but keeping 4? It is not obvious to me. Is it because slotsInOutput is 2? A comment about that might help. #Pending

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

we need to improve this once we have found a better sample. i have noted this in the issue #1209


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

@sfilipisfilipi 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:


Console.WriteLine("Contents of columns 'Label', 'NumericVectorA' and 'NumericVectorB'.");
foreach (var item in rawData)
Console.WriteLine("{0}\t\t{1}\t\t{2}", item.Label, string.Join(" ", item.NumericVectorA), string.Join(" ", item.NumericVectorB));

@sfilipisfilipiApr 4, 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.

[](start = 80, length = 1)

',' #Resolved

var rawData = GetData();
var data = mlContext.Data.LoadFromEnumerable(rawData);

var convertedData = mlContext.Data.CreateEnumerable<InputData>(data, true);

@zeahmedzeahmedApr 4, 2019

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.

convertedData [](start = 16, length = 13)

Why do you convert that back to Enumerable? rawData is already there. #Resolved

foreach (var item in convertedData)
Console.WriteLine("{0}\t\t{1}", string.Join(" ", item.NumericVectorA), string.Join(" ", item.NumericVectorB));

// Here, we see SelectFeaturesBasedOnMutualInformation selected 4 slots.

@sfilipisfilipiApr 4, 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.

4 slot [](start = 76, length = 6)

the 4 slots that had most in common with the respective value in the Label column, maybe? #Resolved

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

yes, these 4 slots carried the most MI with Label.... we should have a better tutorial for this though


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

@sfilipisfilipi 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:

@rogancarrrogancarr left a comment

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.

:shipit:

@abgoswam
abgoswam merged commit 8130567 into dotnet:masterApr 5, 2019
abgoswam added a commit to abgoswam/machinelearning that referenced this pull request Apr 5, 2019
* samples for FeatureSelection transform estimators
* fix review comments
* fix review comments
* review comments
* take care of review comments
* fix copy paste output error
@ghostghost locked as resolved and limited conversation to collaborators Mar 23, 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.

6 participants

@abgoswam@Ivanidzo4ka@shmoradims@sfilipi@rogancarr@zeahmed
, '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

Samples for FeatureSelection transform estimators - #3184

Merged
abgoswam merged 6 commits into
dotnet:masterfrom
abgoswam:abgoswam/featureselection_samples
Apr 5, 2019
Merged

Samples for FeatureSelection transform estimators#3184
abgoswam merged 6 commits into
dotnet:masterfrom
abgoswam:abgoswam/featureselection_samples

Conversation

@abgoswam

Copy link
Copy Markdown
Member

Towards #1209

The PR makes the following changes

  • Adds sample for the SelectFeaturesBasedOnCount transform estimator.
  • Adds sample for the SelectFeaturesBasedOnMutualInformation transform estimator.
  • Delete old sample.

@codecov

codecovBot commented Apr 3, 2019

Copy link
Copy Markdown

Codecov Report

Merging #3184 into master will increase coverage by 0.06%.
The diff coverage is n/a.

@@ Coverage Diff @@## master #3184 +/- ##
==========================================
+ Coverage 72.54% 72.6% +0.06% 
==========================================
Files 807 807 Lines 144774 145077 +303 Branches 16208 16213 +5 ==========================================
+ Hits 105021 105332 +311 + Misses 35339 35326 -13 - Partials 4414 4419 +5
FlagCoverage Δ
#Debug72.6% <ø> (+0.06%)⬆️
#production68.14% <ø> (+0.01%)⬆️
#test88.92% <ø> (+0.09%)⬆️
Impacted FilesCoverage Δ
...Microsoft.ML.Transforms/FeatureSelectionCatalog.cs60% <ø> (ø)⬆️
...c/Microsoft.ML.FastTree/Utils/ThreadTaskManager.cs79.48% <0%> (-20.52%)⬇️
src/Microsoft.ML.DataView/KeyDataViewType.cs74.57% <0%> (-3.76%)⬇️
src/Microsoft.ML.Maml/MAML.cs24.75% <0%> (-1.46%)⬇️
src/Microsoft.ML.Transforms/Text/LdaTransform.cs89.26% <0%> (-0.63%)⬇️
src/Microsoft.ML.Data/Transforms/ValueMapping.cs84.26% <0%> (-0.14%)⬇️
test/Microsoft.ML.Tests/ImagesTests.cs98.69% <0%> (-0.13%)⬇️
src/Microsoft.ML.Transforms/CategoricalCatalog.cs68.42% <0%> (ø)⬆️
...Microsoft.ML.Tests/Transformers/NormalizerTests.cs100% <0%> (ø)⬆️
...crosoft.ML.Tests/Transformers/ValueMappingTests.cs100% <0%> (ø)⬆️
... and 7 more

/// <format type="text/markdown">
/// <![CDATA[
/// [!code-csharp[SelectFeaturesBasedOnMutualInformation](~/../docs/samples/docs/samples/Microsoft.ML.Samples/Dynamic/FeatureSelectionTransform.cs?range=1-4,10-121)]
/// [!code-csharp[SelectFeaturesBasedOnMutualInformation](~/../docs/samples/docs/samples/Microsoft.ML.Samples/Dynamic/SelectFeaturesBasedOnMutualInformation.cs)]

@sfilipisfilipiApr 3, 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.

Dynamic/S [](start = 118, length = 9)

Dynamic/Transforms/ #Resolved

/// <example>
/// <format type="text/markdown">
/// <![CDATA[
/// [!code-csharp[SelectFeaturesBasedOnMutualInformation](~/../docs/samples/docs/samples/Microsoft.ML.Samples/Dynamic/SelectFeaturesBasedOnMutualInformation.cs)]

@sfilipisfilipiApr 3, 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.

Dynamic [](start = 118, length = 7)

Dynamic/Transforms/ #Resolved

{
// Downloading a classification dataset from github.com/dotnet/machinelearning.
// It will be stored in the same path as the executable
string dataFilePath = SamplesUtils.DatasetUtils.DownloadBreastCancerDataset();

@sfilipisfilipiApr 3, 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.

string dataFilePath = SamplesUtils.DatasetUtils.DownloadBreastCancerDataset(); [](start = 9, length = 81)

can it be done with a small in memory dataset? #Resolved

pipeline = mlContext.Transforms.FeatureSelection.SelectFeaturesBasedOnMutualInformation(
new InputOutputColumnPair[] { new InputOutputColumnPair("GroupB"), new InputOutputColumnPair("GroupC") },
labelColumnName: "Label",
slotsInOutput:4);

@sfilipisfilipiApr 3, 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.

slotsInOutput:4 [](start = 16, length = 15)

one line comment about what this does. #Resolved

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

comment in line 28 should clarify this


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

// 3 7 1
// 3 1 1

// Second, we define the transformations that we apply on the data. Remember that an Estimator does not transform data

@sfilipisfilipiApr 3, 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.

Remember [](start = 80, length = 8)

remove #Resolved

{
public float[] GroupB { get; set; }

public float[] GroupC { get; set; }

@sfilipisfilipiApr 3, 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.

space #Resolved

string dataFilePath = SamplesUtils.DatasetUtils.DownloadBreastCancerDataset();

// Data Preview
// 1. Label 0=benign, 1=malignant

@Ivanidzo4kaIvanidzo4kaApr 3, 2019

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.

 [](start = 26, length = 7)

He use tabs! Where is my pitchfork! #Resolved

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

:) lol


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

// In this example we define a CountFeatureSelectingEstimator, that selects slots in a feature vector that have more non-default
// values than the specified count. This transformation can be used to remove slots with too many missing values.
var pipeline = mlContext.Transforms.FeatureSelection.SelectFeaturesBasedOnCount(
outputColumnName: "FeaturesSelectedGroupB", inputColumnName: "GroupB", count: 695);

@Ivanidzo4kaIvanidzo4kaApr 3, 2019

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.

695 [](start = 94, length = 3)

Where this number coming from?
#Resolved

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

comment in line 29 should clarify this now, also the in-memory example should make it more intuitive


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

// 5 7
// 1 2
// 1 3
// 3 2

@Ivanidzo4kaIvanidzo4kaApr 3, 2019

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.

with current data it's not obvious at all. Can we switch to some small in memory sample rather than unknown dataset? #Resolved

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

true. moved over to use a small in-memory dataset instead


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

// We will use the SelectFeaturesBasedOnCount transform estimator, to retain only those slots which have
// at least 'count' non-default values per slot.

// Multi column example : This pipeline uses two columns for transformation

@shmoradimsshmoradimsApr 4, 2019

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This pipeline uses two columns for transformation [](start = 38, length = 49)

i think this is clearer: this pipeline transform two columns using the same options.

just want to make sure it's clear that columns are transformed independently and are not mixed #Resolved

@shmoradimsshmoradims left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

:shipit:

@abgoswam
abgoswam requested a review from rogancarrApril 4, 2019 21:27
// We define a MutualInformationFeatureSelectingEstimator that selects the top k slots in a feature
// vector based on highest mutual information between that slot and a specified label.

var pipeline = mlContext.Transforms.FeatureSelection.SelectFeaturesBasedOnMutualInformation(

@abgoswamabgoswamApr 4, 2019

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

SelectFeaturesBasedOnMutualInformation [](start = 65, length = 38)

this sample is only for API reference, so small in-memory dataset suffices for this example.

we should have a "tutorial" to show the computation of MI..something along the lines of

https://www.researchgate.net/post/How_can_i_calculate_Mutual_Information_theory_from_a_simple_dataset

@sfilipisfilipiApr 4, 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.

+1 @natke was looking into how this transform works.


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

foreach (var item in convertedData)
Console.WriteLine("{0}\t\t\t{1}", string.Join("\t", item.NumericVector), string.Join("\t", item.StringVector));
// 4 NaN 6 A WA Male
// 4 5 6 A Female

@sfilipisfilipiApr 4, 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.

 [](start = 63, length = 5)

align for just here.. no need to make it match exactly to the output and have it looked tabbing off. #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.

or is it a separate column?

It helps to print the headers.


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

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

the alignment here seems good to me... for text this slot is empty or null ..

not sure if u meant something else


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


// We will use the SelectFeaturesBasedOnCount to retain only those slots which have at least 'count' non-default values per slot.

// Usage on numeric column.

@sfilipisfilipiApr 4, 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.

remove space #Resolved

// The pipeline can then be trained, using .Fit(), and the resulting transformer can be used to transform data.
var transformedData = pipeline.Fit(data).Transform(data);

Console.WriteLine("Contents of column 'NumericVector'");

@sfilipisfilipiApr 4, 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.

Console.WriteLine("Contents of column 'NumericVector'"); [](start = 11, length = 57)

convert to just comment. #Resolved

Console.Write($"{row[i]}\t");
Console.WriteLine();
}
// 4 6

@sfilipisfilipiApr 4, 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.

// 4 6 [](start = 12, length = 12)

headers #Resolved

for (var i = 0; i < row.Length; i++)
Console.Write($"{row[i]}\t");
Console.WriteLine();
}

@sfilipisfilipiApr 4, 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.

would it polish it a bit if you made a little helper for this, since it is being used twice? #Resolved

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

one of then is a float[] while the other is string[] .. did not want to over-engineer this...

is there anything specific you had in mind, or can we keep it as is ?


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

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.

object :)


In reply to: 272394600 [](ancestors = 272394600,272392068)


Console.WriteLine("Contents of two columns 'NumericVector' and 'StringVector'.");
foreach (var item in convertedData)
Console.WriteLine("{0}\t\t\t{1}", string.Join("\t", item.NumericVector), string.Join("\t", item.StringVector));

@sfilipisfilipiApr 4, 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.

\t [](start = 63, length = 2)

think for vectors we are using comma ',' as the separator. #Resolved


// Usage on text column.
pipeline = mlContext.Transforms.FeatureSelection.SelectFeaturesBasedOnCount(
outputColumnName: "StringVector", count: 3);

@sfilipisfilipiApr 4, 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.

I'd probably append to the previous pipeline, and show the prints once. Compacts the sample. #Resolved

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

sounds good. will do.


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


Console.WriteLine("Contents of two columns 'NumericVector' and 'StringVector'.");
foreach (var item in rawData)
Console.WriteLine("{0}\t\t\t{1}", string.Join("\t", item.NumericVector), string.Join("\t", item.StringVector));

@sfilipisfilipiApr 4, 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.

\t [](start = 63, length = 2)

same comment, ',' #Resolved


Console.WriteLine("Contents of column 'NumericVector'");
PrintDataColumn(transformedData, "NumericVector");
// 4 0

@sfilipisfilipiApr 4, 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.

4 [](start = 15, length = 1)

Curious, why is it dropping 6, but keeping 4? It is not obvious to me. Is it because slotsInOutput is 2? A comment about that might help. #Pending

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

we need to improve this once we have found a better sample. i have noted this in the issue #1209


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

@sfilipisfilipi 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:


Console.WriteLine("Contents of columns 'Label', 'NumericVectorA' and 'NumericVectorB'.");
foreach (var item in rawData)
Console.WriteLine("{0}\t\t{1}\t\t{2}", item.Label, string.Join(" ", item.NumericVectorA), string.Join(" ", item.NumericVectorB));

@sfilipisfilipiApr 4, 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.

[](start = 80, length = 1)

',' #Resolved

var rawData = GetData();
var data = mlContext.Data.LoadFromEnumerable(rawData);

var convertedData = mlContext.Data.CreateEnumerable<InputData>(data, true);

@zeahmedzeahmedApr 4, 2019

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.

convertedData [](start = 16, length = 13)

Why do you convert that back to Enumerable? rawData is already there. #Resolved

foreach (var item in convertedData)
Console.WriteLine("{0}\t\t{1}", string.Join(" ", item.NumericVectorA), string.Join(" ", item.NumericVectorB));

// Here, we see SelectFeaturesBasedOnMutualInformation selected 4 slots.

@sfilipisfilipiApr 4, 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.

4 slot [](start = 76, length = 6)

the 4 slots that had most in common with the respective value in the Label column, maybe? #Resolved

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

yes, these 4 slots carried the most MI with Label.... we should have a better tutorial for this though


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

@sfilipisfilipi 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:

@rogancarrrogancarr left a comment

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.

:shipit:

@abgoswam
abgoswam merged commit 8130567 into dotnet:masterApr 5, 2019
abgoswam added a commit to abgoswam/machinelearning that referenced this pull request Apr 5, 2019
* samples for FeatureSelection transform estimators
* fix review comments
* fix review comments
* review comments
* take care of review comments
* fix copy paste output error
@ghostghost locked as resolved and limited conversation to collaborators Mar 23, 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.

6 participants

@abgoswam@Ivanidzo4ka@shmoradims@sfilipi@rogancarr@zeahmed
, '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

Samples for FeatureSelection transform estimators - #3184

Merged
abgoswam merged 6 commits into
dotnet:masterfrom
abgoswam:abgoswam/featureselection_samples
Apr 5, 2019
Merged

Samples for FeatureSelection transform estimators#3184
abgoswam merged 6 commits into
dotnet:masterfrom
abgoswam:abgoswam/featureselection_samples

Conversation

@abgoswam

Copy link
Copy Markdown
Member

Towards #1209

The PR makes the following changes

  • Adds sample for the SelectFeaturesBasedOnCount transform estimator.
  • Adds sample for the SelectFeaturesBasedOnMutualInformation transform estimator.
  • Delete old sample.

@codecov

codecovBot commented Apr 3, 2019

Copy link
Copy Markdown

Codecov Report

Merging #3184 into master will increase coverage by 0.06%.
The diff coverage is n/a.

@@ Coverage Diff @@## master #3184 +/- ##
==========================================
+ Coverage 72.54% 72.6% +0.06% 
==========================================
Files 807 807 Lines 144774 145077 +303 Branches 16208 16213 +5 ==========================================
+ Hits 105021 105332 +311 + Misses 35339 35326 -13 - Partials 4414 4419 +5
FlagCoverage Δ
#Debug72.6% <ø> (+0.06%)⬆️
#production68.14% <ø> (+0.01%)⬆️
#test88.92% <ø> (+0.09%)⬆️
Impacted FilesCoverage Δ
...Microsoft.ML.Transforms/FeatureSelectionCatalog.cs60% <ø> (ø)⬆️
...c/Microsoft.ML.FastTree/Utils/ThreadTaskManager.cs79.48% <0%> (-20.52%)⬇️
src/Microsoft.ML.DataView/KeyDataViewType.cs74.57% <0%> (-3.76%)⬇️
src/Microsoft.ML.Maml/MAML.cs24.75% <0%> (-1.46%)⬇️
src/Microsoft.ML.Transforms/Text/LdaTransform.cs89.26% <0%> (-0.63%)⬇️
src/Microsoft.ML.Data/Transforms/ValueMapping.cs84.26% <0%> (-0.14%)⬇️
test/Microsoft.ML.Tests/ImagesTests.cs98.69% <0%> (-0.13%)⬇️
src/Microsoft.ML.Transforms/CategoricalCatalog.cs68.42% <0%> (ø)⬆️
...Microsoft.ML.Tests/Transformers/NormalizerTests.cs100% <0%> (ø)⬆️
...crosoft.ML.Tests/Transformers/ValueMappingTests.cs100% <0%> (ø)⬆️
... and 7 more

/// <format type="text/markdown">
/// <![CDATA[
/// [!code-csharp[SelectFeaturesBasedOnMutualInformation](~/../docs/samples/docs/samples/Microsoft.ML.Samples/Dynamic/FeatureSelectionTransform.cs?range=1-4,10-121)]
/// [!code-csharp[SelectFeaturesBasedOnMutualInformation](~/../docs/samples/docs/samples/Microsoft.ML.Samples/Dynamic/SelectFeaturesBasedOnMutualInformation.cs)]

@sfilipisfilipiApr 3, 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.

Dynamic/S [](start = 118, length = 9)

Dynamic/Transforms/ #Resolved

/// <example>
/// <format type="text/markdown">
/// <![CDATA[
/// [!code-csharp[SelectFeaturesBasedOnMutualInformation](~/../docs/samples/docs/samples/Microsoft.ML.Samples/Dynamic/SelectFeaturesBasedOnMutualInformation.cs)]

@sfilipisfilipiApr 3, 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.

Dynamic [](start = 118, length = 7)

Dynamic/Transforms/ #Resolved

{
// Downloading a classification dataset from github.com/dotnet/machinelearning.
// It will be stored in the same path as the executable
string dataFilePath = SamplesUtils.DatasetUtils.DownloadBreastCancerDataset();

@sfilipisfilipiApr 3, 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.

string dataFilePath = SamplesUtils.DatasetUtils.DownloadBreastCancerDataset(); [](start = 9, length = 81)

can it be done with a small in memory dataset? #Resolved

pipeline = mlContext.Transforms.FeatureSelection.SelectFeaturesBasedOnMutualInformation(
new InputOutputColumnPair[] { new InputOutputColumnPair("GroupB"), new InputOutputColumnPair("GroupC") },
labelColumnName: "Label",
slotsInOutput:4);

@sfilipisfilipiApr 3, 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.

slotsInOutput:4 [](start = 16, length = 15)

one line comment about what this does. #Resolved

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

comment in line 28 should clarify this


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

// 3 7 1
// 3 1 1

// Second, we define the transformations that we apply on the data. Remember that an Estimator does not transform data

@sfilipisfilipiApr 3, 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.

Remember [](start = 80, length = 8)

remove #Resolved

{
public float[] GroupB { get; set; }

public float[] GroupC { get; set; }

@sfilipisfilipiApr 3, 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.

space #Resolved

string dataFilePath = SamplesUtils.DatasetUtils.DownloadBreastCancerDataset();

// Data Preview
// 1. Label 0=benign, 1=malignant

@Ivanidzo4kaIvanidzo4kaApr 3, 2019

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.

 [](start = 26, length = 7)

He use tabs! Where is my pitchfork! #Resolved

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

:) lol


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

// In this example we define a CountFeatureSelectingEstimator, that selects slots in a feature vector that have more non-default
// values than the specified count. This transformation can be used to remove slots with too many missing values.
var pipeline = mlContext.Transforms.FeatureSelection.SelectFeaturesBasedOnCount(
outputColumnName: "FeaturesSelectedGroupB", inputColumnName: "GroupB", count: 695);

@Ivanidzo4kaIvanidzo4kaApr 3, 2019

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.

695 [](start = 94, length = 3)

Where this number coming from?
#Resolved

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

comment in line 29 should clarify this now, also the in-memory example should make it more intuitive


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

// 5 7
// 1 2
// 1 3
// 3 2

@Ivanidzo4kaIvanidzo4kaApr 3, 2019

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.

with current data it's not obvious at all. Can we switch to some small in memory sample rather than unknown dataset? #Resolved

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

true. moved over to use a small in-memory dataset instead


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

// We will use the SelectFeaturesBasedOnCount transform estimator, to retain only those slots which have
// at least 'count' non-default values per slot.

// Multi column example : This pipeline uses two columns for transformation

@shmoradimsshmoradimsApr 4, 2019

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This pipeline uses two columns for transformation [](start = 38, length = 49)

i think this is clearer: this pipeline transform two columns using the same options.

just want to make sure it's clear that columns are transformed independently and are not mixed #Resolved

@shmoradimsshmoradims left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

:shipit:

@abgoswam
abgoswam requested a review from rogancarrApril 4, 2019 21:27
// We define a MutualInformationFeatureSelectingEstimator that selects the top k slots in a feature
// vector based on highest mutual information between that slot and a specified label.

var pipeline = mlContext.Transforms.FeatureSelection.SelectFeaturesBasedOnMutualInformation(

@abgoswamabgoswamApr 4, 2019

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

SelectFeaturesBasedOnMutualInformation [](start = 65, length = 38)

this sample is only for API reference, so small in-memory dataset suffices for this example.

we should have a "tutorial" to show the computation of MI..something along the lines of

https://www.researchgate.net/post/How_can_i_calculate_Mutual_Information_theory_from_a_simple_dataset

@sfilipisfilipiApr 4, 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.

+1 @natke was looking into how this transform works.


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

foreach (var item in convertedData)
Console.WriteLine("{0}\t\t\t{1}", string.Join("\t", item.NumericVector), string.Join("\t", item.StringVector));
// 4 NaN 6 A WA Male
// 4 5 6 A Female

@sfilipisfilipiApr 4, 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.

 [](start = 63, length = 5)

align for just here.. no need to make it match exactly to the output and have it looked tabbing off. #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.

or is it a separate column?

It helps to print the headers.


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

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

the alignment here seems good to me... for text this slot is empty or null ..

not sure if u meant something else


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


// We will use the SelectFeaturesBasedOnCount to retain only those slots which have at least 'count' non-default values per slot.

// Usage on numeric column.

@sfilipisfilipiApr 4, 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.

remove space #Resolved

// The pipeline can then be trained, using .Fit(), and the resulting transformer can be used to transform data.
var transformedData = pipeline.Fit(data).Transform(data);

Console.WriteLine("Contents of column 'NumericVector'");

@sfilipisfilipiApr 4, 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.

Console.WriteLine("Contents of column 'NumericVector'"); [](start = 11, length = 57)

convert to just comment. #Resolved

Console.Write($"{row[i]}\t");
Console.WriteLine();
}
// 4 6

@sfilipisfilipiApr 4, 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.

// 4 6 [](start = 12, length = 12)

headers #Resolved

for (var i = 0; i < row.Length; i++)
Console.Write($"{row[i]}\t");
Console.WriteLine();
}

@sfilipisfilipiApr 4, 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.

would it polish it a bit if you made a little helper for this, since it is being used twice? #Resolved

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

one of then is a float[] while the other is string[] .. did not want to over-engineer this...

is there anything specific you had in mind, or can we keep it as is ?


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

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.

object :)


In reply to: 272394600 [](ancestors = 272394600,272392068)


Console.WriteLine("Contents of two columns 'NumericVector' and 'StringVector'.");
foreach (var item in convertedData)
Console.WriteLine("{0}\t\t\t{1}", string.Join("\t", item.NumericVector), string.Join("\t", item.StringVector));

@sfilipisfilipiApr 4, 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.

\t [](start = 63, length = 2)

think for vectors we are using comma ',' as the separator. #Resolved


// Usage on text column.
pipeline = mlContext.Transforms.FeatureSelection.SelectFeaturesBasedOnCount(
outputColumnName: "StringVector", count: 3);

@sfilipisfilipiApr 4, 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.

I'd probably append to the previous pipeline, and show the prints once. Compacts the sample. #Resolved

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

sounds good. will do.


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


Console.WriteLine("Contents of two columns 'NumericVector' and 'StringVector'.");
foreach (var item in rawData)
Console.WriteLine("{0}\t\t\t{1}", string.Join("\t", item.NumericVector), string.Join("\t", item.StringVector));

@sfilipisfilipiApr 4, 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.

\t [](start = 63, length = 2)

same comment, ',' #Resolved


Console.WriteLine("Contents of column 'NumericVector'");
PrintDataColumn(transformedData, "NumericVector");
// 4 0

@sfilipisfilipiApr 4, 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.

4 [](start = 15, length = 1)

Curious, why is it dropping 6, but keeping 4? It is not obvious to me. Is it because slotsInOutput is 2? A comment about that might help. #Pending

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

we need to improve this once we have found a better sample. i have noted this in the issue #1209


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

@sfilipisfilipi 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:


Console.WriteLine("Contents of columns 'Label', 'NumericVectorA' and 'NumericVectorB'.");
foreach (var item in rawData)
Console.WriteLine("{0}\t\t{1}\t\t{2}", item.Label, string.Join(" ", item.NumericVectorA), string.Join(" ", item.NumericVectorB));

@sfilipisfilipiApr 4, 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.

[](start = 80, length = 1)

',' #Resolved

var rawData = GetData();
var data = mlContext.Data.LoadFromEnumerable(rawData);

var convertedData = mlContext.Data.CreateEnumerable<InputData>(data, true);

@zeahmedzeahmedApr 4, 2019

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.

convertedData [](start = 16, length = 13)

Why do you convert that back to Enumerable? rawData is already there. #Resolved

foreach (var item in convertedData)
Console.WriteLine("{0}\t\t{1}", string.Join(" ", item.NumericVectorA), string.Join(" ", item.NumericVectorB));

// Here, we see SelectFeaturesBasedOnMutualInformation selected 4 slots.

@sfilipisfilipiApr 4, 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.

4 slot [](start = 76, length = 6)

the 4 slots that had most in common with the respective value in the Label column, maybe? #Resolved

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

yes, these 4 slots carried the most MI with Label.... we should have a better tutorial for this though


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

@sfilipisfilipi 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:

@rogancarrrogancarr left a comment

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.

:shipit:

@abgoswam
abgoswam merged commit 8130567 into dotnet:masterApr 5, 2019
abgoswam added a commit to abgoswam/machinelearning that referenced this pull request Apr 5, 2019
* samples for FeatureSelection transform estimators
* fix review comments
* fix review comments
* review comments
* take care of review comments
* fix copy paste output error
@ghostghost locked as resolved and limited conversation to collaborators Mar 23, 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.

6 participants

@abgoswam@Ivanidzo4ka@shmoradims@sfilipi@rogancarr@zeahmed