AI-자연어처리

[Huggingface Tutorial/Ch5] Dataset Library로 huggingface에 데이터셋 다루기 1

옆동네애옹이 2024. 3. 29. 01:20
728x90

- 고급 파인튜닝 위해서, 내 데이터를 쓰기 위해서 꼭 알아야하는 dataset library 다루기

https://wikidocs.net/166816

 

1. 만일 자신의 데이터셋이 허브에 없다면?

우리는 이제 [Hugging Face Hub](https://huggingface.co/datasets)를 사용하여 데이터셋을 다운로드하는 방법을 알고 있지만, 일반적으로는 노트…

wikidocs.net

 

Datasets library가 지원하는 loading script

 

로컬에서 데이터셋 로딩하기

예제 데이터: SQuAD-it dataset

github에서 다운받아주기

!wget https://github.com/crux82/squad-it/raw/master/SQuAD_it-train.json.gz
!wget https://github.com/crux82/squad-it/raw/master/SQuAD_it-test.json.gz

 

나는 이 코드가 SSL 연결에 실패했다고 떠서, request 라이브러리를 통해 get 요청으로 train/test를 각각 가져왔다

import requests

url = 'https://github.com/crux82/squad-it/raw/master/SQuAD_it-test.json.gz'
file_name = 'SQuAD_it-test.json.gz'

# HTTP GET 요청을 통해 파일 다운로드
response = requests.get(url, stream=True)

# 파일 저장
with open(file_name, 'wb') as file:
    for chunk in response.iter_content(chunk_size=1024):
        if chunk:
            file.write(chunk)

print(f"{file_name} 다운로드 완료!")

 

 

리눅스 gzip으로 압축해제

!gzip -dkv SQuAD_it*.json.gz

 

 

json파일을 열어보니 nested format으로 되어있다

 

중첩 파일로, field 매개변수에 'data'를 주어 데이터셋을 로드하였다

잘 정제된 데이터다

* 단일 데이터 저장해보기

데이터 개수는(num_rows) 442개, 열 이름(features) 출력

 

* test, train 데이터를 한번에 한 변수로 저장해보기

 

+) 짜잔~ 자동 gzip 압축해제 함수도 있었지롱~

data_files = {"train": "SQuAD_it-train.json.gz", "test": "SQuAD_it-test.json.gz"}
squad_it_dataset = load_dataset("json", data_files=data_files, field="data")

 

원격에서 데이터셋 로딩하기

load_dataset()의 data_files=url 주기

url = "https://github.com/crux82/squad-it/raw/master/"
data_files = {
    "train": url + "SQuAD_it-train.json.gz",
    "test": url + "SQuAD_it-test.json.gz",
}
squad_it_dataset = load_dataset("json", data_files=data_files, field="data")

 

데이터셋 슬라이싱(slicing)/다이싱(dicing)

- 데이터셋 정제(clean-up)를 위함

새로운 샘플 데이터셋 다운로드

- 깔끔한 데이터셋 처리를 위한 단점 정제

1.  unnamed: 0컬럼은 확실하지 않지만 환자의 식별자 (unique ID)처럼 보임.

2. condition 컬럼에는대/소문자 레이블이 혼합되어 있음.

3. 리뷰의 길이는 다양하며, \r\n과 같은 HTML 문자 코드가 혼합되어 있음.

 

1번 확인) 

 

맞는 것을 확인했으므로, id 이름으로 명확히 정제 (한 번에 두 분할에서 변경 가능)

 

2) Dataset.map()을 사용해, 모든 condition 레이블을 정규화

일부 행이 None

일부 행이 None인 문제 해결하기 위해: none을 걸러내는 함수 작성

람다 함수가 조금 더 간단하다

- datasets 사용하는 상황에서, 람다 함수를 이용해 간단한 map 및 filter 작업 정의 가능

- None 항목을 제거해주었당

다시 train/test 데이터셋에 대해 소문자 적용 및 확인.

 

3) 리뷰 정제: 리뷰의 길이 및 HTML 문자 코드 제거하기.

새로운 컬럼(column) 만들기

방법1: dataset.map method 이용하기

+) 방법2. dataset.add_column() 함수 이용하기.

- 새롭게 추가하고자 하는 열(column)을 Python list or Numpy array로 제공 가능

- dataset.map()이 분석에 적합하지 않은 경우 유용하게 사용.

 

리뷰:

- 한 단어로 구성되거나, 수천 개의 단어로 구성될 수 있음 -> 사용 사례에 따라 상황을 다르게 처리해야 함.

- 각 리뷰의 단어 수를 계산하기 위해, 각 텍스트를 whitespace로 구분하는 대략적인 heuristics를 사용함.

단어의 개수를 전달
새롭게 열(column) 생성해 데이터셋에 추가해주었음
sort를 사용해 극단값(extreme values)이 1임을 확인

- 일부 review에는 길이가 1(단일 단어)인데, 이는 sentiment analysis에는 적합하나, condition을 예상하는 경우에는 적합X

- 따라서 30단어 미만으로 표현된 리뷰 제거하기로 함 -> 리뷰의 길이가 threshold 초과하도록 하여 필터링

HTML 문자 코드 제거

python의 html 모듈 이용해 escape 해제 (html.unescape 메소드)

 

map() 메소드 알아보기

batch 매개변수

매개변수가 True일 때: 호출되는 순간마다 하나의 batch가 한 번에 map 함수에 입력됨: 리스트 컴프리헨션(list comprehension, 내포)를 사용하여 동시에 여러 예제를 한번에 처리하여 속도를 높일 수 있음.

batched=True가 지정되면 Dataset.map() 메서드의 매개변수로 전달되는 함수가 데이터셋의 필드가 포함된 하나의 딕셔너리를 입력받지만  이 딕셔너리 내부의 각 필드값은 이제 단일 값이 아니라 리스트(list of values)

Dataset.map()의 반환 값은 동일해야 함. 즉, 데이터셋에 업데이트하거나 추가하려는 필드들이 존재하는 딕셔너리와 값 리스트. 

- 일반적으로 list comprehension이 for loop에서 동일한 코드를 실행하는 것보다 훨씬 빠름 

- 예제 여러개에 동시에 접근하기 때문에 속도가 월등히 빠름

-> fast tokenizer unlock 위해 필수적으로 사용하는 옵션.

 

데이터셋의 요소 개수 변경

- 하나의 예제(example)에서 여러 training features 추가적으로 만들어야 하는 상황에서 유용.

- dataset.map() 및 batched=True 사용해서 변경 가능.

- 일반적으로 기계 학습에서 하나의 예제(example)는 모델에 제공하는 자질(feature)의 집합으로 정의됨.

- 특정 상황에서 이러한 자질(features)은 Dataset 내의 컬럼(column) 집합으로 표현되지만, 다른 맥락에서는 여러 개의 자질(multiple features)이 하나의 단일 예제(example)에서 추출되어 단일 컬럼(column)에 속하는 경우도 있음.

...

 

728x90