

# 자습서: AWS Glue로 기계 학습 변환 생성
<a name="machine-learning-transform-tutorial"></a>

이 자습서에서는 AWS Glue를 사용하여 ML(기계 학습) 변환을 생성하고 관리하는 작업을 안내합니다. 이 자습서를 사용하기 전에, AWS Glue 콘솔을 사용하여 크롤러 및 작업을 추가하고 스크립트를 편집하는 방법을 숙지해야 합니다. 또한 Amazon Simple Storage Service(Amazon S3) 콘솔에서 파일을 찾고 다운로드하는 방법도 잘 알아야 합니다.

이 예제에서는 `FindMatches` 변환을 만들어 일치하는 레코드를 찾고, 일치 레코드 및 불일치 레코드를 식별하는 방법을 변환에 학습시키고, AWS Glue 작업에 이 변환을 사용해 봅니다. AWS Glue 작업은 `match_id`라는 추가 열을 포함하는 새 Amazon S3 파일을 작성합니다.

이 자습서에서 사용하는 원본 데이터는 `dblp_acm_records.csv`라는 파일입니다. 이 파일은 원래의 [DBLP ACM 데이터 세트](https://doi.org/10.3886/E100843V2)에서 사용 가능한 교육용 게시물(DBLP 및 ACM)을 수정한 버전입니다. `dblp_acm_records.csv` 파일은 BOM(바이트 순서 표시) 없는 UTF-8 형식의 CSV(쉼표로 구분된 값) 파일입니다.

두 번째 파일인 `dblp_acm_labels.csv`는 이 자습서에 따라 변환을 학습시키는 데 사용할 일치 레코드와 불일치 레코드가 둘 다 들어 있는 레이블 지정 예제 파일입니다.

**Topics**
+ [1단계: 소스 데이터 크롤링](#ml-transform-tutorial-crawler)
+ [2단계: 기계 학습 변환 추가](#ml-transform-tutorial-create)
+ [3단계: 기계 학습 변환 학습](#ml-transform-tutorial-teach)
+ [4단계: 기계 학습 변환의 품질 예측](#ml-transform-tutorial-estimate-quality)
+ [5단계: 기계 학습 변환으로 작업 추가 및 실행](#ml-transform-tutorial-add-job)
+ [6단계: Amazon S3의 출력 데이터 확인](#ml-transform-tutorial-data-output)

## 1단계: 소스 데이터 크롤링
<a name="ml-transform-tutorial-crawler"></a>

우선, 원본 Amazon S3 CSV 파일을 크롤링하여 Data Catalog에 그와 상응하는 메타데이터 테이블을 생성합니다.

**중요**  
크롤러가 이 CSV 파일 전용의 테이블을 만들게 하기 위해 CSV 원본 데이터를 나머지 파일과 다른 Amazon S3 폴더에 저장합니다.

1. AWS Management Console에 로그인하여 [https://console.aws.amazon.com/glue/](https://console.aws.amazon.com/glue/)에서 AWS Glue 콘솔을 엽니다.

1. 탐색 창에서 **크롤러**, **크롤러 추가**를 선택합니다.

1. 마법사를 따라 `demo-db-dblp-acm` 데이터베이스로 출력되는 `demo-crawl-dblp-acm`이라는 크롤러를 만들고 실행합니다. `demo-db-dblp-acm` 데이터베이스가 아직 없으면 이 마법사를 실행하는 동안 만듭니다. 현재 AWS 리전에 있는 샘플 데이터로 이동하는 Amazon S3 포함 경로를 선택합니다. 예를 들어 `us-east-1`의 경우, Amazon S3에서 소스 파일로 이동하는 포함 경로는 `s3://ml-transforms-public-datasets-us-east-1/dblp-acm/records/dblp_acm_records.csv`입니다.

   작업이 성공하면 크롤러가 id, title, authors, venue, year 및 source 열이 있는 `dblp_acm_records_csv` 테이블을 만듭니다.

## 2단계: 기계 학습 변환 추가
<a name="ml-transform-tutorial-create"></a>

다음으로, `demo-crawl-dblp-acm`이라는 크롤러에서 만든 데이터 원본 테이블의 스키마를 토대로 한 기계 학습 변환을 추가합니다.

1. AWS Glue Console의 탐색 창의 **데이터 통합 및 ETL** 아래에서 **데이터 분류 도구 > 레코드 일치**를 선택한 다음 **변환 추가**를 선택합니다. 마법사를 따라 다음 속성으로 `Find matches` 변환을 생성합니다.

   1. **변환 이름**으로 **demo-xform-dblp-acm**을 입력합니다. 이것은 원본 데이터에서 일치 항목을 찾을 때 사용하는 변환의 이름입니다.

   1. **IAM 역할(IAM role)**로는 Amazon S3 원본 데이터, 레이블 지정 파일 및 AWS Glue API 작업에 대한 권한이 있는 IAM 역할을 선택합니다. 자세한 내용은 *AWS Glue Developer Guide*의 [Create an IAM Role for AWS Glue](https://docs.aws.amazon.com/glue/latest/dg/create-an-iam-role.html)를 참조하세요.

   1. [**데이터 원본(Data source)**]의 경우, 데이터베이스 [**demo-db-dblp-acm**]의 [**dblp\_acm\_records\_csv**]라는 이름의 테이블을 선택합니다.

   1. **기본 키**로는 테이블의 기본 키 열(**id**)을 선택합니다.

1. 마법사에서 **완료**를 선택하고 **ML transforms(ML 변환)** 목록으로 돌아갑니다.

## 3단계: 기계 학습 변환 학습
<a name="ml-transform-tutorial-teach"></a>

이제 자습서의 레이블 지정 샘플 파일을 사용하여 기계 학습 변환을 학습시켜야 합니다.

**Ready for use(사용 준비 완료)** 상태가 되기 전에는 기계어 변환을 ETL(추출, 변환, 로드) 작업에 사용할 수 없습니다. 변환을 준비시키려면 일치 레코드와 불일치 레코드의 예제를 제공하여 일치 및 불일치 레코드를 식별하는 방법을 가르쳐야 합니다. 변환을 학습시키기 위해 **레이블 파일을 생성**하고, 레이블을 추가하고, 그 **레이블 파일을 업로드**할 수 있습니다. 이 자습서에서는 `dblp_acm_labels.csv`라는 레이블 지정 예제 파일을 사용합니다. 레이블 지정 프로세스에 대한 자세한 내용은 [레이블링](machine-learning.md#machine-learning-labeling) 단원을 참조하십시오.

1. AWS Glue Console의 탐색 창에서 **레코드 일치**를 선택합니다.

1. `demo-xform-dblp-acm` 변환을 선택한 다음 **Action(작업)**과 **Teach(학습)**를 선택합니다. 마법사를 따라 `Find matches` 변환을 학습시킵니다.

1. 변환 속성 페이지에서 **I have labels(레이블 있음)**를 선택합니다. 현재 AWS 리전에 있는 샘플 레이블 지정 파일로 이동하는 Amazon S3 경로를 선택합니다. 예를 들어 `us-east-1`의 경우, Amazon S3 경로 `s3://ml-transforms-public-datasets-us-east-1/dblp-acm/labels/dblp_acm_labels.csv`에서 제공한 레이블 지정 파일을 업로드하되 기존 레이블 [**덮어쓰기(overwrite)**] 옵션을 포함합니다. 레이블 지정 파일이 AWS Glue 콘솔과 같은 리전의 Amazon S3에 있어야 합니다.

   레이블 지정 파일을 업로드하면 해당 변환에 데이터 원본 처리 방법을 학습시키는 데 사용할 레이블을 추가하거나 덮어쓰는 작업이 AWS Glue에서 시작됩니다.

1. 마법사의 마지막 페이지에서 **완료**를 선택하고 **ML transforms(ML 변환)** 목록으로 돌아옵니다.

## 4단계: 기계 학습 변환의 품질 예측
<a name="ml-transform-tutorial-estimate-quality"></a>

이제 기계 학습 변환의 품질을 예측할 수 있습니다. 품질은 레이블 지정 작업을 얼마나 많이 했는지에 따라 달라집니다. 품질 예측에 대한 자세한 내용은 [품질 예측](console-machine-learning-transforms.md#console-machine-learning-transforms-metrics) 단원을 참조하십시오.

1. AWS Glue Console의 탐색 창의 **데이터 통합 및 ETL**에서 **데이터 분류 도구 > 레코드 일치**를 선택합니다.

1. `demo-xform-dblp-acm` 변환을 선택하고 **Estimate quality(품질 예측)** 탭을 선택합니다. 해당 변환의 현재 품질이 예측되어 있으면 이 탭에 표시됩니다.

1. **Estimate quality(품질 예측)**를 선택하여 변환의 품질 예측 작업을 시작합니다. 품질 예측의 정확성은 원본 데이터의 레이블 지정에 달려 있습니다.

1. **History(기록)** 탭으로 이동합니다. 이 창에는 **Estimating quality(품질 예측)** 작업을 비롯하여 해당 변환에 실행한 작업이 나열되어 있습니다. 작업 실행에 대한 자세한 내용은 **로그**를 참조하십시오. 완료된 작업의 실행 상태가 **성공**인지 확인합니다.

## 5단계: 기계 학습 변환으로 작업 추가 및 실행
<a name="ml-transform-tutorial-add-job"></a>

이 단계에서는 기계 학습 변환을 사용하여 AWS Glue에서 작업을 추가하고 실행해 봅니다. `demo-xform-dblp-acm` 변환이 **Ready for use(사용 준비 완료)** 상태이면 ETL 작업에 사용할 수 있습니다.

1. AWS Glue 콘솔의 탐색 창에서 **작업**을 선택합니다.

1. **작업 추가**를 선택하고, 마법사의 단계에 따라 생성된 스크립트로 ETL Spark 작업을 만듭니다. 변환에 대해 다음 속성 값을 선택하십시오.

   1. **이름**으로 이 자습서의 예제 작업인 **demo-etl-dblp-acm**을 선택합니다.

   1. [**IAM 역할(IAM role)**]로는 Amazon S3 원본 데이터, 레이블 지정 파일 및 AWS Glue API 작업에 대한 권한이 있는 IAM 역할을 선택합니다. 자세한 내용은 *AWS Glue Developer Guide*의 [Create an IAM Role for AWS Glue](https://docs.aws.amazon.com/glue/latest/dg/create-an-iam-role.html)를 참조하세요.

   1. **ETL 언어**로 **Scala**를 선택합니다. 이것은 ETL 스크립트의 프로그래밍 언어입니다.

   1. **스크립트 파일 이름**으로 **demo-etl-dblp-acm**을 선택합니다. 이것은 Scala 스크립트의 파일 이름입니다(작업 이름과 동일).

   1. **데이터 원본**으로 **dblp\_acm\_records\_csv**를 선택합니다. 선택한 데이터 원본이 기계 학습 변환의 데이터 원본 스키마와 일치해야 합니다.

   1. **Transform type(변환 유형)**으로 **Find matching records(일치 레코드 찾기)**를 선택하여 기계 학습 변환을 사용하는 작업을 만듭니다.

   1. **Remove duplicate records(중복 레코드 제거)**를 선택 취소합니다. 작성되는 출력 레코드에 `match_id` 필드가 하나 더 추가되므로 중복 레코드를 제거하지 않아도 됩니다.

   1. **변환**으로 이 작업에 사용할 기계 학습 변환인 **demo-xform-dblp-acm**을 선택합니다.

   1. **데이터 대상에서 테이블 생성**에서 다음 속성의 테이블을 만들도록 선택합니다.
      + [**데이터 스토어 유형(Data store type)**] - **Amazon S3**
      + [**포맷(Format)**] - **CSV**
      + [**압축 유형(Compression type)** - **None**
      + [**대상 경로(Target path)**] - 작업의 출력이 쓰이는 Amazon S3 경로(현재 콘솔 AWS 리전에서)

1. **작업 저장 및 스크립트 편집**을 선택하여 스크립트 편집기 페이지를 표시합니다.

1. **대상 경로**에 대한 작업 출력을 파티션 파일 하나에 쓰도록 하는 문을 추가하여 스크립트를 편집합니다. `FindMatches` 변환을 실행하는 문 바로 뒤에 이 문을 추가합니다. 이 문은 다음과 비슷합니다.

   ```
   val single_partition = findmatches1.repartition(1) 
   ```

   출력을 `.writeDynamicFrame(single_partion)`으로 쓰도록 `.writeDynamicFrame(findmatches1)` 문을 수정해야 합니다.

1. 스크립트를 편집한 다음 **저장**을 선택합니다. 수정된 스크립트는 다음 코드와 비슷한 모양이지만 사용자 환경에 맞게 조정되어 있습니다.

   ```
   import com.amazonaws.services.glue.GlueContext
   import com.amazonaws.services.glue.errors.CallSite
   import com.amazonaws.services.glue.ml.FindMatches
   import com.amazonaws.services.glue.util.GlueArgParser
   import com.amazonaws.services.glue.util.Job
   import com.amazonaws.services.glue.util.JsonOptions
   import org.apache.spark.SparkContext
   import scala.collection.JavaConverters._
   
   object GlueApp {
     def main(sysArgs: Array[String]) {
       val spark: SparkContext = new SparkContext()
       val glueContext: GlueContext = new GlueContext(spark)
       // @params: [JOB_NAME]
       val args = GlueArgParser.getResolvedOptions(sysArgs, Seq("JOB_NAME").toArray)
       Job.init(args("JOB_NAME"), glueContext, args.asJava)
       // @type: DataSource
       // @args: [database = "demo-db-dblp-acm", table_name = "dblp_acm_records_csv", transformation_ctx = "datasource0"]
       // @return: datasource0
       // @inputs: []
       val datasource0 = glueContext.getCatalogSource(database = "demo-db-dblp-acm", tableName = "dblp_acm_records_csv", redshiftTmpDir = "", transformationContext = "datasource0").getDynamicFrame()
       // @type: FindMatches
       // @args: [transformId = "{{tfm-123456789012}}", emitFusion = false, survivorComparisonField = "<primary_id>", transformation_ctx = "findmatches1"]
       // @return: findmatches1
       // @inputs: [frame = datasource0]
       val findmatches1 = FindMatches.apply(frame = datasource0, transformId = "{{tfm-123456789012}}", transformationContext = "findmatches1", computeMatchConfidenceScores = true)
     {{
     
       // Repartition the previous DynamicFrame into a single partition. 
       val single_partition = findmatches1.repartition(1)    
    
   }}    
       // @type: DataSink
       // @args: [connection_type = "s3", connection_options = {"path": "s3://aws-glue-ml-transforms-data/sal"}, format = "csv", transformation_ctx = "datasink2"]
       // @return: datasink2
       // @inputs: [frame = findmatches1]
       val datasink2 = glueContext.getSinkWithFormat(connectionType = "s3", options = JsonOptions("""{"path": "s3://aws-glue-ml-transforms-data/sal"}"""), transformationContext = "datasink2", format = "csv").writeDynamicFrame({{single_partition}})
       Job.commit()
     }
   }
   ```

1. **작업 실행**을 선택하여 작업을 실행하기 시작합니다. 작업 목록에서 작업의 상태를 확인합니다. 작업이 완료되면 **ML transform(ML 변환)**의 **History(기록)** 탭에 새로운 **실행 ID** 행이 **ETL 작업** 유형으로 추가됩니다.

1. **작업**, **History(기록)** 탭으로 이동합니다. 이 창에는 작업 실행이 나열되어 있습니다. 작업 실행에 대한 자세한 내용은 **로그**를 참조하십시오. 완료된 작업의 실행 상태가 **성공**인지 확인합니다.

## 6단계: Amazon S3의 출력 데이터 확인
<a name="ml-transform-tutorial-data-output"></a>

이 단계에서는 작업을 추가할 때 선택한 Amazon S3 버킷에서 작업 실행의 출력을 확인합니다. 출력 파일을 로컬 시스템에 다운로드하고, 일치하는 레코드가 식별되었는지 확인할 수 있습니다.

1. [https://console.aws.amazon.com/s3/](https://console.aws.amazon.com/s3/)에서 S3 콘솔을 엽니다.

1. `demo-etl-dblp-acm` 작업의 대상 출력 파일을 다운로드합니다. 해당 파일을 스프레드시트 애플리케이션에서 엽니다. (파일을 제대로 열려면 파일 확장명 `.csv`를 추가해야 할 수 있음)

   아래 그림은 Microsoft Excel의 출력을 발췌한 것입니다.  
![변환의 출력이 표시된 Excel 스프레드시트](http://docs.aws.amazon.com/ko_kr/glue/latest/dg/images/demo_output_dblp_acm.png)

   데이터 원본과 대상 파일 모두 레코드가 4,911개 있습니다. 그러나 `Find matches` 변환은 출력에서 일치하는 레코드를 식별하기 위해 `match_id`라는 열을 하나 더 추가합니다. `match_id`가 동일한 행은 일치하는 레코드로 간주됩니다. `match_confidence_score`는 `Find matches`에서 찾은 일치 항목의 품질을 추정하는, 0에서 1 사이의 숫자입니다.

1. 일치하는 레코드를 보기 쉽도록 출력 파일을 `match_id`로 정렬합니다. 나머지 열의 값을 비교하여 `Find matches` 변환의 결과에 동의할 만한지 알아봅니다. 동의할 수 없으면 계속해서 레이블을 더 추가하여 변환을 학습시킬 수 있습니다.

   또한 `title` 등 다른 필드를 기준으로 파일을 정렬하여 제목이 비슷한 레코드의 `match_id`가 동일한지 확인할 수도 있습니다.