text completion api : 가장 먼저 나온 api로 어떤 문장이 주어졌을때 뒤에 나올 문장을 만들어주는 api.
A→B 에서 A를 프롬프트라고 한다. 프롬프트를 주면 프롬프트 이후에 나올 그럴듯한 말을 만들어준다.
Chat api : 채팅을 위해 assistant와 상호작용하는 대화형 api를 만들때 용이하다.
Embeddings api : 어떤 문장, 문서, 짧은 질의가 있을때 그것을 어떤 고정 차원의 벡터로 만들어주는 것이 임베딩 api라고 한다.
임베딩이란 A라는 단어가 있을때 A를 고정된 크기의 벡터로 변환하는 것.
검색, 분류, 텍스트끼리 비교할 때 사용할 수 있다. 어떤 문장이 있다면 비교하고싶은 문서가 있으면 그 문서도 고정된 벡터로 만들어주고 이 두가지를 코사인 유사도를 계산한다. 벡터는 방향이기 때문에 방향이 유사하면 두 벡터의 의미가 유사하다고 평가한다.
가령 문장 A : “오늘 날씨 어때”이고 문장 B : “날씨 알려줘” 라고 한다면 두 문장의 의미는 유사하기 때문에 두 문장의 코사인 유사도는 높다. 가장 높은 값은 1이다.
B를 문장이 아니라 단락이라고 하고 그러한 단락들을 여러 개 준비하고 모두 임베딩한 후에 나중에 질의가 들어오면 해당 질의(쿼리, A)와 문서(B)의 임베딩을 비교해서 가장 높은 코사인 유사도를 가지는 문서를 발견하면 그 문서에 대응되는 단락을 가져오면 검색 기능을 만들 수 있다.
speech to text api : 음성이 들어오면 문서로 바꿔준다.
Image generation api : 텍스트가 들어가면 이미지로 바꿔준다.
fine-tuning api : text completion api의 성능을 향상시키는데 활용할 수 있다. prompt와 이 프롬프트에 대해서 만들었으면 하는 응답(completion) 쌍(prompt, completion)을 여러개 준비해서 fine-tuning api로 업로드해서 학습시키면 자신만의 fine-tuning된 gpt 모델로 만들 수 있다.
chat completion api 파라미터
model
사용할 모델 지정 가능, completion, chat completion인지에 따라서 사용가능한 모델이 다르다.
prompt
insturction과 질문을 넣는걸 프롬프트라고 한다. 어떤 텍스트던지 넣으면 적절한 다음 문장을 생성한다.
max_tokens
출력에 사용될 토큰의 개수를 제한할 수 있다. 문장을 자르는 기준이 단어나 음절이 아니라 openai 에서 사용하는 토크나이저의 토큰 기준이다.
temperature
모델 출력의 randomness를 조절하는 파라미터. temperature와 randomness는 비례한다. random하다는건 같은 질문을 반복했을때 답변이 다양하게 나온다는 뜻.
top_p
모델과 관계가 있다. 트랜스포머 모델은 출력의 결과물이 총합이 1인 벡터로 나오는데 해당 벡터 전체에서 확률별로 샘플링을 한다. 이때 top_p는 확률이 높은 몇 번째까지 안에서만 샘플링한다는 뜻이다.
가령, [0.5,0.2,0.1 …]인 벡터가 있을때 top_p가 0.8이면 앞에 3개에서만 샘플링을 한다.
따라서 top_p가 커지면 작은 범위에서 샘플링을 하게된다.
n
생성하는 문장의 개수를 선택할 수 있다.
stop
stop에 해당하는 단어를 정하면 해당 단어가 나오기 이전까지의 생성된 문장만 벡터만 return한다.
presence penalty
어떤 토큰이 반복적으로 나올지 영향을 끼치는 토큰. 단어 하나를 만들때 그 단어가 이전에 존재한 단어면 페널티를 준다.
LLAMA2 모델의 답변을 python 코드로 받기 위해서는 우선 LLM 모델을 설치하고 환경설정을 마쳐야한다. 참고로 llama2-7b-chat-gptq 모델로 설명할 예정이다.
코드
환경 설정이 끝났다면 준비가 끝. 코드별로 설명이 들어간다.
패키지 및 모델 경로
from transformers import AutoModelForCausalLM, AutoTokenizer, pipeline
llama2_7b_chat_gptq_path = r"C:\Users\Admin\Documents\tg121\text-generation-webui\models\TheBloke_Llama-2-7B-Chat-GPTQ"
transformers 패키지에서 AutoModelForCausalLM, AutoTokenizer, pipeline 라이브러리를 import하고 경로를 지정한다. Window의 경우 경로에 (백슬래쉬)가 있는데 문자열 처리할때 escape 문자로 인식되기 때문에 앞에 r을 붙이거나 \로 두번 붙여서 사용해야한다.
AutoModelForCausalLM, AutoTokenizer, pipeline 라이브러리에 대한 일반적인 정보
AutoModelForCausalLM:
목적:AutoModelForCausalLM은 텍스트 생성 작업을 위한 인과 언어 모델(LM)을 자동으로 로드하고 인스턴스화하는 방법을 제공하는 transformers 패키지의 클래스입니다. 인과 언어 모델은 이전 토큰이 주어지면 순서대로 다음 토큰을 예측하도록 설계되었습니다. 이러한 유형의 모델은 텍스트 완성, 스토리 생성 또는 일관되고 상황에 맞는 텍스트를 생성하는 것이 목표인 모든 시나리오와 같은 작업에 자주 사용됩니다.
사용:AutoModelForCausalLM을 사용하는 경우 정확한 모델 클래스(예: GPT-2, GPT-3 등)를 지정할 필요가 없습니다. 대신 모델 식별자나 경로를 제공하면 AutoModelForCausalLM 클래스가 사용할 적절한 모델 클래스를 자동으로 감지합니다. 이를 통해 핵심 코드 구조를 변경하지 않고도 다양한 모델로 작업하기가 더 쉬워집니다. 모델이 대화형 또는 서술형 스타일로 텍스트를 생성해야 하는 생성 작업에 특히 유용합니다.
AutoTokenizer:
목적:AutoTokenizer는 주어진 언어 모델에 해당하는 토크나이저를 자동으로 감지하고 로드하는 유틸리티입니다. 토크나이저는 텍스트를 언어 모델에서 처리할 수 있는 형식으로 변환하는 데 필수적입니다(예: 텍스트를 토큰 또는 숫자 표현으로 변환). 각 언어 모델에는 일반적으로 해당 모델의 특정 아키텍처 및 훈련 데이터와 가장 잘 작동하도록 훈련된 자체 토크나이저가 있습니다.
사용:AutoModelForCausalLM과 유사하게 AutoTokenizer는 토크나이저 로드 프로세스를 단순화합니다. 모델 식별자나 경로를 제공하면 적절한 토크나이저가 자동으로 로드됩니다. 이는 모델마다 서로 다른 토큰화 전략이 필요할 수 있기 때문에 특히 유용합니다(예: BERT는 WordPiece를 사용하고 GPT-2/3은 바이트 쌍 인코딩을 사용함). 'AutoTokenizer'는 모델 성능에 중요한 모델과 토크나이저 간의 호환성을 보장합니다.
pipeline:
목적: 'pipeline' 기능은 텍스트를 처리하고, 예측을 생성하고, 모델 출력을 해석하는 데 필요한 하위 수준 코드의 상당 부분을 추상화하는 상위 수준 유틸리티입니다. 쉽게 말해서 보기 좋게 만들어줌. 사용하기 쉽도록 설계되어 사용자가 토큰화, 모델 추론 및 출력 처리의 복잡성에 빠지지 않고도 텍스트 생성, 감정 분석, 질문 답변 등과 같은 다양한 NLP 작업을 빠르고 효율적으로 활용할 수 있습니다.
용도:**pipeline**을 사용할 때 관심 있는 작업(예: "텍스트 생성")을 지정하고 모델과 토크나이저를 제공합니다. 그런 다음 파이프라인은 해당 작업에 대한 end-to-end 프로세스를 생성합니다. 예를 들어 텍스트 생성의 경우 원시 텍스트를 가져와 토큰화하고 모델에 공급한 다음 모델의 출력 토큰을 사람이 읽을 수 있는 텍스트로 다시 변환합니다. 따라서 특정 작업에 대한 모델을 빠르게 설정하고 최소한의 코드로 결과를 얻는 데 이상적입니다.
요약하면 transformers 패키지의 이러한 라이브러리는 복잡한 언어 모델을 사용하는 프로세스를 단순화하도록 설계되었습니다. 모델 선택, 텍스트 처리 및 출력 생성과 관련된 많은 기본 세부 정보를 처리하므로 사용자는 특정 애플리케이션이나 작업에 더 집중할 수 있습니다.
AutoModelForCausalLM
transformers 라이브러리의 AutoModelForCausalLM은 사전 훈련된 인과 언어 모델을 자동으로 로드하기 위한 인터페이스를 제공하는 클래스입니다. 시퀀스의 다음 토큰 예측이 이전 토큰만을 기반으로 하는 작업에 대해 훈련된 모델을 처리하도록 설계되었습니다. 다음은 주요 메서드, 특히 사용법의 핵심인 from_pretrained에 대한 자세한 설명입니다.
from_pretrained
이는 사전 훈련된 모델을 로드하는 데 가장 일반적으로 사용되는 방법입니다. 이를 통해 사용자는 특정 데이터세트에 대해 훈련된 모델 아키텍처를 인스턴스화할 수 있습니다.
매개변수:
pretrained_model_name_or_path (str): 사전 학습된 모델의 이름 또는 모델이 저장되는 경로입니다. 이는 Hugging Face 모델 허브의 모델 식별자일 수 있습니다.
revision (str, optional): 사용할 모델의 특정 버전으로, 모델 버전 제어에 유용합니다.
use_auth_token (bool or str, optional): 원격 파일에 대한 HTTP 전달자 인증으로 사용할 토큰입니다. 이는 모델이나 파일이 개인 저장소에 있는 경우 유용합니다.
cache_dir (str, optional): 사전 훈련된 모델을 다운로드하고 캐시할 디렉터리 경로입니다.
force_download (bool , optional): 이미 캐시된 모델 가중치를 강제로 다시 다운로드할지 여부입니다.
resume_download (bool , optional): 이전에 중단된 다운로드를 재개할지 여부입니다.
프록시(dict, optional): 모델 가중치를 다운로드할 때 사용할 프록시 서버 사전입니다.
output_attentions (bool , optional): 모델이 어텐션 가중치를 반환해야 하는지 여부입니다.
output_hidden_states (bool , optional): 모델이 모든 숨겨진 상태를 반환해야 하는지 여부입니다.
torch_dtype (torch.dtype, optional): 모델 매개변수의 원하는 dtype입니다.
trust_remote_code (bool , optional): 사용자 정의 원격 코드를 신뢰할지 여부(악성 코드에 대한 안전 조치).
device_map (str or dict, optional): 모델 레이어의 장치 배치입니다. 모델을 여러 장치로 분할하는 데 사용할 수 있으며, 특히 대형 모델에 유용합니다.
상세 정보
transformers 라이브러리의 device_map 매개변수는 AutoModelForCausalLM.from_pretrained와 같은 메서드를 통해 모델을 로드할 때 주로 사용되는 고급 기능입니다. 이를 통해 모델의 어느 부분이 다른 GPU 또는 CPU와 같은 하드웨어 장치에 배치되는지를 세밀하게 제어할 수 있습니다. 이는 메모리 제약으로 인해 단일 GPU에 완전히 맞지 않을 수 있는 매우 큰 모델을 작업할 때 특히 유용할 수 있습니다.
device_map이해하기
목적:device_map 매개변수는 사용 가능한 하드웨어 장치에 모델의 다양한 레이어를 배포하는 방법을 지정하는 데 사용됩니다. 이는 신경망의 서로 다른 계층이나 부분이 서로 다른 장치에 배치되는 모델 병렬성의 한 형태입니다.
사용 사례: 단일 모델이 너무 커서 단일 GPU의 메모리에 맞지 않는 시나리오에서 가장 일반적으로 사용됩니다. 모델을 여러 GPU로 분할하면 너무 커서 처리할 수 없는 모델도 작업할 수 있습니다.
device_map 사용 방법
사전으로:device_map을 사용하는 가장 명시적인 방법은 키가 레이어 인덱스를 나타내는 정수이고 값이 장치 이름인 사전을 전달하는 것입니다(예: 'cuda:0', 'cuda :1', 'cpu' 등). 예를 들어 레이어의 첫 번째 절반을 cuda:0에 배치하고 두 번째 절반을 cuda:1에 배치하려면 이를 사전에 명시적으로 지정해야 합니다.
문자열로: 더 간단한 사용 사례의 경우 device_map은 문자열일 수도 있습니다. 예를 들어, device_map="auto"를 설정하면 변환기 라이브러리는 균형 잡힌 방식으로 사용 가능한 모든 GPU에 모델 레이어를 자동으로 배포합니다.
예
다음은 대규모 모델에 device_map을 사용하는 가상의 예입니다.
from transformers import AutoModelForCausalLM
device_map = {
0: 'cuda:0', # Layers 0-5 on GPU 0
6: 'cuda:1', # Layers 6-11 on GPU 1
# ... and so on for more layers and GPUs
}
model = AutoModelForCausalLM.from_pretrained("gpt3-large", device_map=device_map)
이 예에서는 모델의 특정 레이어가 특정 GPU에 할당됩니다. 이를 통해 메모리 사용량을 관리하고 대규모 모델의 훈련 또는 추론 성능을 최적화할 수 있습니다.
고려사항
복잡성:device_map은 뛰어난 제어 기능을 제공하고 대형 모델에 필수적일 수 있지만 모델 설정에 복잡성을 추가하기도 합니다. 하드웨어의 기능과 메모리 제한을 알고 있어야 합니다.
균형: 병목 현상을 방지하려면 여러 장치에서 레이어의 균형을 맞추는 것이 중요합니다. 고르지 못한 분포로 인해 일부 GPU는 활용도가 낮고 다른 GPU는 과부하가 걸릴 수 있습니다.
호환성: 모든 모델 또는 훈련 루틴이 수동 장치 매핑과 호환되는 것은 아닙니다. 일부 특수 모델 또는 사용자 정의 훈련 루프에는 특정 장치 관리가 필요할 수 있습니다.
요약하면 device_map은 여러 하드웨어 장치에 대규모 모델을 배포하는 강력한 도구로, 단일 장치의 메모리에 비해 너무 큰 모델을 처리할 수 있습니다. 그러나 모델의 아키텍처와 사용 가능한 하드웨어에 대한 신중한 계획과 올바른 이해가 필요합니다.
### **다른 Methods**
'`from_pretrained`'가 모델을 로드하는 가장 중요한 방법인 반면, '`AutoModelForCausalLM`'은 PyTorch의 상위 클래스와 '`transformers`' 라이브러리에서 다른 메서드도 상속합니다. 여기에는 다음이 포함됩니다.
- `**generate**` : **`generate`** 메소드는 제공된 입력을 기반으로 텍스트 시퀀스를 생성하는 데 사용됩니다. 가장 간단하게는 입력 ID(토큰화된 텍스트)를 가져와서 출력 텍스트를 생성합니다.
- 세부 설명
### **주요 매개변수**
- **inputs** (**`torch.Tensor`** or **`List[int]`**): 모델에 대한 입력 토큰입니다. 일반적으로 이는 생성의 기반이 되는 텍스트의 토큰화된 버전입니다.
- **max_length** (**`int`**, optional): 생성할 시퀀스의 최대 길이입니다. 기본적으로 모델별 값으로 설정됩니다.
- **min_length** (**`int`**, optional): 생성할 시퀀스의 최소 길이입니다.
- **do_sample** (**`bool`**, optional): **`True`**로 설정된 경우 메서드는 샘플링을 사용하여 텍스트를 생성합니다. 'False'인 경우 욕심 많은 접근 방식을 사용합니다.
- 세부 설명
### **`do_sample` 이해하기**
- **`do_sample=False`인 경우:**
- 생성 프로세스는 **결정론적**입니다. 이 모드에서 모델은 항상 시퀀스의 다음 토큰으로 가장 높은 확률을 가진 토큰을 선택합니다. 이를 **greedy 접근 방식**이라고도 합니다.
- 결과적으로 모델은 주어진 입력에 대해 항상 동일한 출력을 생성하므로 텍스트의 다양성이 줄어듭니다.
- 이 접근 방식은 입력 텍스트의 가능성이 가장 높은(또는 "안전한") 연속을 원할 때 유용할 수 있지만 때로는 반복적이거나 예측 가능한 결과가 발생할 수 있습니다.
- **`do_sample=True`인 경우:**
- 생성 과정은 **확률적**이 됩니다. 항상 가장 높은 확률 토큰을 선택하는 대신 모델은 다음 토큰의 확률 분포에서 샘플링합니다.
- 이는 확률이 더 낮은 토큰이라도 선택될 가능성이 있다는 것을 의미하며, 이는 생성된 텍스트에 무작위성과 변형을 도입합니다.
- 결과적으로 동일한 입력이 있어도 각 실행마다 다른 출력이 생성될 수 있습니다. 이는 텍스트의 다양성과 참신함이 요구되는 스토리 생성과 같은 창의적인 응용 프로그램에 특히 유용합니다.
- randomness의 정도는 '온도', 'top_k', 'top_p'와 같은 다른 매개변수를 통해 추가로 제어할 수 있습니다. 예를 들어 'temperature'가 높을수록 무작위성이 높아집니다.
### **사용예**
차이점을 설명하기 위해 간단한 예를 살펴보겠습니다.
- **샘플링 없음(`do_sample=False`):**
- 입력: "빠른 갈색 여우"
- 출력(결정론적): "빠른 갈색 여우가 게으른 개를 뛰어넘습니다."
- **샘플링 사용(`do_sample=True`):**
- 입력: "빠른 갈색 여우"
- 출력(무작위 1): "빠른 갈색 여우가 울타리를 넘어 미지의 세계로 뛰어올랐습니다."
- 출력(임의 2): "빠른 갈색 여우가 가을 공기를 냄새 맡으며 잠시 멈췄습니다."
첫 번째 경우(샘플링 없음)의 경우 모델은 항상 동일한 방식으로 문장을 완성합니다. 두 번째 경우(샘플링 사용)의 경우 출력이 더 다양해지고 예측 가능성이 떨어집니다.
### **결론**
**`do_sample`** 매개변수는 텍스트 생성의 다양성과 창의성을 제어하는 핵심 도구입니다. 확률적 생성을 활성화하면 모델이 가능한 다양한 출력을 생성할 수 있으므로 참신함과 변형이 중요한 응용 분야에 특히 유용합니다. 그러나 생성된 텍스트가 일관되고 상황에 맞게 유지되도록 하려면 '온도'와 같은 다른 매개변수와 균형을 맞추는 것도 중요합니다.
- **early_stopping** (**`bool`**, optional): **`True`**로 설정하면 시퀀스 끝 토큰이 생성되는 즉시 생성이 중지됩니다.
- **num_beams** (**`int`**, optional): 빔 검색을 위한 빔 수입니다. 빔 검색은 각각 '빔'으로 간주되는 여러 시퀀스를 추적하는 보다 복잡한 생성 전략입니다. 빔이 많을수록 다양성은 높아지지만 생성 속도는 느려집니다.
- Beam search란?
### Beam search
빔 검색은 많은 자연어 처리 작업, 특히 기계 번역, 텍스트 요약, 텍스트 생성과 같은 시퀀스 생성 문제에 사용되는 알고리즘입니다. 제한된 집합에서 가장 유망한 노드를 확장하여 그래프를 탐색하는 휴리스틱 검색 알고리즘입니다.
### Beam search 작동 방식:
1. **Initialization:**
- 빔 검색은 초기 노드(종종 텍스트 생성 시 시작 토큰)로 시작됩니다.
- 각 단계에서 고정된 수의 경로 또는 "beams"를 추적합니다. 이 숫자는 beam width(너비)입니다.
2. **Expansion:**
- 각 단계에서는 각 경로에서 가능한 모든 다음 단계(토큰)를 고려하고 확률을 계산합니다.
- 그런 다음 모든 경로에서 가장 가능성이 높은 상위 'k'개의 다음 단계를 선택합니다. 여기서 'k'는 beam width이다.
3. **Pruning:**
- 알고리즘은 이러한 상위 'k' 경로만 유지하고 나머지는 삭제합니다. 이 단계는 컴퓨팅 리소스를 관리하고 가장 유망한 경로에 집중하는 데 중요합니다.
4. **Termination:**
- 이 프로세스는 종료 조건이 충족될 때까지 반복됩니다. 일반적으로 최대 시퀀스 길이에 도달하거나 시퀀스 끝 토큰이 생성될 때입니다.
5. **Selection:**
- 검색이 종료되면 전체 확률이 가장 높은 경로가 출력으로 선택됩니다.
### 특성:
- **효율성과 품질 간의 균형:** 빔 검색은 단일 최적 경로(빔 폭 = 1)만 유지하는 그리디 검색과 가능한 모든 경로를 고려하는(계산 비용 때문에 비현실적) 너비 우선 검색(breadth-first search) 간의 절충안입니다.
- **장점과 단점:**
- **장점:** 욕심 많은 검색보다 최적의 시퀀스를 찾을 가능성이 더 높습니다.
- **단점:** 초기 단계에서 상위 'k'에 나타나지 않으면 가능성이 높은 시퀀스를 놓칠 수 있습니다. 누적 확률로 인해 더 짧은 시퀀스를 선호하는 경향이 있습니다.
- num_beams 세부 설명
### **텍스트 생성의 num_beam**
Hugging Face **`transformers`** 라이브러리의 **`AutoModelForCausalLM`**과 같은 모델을 사용하는 텍스트 생성의 맥락에서 **`num_beams`**는 빔 검색을 위한 빔 너비를 지정하는 매개변수입니다.
### 자세한 설명:
- **매개변수:** **`num_beams`**(int)
- **목적:** 텍스트 생성 중 빔 검색에 사용되는 beam(경로) 수를 제어합니다.
- **용법:**
- 'num_beams' 값이 클수록 고품질 출력을 찾을 가능성이 높아지지만 계산 리소스와 시간이 희생됩니다. 빔이 많을수록 모델은 각 단계에서 더 많은 가능한 경로를 고려합니다.
- 값이 작을수록(예: 1) 검색이 욕심 많은 검색으로 전환되어 속도는 더 빠르지만 최상의 품질의 출력을 얻지 못할 수 있습니다.
- **고려사항:**
- **상충관계:** 품질과 효율성 사이에는 상충관계가 있습니다. 'num_beams'를 늘리면 더 나은 결과를 얻을 수 있지만 더 많은 메모리와 계산이 필요합니다.
- **일반적인 값:** 일반적인 값의 범위는 3~10이지만 최적의 숫자는 특정 애플리케이션과 사용 가능한 계산 리소스에 따라 달라질 수 있습니다.
### 예:
```python
from transformers import AutoModelForCausalLM, AutoTokenizer
model_name = "gpt2"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(model_name)
input_ids = tokenizer("The capital of France is", return_tensors="pt").input_ids
# Generate text using beam search
output = model.generate(input_ids, num_beams=5, max_length=50)
print(tokenizer.decode(output[0]))
```
이 예에서 **`generate`** 메소드는 빔 너비가 5인 빔 검색을 사용하여 제공된 텍스트의 연속을 생성합니다. 이 설정은 상황에 맞게 보다 관련성이 높고 일관성 있는 텍스트 출력을 생성하는 데 도움이 됩니다.
- **temperature** (**`float`**, optional): 샘플링 전에 로짓의 크기를 조정하여 예측의 무작위성을 제어합니다. 값이 높을수록 더 많은 무작위 출력이 발생합니다.
- **top_k** (**`int`**, optional): 각 단계에서 고려되는 가장 높은 확률의 어휘 토큰 수를 제한합니다. 출력의 무작위성을 제어하는 데 도움이 됩니다.
- **top_p** (**`float`**, optional): Nucleus sampling. 누적 확률이 **`top_p`** 이상인 상위 토큰을 유지합니다. 다시 말하지만 무작위성을 제어합니다.
- **repetition_penalty** (**`float`**, optional): 생성된 텍스트의 반복에 불이익을 주기 위한 매개변수입니다.
- **pad_token_id** (**`int`**, optional): 패딩에 사용할 토큰 ID입니다. 일괄 생성에 유용합니다.
- **bos_token_id** (**`int`**, optional): 시퀀스 시작 토큰 ID입니다.
- **eos_token_id** (**`int`**, optional): 시퀀스 끝 토큰 ID입니다.
- **length_penalty** (**`float`**, optional): 빔 검색에서 길이에 대한 지수 페널티.
- **no_repeat_ngram_size** (**`int`**, optional): 두 번 이상 나타나지 않아야 하는 N-그램의 크기입니다.
- **max_new_tokens**
### **고급 사용법**
보다 복잡한 시나리오에서는 이러한 매개변수를 미세 조정하여 생성된 텍스트의 스타일, 다양성 및 일관성을 제어할 수 있습니다. 예를 들어 '온도', 'top_k' 및 'top_p'를 조정하면 출력의 무작위성과 창의성이 크게 바뀔 수 있습니다.
### **예시**
다음은 **`generate`** 메소드를 사용하는 간단한 예입니다:
```python
from transformers import AutoModelForCausalLM, AutoTokenizer
model_name = "gpt2"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(model_name)
inputs = tokenizer("Hello, my name is", return_tensors="pt")
# Generate text
generated_text_ids = model.generate(inputs["input_ids"], max_length=50)
generated_text = tokenizer.decode(generated_text_ids[0])
print(generated_text)
```
이 예에서는 **`generate`** 메소드를 사용하여 GPT-2를 기본 모델로 사용하여 "Hello, my name is"로 시작하는 텍스트 시퀀스를 생성합니다.
### **결론**
'생성' 방법은 인과 언어 모델에서 텍스트 생성을 위한 다양하고 강력한 도구입니다. 매개변수를 미세 조정하면 다양한 응용 분야와 스타일에 맞게 출력을 맞춤화할 수 있습니다.
- **`forward`**: 모델의 forward pass에 사용되는 방법입니다. input token id와 attention mask, token type id 등과 같은 기타 optional 매개변수를 가져와 모델의 출력을 반환합니다.
- **`save_pretrained`**: 이 방법은 나중에 **`from_pretrained`**를 사용하여 다시 로드할 수 있도록 모델의 가중치와 구성 파일을 디렉터리에 저장하는 데 사용됩니다.
- **`to`**: PyTorch의 **`nn.Module`**에서 상속된 메서드로, 모델의 매개변수를 특정 장치(예: CPU 또는 GPU)로 이동하는 데 사용됩니다.
- **`eval`**: 또한 PyTorch에서 이 메서드는 평가 모드에서 모델을 설정하는 데 사용됩니다. 이는 드롭아웃과 같은 특정 레이어를 끄기 때문에 추론에 필요합니다.
- **`train`**: 모델을 훈련 모드로 설정하여 훈련에는 필수적이지만 추론에는 필요하지 않은 드롭아웃과 같은 레이어를 다시 활성화합니다.
### **용법**
'AutoModelForCausalLM'의 사용은 주로 모델 로드를 위한 'from_pretrained' 방법을 중심으로 이루어지며, 그 후 추론 또는 추가 교육을 위한 표준 PyTorch 워크플로가 따릅니다. 간단한 예는 다음과 같습니다.
```python
from transformers import AutoModelForCausalLM
model = AutoModelForCausalLM.from_pretrained("gpt2") # Load GPT-2, for example
```
요약하자면 **`AutoModelForCausalLM`**은 인과 언어 모델을 로드하고 활용하는 데 쉽게 사용할 수 있도록 설계되었으며, 이러한 모델을 처리하는 데 일반적으로 수반되는 복잡성과 상용구 코드를 많이 추상화합니다.
AutoTokenizer
'AutoTokenizer'는 미리 훈련된 특정 언어 모델에 대해 올바른 토크나이저를 자동으로 로드하는 방법을 제공하는 Hugging Face 'transformers' 라이브러리의 클래스입니다. 서로 다른 언어 모델에는 서로 다른 토큰화 체계가 필요한 경우가 많기 때문에 이 클래스는 매우 중요합니다. 주요 방법에 대한 자세한 설명은 다음과 같습니다.
1. from_pretrained
이는 토크나이저를 로드하는 데 사용되는 기본 방법입니다.
매개변수:
pretrained_model_name_or_path (str): 토크나이저를 로드하려는 사전 훈련된 모델의 이름 또는 경로입니다. Hugging Face 모델 허브의 모델 이름일 수 있습니다.
cache_dir (str, optional): 인터넷에서 다운로드한 사전 학습된 모델을 캐시할 디렉터리 경로입니다.
force_download (bool, optional): 토크나이저가 이미 캐시된 경우에도 다운로드를 강제할지 여부입니다.
padding (bool or str, optional): 시퀀스를 동일한 길이로 채우는 전략('True', 'False' 또는 패딩 전략을 지정하는 문자열일 수 있음).
truncation (bool or str, optional): 시퀀스를 최대 길이로 자를지 여부입니다.
max_length (int, optional): 토큰화 후 시퀀스의 최대 길이입니다.
return_tensors (str, optional): 반환할 텐서 유형입니다(예: PyTorch의 경우 pt, TensorFlow의 경우 tf).
4. encode와 encode_plus
이러한 방법은 토큰화에 사용되며 토큰 유형 ID 및 주의 마스크와 같은 추가 정보를 제공합니다.
매개변수:
__call__과 유사하지만 특수 토큰, 패딩 및 잘림 처리를 위한 특정 옵션이 있습니다.
5. decode
이 메서드는 토큰 ID를 다시 읽을 수 있는 텍스트로 변환하는 데 사용됩니다.
매개변수:
token_ids (List[int]): 다시 텍스트로 변환할 토큰 ID 목록입니다.
skip_special_tokens (부울, 선택 사항): 디코딩 중에 특수 토큰을 제거할지 여부입니다.
input_ids
상세 정보
토큰화와 AutoTokenizer
토큰화(Tokenization): 텍스트를 언어 모델이 이해할 수 있는 형식으로 변환하는 과정입니다. 이 과정은 텍스트를 토큰이라고 하는 더 작은 단위로 나눕니다. 이 토큰들은 토크나이저의 알고리즘에 따라 단어, 서브워드 또는 문자일 수 있습니다.
AutoTokenizer: 이 클래스는 주어진 사전 훈련된 언어 모델에 적합한 토크나이저를 자동으로 감지하고 로드하는 데 사용됩니다. 텍스트가 모델의 훈련과 호환되는 방식으로 토큰화되도록 합니다.
AutoTokenizer의 __call__ 메소드
AutoTokenizer 인스턴스를 사용하여 텍스트를 토큰화할 때, 일반적으로 함수처럼 호출합니다. 이 메소드는 입력된 텍스트를 받아 여러 키-값 쌍이 있는 사전을 반환합니다. 이 키 중 하나가 input_ids입니다.
예제 사용법:
from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained("bert-base-uncased")
tokens = tokenizer("Hello, world!") # __call__ 메소드 사용
### **`input_ids` 이해하기**
- **`input_ids`**: 이 키는 토큰화 과정의 주요 출력을 포함하고 있습니다. 각 ID는 토큰에 해당합니다.
- **목적**: 이 ID들은 언어 모델이 이해하고 처리하는 것입니다. 각 ID는 모델 어휘의 토큰을 참조합니다. 모델은 이 ID를 사용하여 임베딩을 찾아내고 입력된 텍스트를 이해합니다.
- **예시**: 앞의 코드 예제에서 계속해서:
```python
input_ids = tokens["input_ids"]
```
여기서 **`input_ids`**는 각각 토크나이저 어휘에 매핑되는 정수의 리스트입니다.
### **추가 맥락**
- **패딩과 잘라내기**: 모델에 입력하기 위해 토큰화할 때, 모든 시퀀스가 동일한 길이를 가지도록 하는 것이 종종 필요합니다. **`AutoTokenizer`**는 이를 처리하며, 이 작업들은 **`input_ids`**에 반영됩니다.
- **Attention Mask**: **`input_ids`**와 함께, 토크나이저는 실제 데이터와 패딩을 구분하는 데 중요한 **`attention_mask`**도 반환합니다.
- **Token Type IDs**: 일부 모델(예: BERT)의 경우, 토크나이저는 두 가지 다른 시퀀스(예: 문맥과 질문이 있는 질문-응답 작업)를 구분하는 데 사용되는 **`token_type_ids`**를 생성합니다.
요약하자면, **`input_ids`**는 텍스트를 언어 모델이 처리할 수 있는 숫자 형태로 나타내는 토큰화 과정의 중요한 부분입니다. **`transformers`** 라이브러리의 **`AutoTokenizer`** 클래스는 다양한 사전 훈련된 모델과의 호환성을 보장하면서 이 과정을 자동화합니다.
### **사용 예**
다음은 **`AutoTokenizer`**가 어떻게 사용될 수 있는지에 대한 간단한 예입니다:
```python
from transformers import AutoTokenizer
# Load tokenizer
tokenizer = AutoTokenizer.from_pretrained("bert-base-uncased")
# Tokenize text
input_ids = tokenizer("Hello, world!", return_tensors="pt")
# Decode token ids
original_text = tokenizer.decode(input_ids["input_ids"][0])
```
요약하면 **`AutoTokenizer`**는 다양한 언어 모델에서 토크나이저를 로드하고 사용하기 위한 사용자 친화적인 인터페이스를 제공하며, 원시 텍스트를 모델 입력에 적합한 형식으로 변환하는 데 필요한 다양한 전처리 단계를 처리합니다.
pipeline
Hugging Face 'transformers' 라이브러리의 'pipeline' 기능은 사전 학습된 모델을 사용하여 다양한 자연어 처리(NLP) 작업을 수행할 수 있는 간단한 인터페이스를 제공하는 고급 유틸리티입니다. 입력 및 출력 처리와 관련된 많은 복잡성을 추상화하여 이러한 모델을 더 쉽게 적용할 수 있습니다.
pipeline 주요 방법
'파이프라인' 유틸리티의 기본 방법은 특정 작업 파이프라인의 인스턴스를 생성하는 데 사용되는 '파이프라인' 기능 자체입니다. 그런 다음 이 인스턴스를 사용하여 그에 따라 입력을 처리할 수 있습니다.
pipeline 기능
목적: 사전 학습된 모델을 사용하여 텍스트 생성, 감정 분석, 명명된 엔터티 인식 등과 같은 특정 NLP 작업을 처리할 수 있는 개체를 생성합니다.
용법:
from transformers import pipeline
nlp_pipeline = pipeline(task_name, model=model_name, tokenizer=tokenizer_name, ...)
매개변수:
task (str): 수행할 작업입니다. 일반적인 작업에는 text-generation, sentiment-analysis, ner(named entity recognition) ,question-answering 등이 포함됩니다.
model (str 또는 모델 객체, 선택 사항): 사용할 사전 훈련된 모델입니다. 제공되지 않으면 작업의 기본 모델이 사용됩니다. Hugging Face 모델 허브에서 모델 이름을 지정하거나 모델 객체를 전달할 수 있습니다.
config (str or Config object, optional): 모델에 대한 구성입니다. 모델의 동작을 사용자 정의하는 데 유용합니다.
tokenizer (str or Tokenizer object, optional):사용할 토크나이저입니다. 제공되지 않으면 지정된 모델의 기본 토크나이저가 사용됩니다.
framework (str, optional): 사용할 딥 러닝 프레임워크(PyTorch의 경우 "pt", TensorFlow의 경우 "tf"). 설정하지 않으면 프레임워크가 유추됩니다.
device (int, optional): 추론에 사용할 장치입니다(CPU의 경우 -**1**, GPU의 경우 GPU 인덱스).
기타 매개변수: 작업에 따라 max_length(텍스트 생성), padding 및 truncation(고정 길이 입력이 필요한 작업용) 등과 같은 기타 매개변수가 제공될 수 있습니다.
일반적인 작업의 예
텍스트 생성:
text_generator = pipeline("text-generation", model="gpt2")
generated_text = text_generator("Once upon a time", max_length=50)
감정 분석:
sentiment_analyzer = pipeline("sentiment-analysis")
result = sentiment_analyzer("I love this product!")[0]
명명된 엔터티 인식(NER):
ner_pipeline = pipeline("ner", model="dbmdz/bert-large-cased-finetuned-conll03-english")
entities = ner_pipeline("My name is Sarah and I live in London")
질문 답변:
from transformers import pipeline
# Create a pipeline for question answering
qa_pipeline = pipeline("question-answering")
# Define the context and the question
context = "France is a country in Europe known for its rich history and cultural heritage. Its capital is Paris."
question = "What is the capital of France?"
# Use the pipeline to find the answer
answer = qa_pipeline({'question': question, 'context': context})['answer']
# Print the answer
print(answer)
### 결론
**`pipeline`** 유틸리티는 다양한 자연어 처리(NLP) 작업을 수행하기 위해 사전 훈련된 모델을 사용하는 간단한 인터페이스를 제공하는 Hugging Face **`transformers`** 라이브러리의 고급 기능입니다. 복잡한 모델 처리와 토큰화의 세부 사항을 추상화함으로써, 이 유틸리티는 텍스트 생성, 감정 분석, 개체명 인식(NER), 질문 응답 등과 같은 다양한 NLP 작업을 쉽게 적용할 수 있도록 도와줍니다. 특히 모델을 빠르게 테스트하거나 사용자에게 모델의 복잡성을 숨기고 싶은 애플리케이션에 배포할 때 유용합니다.
모델 로드
#Loading the Model
model = AutoModelForCausalLM.from_pretrained(llama2_7b_chat_gptq_path,
device_map="auto",
trust_remote_code=False,
revision="main")
tokenizer = AutoTokenizer.from_pretrained(llama2_7b_chat_gptq_path, use_fast=True)
AutoModelForCausalLM 라이브러리의 from_pretrained 메서드를 사용하여 모델을 로드한다. from_pretrained 메서드의 매개변수로 모델 경로등을 전달한다.
AutoTokenizer 라이브러리의 from_pretrained 메서드를 사용해서 토크나이저를 로드한다. from_pretrained 메서드의 매개변수로 모델 경로등을 전달한다.
프롬프트
instruction = """
질문에 대한 전체 답변을 한국어로 해줘.
"""
prompt = "인공지능에 대해 설명해줘"
prompt_template=f'''{instruction}
### Instruction:
{prompt}
### Response:
'''
위와 같이 포맷팅을 사용해서 문자열 내에 prompt와 instruction을 저장하고 이후 Text Generation 과정에서 사용한다.
위 코드에서 토크나이저는 __call__ 메서드로 사용된다. tokenizer에 매개변수로 앞서 생성한 prompt_template 을 매개변수로 전달한다. 또 다른 매개변수로 return_tensors 를 전달하는데 이는 반환할 텐서 유형으로 pytorch를 사용하는 경우 ‘pt’, tensorflow를 사용하는 경우 ‘tf’이다.
다운로드 파일을 실행하기 앞서서 권한을 주고 ./download.sh 명령어로 다운로드 파일 실행한다.
chmod 755 download.sh
./download.sh
해당 명령어를 실행하면 아래와 같이 “Enter the URL from email:”라는 문구가 나오는데 아까 메일로 받은 url을 여기에 복붙하면 된다.
📌 주의!! 마우스로 긁어서 ctrl+c 로 복사하자. 링크 복사로 하면 오류가 생긴다.
그러고 엔터를 치면 아래와 같은 안내 문구가 나오는데
원하는 모델을 다운로드 하면 된다. 근데 이때 원하는 모델을 띄어쓰기 없이 적으니까 오류가 발생해서(403 Forbidden) 하나하나 다운받으니까 해결되었다. 그래도 안되면 될때까지 다운로드 요청해서 새 url 받아서 하면 된다고 한다(according to github…)
실행 테스트
Meta 공홈을 통해 깃허브에서 다운받으면 example_chat_completion.py 랑 example_text_completion.py가 있는데 해당 파일로 테스트를 진행해볼 수 있다.
TextGen WebUI 줄여서 Textgen UI는 web ui 환경에서 LLM을 사용할 수 있게 만들어주는 소프트웨어. TextGen UI를 통해 huggingface의 다양한 모델들을 간편하게 다운받을 수 있고 fine-tuning을 GUI 상에서 할 수 있으며 prompt 또한 추가할 수 있음.
git clone https://github.com/oobabooga/text-generation-webui.git
cd text-generation-webui
pip install -r requirements.txt
GPU 및 세부 설정
# GPU only:
pip uninstall -y llama-cpp-python
set "CMAKE_ARGS=-DLLAMA_CUBLAS=on"
set "FORCE_CMAKE=1"
pip install llama-cpp-python --no-cache-dir
# If you get: ERROR: Failed building wheel for llama-cpp-python
set "CMAKE_ARGS=-DLLAMA_OPENBLAS=on"
set "FORCE_CMAKE=1"
pip install llama-cpp-python --no-cache-dir
Cuda 확인(GPU 쓰는지 확인)
#shell에서 python 을 쳐서 파이썬 실행
import torch
torch.__version__
torch.cuda.is_available()
TextGen UI 실행
# If you get CUDA Setup failed despite GPU being available.:
pip install bitsandbytes-windows
# If you get AttributeError: module 'bitsandbytes.nn' has no attribute 'Linear4bit'. Did you mean: 'Linear8bitLt'?
pip install git+https://github.com/huggingface/peft@27af2198225cbb9e049f548440f2bd0fba2204aa --force-reinstall --no-deps
# 문제 없으면 바로 아래 코드 실행
python server.py
레이블이 없는 데이터셋을 그룹화하는 것을 클러스터링이라고 한다. 만약 레이블이 있는 데이터셋을 그룹화한다면 지도학습의 일종인 분류가 된다. 데이터셋을 그룹화하려면 유사한것들끼리 묶어야한다. 이를 위해 데이터셋의 특성 데이터를 유사성 측정이라는 측정 항목을 사용으로 결합해서 데이터들 간의 유사성을 측정할 수 있다.
클러스터링의 사용 예시
시장 세분화, 소셜 네트워크 분석, 검색결과 그룹화, 의료영상, 이미지 세분화, 이상 감지
클러스터링을 하면 각 클러스터에 클러스터 ID 라는 번호가 할당된다. 클러스터 ID가 할당되면 예시용 전체 특성 세트를 클러스터 ID로 압축할 수 있다. 이를 통해 복잡한 예를 간단한 클러스터 ID로 표현하면 클러스터링이 강력해진다. 대규모 데이터셋의 처리를 간소화할수있다. 클러스터링 출력은 다운스트림 ML 시스템의 특성 데이터 역할을 합니다.
일반화
클러스터의 일부 예시에 특성 데이터가 누락된 경우 클러스터의 다른 예시에서 누락된 데이터를 추론할 수 있다.
데이터 압축
클러스터의 모든 예시에 대한 특성 데이터는 클러스터 ID로 대체할 수 있다. 이 과정을 거치면 대체로 특성 데이터가 간소화되고 저장장소가 절약된다. 데이터셋의 규모가 커지면 커질수록 이러한 이점들이 두드러진다. 또한, 머신러닝 입력 데이터로 전체 특성 데이터셋 대신에 클러스터터 ID를 사용할수있다.
개인정보 보호
사용자를 클러스터링하고 사용자 데이터를 특정 사용자 대신 클러스터 ID와 매칭해서 개인 정보를 보존할 수 있다. 사용자 데이터로 사용자를 특정할 수 없도록 클러스터는 충분한 수의 사용자를 그룹화해야한다.
2) 차원 축소(Dimension reduction)
차원 축소란 머신러닝이나 통계분야에서 활용되는 기술로 문제의 무작위 변수(random variable)의 규모를 줄여서 주요한 변수의 집합을 구하는 것이다. 차원 축소는 두 과정으로 이루어지는데 첫 번째는 변수 선택(feature selection)과 변수 추출(feature extraction)이다. 변수 선택 과정에서는 모델을 대표할 다차원 데이터의 집합에서 특성들의 작은 부분집합들을 필터링, 임베딩, wrapping을 통해 선택한다. 변수 추출 과정에서는 데이터셋의 차원을 줄여서 변수를 모델화하고 구성 요소들에 대한 분석을 수행한다.
Machine Learning 과정에서 Best Feature Subset 을 주는 것이 아니라, 사용자에게 feature-rank를 줌으로 각 feature의 영향력을 알려주는 방법이다. 따라서 해당 모델에 Best Feature Subset 은 아닐 수 있더라도, 도움이 된다고 볼 수 있다. 또한 여기서 각 ranking 화 한 Feature 들은 독립변수로 본다.
Wrapper Method
Machine Learning의 예측 정확도 측면에서 가장 좋은 성능을 보이는 Subset을 뽑아내는 방법이다. Machine Learning 을 진행하면서 Best Feature Subset을 찾아가는 방법이기 때문에 시간과 비용이 매우 높게 발생한다. 하지만 최종적으로 Best Feature Subset을 찾아주기 때문에 모델의 성능을 위해서는 적절하다. 물론, 해당 모델의 파라미터와 알고리즘 자체는 완성도가 높아야 제대로 된 Best Feature Subset을 찾을 수 있다.
Forward Selection(전진 선택) : 변수가 없는 상태로 시작하며 반복할 때마다 가장 중요한 변수를 추가하여 더 이상 성능의 향상이 없을 때까지 변수를 추가한다.
Backward Elimination(후방 제거) : 모든 변수를 가지고 시작하며, 가장 덜 중요한 변수를 하나씩 제거하면서 모델의 성능을 향상시킨다. 더 이상 성능의 향상이 없을 때까지 반복한다.
Stepwise Selection(단계별 선택): Foward Selection 과 Backward Elimination 을 결합하여 사용하는 방식으로, 모든 변수를 가지고 시작하여 가장 도움이 되지 않는 변수를 삭제하거나, 모델에서 빠져있는 변수 중에서 가장 중요한 변수를 추가하는 방법이다. 이와 같이 변수를 추가 또는 삭제를 반복한다. 반대로 아무것도 없는 모델에서 출발해 변수를 추가, 삭제를 반복할 수도 있다.
1-2 K-Means
가장 고전적이면서 직관적으로 이해하기 쉬운 군집화 기법입니다. K-Means는 다음과 같은 과정을 통해 군집화가 이루어져요!
임의의 중심점 설정
처음엔 임의의 장소에 사전에 설정해준 군집의 수(k)만큼의 중심점을 배치해줍니다. 그리고 일단 가장 기본적으로 이 중심점을 기준으로 데이터들을 군집화 하게 됩니다.
위쪽에 있는 초록색 중심점과 가까운 데이터들은 초록 중심점 소속으로,
아래에 있는 노란색 중심점과 가까운 데이터들은 노랑 중심점 소속으로
각각 구분이 된다는 것이죠.
그러나 저 중심점의 위치가 과연 정말 최적의 위치일까요? 데이터들을 좀 더 잘 구분하려면 *"중심이 데이터들의 가운데"* 에 있어야 합니다.
가운데로 가기 위해서, 중심점은 데이터와 본인과의 거리를 계산하면서 점점 데이터의 중심으로 이동하기 시작합니다.
평균의 중심으로 중심점 이동
각 데이터와 중심점간의 거리를 나타낸 그림입니다. 이 중심점까지의 거리가 평균적으로 비슷할 때까지 중심점을 이동시키는 것이죠.
중심점이 이동되면, 이동한 중심점에 대해 데이터들의 소속 또한 다시 새롭게 정의됩니다. 지금의 그림에선 나타나지 않지만, 이동하기 전에는 초록색 중심점 소속이었지만, 이동하고 나서는 노란색 중심점 소속일 수도 있다는 것이죠.
보시면 초록색 점이 그나마 데이터들의 중심으로 이동했습니다. 이런 식으로 계속해서 중심점을 이동시킵니다.
중심점 확정 및 최종 군집화
위와 같은 방법으로 중심점은 계속 반복해서 이동합니다. 언제까지 이동하냐구요? 이동해도 그 위치일때까지요!
중심점을 이동하다보면,,
이렇게 거리를 계산해서 이동시켜도 더 이상 움직이지 않는 순간이 생깁니다.
이 순간의 중심점을 최종 중심점으로 잡고, 그 순간의 데이터들의 소속 또한 최종 소속으로 잡는 것이죠. 이렇게 군집화가 이루어집니다.
그럼 우리가 원했던 군집화가 이루어지는 것이죠.
문제
아래의 baseline코드에 비어있는 부분에 적절한 코드를 넣어 완성해주세요.
군집화 알고리즘은 KMeans로, 군집의 수는 3개로, random_state는 42로 지정해주세요!
KMeans 함수의 파라미터중 n_clusters 는 군집의 개수를 정해주는 옵션이고, random_state를 통해서 난수를 고정할 수 있다. 이후 make_blobs로 가상의 데이터를 만들고 X, y에 데이터를 로드한다. 독립변수의 수가 두개이므로 생성한 데이터프레임의 칼럼값은 x1, x2로 정한다. 데이터 프레임의 레이블값으로 make_blobs로 로드한 y를 추가한다. 여기서 y값은 클러스터의 종류를 표현하는 일종의 레이블이다. Numpy의 unique 메서드로 target_list를 선언했다. for문을 이용해서 target_cl이란 데이터 프레임을 새로 선언하고 산점도 그래프로 출력했다.
kmeans.label_ : 각 데이터가 어떤 클러스터에 속하는지 그 결과를 표현한다. cluster_centers_ : 학습된 kmeans 모델은 centroids(군집의 중심점)을 갖는다. 이를 수치적으로 출력하기 위해서 위 함수로 좌표값을 확인할 수 있다.
1-3 실루엣 계수
문제
위에서 형성한 k-means 기반 군집의 실루엣 계수를 측정해주세요!
**from** sklearn.metrics **import** silhouette_score, silhouette_samples
*## 각 데이터별 실루엣 점수*samples **=** ```!!HERE YOUR CODE!!
df['silhouette'] = samples
전체 실루엣 점수
score = !!HERE YOUR CODE!!
print(f"🚀전체 실루엣 점수🚀\n{score:.2f}\n")
print("📃군집별 평균 실루엣 점수📃")
print(df.groupby('clusters')['silhouette'].mean())
검색 힌트: sklearn silhouette_score, sklearn silhouette_samples
레이블이 없는 데이터셋을 그룹화하는 것을 클러스터링이라고 한다. 만약 레이블이 있는 데이터셋을 그룹화한다면 지도학습의 일종인 분류가 된다. 데이터셋을 그룹화하려면 유사한것들끼리 묶어야한다. 이를 위해 데이터셋의 특성 데이터를 유사성 측정이라는 측정 항목을 사용으로 결합해서 데이터들 간의 유사성을 측정할 수 있다.
클러스터링의 사용 예시
시장 세분화, 소셜 네트워크 분석, 검색결과 그룹화, 의료영상, 이미지 세분화, 이상 감지
클러스터링을 하면 각 클러스터에 클러스터 ID 라는 번호가 할당된다. 클러스터 ID가 할당되면 예시용 전체 특성 세트를 클러스터 ID로 압축할 수 있다. 이를 통해 복잡한 예를 간단한 클러스터 ID로 표현하면 클러스터링이 강력해진다. 대규모 데이터셋의 처리를 간소화할수있다. 클러스터링 출력은 다운스트림 ML 시스템의 특성 데이터 역할을 합니다.
일반화
클러스터의 일부 예시에 특성 데이터가 누락된 경우 클러스터의 다른 예시에서 누락된 데이터를 추론할 수 있다.
데이터 압축
클러스터의 모든 예시에 대한 특성 데이터는 클러스터 ID로 대체할 수 있다. 이 과정을 거치면 대체로 특성 데이터가 간소화되고 저장장소가 절약된다. 데이터셋의 규모가 커지면 커질수록 이러한 이점들이 두드러진다. 또한, 머신러닝 입력 데이터로 전체 특성 데이터셋 대신에 클러스터터 ID를 사용할수있다.
개인정보 보호
사용자를 클러스터링하고 사용자 데이터를 특정 사용자 대신 클러스터 ID와 매칭해서 개인 정보를 보존할 수 있다. 사용자 데이터로 사용자를 특정할 수 없도록 클러스터는 충분한 수의 사용자를 그룹화해야한다.
2) 차원 축소(Dimension reduction)
차원 축소란 머신러닝이나 통계분야에서 활용되는 기술로 문제의 무작위 변수(random variable)의 규모를 줄여서 주요한 변수의 집합을 구하는 것이다. 차원 축소는 두 과정으로 이루어지는데 첫 번째는 변수 선택(feature selection)과 변수 추출(feature extraction)이다. 변수 선택 과정에서는 모델을 대표할 다차원 데이터의 집합에서 특성들의 작은 부분집합들을 필터링, 임베딩, wrapping을 통해 선택한다. 변수 추출 과정에서는 데이터셋의 차원을 줄여서 변수를 모델화하고 구성 요소들에 대한 분석을 수행한다.
Machine Learning 과정에서 Best Feature Subset 을 주는 것이 아니라, 사용자에게 feature-rank를 줌으로 각 feature의 영향력을 알려주는 방법이다. 따라서 해당 모델에 Best Feature Subset 은 아닐 수 있더라도, 도움이 된다고 볼 수 있다. 또한 여기서 각 ranking 화 한 Feature 들은 독립변수로 본다.
Wrapper Method
Machine Learning의 예측 정확도 측면에서 가장 좋은 성능을 보이는 Subset을 뽑아내는 방법이다. Machine Learning 을 진행하면서 Best Feature Subset을 찾아가는 방법이기 때문에 시간과 비용이 매우 높게 발생한다. 하지만 최종적으로 Best Feature Subset을 찾아주기 때문에 모델의 성능을 위해서는 적절하다. 물론, 해당 모델의 파라미터와 알고리즘 자체는 완성도가 높아야 제대로 된 Best Feature Subset을 찾을 수 있다.
Forward Selection(전진 선택) : 변수가 없는 상태로 시작하며 반복할 때마다 가장 중요한 변수를 추가하여 더 이상 성능의 향상이 없을 때까지 변수를 추가한다.
Backward Elimination(후방 제거) : 모든 변수를 가지고 시작하며, 가장 덜 중요한 변수를 하나씩 제거하면서 모델의 성능을 향상시킨다. 더 이상 성능의 향상이 없을 때까지 반복한다.
Stepwise Selection(단계별 선택): Foward Selection 과 Backward Elimination 을 결합하여 사용하는 방식으로, 모든 변수를 가지고 시작하여 가장 도움이 되지 않는 변수를 삭제하거나, 모델에서 빠져있는 변수 중에서 가장 중요한 변수를 추가하는 방법이다. 이와 같이 변수를 추가 또는 삭제를 반복한다. 반대로 아무것도 없는 모델에서 출발해 변수를 추가, 삭제를 반복할 수도 있다.
1-2 K-Means
가장 고전적이면서 직관적으로 이해하기 쉬운 군집화 기법입니다. K-Means는 다음과 같은 과정을 통해 군집화가 이루어져요!
임의의 중심점 설정
처음엔 임의의 장소에 사전에 설정해준 군집의 수(k)만큼의 중심점을 배치해줍니다. 그리고 일단 가장 기본적으로 이 중심점을 기준으로 데이터들을 군집화 하게 됩니다.
위쪽에 있는 초록색 중심점과 가까운 데이터들은 초록 중심점 소속으로,
아래에 있는 노란색 중심점과 가까운 데이터들은 노랑 중심점 소속으로
각각 구분이 된다는 것이죠.
그러나 저 중심점의 위치가 과연 정말 최적의 위치일까요? 데이터들을 좀 더 잘 구분하려면 *"중심이 데이터들의 가운데"* 에 있어야 합니다.
가운데로 가기 위해서, 중심점은 데이터와 본인과의 거리를 계산하면서 점점 데이터의 중심으로 이동하기 시작합니다.
평균의 중심으로 중심점 이동
각 데이터와 중심점간의 거리를 나타낸 그림입니다. 이 중심점까지의 거리가 평균적으로 비슷할 때까지 중심점을 이동시키는 것이죠.
중심점이 이동되면, 이동한 중심점에 대해 데이터들의 소속 또한 다시 새롭게 정의됩니다. 지금의 그림에선 나타나지 않지만, 이동하기 전에는 초록색 중심점 소속이었지만, 이동하고 나서는 노란색 중심점 소속일 수도 있다는 것이죠.
보시면 초록색 점이 그나마 데이터들의 중심으로 이동했습니다. 이런 식으로 계속해서 중심점을 이동시킵니다.
중심점 확정 및 최종 군집화
위와 같은 방법으로 중심점은 계속 반복해서 이동합니다. 언제까지 이동하냐구요? 이동해도 그 위치일때까지요!
중심점을 이동하다보면,,
이렇게 거리를 계산해서 이동시켜도 더 이상 움직이지 않는 순간이 생깁니다.
이 순간의 중심점을 최종 중심점으로 잡고, 그 순간의 데이터들의 소속 또한 최종 소속으로 잡는 것이죠. 이렇게 군집화가 이루어집니다.
그럼 우리가 원했던 군집화가 이루어지는 것이죠.
1-3 실루엣 계수
위에서 우리는 군집이 잘 형성되었는지 groupby와 시각화를 통해 확인했습니다. 과연 이 방법이 최선일까요?? 우리가 분류와 회귀에서 metric을 통해 모델의 성능을 측정했던 것처럼, 얼마나 잘 묶였는지를 측정하는 지표는 없을까요?🤔
실루엣 계수를 소개합니다. 실루엣 계수는 쉽게 말씀드리면
군집 내의 데이터끼리는 얼마나 잘 뭉쳐있는지, 다른 군집의 데이터와는 얼마나 멀리 떨어져 있는지
를 측정한 지표라고 생각하시면 됩니다.
측정하는 방법을 간단하게 말씀드릴게요!
저기서 초록색으로 표시된 데이터를 i번째 데이터라고 했을 때,
같은 초록색 군집에 속해있는 데이터들과 i번째 데이터와의 거리의 평균을 a(i) 라고 하고,
주황색 군집에 속해있는 다른 데이터들과의 거리의 평균을 b(i) 라고 하는 것이죠.
그럼 직관적으로 "군집내부 데이터끼리 얼마나 잘 뭉쳐져있고, 다른 군집의 데이터와는 얼마나 잘 떨어져있는지"를 나타낼 수 있게 되는 것입니다!
이렇게 나온 실루엣 계수(Silhouette Coefficient)는 -1~1 사이의 값을 가집니다. (정규화 과정을 거쳐서 그래요!)
1일 수록 좋지 않은 것이며, 1일 수록 군집화가 잘 수행된 것입니다.
0이 서로 다른 군집끼리 가까운 것을 의미하는데, 실루엣 계수가 -값을 가진다는 것은.. 군집끼리 서로 영켜있다~~ 라는 말이 되겠죠. 상당히 좋지 않은 경우입니다.
또 하나 주의해야 하는 것이..
실루엣 계수가 무조건 크다고 해서 "오.. 대박"할 수도 없는 게
개별 군집의 실루엣 계수가 높게 나왔지만, 나머지 다른 군집들이 완전 말 그대로 망해버리는 경우가 있습니다. 평균의 함정에 빠져버릴 수 있는 것이죠.
이러면 평균값이 어느 정도 괜찮게 나올 수 있기 때문에.. 주의가 필요합니다. 예를 들어드리면,
이런 식이면, 파란색 군집의 실루엣 계수는 매우 높게, 잘 나올 것입니다.
그러나 주황색 부분의 군집들은 실루엣 계수가 나쁘게 나오게 나오겠죠.
이들의 평균을 구해보면 그럭저럭 꽤 괜찮은 실루엣 계수가 나와버릴 것입니다.
이런 경우가 있을 수 있기 때문에, 이 점을 유념한 채로 계수를 잘 봐야한다~~ 는 것입니다!
이러한 점때문에, 저는 실루엣 계수만을 이용한다기 보다는, 실루엣 계수와 위에서 했던 시각화 기법을 동시에 활용해서 판단합니다 ㅎㅎ 그게 다른 사람들을 설득할 때도 더 좋게 작용했던 것같아요!
🚩심화 문제🚩
K-Means는 각 데이터포인트들 간의 거리를 기반으로 군집을 형성합니다. 그러나 만약 아래와 같은 데이터에도 K-Means가 최선이라고 할 수 있을까요?
만약 K-Means를 적용하면 아래와 같은 결과가 나옵니다.
어... 잘 된 거 같지는 않죠? 위와 같은 데이터 분포에서 거리 기반의 알고리즘을 적용하면 제대로된 군집화가 이루어지지 않습니다. 그럼 어떻게 해야할까요?
거리 기반 외의 다른 군집화 방법이 필요합니다. 분량상 이 컨텐츠에서 코드까지 다뤄보지는 않을 거예요! 다만 알아두시면 군집화 작업이 필요하실 때 분명 유용하게 사용하실 수 있을 거예요.
수많은 군집화 기법 중 아래의 기법에 대해 설명해주세요. 어떤 방식과 과정을 통해 이루어지는지 요약해주시면 됩니다!
DBSCAN
GMM
계층적 군집화
2-1 차원축소
데이터는 많을 수록 좋습니다. 그러나 데이터를 설명하는 Feature가 너무 다양한 경우엔 오히려 모델의 입장에선 부정적인 영향을 줄 수 있습니다. 데이터를 묘사하는 것을 Feature라고 한다면, 데이터를 묘사하는 것이 너무 많으니, 오히려 혼란을 초래한다는 것입니다.
이러는 경우, Feature를 효율적으로 줄일 수 있는 방법은 뭐가 있을까요? 차원축소기법에 대해 알아봅시다.
차원의 저주
차원의 저주란 데이터의 차원이 커질 수록 필요한 데이터의 수가 그만큼 증가하게 되고, 이에 따라 모델의 성능이 저하되는 현상을 말합니다.
또한 동시에 데이터 간의 거리가 벌어져 밀도가 희소해지는데(sparse), 이런 경우 거리에 기반한 알고리즘 성능이 매우 떨어지게 됩니다. 그림으로 보시죠!
위와 같이, 차원이 늘어나면 늘어날 수록 개별 데이터간 거리는 점점 멀어지는 것을 확인하실 수 있습니다. 이렇게 되면 거리에 기반한 알고리즘이 제 힘을 쓰기가 힘들겠죠?
그리고 피쳐가 많을 수록 피쳐가 다른 피쳐에 의해 설명 가능하게 되는 다중 공선성(Multicollinearity) 문제가 발생하게 될 가능성이 커지게 됩니다. 다중 공선성이라는 개념은 매우 중요합니다. Skill과 감을 잡는 데에는 사실 그렇게 주요하지 않지만, 더 엄밀하고 명확한 해석이 필요할 땐 중요하게 고려해야하는 요소이기 때문이죠. 우리는 일단 간단하게 익히는 것이 목표이기 때문에, 다중공선성에 대해 자세히 알고 넘어가진 않겠습니다.
어쨌든, 위와 같은 문제를 해결하기 위해 제시된 것이 바로 차원축소 입니다!
크게 2가지로 나뉘는데
1. Feature Selection
2. Feature Extraction
기법입니다. 1번 문제에서 이미 간단하게 개념을 보고 오셨으니 간단하게만 확인하고 넘어가겠습니다.
Feature Selection 은 말 그대로 필요한 피쳐만 선택하는 것입니다.
예를 들어, 어떤 데이터의 피쳐가
a,b,c,d,e,f,g 로 있을 때, 이 중 필요한 피쳐가 a,b 만 있으면 된다고 판단하면 그냥 a,b만 가져다가 쓰는 것이죠.
Feature Extraction 은 기존의 피쳐를 살짝 변형하면서 압축합니다. 피쳐 선택이 그냥 있는 것 "그대로" 골라오는 것이었다면, 피쳐 추출은 있는 것을 살짝 변형시키면서 압축을 시킵니다.
예를 들어, 어떤 데이터의 피쳐가
a,b,c,d,e,f,g로 이루어져 있을 때, 피쳐 추출을 하면 새로운 피쳐 A,B 로 이들을 압축하는 것이죠.
실생활에 가까운 예시를 들면, 학생을 평가할 때,
모의고사 성적, 내신, 수행평가, 수능, 봉사활동, 독서기록, 선생님 평가... 이런 다양한 피쳐들을
학업성취도, 커뮤니케이션 능력과 같은 피쳐들로 압축이 가능하다는 것이죠.
이런 식으로 피쳐 추출을 진행하게 되면 장점이, 새로운 의미를 도출해낼 수 있음을 의미합니다.
압축 되기 전엔 몰랐는데 압축되고 나니, 비로소 새로운 잠재적인 의미가 눈에 보인다는 것이죠. 이런 잠재적인 요소(Latent Factor)를 뽑아낼 수 있다는 장점 덕분에, 많이 사용되는 것이구요.
이 Latent Factor의 개념은 딥러닝에서도 매우 중요하게 작용합니다. 수많은 정보를 적절하게 요약하는 것. 딱 봐도 사용처가 매우 많을 것같지 않나요? ㅎㅎ
오늘 우리는 이 중 Feature Extraction 기법의 대표주자인 PCA를 사용하는 방법 대해 알아보도록 하겠습니다. PCA를 이해하려면, 공분산, 고유벡터, 고유값에 대한 개념을 알고 계셔야해요! 분량상, PCA에 대한 개념 이해는 한 마디로 요약하면
n_clusters 인수는 k-means의 k를 의미하는 군집형성의 개수를 뜻한다. n_jobs는 scikit-learn의 기본적인 병렬처리로 내부적으로 멀티프로세스를 사용하는 것이다. 만약 CPU 코어의 수가 충분하다면 n_jobs를 늘릴수록 속도가 증가한다. random_state를 통해서 난수를 고정한다.
make_blobs
make_blobs 함수는 등방성 가우시안 정규분포를 이용해 가상 데이터를 생성한다. 이 때 등방성이라는 말은 모든 방향으로 같은 성질을 가진다는 뜻이다. 다음 데이터 생성 코드의 결과를 보면 make_classification 함수로 만든 가상데이터와 모양이 다른 것을 확인 할 수 있다. make_blobs는 보통 클러스링용 가상데이터를 생성하는데 사용한다. make_blobs 함수의 인수와 반환값은 다음과 같다.
인수:
n_samples : 표본 데이터의 수, 디폴트 100
n_features : 독립 변수의 수, 디폴트 20
centers : 생성할 클러스터의 수 혹은 중심, [n_centers, n_features] 크기의 배열. 디폴트 3
unique 내에 리스트, np.array 자료를 넣어주면 된다. 배열의 고유한 원소들을 모은 뒤, 1차원 shape으로 변환하고 정렬한 결과를 반환한다. unique의 axis 옵션을 통해서 행이나 열 기준의 블록을 단위로 고유한 배열들의 집합을 구할 수 있다. numpy의 unique 함수에서는 각 고유 원소가 처음 등장한 위치인 index 정보와 각 값이 몇 번째 고유 원소에 매칭되는지에 대한 inverse 정보, 그리고 각 고유 원소가 등장한 총 횟수를 나타내는 counts 정보를 추가로 받을 수 있다. 각각 return_index, return_inverse, return_counts 인자를 True로 설정하면 튜플 형태로 unique 결과와 함께 위 정보들을 추가로 받는 것이 가능하다.
처음에 dataset을 load하고 concat을 한다. target1은 양성 환자들, resampled는 음성인 환자들중 20명을 샘플링했다. 여기서 pandas의 sample()은 무작위로 표본을 추출하는 메서드이다. 매개변수로 몇 개를 샘플링할지 정할 수 있다. 이후 train_test_split으로 데이터셋을 학습 데이터와 테스트 데이터로 나눈다. 이후 스케일러로 스케일을 해준뒤 스케일한 데이터를 scaled_X_trainscaled_X_val에 저장한다. 이후 일반적으로는 스케일한 데이터로 학습을 진행해야하지만 RandomForestClassifier는 스케일할 필요가 없다. 따라서, 코드상에서 분류를 스케일 하지 않은 데이터로 진행해서 코드를 따라갔다. 이후 classification_report() 로 결과를 출력했다.
1-2 Classification Metrics
위의 분류 결과를 보니, 정확도를 의미하는 accuracy외에 precision, recall, f1-score와 같은 지표를 확인할 수 있습니다. 이게 무엇을 의미할까요?
사실 분류 문제에서 정확도는 모델의 성능을 충분하게 나타내는 만능 지표가 되지 못합니다. 직관적으로 잘 와닿지 않죠? 아니 얼마나 잘 맞췄는지를 알려주는 정확도가 왜 만능 지표가 되지 못한다는 걸까요?
만약 여러분이 시험을 친다고 해봅시다. 시험은 100문제 중, 90문제의 정답이 1이고, 10문제의 정답이 0입니다.
성실한 여러분들은 문제를 다 고심하고 푸신 끝에 아, 90문제 정도가 정답이 1이고, 10문제가 정답이 0이구나~ 하고 OMR을 제출하고 90점의 점수를 받았습니다. 좋은 성적이죠.
그러나 옆자리에 앉은 불성실한 친구는 그냥 답을 전부 1로 찍고 잠들었습니다. 이 친구의 정확도 성적은 어떻게 나왔을까요?
맞습니다. 여러분과 똑같은 90점을 받게 됩니다.
이렇듯, 데이터가 불균형한 경우, 정확도는 좋은 지표가 될 수 없습니다. 대충 많은 target으로 찍으면 정확도는 높게 나올 수 있거든요.
그래서 좀 더 세밀한 지표가 필요합니다 그것들이 바로, 이제부터 여러분이 공부해볼 precision, recall, f1-score의 개념입니다.
문제
구글에 classification metrics를 검색한 후, 각각에 대해 정리한 내용을 아래에 간략하게 적어주세요!
분류 성능 지표(Classification Evaluation Metrics)
분류 성능 지표에는 accuracy(정확도), precision(정밀도), recall(재현율), f1 score, AOC-AUC이 있다.
혼동 행렬(Confusion Matrix)
Confusion Matrix란, 모델이 예측한 Label값과 target의 실제 label값을 비교하기 위한 표이다.
True Positive(TP) : 실제 class가 Positive인데 예측 class도 Positive로 맞게 예측
True Negative(TN) : 실제 class가 Negative인데 예측 class도 Negative로 맞게 예측
False Positive(FP) : 실제 class가 Negative인데 예측 class는 Positive로 다르게 예측
False Negative(FN) : 실제 class가 Positive인데 예측 class는 Negative로 다르게 예측
정확도(Accuracy)
Accuracy는 정확하게 분류 된 data sample의 개수를 총 data sample의 개수로 나눈 것으로, 가장 직관적이고 간단한 분류성능 평가지표.
$$ Accuracy = \frac{TP+TN}{TP+FN+FP+TN} $$
정확도는 class별 data sample 비율에 영향을 많이 받는다. 데이터 구성이 99%가 Negative class인 경우 이 모델은 모든 샘플에 대해 Negative class로 예측해도 99%의 정확도를 보인다.
따라서, 다른 분류성능 평가지표도 확인을 해야한다.
정밀도와 재현율(Precision & Recall)
정밀도와 재현율은 Positive class로 예측한 샘플에 대한 평가지표이다. 두 평가지표 모두 TP를 높이기 위한 목적이 있지만, 경우에 따라 FP나 FN이 낮아야하는 경우가 있다.
정밀도
정밀도는 모델이 Positive class로 예측한 샘플 중 target이 실제 Positive class인 샘플의 비율을 보여주는 평가지표이다. 즉, FP를 줄이는데 초점을 둔다.
$$ Precision = \displaystyle \frac{TP}{TP+FP} $$
스팸 메일 분류시, 일반 메일(N)을 스팸(P)으로 분류하면 사용자가 불현함을 느낀다.
재현율
재현율은 target이 실제로 Positive class를 가진 샘플중 Positive로 예측된 샘플의 비율을 보여주는 평가지표이다. 즉, FN을 줄이는데 초점을 두며, True Positive Rate(TPR) 또는 민감도(sensitivity)라고도 불린다.
$$ Recall = \displaystyle \frac{TP}{TP+FN} $$
암 검출, 테러범 및 금융사기 적발과 같이 생명이나 큰 손해를 주는 심각한 케이스를 positive로 분류해야 할때 재현율이 높아야한다. 보통 recall이 precision보다 중요한 경우가 많다.
F1 Score
Precision과 Recall이 서로 상충관계이므로 이 둘을 적절히 고려해서 종합적인 평가를 하기 위해 F1 Score가 탄생했다. 이를, Precision과 Recall의 조화평균이라 한다.
Accuracy는 dataset의 class 분포가 균일하거나 비슷할 때와 positive 예측과 negative 예측이 옳게 분류가 되었을 지 볼 때 적합하다.
F1 score는 class 분포가 불균일할 때 사용되기 때문에 대부분의 실세계 분류 문제에서는 class 분포가 불균일하여 F1 score가 모델을 평가하기에 더 적합하다. 또한, F1 score는 positive class 예측에 대한 precision과 recall의 균형을 고려할 때 적합하다.
AUC-ROC curve
Area Under the Curve - Receiver Operating Characteristic
$$ x축 : FPR = \frac{FP}{FP+TN} $$
FPR(1 - Specificity) : 실제로 Negative Label인 cases 중에 모델이 Positive로 예측한 비율.
예를 들어, 게임 내에서 어뷰징 유저는 Positive로 놓을때 클린한 유저를 어뷰징 유저로 판단할 경우 게임 충성도에 타격을 입는다.
$$ y축 : TPR = Recall = \frac{TP}{TP+FN} $$
AUC-ROC curve는 머신러닝 알고리즘의 성능을 평가하는데 매우 일반적으로 사용된다. ROC는 모든 임계값에서 분류 모델의 성능을 보여주는 그래프이다. AUC는 ROC 곡선 아래의 영역이다. AUC가 높다는 것은 클래스를 구별하는 모델의 성능이 훌륭하다는 뜻이다.
1-4 불균형이 적은 경우
우리가 방금 실습해본 경우는 target 간의 불균형이 매우 심한 상태였습니다.
1은 357인데 0은 20이라니.. 하지만 현실은 더 한 경우가 많죠 ㅠㅠ
이러나 저러나 아무튼 target의 불균형이 모델의 성능에 있어 얼마나 많은 영향을 주는지 알아봅시다.
불균형을 강제로 준 데이터가 아닌, 본래의 데이터로 학습을 시켰을 때 차이를 확인해보면 다음과 같습니다.
실전에선 어떻게 불균형을 해소시킬까요? 크게 2가지 방법이 있습니다. 바로 Over Sampling과 Under Sampling이죠.
Over Sampling은 쉽게 말해, 부족한 데이터를 늘려 균형을 맞추는 겁니다. 예를 들어, 멍멍이와 고양이를 분류할 때, 멍멍이 사진은 100장, 고양이 사진은 10장이 있다고 해봅시다. 멍멍이 사진은 엄청 많은데 고양이 사진은 너무 적습니다. 이런 경우, 고양이의 사진을 더 구해오거나 약간의 변형을 주어 고양이 사진을 100장으로 늘려줍니다. (나중에 딥러닝에 들어가시면 Augmentation을 배우실 거예요!)
Under Sampling은 반대로, 멍멍이 사진을 10장으로 줄여 데이터의 균형을 맞추는 것입니다. 멍멍이 사진 100장 중, 랜덤으로 10개를 뽑아도 되고, 가장 잘 나온 사진 10개를 추출해도 됩니다.
위와 같이, 데이터간의 균형을 어떻게 맞추느냐에 따라서 모델의 성능이 크게 좌우되기도 합니다. 직관적으로는 데이터의 양도 늘고, 균형도 맞출 수 있는 일석이조의 Over Sampling이 좋아보이지만, 한편으로 생각해보면 억지로 늘린 데이터가 정말 학습에 좋을까,,? 하는 의문이 들기도 하죠. 반대로 Under Sampling은 데이터의 양이 충분이 많으면 상관 없겠으나(멍멍이 사진 1,000,000장, 고양이 사진 100,000장) 두 target 모두 적은 경우엔? 데이터 하나하나가 아까운 상황에서 뭘 버릴지도 굉장히 큰 고민이 될것입니다.
결론: 데이터 상황과 분석 목적에 맞는 기법을 선택해야 한다!
그럼 간단하게 실습을 진행해볼게요!
문제
아래 코드에서 적절한 메소드를 입력하여 코드를 완성해주세요!
❗ !pip install imbalanced-learn을 통해 해당 라이브러리를 설치해주세요! ❗
분류에선, 얼마나 잘 맞췄는지를 기준으로 모델의 성능을 평가했습니다. 그럼 회귀 모델의 성능 평가는 어떻게 할 수 있을까요?
사실 회귀는 그 역사가 정말 오래된 만큼, 다양한 성능 지표가 있습니다. 하지만 결국 모든 건 하나로 이어지죠. 바로예측값과 실제값의 차이를 기준으로 합니다.
모델이 예측한 값과 실제 정답값과의 차이를 Loss라고 하는데요, 우리의 목표는 이 Loss가 가장 적은(=실제 값과 제일 비슷한) 모델을 만드는 게 목표입니다.
이 직관은 나중에 딥러닝에서 매우 중요하게 작용하니, 헷갈리시는 분들은 Loss... 작은 거 짱... 정도로 알고 가셔도 좋을 거 같습니다 ㅎㅎ
문제
아래 적혀있는 지표들이 무엇을 의미하는지 적어주세요! 너무 긴 설명은 필요 없습니다. 여러분이 이해하신 언어 그대로를 적어주세요!
MAE(Mean Absolute Error)
$$ MAE = \frac{1}{n}\sum_{i=1}^{n}{|x_{i}-x|} $$
MAE란 모델이 예측한 값과 실제 값 사이의 절대값의 평균이다. 절대값을 취하기 때문에 가장 직관적으로 알 수 있는 지표이다. 하지만, 오차를 절대값으로 취하기 때문에 모델이 실제보다 낮게 예측했는지(Underperformance) 아니면 높게 예측했는지(Overperformance)는 알 수 없다.
from sklearn.metrics import mean_absolute_error
mean_absolute_error(y, y_pred)
R-squared는 현재 사용하고 있는 x 변수가 y 변수의 분산을 얼마나 줄였는가이다. 단순히 y평균값 모델(기준모델)을 사용했을 때 대비 우리가 가진 x변수를 사용함으로서 얻는 성능 향상의 정도이다. 즉, R-squared 값이 1에 가까우면 데이터를 잘 설명하는 모델이고 0에 가까울수록 설명을 못하는 모델이라고 생각할 수 있다.
regression_report() 라는 함수를 선언해서 앞서 학습한 regression의 평가 지표들을 출력하는 기능을 구현했다. 우선 sklearn 라이브러리의 metrics에서 import한 함수들로 계산을 하고 이 값들을 DataFrame으로 만들었다. 그리고 python의 출력 문자의 색상을 변경해주는 옵션을 통해서 색상을 변경시켰다(\033[92m). 마지막으로 tabulate 함수를 이용해서 결과를 보기 좋게 출력하였다. 우선 load_diabetes()를 통해 정보를 받은후 dataset을 만들었다. 선형회귀 모델로 학습을 시키고 예측을 했다. 예측 결과를 그래프와 앞서 정의한 regression_report() 함수로 출력하였다.
마무리 숙제
우리는 가장 지금까지 간단한 예시로 간단한 모델을 사용해왔습니다. 물론 RandomForest나 LinearRegreesion도 매우 중요하고 좋은 모델이지만 더 다양한 모델을 쓸 수 있으면 써보는 것도 나쁘지 않습니다.
위의 예시에서 사용한 데이터셋을 기반으로, 분류와 회귀에서 각각 우리가 사용했던 모델이 아닌 다른 모델을 사용하고, 그 성능을 비교한 것을 WIL과 함께 올려주세요!
머신러닝은 크게 두가지로 나눌 수 있다. 데이터와 정답을 비교하며 학습하는 지도학습, 정답 없이 데이터만을 보고 판단하는 비지도학습이다. 이번 주차에는 그 중 지도학습에 대해 알아본다. 지도학습의 두 방법인 분류와 회귀에 대해 알아보고, 이들의 차이와 수행 방법에 대해 알아보자.
1. 회귀(Regression)
예측하고자 하는 종속변수가 숫자일때 회귀라는 머신러닝의 방법을 많이 사용한다. 예를 들어 레모네이드의 온도에 따른 판매량을 알아보고자 할때 종속변수인 판매량은 숫자이므로 회귀를 사용하는 것이 적절하다.
독립변수
종속변수
학습시킬 데이터를만드는 방법
공부시간
시험점수(10점, 20점)
사람들의 공부시간을입력받고 점수를 확인한다.
온도
레모네이드판매량
온도와 그날의 판매량을기록한다.
역세권,조망 등
집 값
집과 역까지의 거리,수치화된 조망의 평점 등을집 값과 함께 기록한다
온실기체량
기온변화량
과거에 배출된 온실 기체량과기온의 변화량을 기록한다.
자동차속도
충돌 시사망 확률
충돌시 속도와 사상자를기록한다.
나이
키
학생들의 나이에 따른 키를기록한다.
2. 분류(Classification)
어떤 문제를 만났는데 그 문제에서 추측하고 싶은 결과가 이름 혹은 문자라면 분류의 방법을 사용하면 된다.
독립변수
종속변수
학습시킬 데이터를만드는 방법
공부시간
합격 여부(합격/불합격)
사람들의 공부시간을입력받고, 최종 합격여부를확인한다.
X-ray 사진과영상 속 종양의크기, 두께
악성 종양여부(양성/음성)
의학적으로 양성과 음성이확인된 사진과영상 데이터를 모은다.
품종, 산도,당도, 지역, 연도
와인의등급
소믈리에를 통해서 등급이확인된 와인을 가지고품종, 산도 등의 독립변수를정하고 기록한다.
키, 몸무게,시력, 지병
현역, 공익,면제
키, 몸무게, 시력, 지병 등을토대로 현역, 공익,면제인지를 확인한다.
메일 발신인,제목, 본문 내용(사용된 단어, 이모티콘 등)
스팸 메일여부
이제까지 받은 메일을모으고, 이들을스팸 메일과 일반 메일로구분한다.
고기의 지방함량,지방색, 성숙도, 육색
소고기등급
소고기의 정보를 토대로등급을 측정한다.
분류와 회귀의 차이점
가지고 있는 데이터에 독립변수와 종속변수가 있고 종속 변수가 숫자일 때 회귀를 사용하면 된다.
반대로 종속변수가 이름일때 분류를 사용하면 된다.
양적 데이터와 범주형 데이터
양적(Quantitative)이란 얼마나 큰지, 얼마나 많은지, 어느 정도인지를 의미하는 데이터라는 뜻이다. 즉, 양적 데이터란 숫자라고 생각하면 된다. 반대로 이름이란 표현 대신에 범주(Categorical)이라는 표현을 쓴다.
면적(평)
온도 (섭씨)
판매량 (개)
1000
10
100
200
28
200
300
31
300
위 데이터는 양적 데이터이고 종속 변수가 양적 데이터라면 회귀를 사용하면 된다.
계절
날씨
휴가지
봄
비
바다
여름
흐림
산
산
맑음
강
위 데이터는 범주형 데이터이고 종속변수가 범주형 데이터이면 분류를 사용하면 된다.
미니문제
1. 분류는 정답 데이터(Label)이 있는 것을 의미하고, 회귀는 정답 데이터가 없는 것을 의미한다.
정답은 X이다. 분류와 회귀 모두 정답 데이터가 존재한다. 다만 그 종속변수의 데이터형에 차이가 있다.
2. 분류는 정답값이 범주형(Categorical)으로 이루어져 있고, 회귀는 정답값이 연속형(Continuous)으로 이루어져 있다. (O, X)
정답은 O이다. 분류는 종속변수, 즉 정답 값이 범주형으로 되어있고 회귀는 정답 값이 양적 데이터(숫자) 즉, 연속형으로 이루어져있다.
3. 분류 성능 지표(Classification Evaluation Metrics)
분류 성능 지표에는 accuracy(정확도), precision(정밀도), recall(재현율), f1 score, AOC-AUC이 있다.
혼동 행렬(Confusion Matrix)
Confusion Matrix란, 모델이 예측한 Label값과 target의 실제 label값을 비교하기 위한 표이다.
True Positive(TP) : 실제 class가 Positive인데 예측 class도 Positive로 맞게 예측
True Negative(TN) : 실제 class가 Negative인데 예측 class도 Negative로 맞게 예측
False Positive(FP) : 실제 class가 Negative인데 예측 class는 Positive로 다르게 예측
False Negative(FN) : 실제 class가 Positive인데 예측 class는 Negative로 다르게 예측
정확도(Accuracy)
Accuracy는 정확하게 분류 된 data sample의 개수를 총 data sample의 개수로 나눈 것으로, 가장 직관적이고 간단한 분류성능 평가지표.
$$ Accuracy = \frac{TP+TN}{TP+FN+FP+TN} $$
정확도는 class별 data sample 비율에 영향을 많이 받는다. 데이터 구성이 99%가 Negative class인 경우 이 모델은 모든 샘플에 대해 Negative class로 예측해도 99%의 정확도를 보인다.
따라서, 다른 분류성능 평가지표도 확인을 해야한다.
정밀도와 재현율(Precision & Recall)
정밀도와 재현율은 Positive class로 예측한 샘플에 대한 평가지표이다. 두 평가지표 모두 TP를 높이기 위한 목적이 있지만, 경우에 따라 FP나 FN이 낮아야하는 경우가 있다.
정밀도
정밀도는 모델이 Positive class로 예측한 샘플 중 target이 실제 Positive class인 샘플의 비율을 보여주는 평가지표이다. 즉, FP를 줄이는데 초점을 둔다.
$$ Precision = \displaystyle \frac{TP}{TP+FP} $$
스팸 메일 분류시, 일반 메일(N)을 스팸(P)으로 분류하면 사용자가 불현함을 느낀다.
재현율
재현율은 target이 실제로 Positive class를 가진 샘플중 Positive로 예측된 샘플의 비율을 보여주는 평가지표이다. 즉, FN을 줄이는데 초점을 두며, True Positive Rate(TPR) 또는 민감도(sensitivity)라고도 불린다.
$$ Recall = \displaystyle \frac{TP}{TP+FN} $$
암 검출, 테러범 및 금융사기 적발과 같이 생명이나 큰 손해를 주는 심각한 케이스를 positive로 분류해야 할때 재현율이 높아야한다. 보통 recall이 precision보다 중요한 경우가 많다.
F1 Score
Precision과 Recall이 서로 상충관계이므로 이 둘을 적절히 고려해서 종합적인 평가를 하기 위해 F1 Score가 탄생했다. 이를, Precision과 Recall의 조화평균이라 한다.
Accuracy는 dataset의 class 분포가 균일하거나 비슷할 때와 positive 예측과 negative 예측이 옳게 분류가 되었을 지 볼 때 적합하다.
F1 score는 class 분포가 불균일할 때 사용되기 때문에 대부분의 실세계 분류 문제에서는 class 분포가 불균일하여 F1 score가 모델을 평가하기에 더 적합하다. 또한, F1 score는 positive class 예측에 대한 precision과 recall의 균형을 고려할 때 적합하다.
AUC-ROC curve
Area Under the Curve - Receiver Operating Characteristic
$$ x축 : FPR = \frac{FP}{FP+TN} $$
FPR(1 - Specificity) : 실제로 Negative Label인 cases 중에 모델이 Positive로 예측한 비율.
예를 들어, 게임 내에서 어뷰징 유저는 Positive로 놓을때 클린한 유저를 어뷰징 유저로 판단할 경우 게임 충성도에 타격을 입는다.
$$ y축 : TPR = Recall = \frac{TP}{TP+FN} $$
AUC-ROC curve는 머신러닝 알고리즘의 성능을 평가하는데 매우 일반적으로 사용된다. ROC는 모든 임계값에서 분류 모델의 성능을 보여주는 그래프이다. AUC는 ROC 곡선 아래의 영역이다. AUC가 높다는 것은 클래스를 구별하는 모델의 성능이 훌륭하다는 뜻이다.
4. 불균형 데이터 다루는 법
fit_resample() :
SMOTE
ADASYN
5. 회귀
1)회귀란?
2) 회귀 모델을 평가하는 평가 지표
MAE(Mean Absolute Error)
$$ MAE = \frac{1}{n}\sum_{i=1}^{n}{|x_{i}-x|} $$
MAE란 모델이 예측한 값과 실제 값 사이의 절대값의 평균이다. 절대값을 취하기 때문에 가장 직관적으로 알 수 있는 지표이다. 하지만, 오차를 절대값으로 취하기 때문에 모델이 실제보다 낮게 예측했는지(Underperformance) 아니면 높게 예측했는지(Overperformance)는 알 수 없다.
from sklearn.metrics import mean_absolute_error
mean_absolute_error(y, y_pred)
R-squared는 현재 사용하고 있는 x 변수가 y 변수의 분산을 얼마나 줄였는가이다. 단순히 y평균값 모델(기준모델)을 사용했을 때 대비 우리가 가진 x변수를 사용함으로서 얻는 성능 향상의 정도이다. 즉, R-squared 값이 1에 가까우면 데이터를 잘 설명하는 모델이고 0에 가까울수록 설명을 못하는 모델이라고 생각할 수 있다.
TMI
tabulate
python DataFrame을 가독성 좋게 만들어주는 함수이다.
parameter
DataFrame : 우선 tabulate를 적용할 DataFrame을 전달해야한다.
headers = ‘keys’ : 각 컬럼의 이름(header)를 명시할지 정하는 것이다. headers 옵션을 생략하면 컬럼의 이름이 출력되지 않는다.
tablefmt : tabulate의 보여지는 형식을 정하는 옵션이다. tablefmt = ‘psql’ 의 경우 형식을 psql format으로 정한 예이다. 다른 형식으로는 ‘fancy_grid’ , ‘html’ , ‘pretty’ ,‘plain’ , ‘rst’ , ‘github’ , ‘tsv’ , ‘.4f’등이 있다.
showindex : DataFrame의 row index를 표시할지 결정하는 부분이다. 이 옵션이 True인 경우 row index를 표시하고 False인 경우 row index를 표시하지 않는다.
numalign :
숫자 데이터를 정렬할 위치를 설정하는 옵션. 옵션 값으로는 left, right, center가 있다.
stralign :
텍스트 데이터를 정렬할 위치를 설정하는 옵션. 옵션 값으로는 left, right, center가 있다.