From c1665c58f2fb5dd64cdd1664a926bd6c03c19042 Mon Sep 17 00:00:00 2001 From: Angelos Chatzimparmpas Date: Thu, 17 Oct 2019 19:03:14 +0200 Subject: [PATCH] fixed prediction space data space, etc. --- __pycache__/run.cpython-37.pyc | Bin 25299 -> 27654 bytes frontend/src/components/DataSpace.vue | 57 ++++++--- .../src/components/FinalResultsLinePlot.vue | 13 ++- frontend/src/components/Heatmap.vue | 46 ++++++-- frontend/src/components/Main.vue | 55 ++++++++- frontend/src/components/PredictionsSpace.vue | 72 ++++++++++-- frontend/src/components/Provenance.vue | 23 ++-- frontend/src/components/ScatterPlot.vue | 64 ++++++----- run.py | 108 +++++++++++++++++- 9 files changed, 353 insertions(+), 85 deletions(-) diff --git a/__pycache__/run.cpython-37.pyc b/__pycache__/run.cpython-37.pyc index 011917287b3c42b090991c9e32f1bc3a1701457b..c0a3fa5985a2a6589acd5736782cf2a1202cf68e 100644 GIT binary patch delta 4509 zcmb7H3rw8H5&n1Y!QF8$4mgg712Hy+VDk#Lv5mpN85@j=4Yr(|0sCNo$Q{Q4dutoJ z|KCfE^J;4scbm4V8s$)>J|d-3Ow&fK6sc(=HEmM$A*CrzE2m0ZscMu&s@kM&q|WSt zO|TOshj!S<%xNn}EIvW={gZG!pDm#N~LTf=vrT|mBhBHOI}y=r-W z&GIGopi+~#jhctn@IA~P$*PG=u}9fwFKO}>>!yL*2raA;y2`$|A~ee+`x2akD+3-| z!}DeK6=gt*SqHV6uU@mgR85xU%iGSSy+qT-psC*-K<&`Fprx+Ctk5#V&=!fQO=u>W zYc@1SinXvdTy0WDndOouXvV^<23@3KaDZtsNXBYdn5`J3h&CHKp>zlvv*V0uMU61Z zQ6rm3+v7PIhhc>!yJ3$zGcJ+4NDTWaCyd;}!!)KnNXKchX6A@2uMKz|hGUhNIf^vH z0sIc&_paf03VX(9^b>z>1NgPHB+4!lk>Eu{6%ifjH zqj0c@9~Jb3Qv>=`G?s+pM!YjH9~%>~>13)Sk%$D)0on23Oms}gIp9gJPNoL+1b-Fw z;vPKAf6?sqGQbk?Oo_QB)YTnJMiUVS3>$H%dTJr!VzJarl*h#RrU;ETM(AiGKZu$Y z>A~|9fryIDsdd5WME4_~MqI>7yd+2hK)u8bEdVs2#%@>(5C{DEVa`h2)J_}}=K{n} z9XVE@ZqVS8bjhJh3-OML_;!@0|_#{C(UkgaI!_vH=MmjBiBpPh5Q)$xb9yvY@Rt z#CJiz#>ekMj#?yjNb2Q4+v&PW>^1<2_#gwKQ;^9#bwE!Z2}c6=hNB|dJ9tn3{-lU; zeNY$jrM6PnHsF3AUDGMwX}eSU+sktxsD8?~$)@&;c04S9Uv`X?%ip)>_ElSeQ$1+Z z3vsto2j$Jca-p;y?sl|(Q0HfL4%cA%tlrJ1rv^oIY;p`NRzDEFS?h;n{l4q$MnnC9&jB=pxIQsb^P|N#}97Y1>Km?K00=eMZ z4;Gyl_rtBMxMwnYzQ)BdVEh;o`M=GsbRkGAmvKFHCLvPUBDLh7Qt#ey5`q~dl zG)s^=ELKuL3gC{pDBpn|FUxv-y}cuBgCUg6gWf2;a42>*ypF?j!P-_f*T%y?%M6 zGuOiXL>`R<$*_F7le>5x7|R1dWJ6aq*(~qtYO(Qr9RIkb#MT0xd*%1LYDkN`-Ze>f zgMH1ud_S15_=McGDUh6T*YqFuYkM7OxcU?Z#+v>luT{dRL^7Y8F&{f8B{FF!%M^cFB9^grP?E9 z1cVMAP1@SQ%zwxq9X&wWrDfnZh3caH0R#LRl0PEZB>z6JaZ3kqR)Y&uA(+$Pj^I7P zN(q$_BItlS6Ck`p-aYvB+>*DO2$K(?AWhTQ0!i7d*?a-gS44|DCHg!M<+5`b#SqwLpL50xTz&AyLe9%}h)DDJvCuw@Y!t2Bx z0zL#(6fOK`t5N)jsNE7YQ7$UrsRaL+-no8JBEU#+ai==xErApj%vY?Tkt}`Nh#GFw zuTDp2H+{0$f+x^Blz$UU@h2Sy=m7xipNoT0fK$P!krks{82a=|?8^-|+K=bR+GhBR zAS=||O8R|pMWx~`IkG@!pH&WDmmSHkeMmN>(W0B_us$37A2S;)d_?)nGCQKOfj~A` z_`!AAV3|F*J{!`IyM^M;_(l;FR#7Q7u{_A=z-7Do?(rJd%;rUvO7IngqpFqBT8aEm zEKzVnBAr$H;hPkGVzX8yK9*T6>g=l`H|_cevsfYEhM;`&z6<1(yg#xV@aQ)pd)(Dn zU!R2%`5_Nl*=MlQVoimwo1CH1Ayzvy%D1CH_ibN5*E2T+9M(C8zi lK|V2BTv=P<_L8!^5(iMHBdGqLakM)8B|eyOInr9;{{f7yUseDB delta 2686 zcmb7GYfN0%5k7P7-Q}{dFEDs_&122WY>n|7Y=gkyjUj-D4R&pBp!LGprM%YWa%|)1 zuC~cy*Re!JJ3o@Pma<4qoH$XGX4NRa@*`@cwsxwjt=h`1e?+a6UsWGU+Ei_%&bdom z5?htC=zMz~GiPSLIXlDE-@&hb44z)M+r{Yf@4(IRJuiRD6X3trf6#nK8%P|UiHb$B zO*Bt&5n16viVMpu3$bLPSk#Gn(Lno+E8Ld5xIylcSWB9peE0&j8 zY|a+HvO)Z+_=bJ${6nt2wn6S$alLRY{zh+b3VoDCR`WxSJIxToVCyCB2F!gakpIQr zlK{Qgw7(I2IJEy=@SwM?m3sl#+QazOwxckDFSXTkzY>21W&2Htf4ilcmlxK5I*@~T zwXRU>TR42^J8+rSdH@(hUwZ>wQZPgLn;lI6*YiK`%mREDN4hNU zOG-w!WehND@LpFIycq9pgIoA~_X&3`T^P~Ka*{B&;=j5h@CMc&zUy?;K8b5RZ^94p zt)BWV5!#rvFCtM74F`=QG#2~u!=9z0(wuvZrQMk69S1kw>z%{tBf(u|<|ia#`qXXZ z3Mv$+D9n(857p^k6|^g;!8ea=FOPW4I(1mDph>|t{OHKp?k#HCOc3*)kDKxNgiM%= zeTmeuXsq~jG%n) zxoes-{lb8W-``!1TLOM^d-2u2S`3dl zFgE1#)~dU0mNl}vKYw}X9i8t2e1D=6cH*()gRmWM98bdvhDL^Xd*NUeGb5e8-71CvTJ-y6(ZGkl7`TOYz@*5Sv=#)l~@j%J1yr-sbGR#;X+UH zAWIi5W%fyTl#REf4Xem9XscLiIgj*8pQQ`O3P^vJ&6FjXRs2oJ@-+aqkUYiKO*kJg z;j&zxGf}d1K$eq*U1XueGDJ~;ZM2eEH?!#hGe0@S1jH+3rPPFBX>zkD7OoXXnp-?x zvC2~hF`?T`ysO-?RJ2S6h@;Y_i!x}HW`WGkjPbNP?IHfWOT88oB|%2JZE2qU#6;fwqwWKm`r%f~KK22MJ!_1@QN!G|(Dv87h#W5^{(rriAYe)A$>SV3(1etQ} z;VHD-X}=v3U&w^MST-qs#R)fWkSl&l0$sG3rTt4Y+L-MciyQ`~!YH_A z`8U%$$U=rT*B{(xk8IB$conOB;dPtl&%Fs5p4n<~smnT9FTC_pd@D|R`z+_N9Jz)y zJ4NfO#`RS}BU4cEe*u+(M%klk$cq2xmWsdN_cb2LEm2Ngf77r@r3asx zxIq2%gdH*;7Sh6Juig*o1i)7@ii* z(1cHmXLp-hlvbMpyX2i!v;P(K57hD$!Cl9Bb2=r>!`PFk+fin|PkXV_*~I0MgfyoU z7ZW0;FHX)SV|>nxl}w(SyD*KL}@UlI?_>6jx6AdQv!D9U0=J#Gxk3Uc7OM)&>z<1?f!0e zdOI-Hj?9l0*bP`UXtPB@s{+*@&HW0x6sS&Pst#gyE9g<6BCtK7Hjm-iFuaXDv)A_e p46jjY|2YgFed~tPa2NrjIaK0-D#NG@8T7qqbQ->pmu4;_^IrominRa$ diff --git a/frontend/src/components/DataSpace.vue b/frontend/src/components/DataSpace.vue index 8db7be92a..28af00a90 100644 --- a/frontend/src/components/DataSpace.vue +++ b/frontend/src/components/DataSpace.vue @@ -17,7 +17,12 @@ export default { }, methods: { ScatterPlotDataView () { + + var target_names = JSON.parse(this.DataSpace[4]) const XandYCoordinates = JSON.parse(this.DataSpace[7]) + const DataSet = JSON.parse(this.DataSpace[14]) + const DataSetY = JSON.parse(this.DataSpace[15]) + var DataSetParse = JSON.parse(DataSet) var result = XandYCoordinates.reduce(function(r, a) { a.forEach(function(s, i) { @@ -32,33 +37,59 @@ export default { var dataPointInfo = [] for (let i = 0; i < XandYCoordinates.length; i++) { - dataPointInfo[i] = 'Data Point ID: ' + i + dataPointInfo[i] = 'Data Point ID: ' + i + '; Details: ' + JSON.stringify(DataSetParse[i]) + } + + var colors = ['#a6cee3','#1f78b4','#b2df8a','#33a02c','#fb9a99','#e31a1c','#fdbf6f','#ff7f00','#cab2d6','#6a3d9a'] + + var traces = [] + var countPrev = 0 + var count = 0 + for (let i = 0; i < target_names.length; i++) { + count = 0 + for (let j = 0; j < DataSetY.length; j++) { + if (i == DataSetY[j]) { + count = count + 1 + } + } + + traces.push({ + x: result.Xax.slice(countPrev,count+countPrev), + y: result.Yax.slice(countPrev,count+countPrev), + mode: 'markers', + name: target_names[i], + marker: { + color: colors[i] + }, + hovertemplate: + "%{text}

