blob: a367e1370f3a71b307b6cd695b76c51a1d333ae8 [file] [log] [blame]
Marc Kupietz83305222016-04-28 09:57:22 +02001<!DOCTYPE html>
2<html>
3 <head>
4 <title>DeReKo-Word-Vector-Distances: <%= $word %></title>
Marc Kupietz80bd7b92017-07-04 16:25:54 +02005 <link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
6 <script src="http://code.jquery.com/jquery-latest.min.js"></script>
Marc Kupietz4abcd682017-11-28 20:51:08 +01007 <script src = "https://cdn.datatables.net/1.10.16/js/jquery.dataTables.min.js"></script>
8 <script src = "https://cdn.datatables.net/fixedcolumns/3.2.3/js/dataTables.fixedColumns.min.js"></script>
9 <link rel="stylesheet" href="https://cdn.datatables.net/1.10.16/css/jquery.dataTables.min.css">
Marc Kupietz80bd7b92017-07-04 16:25:54 +020010 <script
Marc Kupietz4abcd682017-11-28 20:51:08 +010011src="http://code.jquery.com/ui/1.12.1/jquery-ui.min.js"
12integrity="sha256-VazP97ZCwtekAsvgPBSUwPFKdrwD3unUfSGVYrahUqU="
13crossorigin="anonymous"></script>
Marc Kupietz80bd7b92017-07-04 16:25:54 +020014 <script>
Marc Kupietz4abcd682017-11-28 20:51:08 +010015 $('#firstable').hide();
16 $(document).ready(function() {
17 $("#xxxtabs").tabs( {
18 "show": function(event, ui) {
19 var oTable = $('div.dataTables_scrollBody>table.display', ui.panel).dataTable();
20 if ( oTable.length > 0 ) {
21 oTable.fnAdjustColumnSizing();
22 }
23 }
24 } );
Marc Kupietz694610d2017-11-25 18:30:03 +010025
Marc Kupietz4abcd682017-11-28 20:51:08 +010026 $(".selector").tabs({ active: 1 });
Marc Kupietz0af83e32017-11-27 09:31:37 +010027
Marc Kupietz4abcd682017-11-28 20:51:08 +010028 $('#firsttable').DataTable({
29 "sScrollY": "780px",
30 "bScrollCollapse": true,
31 "bPaginate": false,
32 "bJQueryUI": true,
33 "dom": '<"top">rt<"bottom"flp><"clear">',
34 "aoColumnDefs": [
35 { "sWidth": "10%", "aTargets": [ -1 ] }
36 ]
37 } );
Marc Kupietz0af83e32017-11-27 09:31:37 +010038
39 $('#secondtable').DataTable({
Marc Kupietz4abcd682017-11-28 20:51:08 +010040 "sScrollY": "800px",
41 "bScrollCollapse": true,
42 "bPaginate": false,
43 "bJQueryUI": true,
44 "dom": '<"top">rt<"bottom"flp><"clear">',
45 "aoColumnDefs": [
46 { "sWidth": "10%", "aTargets": [ -1 ] }
47 ]
48 } );
49 });
Marc Kupietz0af83e32017-11-27 09:31:37 +010050
Marc Kupietz4abcd682017-11-28 20:51:08 +010051 $( function() {
52 $( "#iterations" ).spinner({
53 spin: function( event, ui ) {
54 if ( ui.value < 1000 ) {
55 $( this ).spinner( "value", 1000 );
56 return false;
57 } else if ( ui.value > 10000 ) {
58 $( this ).spinner( "value", 10000 );
59 return false;
60 }
61 }
62 });
63 } );
Marc Kupietz3305b0a2017-11-27 10:46:20 +010064
Marc Kupietz4abcd682017-11-28 20:51:08 +010065 $( function() {
66 $( "#neighbours" ).spinner({
67 spin: function( event, ui ) {
68 if ( ui.value < 0 ) {
69 $( this ).spinner( "value", 0 );
70 return false;
71 } else if ( ui.value > 200 ) {
72 $( this ).spinner( "value", 200 );
73 return false;
74 }
75 }
76 });
77 } );
78
79 $( function() {
80 $( "#cutoff" ).spinner({
81 spin: function( event, ui ) {
82 if ( ui.value < 100000 ) {
83 $( this ).spinner( "value", 100000 );
84 return false;
85 } else if ( ui.value > 2000000 ) {
86 $( this ).spinner( "value", 2000000 );
87 return false;
88 }
89 }
90 });
91 } );
92
93 $( function() {
Marc Kupietz4fcda0c2017-11-29 09:00:31 +010094 $( "#tabs" ).tabs(); // .addClass('ui-helper-clearfix tabs-left-vertical');
95 } );
Marc Kupietz4abcd682017-11-28 20:51:08 +010096
97 $( function() {
98 $( ".controlgroup-vertical" ).controlgroup({
99 "direction": "vertical"
100 });
101 } );
102
103 $(function() {
104 $( document ).tooltip({
105 content: function() {
106 return $(this).attr('title');
107 }}
108 )
Marc Kupietz83305222016-04-28 09:57:22 +0200109 })
Marc Kupietz694610d2017-11-25 18:30:03 +0100110
Marc Kupietz83305222016-04-28 09:57:22 +0200111 </script>
112 <script src="//d3js.org/d3.v3.min.js" charset="utf-8"></script>
Marc Kupietz554aff52017-11-09 14:42:09 +0100113 <script src="/derekovecs/js/tsne.js"></script>
114 <script src="/derekovecs/js/som.js"></script>
115 <script src="/derekovecs/js/labeler.js"></script>
Marc Kupietz83305222016-04-28 09:57:22 +0200116 <style>
117 body, input {
118 font-family: Arial, sans-serif;
119 font-size: 11pt;
120 }
Marc Kupietz30ca4342017-11-22 21:21:20 +0100121
Marc Kupietz4fcda0c2017-11-29 09:00:31 +0100122.tabs-left-vertical .ui-tabs-nav {
123 position: absolute;
124 width: 21em;
125 transform: translate(-100%,0%) rotate(-90deg);
126 transform-origin: 100% 0%;
127}
128 .
129.tabs-left-vertical .ui-tabs-nav li {
130 float: right;
131}
132
133.tabs-left-vertical .ui-tabs-panel {
134 padding-left: 3.5em;
135}
136
137.tabs-left-vertical .ui-tabs-panel {
138 height: 20em;
139 }
140
Marc Kupietz30ca4342017-11-22 21:21:20 +0100141 .mono {
142 font-family: "DejaVu Sans Mono", Inconsolata, SourceCodePro, Courier;
143 }
144
Marc Kupietz83305222016-04-28 09:57:22 +0200145 .ui-tooltip-content {
146 font-size: 9pt;
147 color: #222222;
148 }
149
150 svg > .ui-tooltip-content {
151 font-size: 8pt;
152 color: #222222;
153 }
154
155 a.merged {
156 color: green;
157 fill: green;
158 }
159
160 #first a {
161 text-decoration: none;
162 }
163
164 a.marked, #first a.marked {
165 text-decoration: underline;
166 }
Marc Kupietzf4b49392016-04-28 10:49:56 +0200167
Marc Kupietz83305222016-04-28 09:57:22 +0200168 a.target {
169 color: red;
170 fill: red;
171 }
Marc Kupietz694610d2017-11-25 18:30:03 +0100172
Marc Kupietz4abcd682017-11-28 20:51:08 +0100173 table.display {
174 width: 40% important!;
175 margin: 1; /* <- works for me this way ****/
176 }
177 table.dataTable thead th, table.dataTable thead td, table.dataTable tbody td {
178 padding: 2px 2px;
179 // border-bottom: 1px solid #111;
180 }
Marc Kupietz83305222016-04-28 09:57:22 +0200181 #collocators {
182 margin-bottom: 15px;
183 }
184
Marc Kupietz4abcd682017-11-28 20:51:08 +0100185 #topwrapper {
Marc Kupietz83305222016-04-28 09:57:22 +0200186 width: 100%;
187 // border: 1px solid red;
188 overflow: hidden; /* will contain if #first is longer than #second */
189 }
Marc Kupietz4abcd682017-11-28 20:51:08 +0100190
191 #wrapper {
192 width: 1200px;
193 // border: 1px solid red;
194 overflow: hidden; /* will contain if #first is longer than #second */
195 }
196
197 #options {
198 float: right;
199 margin: 20px;
200 max-width: 280px;
201 overflow: hidden; /* if you don't want #second to wrap below #first */
202 }
203
Marc Kupietz83305222016-04-28 09:57:22 +0200204 #first {
205 margin-right: 20px;
206 float: left;
Marc Kupietz4abcd682017-11-28 20:51:08 +0100207 overflow: hidden; /* if you don't want #second to wrap below #first */
Marc Kupietz83305222016-04-28 09:57:22 +0200208 // border: 1px solid green;
209 }
Marc Kupietz4abcd682017-11-28 20:51:08 +0100210 #tabs {
211 margin-right: 20px;
212 overflow: hidden; /* if you don't want #second to wrap below #first */
213 }
214
215 #embed {
216 max-width: 802px;
217 border: 1px solid #333;
218 }
219
Marc Kupietz83305222016-04-28 09:57:22 +0200220 #second {
Marc Kupietz4abcd682017-11-28 20:51:08 +0100221// border: 1px solid #333;
Marc Kupietz83305222016-04-28 09:57:22 +0200222 overflow: hidden; /* if you don't want #second to wrap below #first */
223 }
224 #som2 svg {
225 border: 1px solid #333;
226 }
227
228 #cost {
229 font-size: 8pt;
230 color: #222222;
231 margin-top: 4px;
232 margin-bottom: 12px;
233 }
234
235 #sominfo1, #sominfo {
236 font-size: 8pt;
237 color: #222222;
238 margin-top: 0px;
239 }
240
241 #somcolor1, #somcolor2, #somcolor3 {
242 display: inline-block;
243 height: 10px;
244 width: 10px;
245 }
246
247 #third {
248 border: 1px solid #333;
249 }
250
251 </style>
252 <script>
253
254 var opt = {epsilon: <%= $epsilon %>, perplexity: <%= $perplexity %>},
255 mapWidth = 800, // width map
256 mapHeight = 800,
257 jitterRadius = 7;
258
259 var T = new tsnejs.tSNE(opt); // create a tSNE instance
260
261 var Y;
262
263 var data;
264 var labeler;
265
266 function applyJitter() {
Marc Kupietz4abcd682017-11-28 20:51:08 +0100267 svg.selectAll('.tsnet')
268 .data(labels)
269 .transition()
270 .duration(50)
271 .attr("transform", function(d, i) {
272 T.Y[i][0] = (d.x - mapWidth/2 - tx)/ss/20;
273 T.Y[i][1] = (d.y - mapHeight/2 - ty)/ss/20;
274 return "translate(" +
275 (d.x) + "," +
276 (d.y) + ")";
277 });
Marc Kupietz83305222016-04-28 09:57:22 +0200278 }
279
280 function updateEmbedding() {
Marc Kupietz4abcd682017-11-28 20:51:08 +0100281 var Y = T.getSolution();
282 svg.selectAll('.tsnet')
283 .data(data.words)
284 .attr("transform", function(d, i) {
285 return "translate(" +
286 ((Y[i][0]*20*ss + tx) + mapWidth/2) + "," +
287 ((Y[i][1]*20*ss + ty) + mapHeight/2) + ")"; });
Marc Kupietz83305222016-04-28 09:57:22 +0200288 }
289
290 var svg;
291 var labels = [];
292 var anchor_array = [];
293 var text;
294
295 function drawEmbedding() {
Marc Kupietz4abcd682017-11-28 20:51:08 +0100296 $("#embed").empty();
297 var div = d3.select("#embed");
298
299 // get min and max in each column of Y
300 var Y = T.Y;
301
302 svg = div.append("svg") // svg is global
303 .attr("width", mapWidth)
304 .attr("height", mapHeight);
305
306 var g = svg.selectAll(".b")
307 .data(data.words)
308 .enter().append("g")
309 .attr("class", "tsnet");
310
311 g.append("a")
312 .attr("xlink:href", function(word) {
313 return (data.urlprefix+word);})
314 .attr("class", function(d, i) {
315 var res="";
316 if(data.marked[i]) {
317 res="marked ";
318 }
319 if(data.target.indexOf(" "+d+" ") >= 0) {
320 return res+"target";
321 } else if(data.ranks[i] < data.mergedEnd) {
322 return res+"merged";
323 } else {
324 return res;
325 }
326 })
327 .attr("title", function(d, i) {
328 if(data.mergedEnd > 0) {
329 if(data.ranks[i] >= data.mergedEnd) {
330 return "rank: "+i +" "+"freq. rank: "+(data.ranks[i]).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
331 } else {
332 return "rank: "+i +" "+"freq. rank: "+data.ranks[i].toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",") + " (merged vocab)";
333 }
334 } else {
335 return "rank: "+i +" "+"freq. rank: "+data.ranks[i].toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
336 }
337 })
338 .append("text")
339 .attr("text-anchor", "top")
340 .attr("font-size", 12)
341 .text(function(d) { return d; });
342
343 var zoomListener = d3.behavior.zoom()
344 .scaleExtent([0.1, 10])
345 .center([0,0])
346 .on("zoom", zoomHandler);
347 zoomListener(svg);
Marc Kupietz83305222016-04-28 09:57:22 +0200348 }
349
350 var tx=0, ty=0;
351 var ss=1;
352 var iter_id=-1;
353
354 function zoomHandler() {
Marc Kupietz4abcd682017-11-28 20:51:08 +0100355 tx = d3.event.translate[0];
356 ty = d3.event.translate[1];
357 ss = d3.event.scale;
358 updateEmbedding();
Marc Kupietz83305222016-04-28 09:57:22 +0200359 }
360
361 var stepnum = 0;
362
363 function stopStep() {
Marc Kupietz4abcd682017-11-28 20:51:08 +0100364 clearInterval(iter_id);
365 text = svg.selectAll("text");
366
367 // jitter function needs different data and co-ordinate representation
368 labels = d3.range(data.words.length).map(function(i) {
369 var x = (T.Y[i][0]*20*ss + tx) + mapWidth/2;
370 var y = (T.Y[i][1]*20*ss + ty) + mapHeight/2;
371 anchor_array.push({x: x, y: y, r: jitterRadius});
372 return {
373 x: x,
374 y: y,
375 name: data.words[i]
376 };
377 });
378
379 // get the actual label bounding boxes for the jitter function
380 var index = 0;
381 text.each(function() {
382 labels[index].width = this.getBBox().width;
383 labels[index].height = this.getBBox().height;
384 index += 1;
385 });
Marc Kupietz83305222016-04-28 09:57:22 +0200386
Marc Kupietz4abcd682017-11-28 20:51:08 +0100387
388 // setTimeout(updateEmbedding, 1);
389 // setTimeout(
390 labeler = d3.labeler()
391 .label(labels)
392 .anchor(anchor_array)
393 .width(mapWidth)
394 .height(mapHeight)
395 .update(applyJitter);
396 // .start(1000);
Marc Kupietz83305222016-04-28 09:57:22 +0200397
Marc Kupietz4abcd682017-11-28 20:51:08 +0100398 iter_id = setInterval(jitterStep, 1);
Marc Kupietz83305222016-04-28 09:57:22 +0200399 }
400
401 var jitter_i=0;
402
403 function jitterStep() {
Marc Kupietz4abcd682017-11-28 20:51:08 +0100404 if(jitter_i++ > 100) {
405 clearInterval(iter_id);
406 } else {
407 labeler.start2(10);
408 applyJitter();
409 }
Marc Kupietz83305222016-04-28 09:57:22 +0200410 }
411
412 var last_cost=1000;
413
414 function step() {
Marc Kupietz4abcd682017-11-28 20:51:08 +0100415 var i = T.iter;
416
417 if(i > <%= $no_iterations %>) {
418 stopStep();
419 } else {
420 var cost = Math.round(T.step() * 100000) / 100000; // do a few steps
421 $("#cost").html("tsne iteration " + i + ", cost: " + cost.toFixed(5));
422 if(i % 250 == 0 && cost >= last_cost) {
423 stopStep();
424 } else {
425 last_cost = cost;
426 updateEmbedding();
427 }
428 }
Marc Kupietz83305222016-04-28 09:57:22 +0200429 }
430
431 function showMap(j) {
Marc Kupietz4abcd682017-11-28 20:51:08 +0100432 data=j;
433 T.iter=0;
434 T.initDataRaw(data.vecs); // init embedding
435 drawEmbedding(); // draw initial embedding
436
437 if(iter_id >= 0) {
438 clearInterval(iter_id);
439 }
440 //T.debugGrad();
441 iter_id = setInterval(step, 1);
442 if(<%= $show_som %>) {
443 makeSOM(j, <%= $no_iterations %>);
444 }
Marc Kupietz83305222016-04-28 09:57:22 +0200445 }
Marc Kupietz39179ab2017-07-04 16:28:06 +0200446 var queryword;
447
448 function onload() {
Marc Kupietz4abcd682017-11-28 20:51:08 +0100449 queryword = document.getElementById('word');
Marc Kupietz39179ab2017-07-04 16:28:06 +0200450 }
451
452 function queryKorAP() {
453 window.open('http://korap.ids-mannheim.de/kalamar/?q='+queryword.value, 'KorAP');
454 }
Marc Kupietz4dc270c2017-11-24 10:17:12 +0100455
456 function queryKorAPCII(query) {
457 window.open('http://korap.ids-mannheim.de/kalamar/?ql=cosmas2&q='+query, 'KorAP');
458 }
Marc Kupietz83305222016-04-28 09:57:22 +0200459 </script>
460 </head>
Marc Kupietz39179ab2017-07-04 16:28:06 +0200461 <body onload="onload()">
Marc Kupietz4abcd682017-11-28 20:51:08 +0100462 <div id="topwrapper">
463 <div id="options" class="widget">
464 <form>
465 <input id="word" type="text" name="word" size="20" placeholder="Word(s) to be searched" value="<%= $word %>"
466 title="When looking for multiple words use spaces as separators to search around the average vector and | as separator to get the neighbours for each word."/>
467 <input type="submit" value="SEARCH">
468 <fieldset>
469 <legend>Settings</legend>
470 <div class="controlgroup-vertical">
471 <label for="cutoff">cut-off</label>
472 <input id="cutoff" type="text" name="cutoff" size="10" value="<%= $cutoff %>" title="Only consider the most frequent x word forms.">
473 <label for="dedupe">dedupe</label>
474 <input id="dedupe" type="checkbox" name="dedupe" value="1" <%= ($dedupe ? "checked" : "") %> title="radically filter out any near-duplicates">
475 % if($mergedEnd > 0) {
476 <label for="sbf">backw.</label>
477 <input id="sbf" type="checkbox" name="sbf" value="1" <%= ($searchBaseVocabFirst ? "checked" : "") %> title="If checkecked base vocabulary will be searched first. Otherwise merged vocabulray will be searched first.">
478 % }
479 <label for="neighbours">max. neighbours:</label>
480 <input id="neighbours" size="4" name="n" value="<%= $no_nbs %>">
481 <label for="iterations">max. iterations</label>
482 <input id="iterations" name="N" size="4" value="<%= $no_iterations %>">
483 <label for="dosom">SOM</label>
484 <input id="dosom" type="checkbox" name="som" value="1" <%= ($show_som ? "checked" : "") %>>
485 % if($collocators) {
486 <label for="sortby">window/sort</label>
487 <select id="sortby" name="sort">
488 <option value="0" <%= ($sort!=1 && $sort!=2? "selected":"") %>>auto focus</option>
489 <option value="1" <%= ($sort==1? "selected":"") %>>any single position</option>
490 <option value="2" <%= ($sort==2? "selected":"") %>>whole window</option>
491 </select>
492 % }
493 <span> </span><input type="button" value="→ KorAP" onclick="queryKorAP();" title="query word with KorAP"/>
494 <br>
495 </div>
496 </fieldset>
497 </form>
Marc Kupietz0af83e32017-11-27 09:31:37 +0100498 </div>
Marc Kupietz4abcd682017-11-28 20:51:08 +0100499 <div id="tabs">
500 <ul>
Marc Kupietz4fcda0c2017-11-29 09:00:31 +0100501 <li><a href="#tabs-1">Semantics (TSNE-map)</a></li>
502 <li><a href="#tabs-2">Semantics (SOM)</a></li>
503 <li><a href="#tabs-3">Syntagmatic (collocators)</a></li>
Marc Kupietz4abcd682017-11-28 20:51:08 +0100504 </ul>
505 <div id="tabs-1">
506 % if($lists && (@$lists) > 0 && (@$lists)[0]) {
507 <div id="wrapper">
508 <div id="first" style="width:220px">
509 <table class="display compact nowrap" id="firsttable">
510 <thead>
511 <tr>
512 <th align="right">#</th><th align="right">cos</th><th align="left">paradigmatic</th>
513 </tr>
514 </thead>
515 <tbody>
516 % my $j=0; my @words; my @vecs; my @ranks; my @marked;
517 % for my $list (@$lists) {
518 % my $i=0; while($list) {
519 % my $item = (@$list)[$i];
520 % my $c = ($collocators? (@$collocators)[$i] : 0);
521 % last if(!$c && !$item);
522 <tr>
523 <td align="right">
524 <%= ++$i %>.
525 </td>
526 % if($item) {
527 % if(!grep{$_ eq $item->{word}} @words) {
528 % push @vecs, $item->{vector};
529 % push @words, $item->{word};
530 % push @ranks, $item->{rank};
531 % push @marked, ($marked->{$item->{word}}? 1 : 0);
532 % }
533 <td align="right">
534 <%= sprintf("%.3f", $item->{dist}) %>
535 </td>
536 <td>
537 % my $class = ($marked->{$item->{word}}? "marked " : "");
538 % my $r = $item->{rank};
539 % if($r < $mergedEnd) {
540 % $class .= "merged";
541 % $r .= " (merged vocab)";
542 % } elsif($mergedEnd!=0 && $r > $mergedEnd) {
543 % $r -= $mergedEnd;
544 % }
545 <a class="<%= $class =%>"
546 title="freq. rank: <%= $r =%>"
547 href="<%= url_with->query([word => $item->{word}]) =%>">
548 <%= $item->{word} =%>
549 </a>
550 </td>
551 % } else {
552 <td colspan="2"/>
553 % }
554 </tr>
555 % last if($i >= 100);
556 % }
557 % }
558 </tbody>
559 </table>
560 </div>
561 <script>
562 % use Mojo::ByteStream 'b';
563 % my $urlprefix = url_with->query([word=>'']);
564 $(window).load(function() {
565 showMap(<%= b(Mojo::JSON::to_json({target => " $word ", mergedEnd=> $mergedEnd, words => \@words, vecs => \@vecs, ranks => \@ranks, marked => \@marked, urlprefix => $urlprefix})); %>);
566 });
567 </script>
568 % } else {
569 <div id="wrapper">
570 <p>
571 ERROR: "<%= $word %>" not found in vocabluary.
572 </p>
573 </div>
574 % }
575 <div id="second">
576 <div id="embed">
577 </div>
578 <div id="cost">
579 </div>
Marc Kupietz4abcd682017-11-28 20:51:08 +0100580 </div>
Marc Kupietz4fcda0c2017-11-29 09:00:31 +0100581 </div>
Marc Kupietz4abcd682017-11-28 20:51:08 +0100582 </div>
Marc Kupietz4fcda0c2017-11-29 09:00:31 +0100583 <div id="tabs-2">
584 <div id="som2" style="width: 800; height: 800px">
585 </div>
586 <div id="sominfo1"><span id="somcolor1"> </span> <span id="somword1"> </span> <span id="somcolor2"> </span> <span id="somword2"> </span> <span id="somcolor3"> </span></div>
587 <div id="sominfo">SOM iteration <span id="iterations">0</span></div>
588 </div>
589 <div id="tabs-3">
Marc Kupietz4abcd682017-11-28 20:51:08 +0100590 <div id="second" style="width:500px">
591 <table class="display compact nowrap" id="secondtable">
592 <thead>
593 <tr>
594 % if($collocators) {
595 <th>#</th>
596 <th align="right" title="The window around the target word that is considered for summation.">w'</th>
597 <th align="right" title="Raw (max.) activation of the collocator in the output layers.">a</th>
598 <th title="Σp(c<sub><small>@</small></sub>) – Sum of the probability approximations that the combination of the target word and the collocator at the relative position @ come from the training corpus. Single approximations can be distorted because of sub-sampling frequent words and the sum cannot itself be interpreted as probability." align="right">Σp</th>
599 <th align="right">Σp/|w|</th>
600 <th title="c" align="left">collocator</th>
601 % }
602 </tr>
603 </thead>
604 <tbody>
605 % for(my $i=0; $i < 100; $i++) {
606 % my $c = ($collocators? (@$collocators)[$i] : 0);
607 <tr>
608 <td align="right">
609 <%= $i %>
610 </td>
611 % if($c) {
612 <td align="right">
613 <span class="mono"><%= bitvec2window( $c->{pos} ) %></span>
614 </td>
615 <td align="right">
616 <%= sprintf("%.3f", $c->{dist}) %>
617 </td>
618 <td align="right">
619 <%= sprintf("%.3e", $c->{norm}) %>
620 </td>
621 <td align="right">
622 <%= sprintf("%.3e", $c->{sum}) %>
623 </td>
624 <td align="left">
625 <a onclick="<%= sprintf("queryKorAPCII('%s /w5 %s')", $c->{word}, $word) =%>"
626 title="freq. rank: <%= $c->{rank} =%>">
627 <%= $c->{word} %>
628 </a>
629 </td>
630 % } else {
631 <td colspan="5"/>
632 % }
633 </tr>
634 % }
635 </tbody>
636 </table>
637 </div> <!-- - tab2 -->
Marc Kupietz4fcda0c2017-11-29 09:00:31 +0100638 </div> <!-- tabs -->
639 </div>
Marc Kupietz4abcd682017-11-28 20:51:08 +0100640 </div> <!-- topwrapper -->
641 <div style="clear: both;"></div>
Marc Kupietz0af83e32017-11-27 09:31:37 +0100642 </div>
Marc Kupietz4abcd682017-11-28 20:51:08 +0100643 % if($training_args) {
644 <p>
645 Word vector model trained with <a href="https://code.google.com/p/word2vec/">word2vec</a> using the following parameters: <pre><%= $training_args %></pre>
646 </p>
Marc Kupietz83305222016-04-28 09:57:22 +0200647 % }
Marc Kupietz4abcd682017-11-28 20:51:08 +0100648 </body>
Marc Kupietz83305222016-04-28 09:57:22 +0200649</html>