AI 부트캠프/챕터2(10.14~11.08)

TIL 26

musukie 2024. 10. 31. 09:15

AI 활용

우리가 AI에 대한 개념이 없어도 AI를 활용할 수는 있다. 그러나 제대로 된 의미있는 서비스를 만들기 위해서는 AI 개념을 바탕으로 AI를 활용해야 한다. 관련 용어들을 살펴보자.

 

API (Application Programming Interface)는 프로그램끼리 통신하는 방법이다. (즉, 프로그램끼리 통신하는 인터페이스.) 다른 사람이 제공하는 서비스를 활용하려고 할 때, 다른 사람이 제공하는 프로그램과 나의 프로그램이 통신해야한다. API는 그 통신 방법 중 하나로, AI 서비스가 가장 많이 제공되는 방식이라고 할 수 있다. 예시로는 Google, ChatGPT, ElevenLabs 등이 있다.

더보기

구글에서 Vision API를 사용하면 이미지를 분석할 수 있다.

ChatGPT API를 사용하면 이미지를 생성하거나, 대화하는 프로그램을 만들 수 있다.

ElevenLabs를 사용하면 음성을 생성할 수 있다.

AI는 연구를 했다고 끝나는 것이 아니다. 이 모델을 코드에서 사용할 수 있는 형태로 바꿔야 하는데, API를 쓰면 자동으로 되기 때문에 편리해졌다.

 

사전 학습 모델(Pre-trained Model)은 많은 데이터로 미리 학습된 AI 모델이다. 이는 모델 단위로 많은 데이터를 통해 학습을 진행한 다음 학습된 결과가 제공되는 것이다. 장점은 학습 과정을 생략할 수 있고, 모델 단위로 제공되기 때문에 모델을 결합해서 사용하는 게 편하고, 안정성이 높다(다른 사람들이 제공해놓거나, 이미 라이브러리에서 사전 학습됐다고 제공되는 것들은 어느 정도 검증이 철저하게 됐다고 생각하면 된다.)는 것이다.  모델 연구나 개발 이외에도 다양한 작업들이 이미 돼있기 때문에 활용하기에 따라 결과를 천차만별로 낼 수 있다.

사전 학습 모델에는 Fine-Tuning이라는 중요한 개념이 있다. 사전 학습 모델은 개발자나 활용하는 사람이 별도로 학습을 시킴으로써 본인의 문제에 맞게 좀 더 최적화시킬 수 있다. 

더보기

API는 이미 완성된 집을 준 것이고, 사전 학습 모델은 검증이 철저하게 된 상태로 방 단위로 모듈을 준 것이라고 할 수 있다.


허깅페이스(Hugging Face)

자연어 처리(NLP)를 중심으로 다양한 AI 모델들을 제공하는 플랫폼이다. 특징을 살펴보자. 먼저, Transformers 라이브러리를 통해 이미 검증된 모델들을 쉽게 사용할 수 있다. 모델 허브(Model Hub)의 역할을 한다. 이미 학습된 모델들이 많기 때문에 클릭 몇 번으로 학습과 구현을 모두 생략할 수 있다. 언어 모델을 통해 수행하려는 작업들에 관해 연구된 내용은 거의 있는 것 같다. 따라서 우리는 쉽게 NLP 모델을 학습된 상태로 사용할 수 있다. 커뮤니티 중심이다. 오픈 소스 커뮤니티 중심으로 운영되어, 전 세계의 개발자들이 협력해서 모델을 만들고 공유할 수 있다.

 

장점으로는 쉬운 접근성, 광범위한 모델 선택, 오픈소스, 강력한 커뮤니티 지원이 있다. 단점으로는 리소스 요구량이 많고, 초기 설정이 복잡하며, NLP에만 특화되어 다른 AI 분야의 모델 수가 상대적으로 적다는 점이 있다.

더보기
import warnings
warnigs.filterwarnings('ignore')

 경고가 나왔을 때 무시하는 기능을 한다.

실습

이제 '문장의 앞 부분을 넣으면, 뒷 부분을 자동으로 만들어주는 인공지능 서비스'를 만들어보자.

from transformers import GPT2Tokenizer, GPT2LMHeadModel

tokenizer = GPT2Tokenizer.from_pretrained('gpt2')
model = GPT2LMHeadModel.from_pretrained('gpt2')

