feature selection

master
parent 0b2262cffd
commit 9bfba6023f
  1. 2
      .vscode/settings.json
  2. BIN
      __pycache__/run.cpython-37.pyc
  3. 91
      frontend/src/components/FeatureSelection.vue
  4. 20
      frontend/src/components/Main.vue
  5. 5
      frontend/src/components/ParametersSetting.vue
  6. 102
      frontend/src/components/StretchedChord.vue
  7. 37
      run.py

@ -1,4 +1,4 @@
{
"git.ignoreLimitWarning": true,
"python.pythonPath": "/Library/Frameworks/Python.framework/Versions/3.7/bin/python3"
"python.pythonPath": "/usr/local/bin/python3"
}

Binary file not shown.

@ -0,0 +1,91 @@
<template>
<div id="myDynamicTable" v-on:change="this.getFeatureSelection"></div>
</template>
<script>
import { EventBus } from '../main.js'
export default {
name: 'FeatureSelection',
data () {
return {
GetResults: '',
datafromCheckbox: ''
}
},
methods: {
FeatureSelection () {
document.getElementById("myDynamicTable").innerHTML = "";
var myTableDiv = document.getElementById("myDynamicTable");
var table = document.createElement('TABLE');
table.border = '1';
var tableBody = document.createElement('TBODY');
table.appendChild(tableBody);
var checkBoxArray = []
for (var i = 0; i < 3; i++) {
var tr = document.createElement('TR');
tableBody.appendChild(tr);
for (var j = 0; j < 4; j++) {
if (j == 0){
if (i == 0) {
var td = document.createElement('TD');
td.width = '75';
td.appendChild(document.createTextNode(''));
tr.appendChild(td);
} else {
var td = document.createElement('TD');
td.width = '90';
td.appendChild(document.createTextNode('Classifier ' + i));
tr.appendChild(td);
}
}
if (i == 0){
var td = document.createElement('TD');
td.width = '30';
td.appendChild(document.createTextNode('F ' + j));
tr.appendChild(td);
} else {
var checkbox = document.createElement('input');
checkbox.type = "checkbox";
checkbox.checked = true;
checkbox.name = i;
checkbox.text = "F " + j
checkbox.value = "value";
checkbox.id = "Cl " + i + ", F " + j;
checkBoxArray.push(checkbox)
var td = document.createElement('TD');
td.appendChild(myTableDiv.appendChild(checkbox));
tr.appendChild(td);
}
}
}
myTableDiv.appendChild(table);
this.datafromCheckbox = checkBoxArray
},
getFeatureSelection () {
var results = new Array();
this.datafromCheckbox.forEach(eachCheckbox => {
if (eachCheckbox.checked == true) {
results.push('ClassifierID: ' + eachCheckbox.name, 'FeatureName: ' + eachCheckbox.text, 'Check: 1')
}
else {
results.push('ClassifierID: ' + eachCheckbox.name, 'FeatureName: ' + eachCheckbox.text, 'Check: 0')
}
});
console.log(results)
EventBus.$emit('SendSelectedFeaturesEvent', results)
}
},
mounted () {
EventBus.$on('emittedEventCallingTableView', data => { this.GetResults = data })
EventBus.$on('emittedEventCallingTableView', this.FeatureSelection)
}
}
</script>

