VisEvol: Visual Analytics to Support Hyperparameter Search through Evolutionary Optimization https://doi.org/10.1111/cgf.14300
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
VisEvol/frontend/src/components/HyperParameterSpace.vue

312 lines
9.5 KiB

<template>
<div>
<div align="center">
Projection method: <select id="selectBarChart" @change="selectVisualRepresentation()">
<option value="mds" selected>MDS</option>
<option value="tsne">t-SNE</option>
<option value="umap">UMAP</option>
</select>
&nbsp;&nbsp;
Action: <button
id="Remove"
v-on:click="Remove">
<font-awesome-icon icon="dna" />
{{ CrossoverMutateText }}
</button>
</div>
<div id="OverviewPlotly" class="OverviewPlotly"></div>
</div>
</template>
<script>
import * as Plotly from 'plotly.js'
import * as d3Base from 'd3'
import { EventBus } from '../main.js'
// attach all d3 plugins to the d3 library
const d3 = Object.assign(d3Base)
export default {
name: 'HyperParameterSpace',
data () {
return {
CrossoverMutateText: 'Unselected points\' crossover & mutation',
WH: [],
ScatterPlotResults: '',
representationDef: 'mds',
}
},
methods: {
reset () {
Plotly.purge('OverviewPlotly')
},
clean(obj) {
var propNames = Object.getOwnPropertyNames(obj);
for (var i = 0; i < propNames.length; i++) {
var propName = propNames[i];
if (obj[propName] === null || obj[propName] === undefined) {
delete obj[propName];
}
}
},
selectVisualRepresentation () {
const representationSelectionDocum = document.getElementById('selectBarChart')
this.representationSelection = representationSelectionDocum.options[representationSelectionDocum.selectedIndex].value
EventBus.$emit('RepresentationSelection', this.representationSelection)
},
ScatterPlotView () {
Plotly.purge('OverviewPlotly')
var modelId = JSON.parse(this.ScatterPlotResults[0])
var colorsforScatterPlot = JSON.parse(this.ScatterPlotResults[1])
var parametersLoc = JSON.parse(this.ScatterPlotResults[2])
var parameters = JSON.parse(parametersLoc)
var MDSData= JSON.parse(this.ScatterPlotResults[9])
var TSNEData = JSON.parse(this.ScatterPlotResults[10])
var UMAPData = JSON.parse(this.ScatterPlotResults[11])
EventBus.$emit('sendPointsNumber', modelId.length)
var stringParameters = []
for (let i = 0; i < parameters.length; i++) {
this.clean(parameters[i])
stringParameters.push(JSON.stringify(parameters[i]).replace(/,/gi, '<br>'))
}
var classifiersInfoProcessing = []
for (let i = 0; i < modelId.length; i++) {
if (i < 100) {
classifiersInfoProcessing[i] = '<b>Model ID:</b> ' + modelId[i] + '<br><b>Algorithm:</b> k-nearest neighbor' + '<br><b>Parameters:</b> ' + stringParameters[i]
}
else {
classifiersInfoProcessing[i] = '<b>Model ID:</b> ' + modelId[i] + '<br><b>Algorithm:</b> logistic regression' + '<br><b>Parameters:</b> ' + stringParameters[i]
}
}
var DataGeneral, maxX, minX, maxY, minY, layout
var width = this.WH[0]*8 // interactive visualization
var height = this.WH[1]*4 // interactive visualization
if (this.representationDef == 'mds') {
maxX = Math.max(MDSData[0])
minX = Math.min(MDSData[0])
maxY = Math.max(MDSData[1])
minY = Math.max(MDSData[1])
DataGeneral = [{
type: 'scatter',
mode: 'markers',
x: MDSData[0],
y: MDSData[1],
hovertemplate:
"%{text}<br><br>" +
"<extra></extra>",
text: classifiersInfoProcessing,
marker: {
line: { color: 'rgb(0, 0, 0)', width: 3 },
color: colorsforScatterPlot,
size: 12,
colorscale: 'Viridis',
colorbar: {
title: '# Performance (%) #',
titleside:'right',
},
}
}]
layout = {
xaxis: {
visible: false,
range: [minX, maxX]
},
yaxis: {
visible: false,
range: [minY, maxY]
},
font: { family: 'Helvetica', size: 16, color: '#000000' },
autosize: true,
width: width,
height: height,
dragmode: 'lasso',
hovermode: "closest",
hoverlabel: { bgcolor: "#FFF" },
legend: {orientation: 'h', y: -0.3},
margin: {
l: 50,
r: 0,
b: 30,
t: 40,
pad: 0
},
}
} else if (this.representationDef == 'tsne') {
var result = TSNEData.reduce(function(r, a) {
a.forEach(function(s, i) {
var key = i === 0 ? 'Xax' : 'Yax';
r[key] || (r[key] = []); // if key not found on result object, add the key with empty array as the value
r[key].push(s);
})
return r;
}, {})
maxX = Math.max(result.Xax)
minX = Math.min(result.Xax)
maxY = Math.max(result.Yax)
minY = Math.max(result.Yax)
DataGeneral = [{
type: 'scatter',
mode: 'markers',
x: result.Xax,
y: result.Yax,
hovertemplate:
"%{text}<br><br>" +
"<extra></extra>",
text: classifiersInfoProcessing,
marker: {
line: { color: 'rgb(0, 0, 0)', width: 3 },
color: colorsforScatterPlot,
size: 12,
colorscale: 'Viridis',
colorbar: {
title: 'Metrics Average',
titleside: 'Top'
},
}
}]
layout = {
xaxis: {
visible: false,
range: [minX, maxX]
},
yaxis: {
visible: false,
range: [minY, maxY]
},
autosize: true,
width: width,
height: height,
dragmode: 'lasso',
hovermode: "closest",
hoverlabel: { bgcolor: "#FFF" },
legend: {orientation: 'h', y: -0.3},
margin: {
l: 50,
r: 0,
b: 30,
t: 40,
pad: 0
},
}
} else {
maxX = Math.max(UMAPData[0])
minX = Math.min(UMAPData[0])
maxY = Math.max(UMAPData[1])
minY = Math.max(UMAPData[1])
DataGeneral = [{
type: 'scatter',
mode: 'markers',
x: UMAPData[0],
y: UMAPData[1],
hovertemplate:
"%{text}<br><br>" +
"<extra></extra>",
text: classifiersInfoProcessing,
marker: {
line: { color: 'rgb(0, 0, 0)', width: 3 },
color: colorsforScatterPlot,
size: 12,
colorscale: 'Viridis',
colorbar: {
title: 'Metrics Average',
titleside: 'Top'
},
}
}]
layout = {
xaxis: {
visible: false,
range: [minX, maxX]
},
yaxis: {
visible: false,
range: [minY, maxY]
},
autosize: true,
width: width,
height: height,
dragmode: 'lasso',
hovermode: "closest",
hoverlabel: { bgcolor: "#FFF" },
legend: {orientation: 'h', y: -0.3},
margin: {
l: 50,
r: 0,
b: 30,
t: 40,
pad: 0
},
}
}
var config = {scrollZoom: true, displaylogo: false, showLink: false, showSendToCloud: false, modeBarButtonsToRemove: ['toImage', 'toggleSpikelines', 'autoScale2d', 'hoverClosestGl2d','hoverCompareCartesian','select2d','hoverClosestCartesian','zoomIn2d','zoomOut2d','zoom2d'], responsive: true}
var scat = document.getElementById('OverviewPlotly')
Plotly.newPlot(scat, DataGeneral, layout, config)
this.selectedPointsOverview()
},
selectedPointsOverview () {
const OverviewPlotly = document.getElementById('OverviewPlotly')
var allModels = JSON.parse(this.ScatterPlotResults[0])
OverviewPlotly.on('plotly_selected', function (evt) {
if (typeof evt !== 'undefined') {
var pushModelsRemainingTemp = []
const ClassifierIDsList = []
for (let i = 0; evt.points.length; i++) {
if (evt.points[i] === undefined) {
break
} else {
const OnlyId = evt.points[i].text.split(' ')[2]
const OnlyIdCleared = OnlyId.split('<br>')
ClassifierIDsList.push(OnlyIdCleared[0])
}
}
for (let i = 0; i < allModels.length; i++) {
if (ClassifierIDsList.indexOf((allModels[i])) < 0) {
pushModelsRemainingTemp.push(allModels[i])
}
}
EventBus.$emit('RemainingPoints', pushModelsRemainingTemp)
EventBus.$emit('SendSelectedPointsUpdateIndicator', ClassifierIDsList)
EventBus.$emit('SendSelectedPointsToServerEvent', ClassifierIDsList)
}
})
},
Remove () {
EventBus.$emit('InitializeCrossoverMutation')
}
},
mounted() {
EventBus.$on('emittedEventCallingScatterPlot', data => {
this.ScatterPlotResults = data})
EventBus.$on('emittedEventCallingScatterPlot', this.ScatterPlotView)
EventBus.$on('RepresentationSelection', data => {this.representationDef = data})
EventBus.$on('RepresentationSelection', this.ScatterPlotView)
// reset view
EventBus.$on('resetViews', this.reset)
}
}
</script>