text = "Hello, it's"
encoded_input = tokenizer(text, return_tensors = 'pt')

encoded_input
# 출력 : {'input_ids': tensor([[15496,    11,   340,   338]]), 'attention_mask': tensor([[1, 1, 1, 1]])}

text는 입력에 사용될 문장이라고 생각하면 된다. 이 입력을 그대로 사용하면 안 되고, 모델이 사용할 수 있는 형태로 바꿔줘야 한다. tokenizer에 text를 전달하고, return_tensors = 'pt'라고 적어준다.  출력된 것을 살펴보면, 언어가 언어 모델이 사용할 수 있는 형태로 바뀌었다는 것을 확인할 수 있다.

 

입력을 만들었으니 모델의 결과값을 저장할 output을 만들어보자.

output = model.generate(encoded_input['input_ids'], max_length = 50)
generated_text = tokenizer.decode(output[0], skip_special_tokens = True)

generate에 encoded_input을 가져오고, 나머지를 지정해준다. 그리고 generated_text를 사람이 인지할 수 있는 형태로 바꿔주어야 하기 때문에 tokenizer를 다시 활용한다. output[0], skip_special_tokens = True 부분은 언어 모델에 따라 특별한 토큰이 있는 경우가 있는데, 그와 비슷한 옵션이라고 생각하면 된다. 위의 코드를 실행하면 아래의 워닝이 나오지만, 생성은 완료되었으니 결과를 출력하면 된다. 

The attention mask and the pad token id were not set. As a consequence, you may observe unexpected behavior. Please pass your input's `attention_mask` to obtain reliable results.
Setting `pad_token_id` to `eos_token_id`:None for open-end generation.
The attention mask is not set and cannot be inferred from input because pad token is same as eos token. As a consequence, you may observe unexpected behavior. Please pass your input's `attention_mask` to obtain reliable results.
generated_text
# 출력 : "Hello, it's been a while since I've posted a post about this. I'm not sure if I've been able to get it to work, but I'm sure it's something that I'll be able to do.\n\nI'm"

output
# 출력 : tensor([[15496,    11,   340,   338,   587,   257,   981,  1201,   314,  1053,
          4481,   257,  1281,   546,   428,    13,   314,  1101,   407,  1654,
           611,   314,  1053,   587,  1498,   284,   651,   340,   284,   670,
            11,   475,   314,  1101,  1654,   340,   338,  1223,   326,   314,
          1183,   307,  1498,   284,   466,    13,   198,   198,    40,  1101]])

generated_text는 사람이 인식할 수 있는 형태로 바꿔주어서 알아볼 수 있지만, 바꾸기 전인 output은 사람이 해석할 수 없다는 것을 확인할 수 있다.

 

text를 "My name is"로 바꿔서 다시 실행해보자.

text = "My name is"
# 사이의 나머지 코드는 동일하다.

generated_text
# 출력 : "My name is John. I'm a man of God. I'm a man of God. I'm a man of God. I'm a man of God. I'm a man of God. I'm a man of God. I'm a"

결과가 다르게 나온 것을 확인할 수 있다.

 

우리가 단순히 문장 생성이라는 간단한 작업을 진행한다고 가정해도, 그 작업 자체는 인공지능에게는 매우 어려운 작업이다. 언어 분석과 생성이 모두 포함돼야 한다. 따라서 이를 우리가 일일이 만드려고 하면 굉장히 어렵다. 그러나 허깅페이스를 통해 코드 몇 줄로 간단하게 AI 서비스를 만들 수 있게 되었다.


GitHub는 AI를 활용하는 방법 중 하나다.

더보기

상황을 가정해보자. 우리는 데이터가 많아서 특정 모델만 있으면 그 데이터를 활용할 수 있다. 그러나 사전학습된 모델(pre-trained)은 원하지 않고, 우리의 데이터로만 학습된 모델을 원한다. 모델을 처음부터 구현하기에는 너무 어려워서 다른 사람이 공개적으로 발표한 모델을 활용하고 싶고, 코드까지 알고 싶다. 이럴 때 GitHub를 활용하면 된다. 또 완성된 모델이 아닌 개발된 모델을 가져와서 특정 부분만 수정하고 싶을 때도 코드 단위로 모델이 제공되기 때문에 GitHub를 통해 편하게 AI를 활용할 수 있다.

GitHub 를 사용할 때 주의점에 대해 알아보자.

