DL4J의 Word2Vec을 활용하여 여러가지 실험을 해보고 있습니다.


DL4J 내부적으로 다차원 vector로 처리된 파일을 사람이 인지할 수 있도록 2차원으로 차원을 축소하여 csv 파일로 변환하는 tsne library를 제공하고 있습니다.


해당 tsne로 처리된 csv파일을 이미지화 하기 위해서 DL4J 내부적으로 UIServer를 제공합니다만, 아무리 노력해도 해당서버는 장황한 에러메시지를 뱉아내며 실행이 되지 않습니다.


UIServer의 문제를 해결해볼까 하다가, 그림 그리기가 그리 복잡하지 않은 듯 하여 D3.js를 활용하여, csv 파일 시각화하는 코드를 작성해 보았습니다.


아래는 어느 무협지를 학습시켜서, tsne로 2차원 csv 파일 추출후, 시각화한 화면입니다.




이해할 수 없는 부분이 더 많기는 합니다만, 중간중간 의미적으로 유사성이 높은 단어가 뭉쳐져 있는 모습을 확인 할 수 있습니다.


저같은 시각화로 인한 고민을 하시는 분들이 어딘가엔 계실듯 하여 대충 만들어진 html 파일을 공유합니다. 

csv파일 로딩 때문에 톰켓이나 was에 올려야 동작하며, 적절히 수정해서 쓰시면 될 듯 합니다.

파일처리를 위하여 csv 상단에 아래의 header가 추가되어야 합니다.

 ax,ay,word

1601.4119873046875,2464.052734375,검법 

-5537.662109375,1058.436767578125,독물 

-1954.671142578125,-3149.0380859375,탄로 

57.20676040649414,494.7344970703125,부축 

0.006148473359644413,-0.020917901769280434,시인 

0.001806588377803564,0.13746240735054016,겸허 

-0.039052389562129974,-0.013289138674736023,동료 


....



html 파일


 <html>

<head>

<title>D3 Axis Example</title>

<script src="http://d3js.org/d3.v2.js"></script>

<style type="text/css">

.axis path,

.axis line {

fill: none;

stroke: black;

shape-rendering: crispEdges;

}

.axis text {

font-family: sans-serif;

font-size: 9px;

}


</style>

    </head>

    

    <body>

    

    <script>

        var width = 1000,   // width of svg

            height = 1000,  // height of svg

            padding = 40; // space around the chart, not including labels

       

        var x_domain = [-500, 500],

        y_domain = [-500, 500];

            

        // display date format

        var  date_format = d3.time.format("%d %b");

        

        // create an svg container

        var vis = d3.select("body").

            append("svg:svg")

                .attr("width", width + padding * 2)

                .attr("height", height + padding * 2);

                

        // define the y scale  (vertical)

        var yScale = d3.scale.linear()

        .domain(y_domain) // make axis end in round number

.range([height - padding, padding]);   

            

        var xScale = d3.scale.linear()

        .domain(x_domain)    // values between for month of january

    .range([padding, width - padding]);   

        // define the y axis

        var yAxis = d3.svg.axis()

            .orient("left")

            .scale(yScale);

        

        // define the x axis

        var xAxis = d3.svg.axis()

            .orient("bottom")

            .scale(xScale);

            //.tickFormat(date_format);

            

        // draw y axis with labels and move in from the size by the amount of padding

        vis.append("g")

        .attr("class", "axis")

            .attr("transform", "translate("+ (width/2 ) +",0)")

            .call(yAxis);


        // draw x axis with labels and move to the bottom of the chart area

        vis.append("g")

            .attr("class", "xaxis axis")  // two classes, one for css formatting, one for selection below

            .attr("transform", "translate(0," + (height/2) + ")")

            .call(xAxis);

            

          vis.selectAll(".xaxis text")  // select all the text elements for the xaxis

          .attr("transform", function(d) {

             return "translate(" + this.getBBox().height*-2 + "," + this.getBBox().height + ")rotate(-45)";

         });

    

        vis.append("text")

            .attr("text-anchor", "middle")  // this makes it easy to centre the text as the transform is applied to the anchor

            .attr("transform", "translate("+ (padding/2) +","+(height/2)+")rotate(-90)")  // text is drawn off the screen top left, move down and out and rotate

            .text("Y-axis");


        vis.append("text")

            .attr("text-anchor", "middle")  // this makes it easy to centre the text as the transform is applied to the anchor

            .attr("transform", "translate("+ (width/2) +","+(height-(padding/3))+")")  // centre below axis

            .text("X-axis");

        

        var maxX = 10, 

        maxY = 10;

        var dirX = 1, 

        dirY = 1 ;

        

        // check max value

        d3.csv("visual7.csv", function(data){

        data.forEach(function(d){

        //console.log(d.ax + ' --- ' + maxX + ' === ' + (d.ax > maxX));

        if(Math.abs(d.ax) > maxX) maxX = Math.abs(d.ax);

        if(Math.abs(d.ay) > maxY) maxY = Math.abs(d.ay);

        });

        console.log('max X:Y = ' + maxX + ':' + maxY);

        // draw text

        drawText(vis) ;

        });

               

        function drawText(pannel) {

        d3.csv("visual7.csv", function(data){

            data.forEach(function(d){

              console.log('Word -> ' + d.ax + ',' + d.ay + ':' + d.word);

                        

              pannel.append("text")

          .style("font-size", "10px")

          .attr("x", ((d.ax/maxX) * (width/2) + width/2))

          .attr("y", (height/2 - (d.ay/maxY) * (height/2)))

          .attr("dy", '-10')

          .text(d.word)

          

            });

          });

        }

    </script>

    

    </body>

</html>


다차원을 2차원으로 축소하는 개념이라 왜곡이나 이해 못 할 부분들이 많은 것 같습니다.

t-sne 의 여러 옵션에 대한 이해가 있어야 아름다운 그림이 나올 듯 하네요. 


옵션에 대한 대략적인 이해는 아래 링크를 참조하면 될 듯 하네요.. (결국엔 이것저것 넣어보고 돌려보는게 답일 듯.. -_-)


http://docs.flowjo.com/v9/flowjo-v9-documentation-home/platforms/t-sne/


'Expired > Web Art' 카테고리의 다른 글

Java 물리 시뮬레이션 툴  (0) 2008.11.03
Tree Viewer  (0) 2008.11.02

+ Recent posts