" + + "", + text: dataPointInfo.slice(countPrev,count+countPrev), + }) + countPrev = count + countPrev } var width = this.WH[0]*3 // interactive visualization - var height = this.WH[1]*1.5 // interactive visualization - const Data = [{ - x: result.Xax, - y: result.Yax, - mode: 'markers', - hovertemplate: - "%{text}

" + - "", - text: dataPointInfo, - }] + var height = this.WH[1]*2.1 // interactive visualization + const layout = { - title: 'Data Space Projection (tSNE)', + title: 'Data Space Projection (t-SNE)', xaxis: { visible: false }, yaxis: { visible: false }, + dragmode: 'lasso', + hovermode: "closest", autosize: true, width: width, height: height, } - Plotly.newPlot('OverviewDataPlotly', Data, layout, {responsive: true}) + + var config = {scrollZoom: true, displaylogo: false, showLink: false, showSendToCloud: false, modeBarButtonsToRemove: ['toImage', 'toggleSpikelines', 'autoScale2d', 'hoverClosestGl2d','hoverCompareCartesian','select2d','hoverClosestCartesian','zoomIn2d','zoomOut2d','zoom2d'], responsive: true} + + Plotly.newPlot('OverviewDataPlotly', traces, layout, config) } }, mounted() { diff --git a/frontend/src/components/FinalResultsLinePlot.vue b/frontend/src/components/FinalResultsLinePlot.vue index 5639bc3a2..e969d46f0 100644 --- a/frontend/src/components/FinalResultsLinePlot.vue +++ b/frontend/src/components/FinalResultsLinePlot.vue @@ -46,7 +46,6 @@ export default { this.xaxis.push(this.NumberofExecutions) // Under Exploration = Current - console.log(this.FinalResultsforLinePlot) this.scoresMean.push((JSON.parse(this.FinalResultsforLinePlot[0])*100).toFixed(1)) this.scoresSTD.push((JSON.parse(this.FinalResultsforLinePlot[1])*100).toFixed(1)) @@ -106,7 +105,9 @@ export default { text: text, line: {color: "rgb(127,201,127)"}, mode: "lines+markers", - name: "Current Accuracy", + marker : { + symbol: 'pentagon' }, + name: "Current Accuracy", type: "scatter" } @@ -182,7 +183,7 @@ export default { line: {color: "rgb(190,174,212)"}, mode: "lines+markers", marker : { - symbol: 'square' }, + symbol: 'circle' }, name: "Stack Accuracy", type: "scatter" } @@ -207,7 +208,7 @@ export default { line: {color: "rgb(56,108,176)"}, mode: "lines+markers", marker : { - symbol: 'star-triangle-up' }, + symbol: 'square' }, name: "Stack Precision", type: "scatter" } @@ -230,9 +231,9 @@ export default { y: this.Stack_scoresMean3, text: text, line: {color: "rgb(240,2,127)"}, - mode: "lines+markers", + mode: "lines+markers", marker : { - symbol: 'pentagon' }, + symbol: 'star-triangle-up' }, name: "Stack Recall", type: "scatter" } diff --git a/frontend/src/components/Heatmap.vue b/frontend/src/components/Heatmap.vue index d3226e011..52123cf71 100644 --- a/frontend/src/components/Heatmap.vue +++ b/frontend/src/components/Heatmap.vue @@ -21,7 +21,8 @@ export default { limitation: 0, flag: false, classesNumber: 10, - cellSize: 20 + cellSize: 20, + ModelsIDHeatStack: [] } }, methods: { @@ -30,16 +31,15 @@ export default { }, Heatmap () { - // Clear Heatmap first - var svg = d3.select("#Heatmap"); - svg.selectAll("*").remove(); + // Clear Heatmap first + var svg = d3.select("#Heatmap"); + svg.selectAll("*").remove(); - var FeaturesAccuracy = JSON.parse(this.GetResultsAll[5]) - var Features= JSON.parse(this.GetResultsAll[6]) - var keepingArrayIndices = this.indicestoRem - var PermImpEli = JSON.parse(this.GetResultsAll[10]) - var featureUni = JSON.parse(this.GetResultsAll[11]) - var modelIds = JSON.parse(this.GetResultsAll[13]) + var FeaturesAccuracy = JSON.parse(this.GetResultsAll[5]) + var Features = JSON.parse(this.GetResultsAll[6]) + var PermImpEli = JSON.parse(this.GetResultsAll[10]) + var featureUni = JSON.parse(this.GetResultsAll[11]) + var modelIds = JSON.parse(this.GetResultsAll[13]) var len2 = modelIds.length @@ -59,6 +59,30 @@ export default { indicesXAxis[i] = temp } + if (this.ModelsIDHeatStack.length != 0) { + + var FeaturesAccuracyNew = [] + var PermImpEliNew = [] + indicesXAxis = new Array(len) + + for (let i = 0; i < modelIds.length; i++) { + if (this.ModelsIDHeatStack.includes(modelIds[i])) { + } else { + FeaturesAccuracyNew.push(FeaturesAccuracy[i]) + PermImpEliNew.push(PermImpEli[i]) + } + } + FeaturesAccuracy = FeaturesAccuracyNew + PermImpEli = PermImpEliNew + len2 = this.ModelsIDHeatStack.length + for (let i = 0; i < len2; i++) { + temp = [] + temp.push("R") + temp.push("Model "+this.ModelsIDHeatStack[i].toString()) + indicesXAxis[i] = temp + } + } + temp = [] temp.push("R") temp.push("Average") @@ -525,6 +549,8 @@ export default { } }, mounted () { + EventBus.$on('NewHeatmapAccordingtoNewStack', data => { this.ModelsIDHeatStack = data }) + EventBus.$on('NewHeatmapAccordingtoNewStack', this.Heatmap) EventBus.$on('emittedEventCallingToggles', data => { this.Toggles = data }) EventBus.$on('emittedEventCallingHeatmapView', data => { this.GetResultsAll = data; this.flag = false }) EventBus.$on('emittedEventCallingHeatmapView', this.Heatmap) diff --git a/frontend/src/components/Main.vue b/frontend/src/components/Main.vue index 2b241f511..f1f312ae0 100755 --- a/frontend/src/components/Main.vue +++ b/frontend/src/components/Main.vue @@ -186,7 +186,7 @@ export default Vue.extend({ PerformancePerModel: '', PerformanceCheck: '', firstTimeFlag: 1, - selectedAlgorithms_Stack: [], + selectedModels_Stack: [], selectedAlgorithms: [], parametersofModels: [], reset: false, @@ -252,8 +252,9 @@ export default Vue.extend({ console.log('Server successfully sent all the data related to visualizations!') EventBus.$emit('emittedEventCallingScatterPlot', this.OverviewResults) if (this.firstTimeFlag == 1) { - this.selectedAlgorithms_Stack = this.selectedAlgorithms - EventBus.$emit('InitializeProvenance', this.selectedAlgorithms_Stack) + this.selectedModels_Stack.push(0) + this.selectedModels_Stack.push(JSON.stringify(this.modelsUpdate)) + EventBus.$emit('InitializeProvenance', this.selectedModels_Stack) } this.firstTimeFlag = 0 EventBus.$emit('InitializeMetricsBarChart', this.OverviewResults) @@ -332,6 +333,53 @@ export default Vue.extend({ }) } }, + RemoveFromStackModels () { + const path = `http://127.0.0.1:5000/data/ServerRemoveFromStack` + + const postData = { + ClassifiersList: this.ClassifierIDsList + } + const axiosConfig = { + headers: { + 'Content-Type': 'application/json', + 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Headers': 'Origin, Content-Type, X-Auth-Token', + 'Access-Control-Allow-Methods': 'GET, PUT, POST, DELETE, OPTIONS' + } + } + axios.post(path, postData, axiosConfig) + .then(response => { + console.log('Sent the selected points to the server (scatterplot)!') + EventBus.$emit('GrayOutPoints', this.ClassifierIDsList) + this.updatePredictionsSpace() + this.getFinalResults() + }) + .catch(error => { + console.log(error) + }) + }, + updatePredictionsSpace () { + const path = `http://localhost:5000/data/UpdatePredictionsSpace` + + const axiosConfig = { + headers: { + 'Content-Type': 'application/json', + 'Access-Control-Allow-Origin': '*', + 'Access-Control-Allow-Headers': 'Origin, Content-Type, X-Auth-Token', + 'Access-Control-Allow-Methods': 'GET, PUT, POST, DELETE, OPTIONS' + } + } + axios.get(path, axiosConfig) + .then(response => { + this.UpdatePredictions = response.data.UpdatePredictions + console.log('Updating Predictions Space!') + EventBus.$emit('updatePredictionsSpace', this.UpdatePredictions) + EventBus.$emit('InitializeProvenance', this.UpdatePredictions) + }) + .catch(error => { + console.log(error) + }) + }, SendSelectedDataPointsToServer () { const path = `http://127.0.0.1:5000/data/ServerRequestDataPoint` @@ -691,6 +739,7 @@ export default Vue.extend({ EventBus.$on('sendPointsNumber', data => {this.OverSelLength = data}) EventBus.$on('sendPointsNumber', data => {this.OverAllLength = data}) EventBus.$on('AllSelModels', data => {this.valueSel = data}) + EventBus.$on('RemoveFromStack', this.RemoveFromStackModels) //Prevent double click to search for a word. document.addEventListener('mousedown', function (event) { if (event.detail > 1) { diff --git a/frontend/src/components/PredictionsSpace.vue b/frontend/src/components/PredictionsSpace.vue index ad79575fa..2faac994e 100644 --- a/frontend/src/components/PredictionsSpace.vue +++ b/frontend/src/components/PredictionsSpace.vue @@ -11,12 +11,17 @@ export default { data () { return { PredictionsData: '', + UpdatedData: '', WH: [] } }, methods: { ScatterPlotDataView () { + var target_names = JSON.parse(this.PredictionsData[4]) const XandYCoordinates = JSON.parse(this.PredictionsData[8]) + const DataSet = JSON.parse(this.PredictionsData[14]) + const DataSetY = JSON.parse(this.PredictionsData[15]) + var DataSetParse = JSON.parse(DataSet) var result = XandYCoordinates.reduce(function(r, a) { a.forEach(function(s, i) { @@ -31,22 +36,43 @@ export default { var dataPointInfo = [] for (let i = 0; i < XandYCoordinates.length; i++) { - dataPointInfo[i] = 'Data Point ID: ' + i + dataPointInfo[i] = 'Data Point ID: ' + i + '; Details: ' + JSON.stringify(DataSetParse[i]) } + + var colors = ['#a6cee3','#1f78b4','#b2df8a','#33a02c','#fb9a99','#e31a1c','#fdbf6f','#ff7f00','#cab2d6','#6a3d9a'] + var traces = [] + var countPrev = 0 + var count = 0 + for (let i = 0; i < target_names.length; i++) { + count = 0 + for (let j = 0; j < DataSetY.length; j++) { + if (i == DataSetY[j]) { + count = count + 1 + } + } + + traces.push({ + x: result.Xax.slice(countPrev,count+countPrev), + y: result.Yax.slice(countPrev,count+countPrev), + mode: 'markers', + name: target_names[i], + marker: { + color: colors[i] + }, + hovertemplate: + "%{text}