각각의 코드마다 라이센스가 다르기 때문에, 해당 코드를 활용했을 때 내가 이 코드를 활용해서 프로그램을 만들었다는 것을 명시해야할 수도 있다. 또 수정 자체도 불가능할 수도 있다. 따라서 GitHub에서 제공하는 오픈소스 AI 프로젝트를 활용할 때는 반드시 라이센스를 확인해야 한다.

Git 깃

Git은 분산 버전 관리 시스템이다. 파일이 변경됐을 때, 그 이력을 추적할 수 있고, 여러 사람이 하나의 프로젝트와 하나의 파일에서 동시에 작업할 수 있게 도와주는 툴이라고 생각하면 된다. repository(레포지토리)는 프로젝트의 파일과 폴더, 변경 내역을 저장하는 데이터베이스다. 여기에는 로컬 레포지토리라는 자신의 컴퓨터에 있는 레포지토리와, 원격 레포지토리라는 서버에 저장된 레포지토리가 있다. commit(커밋)은 파일을 변경했을 때 하나의 스냅샷으로 저장하는 작업이다. 커밋을 통해 코드의 특정 상태를 기록하고, 특정 시점의 코드를 다시 백업할 수도 있다. Branch, Merge, Clone, Push, Pull과 같은 기능들이 있는데, 이들도 모두 협업을 위해 사용되는 기능들이다. 이 중 Clone은 원격 레포지토리를 로컬로 복사해오는 작업으로, 전체 내용을 자신의 컴퓨터로 가져올 수 있다.

GitHub 깃허브

GitHub는  Git을 기반으로 한 소프트웨어 개발 플랫폼으로, 코드를 저장하고 협업할 수 있는 플랫폼이다. Git을 좀 더 편하게 사용할 수 있고, 자신이 진행한 프로젝트를 공개하거나, 다른 사람들이 진행한 프로젝트에 참여할 수 있다. Public은 모두에게 공개되지만, Privacy를 통해 자체적으로 공개되지 않는 프로젝트를 설정할 수 있다.

 

오픈소스는 소스 코드가 공개된 소프트웨어를 말하며, 누구나 이 코드를 보고 수정·배포할 수 있다. 그러나 오픈소스로 공개했더라도 세부적인 라이센스가 다르다. 버전마다 라이센스가 다른 경우도 있다. 예를 들어 이 코드를 수정해서 상용 프로그램을 만드는 것은 안 된다거나 이 코드를 수정한 경우 명시해달라고 돼있는 경우도 있기 때문에 라이센스의 종류에 대해 상세히 살펴봐야 한다.

깃허브의 프로젝트 페이지를 살펴보자. 

Issues는 해당 코드를 사용할 때, 질문이나 문제가 있는 경우 공유하는 기능이다.

더보기

N사의 지식인같은 것이다. 해당 오픈 소스를 사용할 때 발생했던 문제들이 많이 공유돼있기 때문에 이를 확인해야 한다. 문제들이 자신이 해결할 수 있는지, 프로젝트 자체의 문제인지, 어떤 버전은 문제가 없다는 등의 정보를 확인한 후 활용하자.

Wiki에서는 유용한 정보들을 확인할 수 있다. 우리가 특정 패키지만을 사용한다고 하더라도, 그 패키지가 오픈소스 GitHub에 등록돼있다면 Wiki를 확인해보자. 몰랐던 정보나 유용한 팁들을 많이 알게 될  있다.  Pull requests는 우리가 오픈소스에 기여하는 방법 중 하나다. 이외에도 Actions, Projects 등 다양한 기능이 있는 것을 확인할 수 있다.

 

PyTorch 프로젝트 페이지를 살펴보자. 내용을 살펴보면 Readme를 통해 소스 코드로부터 패키지를 만드는 방법까지 알 수 있다. 예를 들어, 파이토치는 빌드 옵션에 따라 조금 더 최적화된 방식으로 사용할 수 있다. 패키지가 공개된 경우에는 빌드, 즉 소스 코드에서 패키지로 만드는 작업을 좀 더 상세하게 알 수 있다. Readme에는 일반적으로 라이센스가 같이 적혀있다. 

더보기

만약 코드 단위로 수정하고, 내가 수정한 나만의 pytorch 버전을 사용하고 싶을 때.

