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

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

@ -23,12 +23,19 @@ export default {
const ClassNames = JSON.parse(this.AllResults[5]) const ClassNames = JSON.parse(this.AllResults[5])
var SortFeaturesPerClass = [] var SortFeaturesPerClass = []
var MergeSortFeaturesPerClass = []
var counter = 0
FeatureImportance.forEach(classifier => { FeatureImportance.forEach(classifier => {
counter++
var length = this.ObjectSize(classifier)
for (let i = 0; i < length; i++) { 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}, var margin = {left:80, top:40, right:120, bottom:50},
width = Math.max( Math.min(window.innerWidth, 1100) - margin.left - margin.right - 20, 400), 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), 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() var loom = d3.loom()
.padAngle(0.05) .padAngle(0.05)
//.sortSubgroups(sortAlpha) //.sortSubgroups(sortCharacter)
//.heightInner(28) //.heightInner(0)
.emptyPerc(0.2) //.sortGroups(function(d) { return d.words })
.widthInner(30) //.sortLooms(d3.descending)
.emptyPerc(0)
.widthInner(40)
//.widthInner(function(d) { return 6 * d.length; }) //.widthInner(function(d) { return 6 * d.length; })
.value(function(d) { return d.words; }) .value(function(d) { return d.importancerate; })
.inner(function(d) { return d.character; }) .outercolorfun(function(d) { return d.class; })
.outer(function(d) { return d.location; }); .inner(function(d) { return d.feature; })
.outer(function(d) { return d.classifier; });
var arc = d3.arc() var arc = d3.arc()
.innerRadius(innerRadius*1.01) .innerRadius(innerRadius*1.01)
@ -71,16 +81,12 @@ export default {
.radius(innerRadius) .radius(innerRadius)
.pullout(pullOutSize); .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 ////////////////////////// ////////////////////// Create SVG //////////////////////////
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
d3.select("#chart").selectAll("*").remove();
var svg = d3.select("#chart").append("svg") var svg = d3.select("#chart").append("svg")
.attr("width", width + margin.left + margin.right) .attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom); .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 //Sort the inner characters based on the total number of words spoken
var dataAgg = [ var dataAgg = MergeSortFeaturesPerClass
{
"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
},
]
//Find the total number of words per character //Find the total number of words per character
var dataChar = d3.nest() var dataChar = d3.nest()
.key(function(d) { return d.character; }) .key(function(d) { return d.character; })
@ -138,16 +119,16 @@ export default {
//Set more loom functions //Set more loom functions
loom loom
.sortSubgroups(sortCharacter) .sortSubgroups(sortCharacter)
.heightInner(innerRadius*0.75/characterOrder.length) .heightInner(innerRadius*0.2/characterOrder.length)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
///////////////////////// Colors /////////////////////////// ///////////////////////// Colors ///////////////////////////
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
var locations = ["Iris Setosa", "Iris Versicolour", "Iris Virginica"] var categories = ClassNames
var colors = ["#5a3511", "#47635f", "#223e15"] var colors = ["#0000FF", "#ff0000", "#00ff00"]
var color = d3.scaleOrdinal() var color = d3.scaleOrdinal()
.domain(locations) .domain(categories)
.range(colors) .range(colors)
//Create a group that already holds the data //Create a group that already holds the data
@ -238,7 +219,7 @@ export default {
var outerArcs = arcs.append("path") var outerArcs = arcs.append("path")
.attr("class", "arc") .attr("class", "arc")
.style("fill", function(d) { return color(d.innername) }) //.style("fill", function(d) { return color(d.outer.innername) })
.attr("d", arc) .attr("d", arc)
.attr("transform", function(d, i) { //Pull the two slices apart .attr("transform", function(d, i) { //Pull the two slices apart
return "translate(" + d.pullOutSize + ',' + 0 + ")" return "translate(" + d.pullOutSize + ',' + 0 + ")"
@ -271,7 +252,7 @@ export default {
outerLabels.append("text") outerLabels.append("text")
.attr("class", "outer-label-value") .attr("class", "outer-label-value")
.attr("dy", "1.5em") .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 ////////////////////// ////////////////// Draw inner strings //////////////////////
@ -288,7 +269,9 @@ export default {
.attr("class", "string") .attr("class", "string")
.style("mix-blend-mode", "multiply") .style("mix-blend-mode", "multiply")
.attr("d", string) .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) .style("opacity", defaultOpacity)
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
@ -355,11 +338,6 @@ export default {
return numFormat(words[0].value) 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) { .on("mouseout", function(d) {
@ -370,7 +348,7 @@ export default {
//Return the word count to what it was //Return the word count to what it was
d3.selectAll(".outer-label-value") 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 //Show all arcs again
d3.selectAll(".arc-wrapper") d3.selectAll(".arc-wrapper")
@ -430,19 +408,21 @@ export default {
}) })
}//wrap }//wrap
}, },
sortObject (obj) { sortObject (obj, classifierID, ClassName) {
var arr = [] var arr = []
for (var prop in obj) { for (var prop in obj) {
if (Object.prototype.hasOwnProperty.call(obj, prop)) { 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({ arr.push({
'FeatureID': prop, 'feature': 'Feature ' + prop,
'ImportanceValue': obj[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 return arr
}, },
ObjectSize (obj) { ObjectSize (obj) {

@ -38,6 +38,9 @@ cors = CORS(app, resources={r"/data/*": {"origins": "*"}})
def RetrieveFileName(): def RetrieveFileName():
global fileName global fileName
fileName = request.get_data().decode('utf8').replace("'", '"') fileName = request.get_data().decode('utf8').replace("'", '"')
global featureSelection
featureSelection = request.get_data().decode('utf8').replace("'", '"')
featureSelection = json.loads(featureSelection)
return jsonify(fileName) return jsonify(fileName)
# Sent data to client # Sent data to client
@ -92,10 +95,8 @@ def GridSearch(clf, params, scoring, FI, target_names):
cv=5, cv=5,
refit='accuracy', refit='accuracy',
n_jobs = -1) n_jobs = -1)
global subset
subset = XData
grid.fit(subset, yData) grid.fit(XData, yData)
cv_results = [] cv_results = []
cv_results.append(grid.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'] parameters = df_cv_results_classifiers['params']
PerClassMetrics = [] PerClassMetrics = []
FeatureImp = [] 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 = {} eachClassifierParamsDictList = {}
for key, value in eachClassifierParams.items(): for key, value in eachClassifierParams.items():
Listvalue = [] Listvalue = []
Listvalue.append(value) Listvalue.append(value)
eachClassifierParamsDictList[key] = Listvalue 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, grid = GridSearchCV(estimator=clf,
param_grid=eachClassifierParamsDictList, param_grid=eachClassifierParamsDictList,
scoring=scoring, scoring=scoring,

Loading…
Cancel
Save