IV. 데이터분 의실 예 1. Mahout 83 를이용한군집분 (1). Mahout 프 의 Mahout 는 Apache 프 의한분 진 되 는기계 습용 Java 브 다. 기계 습 란 84 컨대 ' 대상 터 대 컴퓨터 알 분 할 을 는것 ' 을말 는 간 런기 터 닝솔 션들 현되 활 히 용되 다. 다 최근 Hadoop 의 MapReduce 프 워크활용을전 한기계 습프 램으 Mahout 되 인기를끌 다. Mahout 는 Lucene 프 되 되 다. 스 검 및 스 프 인 Lucene 스 닝관련된프 램 꾸준히 되 2008 년 를 Mahout 프 키게된것 다. 별 프 한 기 Mahout 는 Taste 는별 의기계 습용프 램 흡 짧은 간 의계기를 다. Mahout 와관련된 종프 으 표현되 다. 83 Mahout 는흔히 ' ' 음한다. 84 앞 기계 습을 인공 의한 으 람 닌컴퓨터 습할 알 즘을연 및분, 는기술 의한 다. 268
다중 한것은 Mahout 터 닝알 즘몇 를 현 다는것외 들을 현 Hadoop 의 MapReduce 프 워크와결 을 다는것 다. 계산 많은 닝은 컴퓨터의큰메 와연산기 을 만 Mahout 는최대한 MapReduce 기 을활용 터분 다용 졌다.. Mahout 의설 Mahout 다른 Java 응용프 램설 와 찬 JVM 위 동 므 대한환 선 한다. 위 Maven 의 설 필 다. 는 Mahout 현재활 히 진 중 update 와 upgrade 빈번 므 들관 를 동 기위한것 다., 브 의존관계및컴파 관 를 Maven 는 build 및 release 관 프 램을통 실 한다. 다른 건으 는 Mahout 는 히 Hadoop 의 MapReduce 분산 기 의활용을전 므 Mahout 의운 을위 는 Hadoop 을설 한다. 울 프 램의 및 을위한 환 85 을선 한다., 선 한 IDE Mahout 프 를생 는방 으 Mahout 를설 한다. 85 Eclipse, NetBeans 등을 인의취향 따 선. 269
다. Mahout 공 는기 Mahout 는 떤프 못 않게활 히 진 중 며 운기 들 되 으므 당프 현황을홈페 를통 인할필 다. 2013 년 7 월현재 86 Mahout 는다음 같은기 을 공한다. Collaborative Filtering 천 스 예 : Amazon의 분 따른 천. 군 (clustering) K-Means, Fuzzy K-Means Mean Shift clustering Dirichlet process clustering LDA (Latent Dirichlet Allocation) 빈 턴 닝 분류 (Classification) Naive Bayes 분류기 Random forest 의 결 분류기 기 는 Mahout 의군 대 만살펴본다. 외의기 대 는 Mahout 프 (mahout.apache.org) 를참. 86 version 0.7 270
(2) Mahout 의군 기 87. 첫 : 단순 표 터의군 례 군 현 중 한것은 다 항 간의 질 을 떻게판단 를 떻게프 램 표현할것인 의문 다. 한편, 앞 는 군 관련 근 을살펴본 는 Mahout 용 는 체 알 즘중 기 는 히대표 인알 즘의 인 k-means 를 용 기 한다. k-means fuzzy k-means canopy 기 단순한예를통 Mahout 용방 을살펴본다. 다음 같 x-y 표계상의 으 표현되는 9 의 (point) 주 졌다. 다음페 의 표 당 9 터 되 오른편 를 x-y 표면 표 다. 들 9 을 Mahout 를 용 2 룹으 군 는것 기 의 용 다. 선 들 터를프 램 기위 는 진의 터 맷을 SequenceFile 표현한다. 87 Mahout 를이용한군집화사례에대한설명은 Sean Owen ( 외 ), Mahout In Action, 2012 의해당부분을인용및 정 다. 271
(x 표, y 표 ) (1,1) (2,1) (1,2) (2,2) (3,3) (8,8) (8,9) (9,8) (9,9) 흔히 터 (vector) 란 ' 크기와방향을동 는 량 ' 을뜻 만 Mahout 는 터의 를 ordered list 의 표현한것을의 한다. 히단순한예 는 를 2 원 표상의 대한 터를 ordered list 표현한것으 볼 다. 먼 k-means 알 즘 필 한 다음파 터를 한다. SequenceFile: 할 터 와, 군 별중 대한 를 기 한다. 평 대한. 평 의다양한거 념 대 앞 살펴본 다. EuclideanDistanceMeasure의 Euclide 거 를 용할때 용된다. convergencethreshold : 기 된 를출 으 군 반 으 진 되는 한반 을계 할 부 대한판단기준을 낸다. 터 대한 Vector 들 를 다음의순 군 을 한다. 272
Vectorizatoin 입력데이터를 vector 형태 변환 Vector 를해당위치에기 입력데이터 군집화 (clustering) 업을반복수행 출력디렉토리 업결과를획득 중심부초기화 목표군집 (grouping) 의중심위치를지정 을 는 Java 프 램 다음 같 되 다. public class MahoutClusterFirst { public static final double[][] points ={{1,1,{2,1,{1,2,{2,2,{3,3,{8,8,{9,8,{8,9,{9,9; public static void writepointstofile(list<vector> points, String filename, FileSystem fs, Configuration conf) throws IOException { Path path = new Path(fileName); SequenceFile.Writer writer = new SequenceFile.Writer(fs, conf, path, LongWritable.class, VectorWritable.class); long recnum = 0; VectorWritable vec = new VectorWritable(); for (Vector point : points) { vec.set(point); writer.append(new LongWritable(recNum++), vec); writer.close(); public static List<Vector> getpoints(double[][] raw) { List<Vector> points = new ArrayList<Vector>(); for (int i = 0; i < raw.length; i++) { double[] fr = raw[i]; Vector vec = new RandomAccessSparseVector(fr.length); vec.assign(fr); 273
points.add(vec); return points; public static void main(string args[]) throws Exception { int k = 2; List<Vector> vectors = getpoints(points); File testdata = new File("testdata"); if (!testdata.exists()) { testdata.mkdir(); testdata = new File("testdata/points"); if (!testdata.exists()) { testdata.mkdir(); Configuration conf = new Configuration(); FileSystem fs = FileSystem.get(conf); writepointstofile(vectors,"testdata/points/file1",fs,conf); Path path = new Path("testdata/clusters/part-00000"); SequenceFile.Writer writer = new SequenceFile.Writer( fs, conf, path, Text.class, Cluster.class); for (int i = 0; i < k; i++) { Vector vec = vectors.get(i); Cluster cluster = new Cluster( vec, i, new EuclideanDistanceMeasure()); writer.append(new Text(cluster.getIdentifier()), cluster); writer.close(); KMeansDriver.run(conf, new Path("testdata/points"), new Path("testdata/clusters"), new Path("output"), new EuclideanDistanceMeasure(), 0.001, 10, true, false); SequenceFile.Reader reader = new SequenceFile.Reader(fs, new Path("output/" + Cluster.CLUSTERED_POINTS_DIR + "/part-m-00000"), conf); IntWritable key = new IntWritable(); WeightedVectorWritable value 274
= new WeightedVectorWritable(); while (reader.next(key, value)) { System.out.println( value.tostring() + " belongs to cluster " + key.tostring()); reader.close(); 위프 램 는주 진 터를 2 의 룹으 기위한 군 의출 으 (1,1) (2,1) 의 2 을 는 따른산출 다음 표 되 다. 1.0: [1.000, 1.000] belongs to cluster 0 1.0: [2.000, 1.000] belongs to cluster 0 1.0: [1.000, 2.000] belongs to cluster 0 1.0: [2.000, 2.000] belongs to cluster 0 1.0: [3.000, 3.000] belongs to cluster 0 1.0: [8.000, 8.000] belongs to cluster 1 1.0: [9.000, 8.000] belongs to cluster 1 1.0: [8.000, 9.000] belongs to cluster 1, 맨 음 되 던 9 의 들 표 터 따 cluster-0 와 cluster-1 의 2 룹으 군 되 음을알 다. 275
앞 듯 88 거 념 는 상황 따 선 게되는 Mahout 브 EucliideanDistanceMeasure 외 다음의다양한거 공되 다. SquredEucliideanDistanceMeasure ManhattanDistanceMeasure CosineDistanceMeasure TanimotoDistanceMeasure WeightedDistanceMeasure 들 의 용은 름으 쉽게눈 챌 거 대한설명 앞부분 으므 주 거 용을 으 표현한것을 는것으 대신한다. 위 중왼 Euclid 거 와 Manhattan 거 계산을 교 다. 오른 는 cosine 의한거 계산방 을 주 다. 88 III. 분 기 3. 주 분 기 (5) 군 론 ( ) 간 276
한편 살펴본 9 의 대한 표 터 위의 다른 거 를 용한결 다음 같다. 거 반 0 번군 1 번군 는 vector 는 vector EucliideanDistanceMeasure 3 0,1,2,3,4 5,6,7,8 SquredEucliideanDistanceMeasure 5 0,1,2,3,4 5,6,7,8 ManhattanDistanceMeasure 3 0,1,2,3,4 5,6,7,8 CosineDistanceMeasure 1 1 0,2,3,4, 5,6,7,8 TanimotoDistanceMeasure 3 0,1,2,3,4 5,6,7,8 위결 를 면 반 다르 결 한 음을알 다. 는 거 의절대 열때문 기 다 용분 따 한 을 는것으 볼 을것 다.. 둘째 : 턴의군 례 실 의군 는앞 표 터와같 터 단순한 주 않으므 분 대상 되는 체의 터를올 르게 vector 터 변환 는 선 되 한다. Mahout 는다음 3 class 를통 vector 터를표현한다. DenseVector: vector 터를 double 터 의 열의 표현 는 class 다. RandomAccessSparseVector: HashMap으 현된 random access 용의 sparse vector 다. SequentialAccessSparseVector: 순 용 vector 다. 277
들중 떤클 스를 용 분 대상 되는 체 터를 vector 표현할것인 는 용알 즘 따 진다. Mahout 는 vector 를 Java 의 interface 공 는 히관련 vector 터중빈항 많은 -, sparse 인 - 를 sparse vector 대부분의 vector 터 실 터 워진 를 dense vector 한다. Mahout 는 다양한 vector 연산을할 class 되 다. 의예 를분류 는예를살펴본다. 를분류할때는 선크기, 깔, 게등의 떤분류기준을 용할것인 한다. 론 만 다면 떤것 든분류기준으 을 들 를 중 용 종 판단 다. 편의상 는다음 같 표와같 게 (Kg 단위 ), 깔 (, 빨, ), 크기 (Small, Large, Medium) 다른 5 의 주 졌다. 게 (Kg) 깔 (RGB) 크기 Vector 분 대상 0 원 1 원 2 원 터표현 Small,round, green 0.11 510 1 [0.11, 510,1] Large, oval, red 0.23 650 3 [0.23, 650,3] Small,elongated, red 0.09 630 1 [0.09,630,1] Large, round, yellow 0.25 590 3 [0.25,590,3] Medium, Oval, green 0.18 520 2 [0.18,520,2] Mahout 들 터의 vector 표현은 들 터를 의 원으 표현 는 위표의 열 표 되 다. 를분류 기위한 vector 생 프 램은다음 같다. 278
public class MahoutClsterSecond { public class MahoutClusterFirst { public static final double[][] points = {{1, 1, {2, 1, {1, 2, {2, 2, {3, 3, {8, 8, {9, 8, {8, 9, {9, 9; public static void writepointstofile(list<vector> points, String filename, FileSystem fs, Configuration conf) throws IOException { Path path = new Path(fileName); SequenceFile.Writer writer =new SequenceFile.Writer(fs, conf, path, LongWritable.class, VectorWritable.class); long recnum = 0; VectorWritable vec = new VectorWritable(); for (Vector point : points) { vec.set(point); writer.append(new LongWritable(recNum++), vec); writer.close(); public static List<Vector> getpoints(double[][] raw) { List<Vector> points = new ArrayList<Vector>(); for (int i = 0; i < raw.length; i++) { double[] fr = raw[i]; Vector vec=new RandomAccessSparseVector(fr.length); vec.assign(fr); points.add(vec); return points; public static void main(string args[]) throws Exception { int k = 2; List<Vector> vectors = getpoints(points); File testdata = new File("testdata"); if (!testdata.exists()) { testdata.mkdir(); testdata = new File("testdata/points"); if (!testdata.exists()) { 279
testdata.mkdir(); Configuration conf = new Configuration(); FileSystem fs = FileSystem.get(conf); writepointstofile(vectors, "testdata/points/file1", fs, conf); Path path = new Path("testdata/clusters/part-00000"); SequenceFile.Writer writer = new SequenceFile.Writer( fs, conf, path, Text.class, Cluster.class); for (int i = 0; i < k; i++) { Vector vec = vectors.get(i); Cluster cluster = new Cluster( vec, i, new EuclideanDistanceMeasure()); writer.append(new Text(cluster.getIdentifier()), cluster); writer.close(); KMeansDriver.run(conf, new Path("testdata/points"), new Path("testdata/clusters"), new Path("output"), new EuclideanDistanceMeasure(), 0.001, 10, true, false); SequenceFile.Reader reader = new SequenceFile.Reader(fs,new Path("output/" + Cluster.CLUSTERED_POINTS_DIR + "/part-m-00000"), conf); IntWritable key = new IntWritable(); WeightedVectorWritable value = new WeightedVectorWritable(); while (reader.next(key, value)) { System.out.println( value.tostring() + " belongs to cluster " + key.tostring()); reader.close(); 게표현된 vector 터 대 앞 표 을분류 와 같 알 즘을선 면분류 완 되게된다. 280