먼저, 라이센스를 확인해야 한다. 그리고 코드를 Clone이라는 기능을 사용하거나 간단하게 파일을 다운로드할 수도 있다.  그 파일을 수정한 다음 패키지화해서 사용하면 된다.

다양한 AI 프로젝트

요즘에는 AI 프로젝트가 수없이 많다. AI로 그림 그리기, 강화학습을 위한 게임 환경, 음성 인식 데이터셋 구축, Scikit-learn, Hugging Face, 단백질 구조 예측 등이 다. 모델만 있는 것이 아닌, 개발에 있어 거의 대부분의 프로젝트가 포함돼있다. 따라서 우리는 특정 모델을 구현하기 전에, 오픈 소스 프로젝트를 먼저 확인해보면 좋다.

GitHub에서 AI 프로젝트 클론하기

먼저 프로젝트를 찾아봐야 한다. 그런 다음, 프로젝트 페이지에서 Download ZIP을 클릭해 압축 파일을 다운받든지, 터미널에서 git clone을 입력하고 해당 프로젝트의 주소를 입력하면 자동으로 클론이 된다. 그 후에는 환경 설정하고, 각각의 코드별로 사용법이 다르기 때문에 Readme라는 사용 설명서 페이지에 있는 방법들을 수행하면 프로젝트를 실행할 수 있게 된다.

더보기

SNS의 좋아요와같이 깃허브에도 포크(Fork)와 별(Starring) 주기라는 문화가 있다. 이 기능을 활용하면, 깃허브를 단순히 코드가 저장돼있는 데이터베이스가 아닌, 플랫폼과 커뮤니티처럼 활용할 수 있을 것이다.


강의 외부에서 추가로 알게 된 내용

  • 비트 연산자는 AND 연산자(&)로 짝수 홀수 구분하기

숫자에 1을 AND 연산하면 홀수와 짝수를 구분할 수 있다.

짝수는 이진수로 표현할 때 마지막 비트가 0이다. (2, 4, 6 등)

홀수는 이진수로 표현할 때 마지막 비트가 1이다. (1, 3, 5 등)

따라서, 아래의 코드와 같이 x & 1 연산을 사용하여 짝수와 홀수를 구분할 수 있다.

x & 1 == 0: 짝수
x & 1 == 1: 홀수

 예시 코드는 아래와 같다.

x = 5
if x & 1:
    print("홀수입니다.")
else:
    print("짝수입니다.")
# 5는 이진수로 101이므로 5 & 1은 1. 따라서 홀수로 출력된다.
# 4는 이진수로 100이므로 4 & 1은 0. 따라서 짝수로 출력된다.

비트 연산자를 사용하면 일반적인 나머지 연산보다 속도가 빠르기 때문에, 짝수와 홀수를 구분하는 데 효율적이다.

 

  • 프로그래밍 관련 개념들의 포함 관계

포함 관계 다이어그램은 아래와 같다.

모듈
│
├── 패키지
│   ├── 모듈 (하위 모듈)
│   │   ├── 클래스
│   │   │   ├── 속성
│   │   │   ├── 메서드
│   │   │   ├── 클래스 변수
│   │   │   └── 인터페이스 (구현)
│   │   └── 함수
│   └── 인터페이스
│
└── 예외 처리

모듈
│
├── 패키지
│   ├── 모듈 (하위 모듈)
│   │   ├── 추상 클래스
│   │   │   ├── 속성
│   │   │   ├── 추상 메서드
│   │   │   └── 메서드 (구현)
│   │   ├── 클래스 (서브클래스)
│   │   │   ├── 속성
│   │   │   ├── 메서드 (구현)
│   │   └── 함수
│   └── 인터페이스
│
└── 예외 처리

 

모듈 (Module)은 관련된 함수, 클래스, 변수 등을 하나의 파일로 묶은 것이다. 파이썬에서 모듈은 .py 확장자를 가진 파일이다. 예) math, itertools, os 등의 내장 모듈. 사용 목적은 코드의 재사용성을 높이고, 프로그램을 조직적으로 관리하기 위해서이다. 모듈은 주로 여러 기능을 제공하는 하나의 파일로서, 파일의 경로를 통해 임포트하여 사용할 수 있다.

 

패키지 (Package)여러 모듈을 묶어서 하나의 그룹으로 관리할 수 있는 구조이다. 대규모 프로젝트에서 모듈을 그룹화하여 관리하기 위해 사용한다.

 