" + + "", + text: dataPointInfo.slice(countPrev,count+countPrev), + }) + countPrev = count + countPrev + } + var width = this.WH[0]*3 // interactive visualization var height = this.WH[1]*1.48 // interactive visualization - const Data = [{ - x: result.Xax, - y: result.Yax, - mode: 'markers', - hovertemplate: - "%{text}

" + - "", - text: dataPointInfo, - }] + const layout = { - title: 'Predictions Space Projection (tSNE)', + title: 'Predictions Space Projection (t-SNE)', xaxis: { visible: false }, @@ -62,9 +88,29 @@ export default { var config = {scrollZoom: true, displaylogo: false, showLink: false, showSendToCloud: false, modeBarButtonsToRemove: ['toImage', 'toggleSpikelines', 'autoScale2d', 'hoverClosestGl2d','hoverCompareCartesian','select2d','hoverClosestCartesian','zoomIn2d','zoomOut2d','zoom2d'], responsive: true} - Plotly.newPlot('OverviewPredPlotly', Data, layout, config) + Plotly.newPlot('OverviewPredPlotly', traces, layout, config) this.selectedPointsOverview() }, + UpdateScatterPlot () { + const XandYCoordinates = JSON.parse(this.UpdatedData[0]) + + Plotly.animate('OverviewPredPlotly', { + data: [ + {x: XandYCoordinates[0], y: XandYCoordinates[1]} + ], + traces: [0], + layout: {} + }, { + transition: { + duration: 1000, + easing: 'cubic-in-out' + }, + frame: { + duration: 1000 + } + }) + this.selectedPointsOverview() + }, selectedPointsOverview () { const OverviewPlotly = document.getElementById('OverviewPredPlotly') OverviewPlotly.on('plotly_selected', function (evt) { @@ -88,6 +134,8 @@ export default { }, }, mounted() { + EventBus.$on('updatePredictionsSpace', data => { this.UpdatedData = data }) + EventBus.$on('updatePredictionsSpace', this.UpdateScatterPlot) EventBus.$on('emittedEventCallingPredictionsSpacePlotView', data => { this.PredictionsData = data}) EventBus.$on('emittedEventCallingPredictionsSpacePlotView', this.ScatterPlotDataView) diff --git a/frontend/src/components/Provenance.vue b/frontend/src/components/Provenance.vue index 6af84176f..ecd48cb37 100644 --- a/frontend/src/components/Provenance.vue +++ b/frontend/src/components/Provenance.vue @@ -26,7 +26,8 @@ export default { data: [], counter: 0, typeCounter: [], - typeColumnCounter: [] + typeColumnCounter: [], + KNNModels: 576, //KNN models } }, @@ -38,12 +39,12 @@ export default { var flagKNN = 0 var flagRF = 0 - + var StackInfo = JSON.parse(this.stackInformation[1]) // Create a WebGL 2D platform on the canvas: var platform = Stardust.platform("webgl-2d", canvas, width, height); - - for (let i = 0; i < this.stackInformation.length; i++) { - if (this.stackInformation[i] == 'KNN'){ + + for (let i = 0; i < StackInfo.length; i++) { + if (StackInfo[i] < this.KNNModels){ this.data.push({ type:0, column:this.counter, height:height }) @@ -62,10 +63,12 @@ export default { this.typeCounter.push(0) } this.typeColumnCounter.push(0) - + this.data.forEach(d => { - d.typeIndex = this.typeCounter[d.type]++; - d.typeColumnIndex = this.typeColumnCounter[d.column]++; + if (d.column == this.counter) { + d.typeIndex = this.typeCounter[d.type]++; + d.typeColumnIndex = this.typeColumnCounter[d.column]++; + } }); // Convert the SVG file to Stardust mark spec. @@ -80,7 +83,7 @@ export default { let pScale = Stardust.scale.custom(` Vector2( - 20 + column * 160 + typeColumnIndex % 5 * 8, + 20 + column * 100 + typeColumnIndex % 5 * 8, height - 10 - floor(typeColumnIndex / 5) * 10 ) `); @@ -110,7 +113,7 @@ export default { isotypes.data(this.data); isotypes.render(); - + this.counter = this.counter + 1 } }, mounted () { diff --git a/frontend/src/components/ScatterPlot.vue b/frontend/src/components/ScatterPlot.vue index 4fd7fe084..b89ee9b4a 100644 --- a/frontend/src/components/ScatterPlot.vue +++ b/frontend/src/components/ScatterPlot.vue @@ -40,7 +40,8 @@ export default { parametersAll: [], length: 0, valueStackRemove: 'Remove from Stack', - DataPointsSelUpdate: [] + DataPointsSelUpdate: [], + ModelsIDGray: [] } }, methods: { @@ -50,36 +51,10 @@ export default { EventBus.$emit('RepresentationSelection', this.representationSelection) }, RemoveStack () { - EventBus.$emit('PCPCallDB') + EventBus.$emit('RemoveFromStack') }, ScatterPlotView () { - function isEquivalent(a, b) { - // Create arrays of property names - var aProps = Object.getOwnPropertyNames(a); - var bProps = Object.getOwnPropertyNames(b); - - // If number of properties is different, - // objects are not equivalent - if (aProps.length != bProps.length) { - return false; - } - - for (var i = 0; i < aProps.length; i++) { - var propName = aProps[i]; - - // If values of same property are not equal, - // objects are not equivalent - if (a[propName] !== b[propName]) { - return false; - } - } - - // If we made it this far, objects - // are considered equivalent - return true; - } - Plotly.purge('OverviewPlotly') var colorsforScatterPlot = JSON.parse(this.ScatterPlotResults[0]) var MDSData = JSON.parse(this.ScatterPlotResults[1]) @@ -106,6 +81,37 @@ export default { classifiersInfoProcessing[i] = 'Model ID: ' + modelId[i] + '; Details: ' + JSON.stringify(parameters[i]) } + var listofNumbersModelsIDs = [] + var StackModelsIDs = [] + if (this.ModelsIDGray.length != 0) { + for (let j = 0; j < this.ModelsIDGray.length; j++){ + listofNumbersModelsIDs.push(parseInt(this.ModelsIDGray[j].replace(/\D/g, ""))) + } + + var parametersNew = [] + var MDSDataNewX = [] + var MDSDataNewY = [] + var colorsforScatterPlotNew = [] + for (let i = 0; i < modelId.length; i++) { + if (listofNumbersModelsIDs.includes(modelId[i])) { + } else { + StackModelsIDs.push(modelId[i]) + parametersNew.push(parameters[i]) + colorsforScatterPlotNew.push(colorsforScatterPlot[i]) + MDSDataNewX.push(MDSData[0][i]) + MDSDataNewY.push(MDSData[1][i]) + } + } + EventBus.$emit('sendPointsNumber', StackModelsIDs.length) + var classifiersInfoProcessing = [] + for (let i = 0; i < StackModelsIDs.length; i++) { + classifiersInfoProcessing[i] = 'Model ID: ' + StackModelsIDs[i] + '; Details: ' + JSON.stringify(parametersNew[i]) + } + MDSData[0] = MDSDataNewX + MDSData[1] = MDSDataNewY + colorsforScatterPlot = colorsforScatterPlotNew + EventBus.$emit('NewHeatmapAccordingtoNewStack', StackModelsIDs) + } var DataGeneral var layout if (this.representationDef == 'mds') { @@ -249,6 +255,8 @@ export default { } }, mounted() { + EventBus.$on('GrayOutPoints', data => { this.ModelsIDGray = data }) + EventBus.$on('GrayOutPoints', this.ScatterPlotView) EventBus.$on('emittedEventCallingBrushedBoxPlot', data => { this.brushedBox = data}) EventBus.$on('emittedEventCallingScatterPlot', data => { diff --git a/run.py b/run.py index 57d61f212..b4a70dd1e 100644 --- a/run.py +++ b/run.py @@ -575,6 +575,54 @@ def PreprocessingPred(): predictions.append(el) return predictions +def PreprocessingPredUpdate(Models): + Models = json.loads(Models) + ModelsList= [] + for loop in Models['ClassifiersList']: + temp = [int(s) for s in re.findall(r'\b\d+\b', loop)] + ModelsList.append(temp[0]) + dicKNN = json.loads(allParametersPerformancePerModel[7]) + dicRF = json.loads(allParametersPerformancePerModel[15]) + dfKNN = pd.DataFrame.from_dict(dicKNN) + dfKNN.index = dfKNN.index.astype(int) + dfKNNFiltered = dfKNN.loc[KNNModels, :] + dfRF = pd.DataFrame.from_dict(dicRF) + dfRF.index = dfRF.index.astype(int) + 576 + dfRFFiltered = dfRF.loc[RFModels, :] + df_concatProbs = pd.concat([dfKNNFiltered, dfRFFiltered]) + listProbs = df_concatProbs.index.values.tolist() + deletedElements = 0 + for index, element in enumerate(listProbs): + if element in ModelsList: + index = index - deletedElements + df_concatProbs = df_concatProbs.drop(df_concatProbs.index[index]) + deletedElements = deletedElements + 1 + df_concatProbsCleared = df_concatProbs + listIDsRemaining = df_concatProbsCleared.index.values.tolist() + + predictionsAll = PreprocessingPred() + PredictionSpaceAll = FunTsne(predictionsAll) + + predictionsSel = [] + for column, content in df_concatProbsCleared.items(): + el = [sum(x)/len(x) for x in zip(*content)] + predictionsSel.append(el) + + PredictionSpaceSel = FunTsne(predictionsSel) + + #ModelSpaceMDSNewComb = [list(a) for a in zip(PredictionSpaceAll[0], ModelSpaceMDS[1])] + + #ModelSpaceMDSNewSel = FunMDS(df_concatMetrics) + #ModelSpaceMDSNewSelComb = [list(a) for a in zip(ModelSpaceMDSNewSel[0], ModelSpaceMDSNewSel[1])] + + mtx2PredFinal = [] + mtx1Pred, mtx2Pred, disparity2 = procrustes(PredictionSpaceAll, PredictionSpaceSel) + + a1, b1 = zip(*mtx2Pred) + mtx2PredFinal.append(a1) + mtx2PredFinal.append(b1) + return [mtx2PredFinal,listIDsRemaining] + def PreprocessingParam(): dicKNN = json.loads(allParametersPerformancePerModel[1]) dicRF = json.loads(allParametersPerformancePerModel[9]) @@ -733,6 +781,7 @@ def ReturnResults(ModelSpaceMDS,ModelSpaceTSNE,DataSpaceList,PredictionSpaceList FeatureAccuracy = FeatureAccuracy.to_json(orient='records') perm_imp_eli5PDCon = perm_imp_eli5PDCon.to_json(orient='records') featureScoresCon = featureScoresCon.to_json(orient='records') + XDataJSONEntireSet = XData.to_json(orient='records') XDataJSON = XData.columns.tolist() Results.append(json.dumps(sumPerClassifier)) # Position: 0 @@ -749,6 +798,8 @@ def ReturnResults(ModelSpaceMDS,ModelSpaceTSNE,DataSpaceList,PredictionSpaceList Results.append(featureScoresCon) # Position: 11 Results.append(json.dumps(ModelSpaceTSNE)) # Position: 12 Results.append(json.dumps(ModelsIDs)) # Position: 13 + Results.append(json.dumps(XDataJSONEntireSet)) # Position: 14 + Results.append(json.dumps(yData)) # Position: 15 return Results @@ -764,12 +815,40 @@ def SendToPlot(): } return jsonify(response) + +# Retrieve data from client +@cross_origin(origin='localhost',headers=['Content-Type','Authorization']) +@app.route('/data/ServerRemoveFromStack', methods=["GET", "POST"]) +def RetrieveSelClassifiersIDandRemoveFromStack(): + ClassifierIDsList = request.get_data().decode('utf8').replace("'", '"') + + PredictionProbSelUpdate = PreprocessingPredUpdate(ClassifierIDsList) + + global resultsUpdatePredictionSpace + resultsUpdatePredictionSpace = [] + resultsUpdatePredictionSpace.append(json.dumps(PredictionProbSelUpdate[0])) # Position: 0 + resultsUpdatePredictionSpace.append(json.dumps(PredictionProbSelUpdate[1])) + + key = 3 + EnsembleModel(ClassifierIDsList, key) + + return 'Everything Okay' + +# Sending the overview classifiers' results to be visualized as a scatterplot +@app.route('/data/UpdatePredictionsSpace', methods=["GET", "POST"]) +def SendPredBacktobeUpdated(): + response = { + 'UpdatePredictions': resultsUpdatePredictionSpace + } + return jsonify(response) + # Retrieve data from client @cross_origin(origin='localhost',headers=['Content-Type','Authorization']) @app.route('/data/ServerRequestSelPoin', methods=["GET", "POST"]) def RetrieveSelClassifiersID(): ClassifierIDsList = request.get_data().decode('utf8').replace("'", '"') ComputeMetricsForSel(ClassifierIDsList) + key = 1 EnsembleModel(ClassifierIDsList, key) return 'Everything Okay' @@ -909,6 +988,7 @@ def RetrieveSelDataPoints(): ModelSpaceMDSNewComb = [list(a) for a in zip(ModelSpaceMDS[0], ModelSpaceMDS[1])] ModelSpaceMDSNewSel = FunMDS(df_concatMetrics) + ModelSpaceMDSNewSelComb = [list(a) for a in zip(ModelSpaceMDSNewSel[0], ModelSpaceMDSNewSel[1])] global mt2xFinal @@ -917,6 +997,7 @@ def RetrieveSelDataPoints(): a, b = zip(*mtx2) mt2xFinal.append(a) mt2xFinal.append(b) + return 'Everything Okay' @@ -1029,7 +1110,6 @@ def EnsembleModel(Models, keyRetrieved): global all_classifiersSelection all_classifiersSelection = [] - sclf = 0 lr = LogisticRegression() if (keyRetrieved == 0): @@ -1055,6 +1135,9 @@ def EnsembleModel(Models, keyRetrieved): global sclfStack sclfStack = 0 + + global sclf + sclf = 0 sclf = StackingCVClassifier(classifiers=all_classifiers, use_probas=True, meta_classifier=lr, @@ -1078,7 +1161,8 @@ def EnsembleModel(Models, keyRetrieved): meta_classifier=lr, random_state=RANDOM_SEED, n_jobs = -1) - else: + elif (keyRetrieved == 2): + # fix this part! if (len(all_classifiersSelection) == 0): all_classifiers = [] columnsInit = [] @@ -1106,12 +1190,30 @@ def EnsembleModel(Models, keyRetrieved): print(index) print(featureSelection['featureSelection'][index+store]) all_classifiers.append(make_pipeline(ColumnSelector(cols=featureSelection['featureSelection'][index+store]), RandomForestClassifier().set_params(**arg))) - + sclf = StackingCVClassifier(classifiers=all_classifiers, use_probas=True, meta_classifier=lr, random_state=RANDOM_SEED, n_jobs = -1) + else: + Models = json.loads(Models) + ModelsAll = preProceModels() + for index, modHere in enumerate(ModelsAll): + flag = 0 + for loop in Models['ClassifiersList']: + temp = [int(s) for s in re.findall(r'\b\d+\b', loop)] + if (int(temp[0]) == int(modHere)): + flag = 1 + if (flag is 0): + all_classifiersSelection.append(all_classifiers[index]) + + sclfStack = StackingCVClassifier(classifiers=all_classifiersSelection, + use_probas=True, + meta_classifier=lr, + random_state=RANDOM_SEED, + n_jobs = -1) + #else: # for index, eachelem in enumerate(algorithmsWithoutDuplicates): # if (eachelem == 'KNN'):