<aside> <img src="/icons/bullseye_gray.svg" alt="/icons/bullseye_gray.svg" width="40px" /> ABOUT:


</aside>


1. 데이터 수집 & 전처리

1-1. 데이터 수집

https://huggingface.co/datasets/codeparrot/github-code

데이터 수집은 hugging face로 부터 얻게 되었다. repo 이름은 “codeparrot/github-code” 로 github의 코드를 api 상으로 제공하는 프로젝트이다.

api 사용시 반환 형식은 다음과 같다.

{
 'code': "import mod189 from './mod189';\\nvar value=mod189+1;\\nexport default value;\\n",
 'repo_name': 'MirekSz/webpack-es6-ts',
 'path': 'app/mods/mod190.js',
 'language': 'JavaScript',
 'license': 'isc',
 'size': 73
}

다음과 같이 json 형식으로 반환되며 의외로 매우 큰 양의 데이터도 제공해 질이 상당히 높다. 반환 가능 언어는 [JavaScript, HTML, Markdown, C++, Python, TypeScript, CSS, SQL … ] ****등으로, 나는 이중 [JavaScript, Python] ****코드에 대해 모델을 만들 것이다.


먼저, tokenizer를 위한 데이터를 수집할 것이다. 기본적으로 언어당 5000개씩의 코드 파일에서 코드 조각을 수집해 tokenizer의 vocab을 만드는데 사용할 것이다. vacab은 사전에 정의된 문자의 공간이라고 할 수 있다. 추후 자세히 다루겠다.

hugging face의 datasets 모듈을 이용해 api로 코드를 불러온다.

	
import os
from datasets import load_dataset
import pandas as pd
import re, ast

dataset = load_dataset("codeparrot/github-code", split="train", streaming=True)

# languages = ["JavaScript", "HTML", "Markdown", "C++", "Python", "TypeScript", "CSS", "SQL"]
languages = ["Python", "JavaScript"]

num_samples =  20000

#주석 삭제(주석은 코드 맥락에 도움을 주지 않는다고 판단)
def remove_comments_from_code(code_content):
    single_line_comment_pattern = r'//.*?$'
    multi_line_comment_pattern = r'/\\*[\\s\\S]*?\\*/'
    
    code_content = re.sub(single_line_comment_pattern, '', code_content, flags=re.MULTILINE)
    code_content = re.sub(multi_line_comment_pattern, '', code_content)
        
    return code_content

# 주어진 언어에 대해 num_samples 개의 코드 파일 불러오기
def fetch_samples_for_language(lang, num_sample):
    filtered_samples = dataset.filter(lambda example: example["language"] == lang)
    samples = []
    for sample in filtered_samples:
        samples.append(sample)
        if len(samples) >= num_sample:
            break
    return samples

# 각 언어에 대해 지정된 수의 샘플을 가져오기
language_samples = {lang: fetch_samples_for_language(lang, num_samples) for lang in languages}

# 필요한 필드를 추출하여 데이터프레임 준비
data = []
for lang, samples in language_samples.items():
    for sample in samples:
      path_without_extension = os.path.splitext(sample["path"])[0]
      processed_code = remove_comments_from_code(sample["code"])
      data.append({
          "code": processed_code,
          "language": sample["language"],
      })

df = pd.DataFrame(data)

# 각 라벨에 대해 5000개씩 샘플링 및 잘라내기
token_js = df[df['language'] == 'JavaScript'].sample(n=5000, random_state=42)
token_py = df[df['language'] == 'Python'].sample(n=5000, random_state=42)

# 잘라낸 데이터를 원본 데이터에서 제거
df = df.drop(token_js.index)
df = df.drop(token_py.index)

# tokenizer를 위한 CSV 파일로 저장
token_data = pd.concat([token_js, token_py])
token_data.to_csv('code4token.csv', index=False)

# 모델을 위한 CSV 파일로 저장
df.to_csv('code4model.csv', index=False)

해당 코드를 통해 JavaScript, Python 코드의 데이터를 불러올 수 있었다.

num_samples 의 값을 보면 5000이 아닌 값이 20000인 것을 볼 수 있는데, 이는 tokenizer에서 5000, model에서 15000개의 파일을 사용하려고 하기 때문이다.

1-2. 데이터 전처리