클래스 (Class)는 객체를 생성하기 위한 템플릿으로, 객체의 속성과 메서드를 정의한다. 클래스는 속성과 메서드를 통해 상태를 유지하고 동작을 수행한다.


추상 클래스 (Abstract Class)
 일부 메서드에 대한 구체적인 구현을 제공하지 않고, 서브클래스에서 이 메서드를 구현하도록 강제하는 클래스이다. 이는 인터페이스와 유사하지만, 일반적인 속성과 메서드를 포함할 수 있다.

 

속성 (Attribute)은 객체에 속하는 변수로, 클래스의 인스턴스에 포함된 데이터를 나타낸다. 객체의 상태나 특성을 나타낸다. 예) obj.attribute처럼 객체 obj의 attribute라는 속성. 사용 목적은 객체가 가지고 있는 정보를 저장하고, 해당 객체의 상태를 유지하기 위해서이다. 속성은 클래스의 인스턴스와 관련이 있으며, 객체에 대한 정보를 담고 있는 변수이다.

 

메서드 (Method)는 클래스 내에 정의된 함수로, 클래스의 인스턴스에서 호출할 수 있다. 메서드는 클래스와 밀접한 관계가 있다. 예)  class Dog: def bark(self): print("Woof!")에서 bark는 메서드이다. 사용 목적 객체의 상태를 변경하거나 객체와 관련된 작업을 수행하기 위해서이다. 메서드는 클래스에 속하는 함수이며, 일반적인 함수와는 다르게 객체의 상태를 조작할 수 있다.

 

클래스 변수 (Class Variable)클래스에 속하는 변수로, 모든 인스턴스가 공유하는 속성이다. 인스턴스 변수와는 달리, 모든 인스턴스가 동일한 값을 갖다.

 

인터페이스 (Interface)특정 메서드를 정의하지만, 그 메서드의 구체적인 구현을 제공하지 않는 클래스이다. 다른 클래스에서 이 인터페이스를 구현하여 해당 메서드를 정의할 수 있다. 파이썬에서는 인터페이스를 명시적으로 정의하는 방법은 없지만, 추상 클래스를 통해 유사하게 사용할 수 있다.

 

함수 (Function)는 특정 작업을 수행하는 코드 블록으로, 입력값을 받아 결과값을 반환한다. 독립적으로 호출할 수 있다. 예)  def add(a, b): return a + b처럼 정의된 함수. 사용 목적 코드의 재사용성을 높이고, 특정 작업을 반복적으로 수행하기 위해서이다. 함수는 독립적으로 호출될 수 있는 코드 블록이며, 특정 작업을 수행한다.

 

예외 처리 (Exception Handling)프로그램 실행 중 발생할 수 있는 오류를 관리하는 구조이다. 예외 처리는 일반적인 프로그램 흐름과는 별개로 동작하며, 예외 발생 시 특정 작업을 수행하도록 구성할 수 있다.

 

  • combinations(iterable, r)

Python의 itertools 모듈에 포함된 함수로, 주어진 iterable(예: 리스트, 튜플 등)에서 r개의 요소를 선택하여 조합(combination) 을 생성하는 데 사용된다. 조합은 순서가 중요하지 않으며, 중복을 허용하지 않는다. 기본 사용법은 아래의 코드와 같다. 반환값길이가 r인 조합의 튜플로 이루어진 iterator를 반환한다.

from itertools import combinations

combinations(iterable, r)
# iterable: 조합을 생성할 원본 데이터 구조 (리스트, 튜플, 문자열 등).
# r: 조합에 포함될 요소의 개수.

예시를 살펴보자.

# 기본 예시
from itertools import combinations

data = ['A', 'B', 'C']
result = list(combinations(data, 2))
print(result)
# 출력 : 리스트 ['A', 'B', 'C']에서 2개의 요소를 선택한 모든 조합을 생성한다.
[('A', 'B'), ('A', 'C'), ('B', 'C')]

# 숫자 리스트 조합
from itertools import combinations

numbers = [1, 2, 3, 4]
result = list(combinations(numbers, 3))
print(result)
# 출력 : 리스트 [1, 2, 3, 4]에서 3개의 숫자를 선택한 모든 조합을 생성한다.
[(1, 2, 3), (1, 2, 4), (1, 3, 4), (2, 3, 4)]