@ -53,6 +53,14 @@
</mdb-card-body>
</mdb-card>
</b-col>
<b-col cols="3">
<mdb-card>
<mdb-card-header color="primary-color" tag="h5" class="text-center">Subset Feature Selection</mdb-card-header>
<mdb-card-body>
<FeatureSelection/>
</mdb-card-body>
</mdb-card>
</b-col>
</b-row>
<b-row>
<b-col cols="3">
@ -77,6 +85,7 @@ import ScatterPlot from './ScatterPlot.vue'
import BarChart from './BarChart.vue'
import StretchedChord from './StretchedChord.vue'
import Tuning from './Tuning.vue'
import FeatureSelection from './FeatureSelection.vue'
import axios from 'axios'
import { mdbCard, mdbCardBody, mdbCardText, mdbCardHeader } from 'mdbvue'
import { EventBus } from '../main.js'
@ -90,6 +99,7 @@ export default Vue.extend({
BarChart,
StretchedChord,
Tuning,
FeatureSelection,
mdbCard,
mdbCardBody,
mdbCardHeader,
@ -100,7 +110,8 @@ export default Vue.extend({
Collection: 0,
OverviewResults: 0,
RetrieveValueFile: 'IrisC',
ClassifierIDsList: ''
ClassifierIDsList: '',
SelectedFeaturesPerClassifier: ''
}
},
methods: {
@ -110,7 +121,8 @@ export default Vue.extend({
DataBaseRequestDataSetName () {
const path = `http://127.0.0.1:5000/data/ServerRequest`
const postData = {
fileName: this.RetrieveValueFile
fileName: this.RetrieveValueFile,
featureSelection: this.SelectedFeaturesPerClassifier
}
const axiosConfig = {
headers: {
@ -122,6 +134,7 @@ export default Vue.extend({
}
axios.post(path, postData, axiosConfig)
.then(response => {
console.log(response)
console.log('Send request to server! FileName was sent successfully!')
})
.catch(error => {
@ -174,6 +187,8 @@ export default Vue.extend({
EventBus.$emit('emittedEventCallingScatterPlot', this.OverviewResults)
EventBus.$emit('emittedEventCallingBarChart', this.OverviewResults)
EventBus.$emit('emittedEventCallingChordView', this.OverviewResults)
EventBus.$emit('emittedEventCallingTableView', this.OverviewResults)
})
.catch(error => {
console.log(error)
@ -204,6 +219,7 @@ export default Vue.extend({
mounted() {
EventBus.$on('SendSelectedPointsToServerEvent', data => { this.ClassifierIDsList = data })
EventBus.$on('SendSelectedPointsToServerEvent', this.SendSelectedPointsToServer)
EventBus.$on('SendSelectedFeaturesEvent', data => { this.SelectedFeaturesPerClassifier = data })
}
})
</script>

@ -3,7 +3,8 @@
id="Execute"
v-on:click="execute">
<font-awesome-icon icon="play" />
Execute</button>
{{ value }}
</button>
</template>
<script>
@ -12,11 +13,13 @@ export default {
data () {
return {
InitializeEnsemble: false,
value: 'Execute'
};
},
methods: {
execute () {
this.InitializeEnsemble = true
this.value = 'ReExecute'
this.$emit('InitializeEnsembleLearningEvent')
}
}

@ -23,12 +23,19 @@ export default {
const ClassNames = JSON.parse(this.AllResults[5])
var SortFeaturesPerClass = []
var MergeSortFeaturesPerClass = []
var counter = 0
FeatureImportance.forEach(classifier => {
counter++
var length = this.ObjectSize(classifier)
for (let i = 0; i < length; i++) {
SortFeaturesPerClass.push(this.sortObject(classifier[i]))
SortFeaturesPerClass.push(this.sortObject(classifier[i], counter, ClassNames[i]))
}
})
MergeSortFeaturesPerClass = SortFeaturesPerClass[0]
for (let i = 0; i < SortFeaturesPerClass.length - 1; i++) {
MergeSortFeaturesPerClass = MergeSortFeaturesPerClass.concat(SortFeaturesPerClass[i+1])
}
var margin = {left:80, top:40, right:120, bottom:50},
width = Math.max( Math.min(window.innerWidth, 1100) - margin.left - margin.right - 20, 400),
height = Math.max( Math.min(window.innerHeight - 250, 900) - margin.top - margin.bottom - 20, 400),
@ -54,14 +61,17 @@ export default {
var loom = d3.loom()
.padAngle(0.05)
//.sortSubgroups(sortAlpha)
//.heightInner(28)
.emptyPerc(0.2)
.widthInner(30)
//.sortSubgroups(sortCharacter)
//.heightInner(0)
//.sortGroups(function(d) { return d.words })
//.sortLooms(d3.descending)
.emptyPerc(0)
.widthInner(40)
//.widthInner(function(d) { return 6 * d.length; })
.value(function(d) { return d.words; })
.inner(function(d) { return d.character; })
.outer(function(d) { return d.location; });
.value(function(d) { return d.importancerate; })
.outercolorfun(function(d) { return d.class; })
.inner(function(d) { return d.feature; })
.outer(function(d) { return d.classifier; });
var arc = d3.arc()
.innerRadius(innerRadius*1.01)
@ -71,16 +81,12 @@ export default {
.radius(innerRadius)
.pullout(pullOutSize);
var characterNotes = [];
characterNotes["Iris Setosa"] = "Speaking almost twice as many words as the second most abundant speaker, Gandalf is taking up a large portion of dialogue in almost every location he's in, but stays rather quiet in Mordor";
characterNotes["Iris Versicolour"] = "An unexpected runner up to having spoken the most words, Sam flourishes after the battle at Amon Hen, taking up a considerable portion of the words said in both Mordor and Gondor";
characterNotes["Iris Virginica"] = "Although eventually being crowned in Minas Tirith, Gondor, Aragorn is by far most talkative in that other human region, Rohan, fighting a battle at Helm's Deep and convincing an army of dead";
////////////////////////////////////////////////////////////
////////////////////// Create SVG //////////////////////////
////////////////////////////////////////////////////////////
d3.select("#chart").selectAll("*").remove();
var svg = d3.select("#chart").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom);
@ -95,33 +101,8 @@ export default {
////////////////////////////////////////////////////////////
//Sort the inner characters based on the total number of words spoken
var dataAgg = [
{
"location": "Classifier 1",
"character": "Iris Setosa",
"words": 94
},
{
"location": "Classifier 1",
"character": "Iris Versicolour",
"words": 100
},
{
"location": "Classifier 1",
"character": "Iris Virginica",
"words": 100
},
{
"location": "Feature 1",
"character": "Iris Virginica",
"words": 40
},
{
"location": "Feature 2",
"character": "Iris Virginica",
"words": 60
},
]
var dataAgg = MergeSortFeaturesPerClass
//Find the total number of words per character
var dataChar = d3.nest()
.key(function(d) { return d.character; })
@ -138,16 +119,16 @@ export default {
//Set more loom functions
loom
.sortSubgroups(sortCharacter)
.heightInner(innerRadius*0.75/characterOrder.length)
.heightInner(innerRadius*0.2/characterOrder.length)
////////////////////////////////////////////////////////////
///////////////////////// Colors ///////////////////////////
////////////////////////////////////////////////////////////
var locations = ["Iris Setosa", "Iris Versicolour", "Iris Virginica"]
var colors = ["#5a3511", "#47635f", "#223e15"]
var categories = ClassNames
var colors = ["#0000FF", "#ff0000", "#00ff00"]
var color = d3.scaleOrdinal()
.domain(locations)
.domain(categories)
.range(colors)
//Create a group that already holds the data
@ -238,7 +219,7 @@ export default {
var outerArcs = arcs.append("path")
.attr("class", "arc")
.style("fill", function(d) { return color(d.innername) })
//.style("fill", function(d) { return color(d.outer.innername) })
.attr("d", arc)
.attr("transform", function(d, i) { //Pull the two slices apart
return "translate(" + d.pullOutSize + ',' + 0 + ")"
@ -271,7 +252,7 @@ export default {
outerLabels.append("text")
.attr("class", "outer-label-value")
.attr("dy", "1.5em")
.text(function(d,i){ return numFormat(d.value) + " words" })
.text(function(d,i){ return 'Relation:' + numFormat(d.value) + '%'})
////////////////////////////////////////////////////////////
////////////////// Draw inner strings //////////////////////
@ -288,7 +269,9 @@ export default {
.attr("class", "string")
.style("mix-blend-mode", "multiply")
.attr("d", string)
.style("fill", function(d) { return d3.rgb( color(d.outer.innername) ).brighter(0.2) })
.style("fill", function(d) {
return d3.rgb( color(d.outer.outercolor) ).brighter(0.2)
})
.style("opacity", defaultOpacity)
////////////////////////////////////////////////////////////
@ -355,11 +338,6 @@ export default {
return numFormat(words[0].value)
})
//Show the character note
d3.selectAll(".character-note")
.text(characterNotes[d.name])
.call(wrap, 2.25*pullOutSize)
})
.on("mouseout", function(d) {
@ -370,7 +348,7 @@ export default {
//Return the word count to what it was
d3.selectAll(".outer-label-value")
.text(function(s,i){ return numFormat(s.value) + " words" })
.text(function(s,i){ return 'Importance Rate: ' + numFormat(s.value) })
//Show all arcs again
d3.selectAll(".arc-wrapper")
@ -430,19 +408,21 @@ export default {
})
}//wrap
},
sortObject (obj) {
sortObject (obj, classifierID, ClassName) {
var arr = []
for (var prop in obj) {
if (Object.prototype.hasOwnProperty.call(obj, prop)) {
if ((this.LimitFeatureImportance/100) < Math.abs(obj[prop])) {
//if ((this.LimitFeatureImportance/100) < Math.abs(obj[prop])) {
arr.push({
'FeatureID': prop,
'ImportanceValue': obj[prop]
'feature': 'Feature ' + prop,
'classifier': 'Classifier ' + classifierID,
'class': ClassName,
'importancerate': Math.abs(Math.round(obj[prop] * 100))
})
//}
}
}
}
arr = arr.sort(function (a, b) { return Math.abs(b.ImportanceValue) - Math.abs(a.ImportanceValue) })
arr = arr.sort(function (a, b) { return Math.abs(b.ImportanceValue - a.ImportanceValue) })
return arr
},
ObjectSize (obj) {

@ -38,6 +38,9 @@ cors = CORS(app, resources={r"/data/*": {"origins": "*"}})
def RetrieveFileName():
global fileName
fileName = request.get_data().decode('utf8').replace("'", '"')
global featureSelection
featureSelection = request.get_data().decode('utf8').replace("'", '"')
featureSelection = json.loads(featureSelection)
return jsonify(fileName)
# Sent data to client
@ -92,10 +95,8 @@ def GridSearch(clf, params, scoring, FI, target_names):
cv=5,
refit='accuracy',
n_jobs = -1)
global subset
subset = XData
grid.fit(subset, yData)
grid.fit(XData, yData)
cv_results = []
cv_results.append(grid.cv_results_)
@ -116,12 +117,40 @@ def GridSearch(clf, params, scoring, FI, target_names):
parameters = df_cv_results_classifiers['params']
PerClassMetrics = []
FeatureImp = []
for eachClassifierParams in grid.cv_results_['params']:
global subset
print(XData.columns)
subset = XData
for i, eachClassifierParams in enumerate(grid.cv_results_['params']):
eachClassifierParamsDictList = {}
for key, value in eachClassifierParams.items():
Listvalue = []
Listvalue.append(value)
eachClassifierParamsDictList[key] = Listvalue
if (FI == 1):
if (featureSelection['featureSelection'] == ''):
subset = XData
else:
featureSelected = []
if ((i+1) == int(''.join(x for x in featureSelection['featureSelection'][0] if x.isdigit()))):
if (int(''.join(x for x in featureSelection['featureSelection'][2] if x.isdigit())) == 1):
featureSelected.append('petal_l')
if (int(''.join(x for x in featureSelection['featureSelection'][5] if x.isdigit())) == 1):
featureSelected.append('petal_w')
if (int(''.join(x for x in featureSelection['featureSelection'][8] if x.isdigit())) == 1):
featureSelected.append('sepal_l')
if (int(''.join(x for x in featureSelection['featureSelection'][11] if x.isdigit())) == 1):
featureSelected.append('sepal_w')
else:
if (int(''.join(x for x in featureSelection['featureSelection'][14] if x.isdigit())) == 1):
featureSelected.append('petal_l')
if (int(''.join(x for x in featureSelection['featureSelection'][17] if x.isdigit())) == 1):
featureSelected.append('petal_w')
if (int(''.join(x for x in featureSelection['featureSelection'][20] if x.isdigit())) == 1):
featureSelected.append('sepal_l')
if (int(''.join(x for x in featureSelection['featureSelection'][23] if x.isdigit())) == 1):
featureSelected.append('sepal_w')
print(featureSelected)
subset = XData[featureSelected]
grid = GridSearchCV(estimator=clf,
param_grid=eachClassifierParamsDictList,
scoring=scoring,

Loading…
Cancel
Save