# 문자열 조합
from itertools import combinations

word = 'abc'
result = list(combinations(word, 2))
print(result)
# 출력 : 문자열 'abc'에서 2개의 문자를 선택한 모든 조합을 생성한다.
[('a', 'b'), ('a', 'c'), ('b', 'c')]

 

주의사항에 대해 알아보자. 조합의 순서가 중요하지 않기 때문에, (A, B)와 (B, A)는 같은 조합으로 간주된다. r의 값이 iterable의 길이보다 크면 빈 조합이 반환된다. combinations는 iterator를 반환하므로, 결과를 사용하기 위해서는 list()와 같은 방법으로 변환해야 한다.

 

  • ord()chr()

ord()chr() 함수는 문자와 그에 해당하는 Unicode 코드 포인트 간의 변환을 쉽게 할 수 있도록 도와주는 Python의 내장 함수이다. 두 함수는 서로의 기능을 보완하며 자주 함께 사용된다. 표를 통해 비교해보자.

함수 설명 입력 값 반환 값
ord() 주어진 문자의 Unicode 코드 포인트(정수 값)를 반환 단일 문자(1글자) 해당 문자에 대한 정수 값
chr() 주어진 Unicode 코드 포인트에 해당하는 문자를 반환 Unicode 코드 포인트(정수) 해당 정수 값에 대한 문자

예시를 살펴보자.

문자 ord() 반환 값 chr() 입력 값 chr() 반환 값
'a' 97 97 'a'
'A' 65 65 'A'
'!' 33 33 '!'
'@' 64 64 '@'
'가' 44032 44032 '가'

예시 코드도 살펴보자.

# 문자를 정수로 변환(ord)
print(ord('a'))  # 출력: 97
print(ord('A'))  # 출력: 65
print(ord('가'))  # 출력: 44032

# 정수를 문자로 변환 (chr)
print(chr(97))   # 출력: 'a'
print(chr(65))   # 출력: 'A'
print(chr(44032))  # 출력: '가'

# 시저 암호 예시
# 문자 'B'를 1만큼 밀어서 'C'로 변환
original_char = 'B'
shifted_char = chr(ord(original_char) + 1)  # 'C'
print(shifted_char)  # 출력: C

 

  • MONTH() 함수

SQL에서 날짜 또는 시간 값에서 월 정보를 추출하는 데 사용되는 함수다. 이 함수는 입력된 날짜의 월 부분을 정수로 반환한다. 기본 사용법은 아래와 같다.

MONTH(date)
# date: 날짜 형식의 데이터.
# 이 값은 날짜, 타임스탬프 형식일 수 있으며, 특정 형식으로 날짜를 입력해야 한다.

반환값으로는 1부터 12까지의 정수 값을 반환한다. 각 정수는 해당하는 월을 나타낸다. 예시는 아래와 같다.

# 기본 사용
SELECT MONTH('2024-10-31') AS MonthValue;
# 결과 : 10

# 테이블에서 사용 예
SELECT order_id, MONTH(order_date) AS OrderMonth
FROM orders;
# 출력
# 첫 번째 주문의 날짜는 2024-01-15로 월이 1.
# 두 번째 주문의 날짜는 2024-05-23로 월이 5.
# 세 번째 주문의 날짜는 2024-10-31로 월이 10.

 

  • UNION UNION ALL

UNION UNION ALL은 SQL에서 두 개 이상의 SELECT 쿼리의 결과를 결합하는 데 사용되는 연산자다. 이 두 연산자는 결과 집합을 합치는 방식에 차이가 있다.

 

먼저 UNION기본 기능 두 개 이상의 SELECT 쿼리 결과를 결합하고, 중복된 행을 제거하여 반환하는 것이다.조건은 모든 SELECT 쿼리는 같은 수의 열을 가져야 하며, 각 열의 데이터 타입도 서로 호환되어야 한다는 것이다. 사용 예시 코드는 아래와 같다.

SELECT column1 FROM table1
UNION
SELECT column1 FROM table2;
# 이 쿼리는 table1과 table2에서 column1의 값을 가져오되, 중복된 값은 하나만 반환한다.

 

UNION ALL 기본 기능 두 개 이상의 SELECT 쿼리 결과를 결합하지만, 중복된 행을 제거하지 않고 모든 행을 포함하는 것이다. 조건은 UNION과 마찬가지로 모든 SELECT 쿼리는 같은 수의 열을 가져야 하며, 각 열의 데이터 타입도 서로 호환되어야 한다는 것이다. 사용 예시 코드는 아래와 같다.

SELECT column1 FROM table1
UNION ALL
SELECT column1 FROM table2;
# 이 쿼리는 table1과 table2에서 column1의 값을 가져오고, 중복된 값도 포함하여 반환한다.

 

이를 표로 나타내면 아래와 같다.

  UNION UNION ALL
중복 제거 예 (중복된 행 제거) 아니오 (모든 행 포함)
성능 느림 (중복 제거 작업 수행) 빠름 (중복 제거 작업 없음)
사용 상황 중복된 값을 원하지 않을 때 모든 결과를 보고 싶을 때

 

각각의 사용 예시도 살펴보자.

# UNION 사용 예시
SELECT name FROM employees
UNION
SELECT name FROM managers;
# 이 쿼리는 employees 테이블과 managers 테이블에서 중복을 제거한 이름 목록을 반환한다.

# UNION ALL 사용 예시
SELECT name FROM employees
UNION ALL
SELECT name FROM managers;
# 이 쿼리는 employees와 managers에서 모든 이름 목록을 반환하며, 중복된 이름도 포함된다.

즉, UNIONUNION ALL은 데이터를 결합할 때 유용하게 사용되며, 중복 처리 여부에 따라 선택적으로 사용하면 된다. 데이터베이스의 성능과 결과의 필요에 따라 적절한 방법을 선택하는 것이 중요하다.

 

  • eval() 함수

Python에서 주어진 문자열을 Python 표현식으로 평가하여 그 결과를 반환하는 함수다. 이 함수는 주로 문자열로 표현된 코드를 실행하거나 수식을 계산할 때 사용된다. 하지만 eval()은 보안상의 이유로 주의해서 사용해야 한다. 기본 사용법은 아래와 같다.

result = eval(expression)
# expression: 문자열 형태의 Python 표현식

예시 코드를 살펴보자.

# 수식 계산
expression = "3 + 5"
result = eval(expression)
print(result)  # 출력: 8

# 리스트 생성
def add(a, b):
    return a + b

expression = "add(10, 5)"
result = eval(expression)
print(result)  # 출력: 15

# 함수 호출
def add(a, b):
    return a + b

expression = "add(10, 5)"
result = eval(expression)
print(result)  # 출력: 15

 

보안상 위험한 이유를 알아보자. eval() 함수는 문자열의 내용을 그대로 실행하므로, 악의적인 코드가 포함될 수 있다. 예를 들어보자.

user_input = "__import__('os').system('ls')"  # 악의적인 코드
eval(user_input)  # 시스템의 파일 목록을 출력하는 명령어가 실행됨
# 이러한 이유로, 신뢰할 수 없는 입력을 eval()로 처리하는 것은 매우 위험하다.

 

안전하게 대체할 방법에 대해 알아보자. ast.literal_eval()은 수치, 문자열, 튜플, 리스트, 딕셔너리와 같은 안전한 리터럴 표현식을 평가하는 데 사용할 수 있는 안전한 대안입니다. 예를 들어보자

import ast

safe_expression = "[1, 2, 3]"
result = ast.literal_eval(safe_expression)
print(result)  # 출력: [1, 2, 3]

eval() 함수는 매우 유용하지만, 보안상의 위험이 있으므로 사용에 주의해야 한다. 사용자 입력을 직접 실행하는 경우에는 항상 안전성을 고려해야 한다.

 

  • & 연산자

집합의 교집합을 구하는 연산자입니다. 두 집합에서 공통적으로 포함된 원소만을 반환한다. 교집합을 구하는 것은 두 집합의 원소 중에서 서로 공통된 원소를 찾는 것을 의미한다. 예시는 아래와 같다.

set1 = {'apple', 'banana', 'cherry'}
set2 = {'banana', 'kiwi', 'date'}

# 교집합을 구한다
common = set1 & set2  # {'banana'}

 

 

 

'AI 부트캠프 > 챕터2(10.14~11.08)' 카테고리의 다른 글

TIL 28  (3) 2024.11.04
TIL 27  (0) 2024.11.01
TIL 25  (0) 2024.10.30
TIL 24  (0) 2024.10.29
TIL 23  (0) 2024.10.28