Showing preview only (292K chars total). Download the full file or copy to clipboard to get everything.
Repository: boost-devs/ai-tech-interview
Branch: main
Commit: ee05fc3166a8
Files: 17
Total size: 281.9 KB
Directory structure:
gitextract_wex188is/
├── .github/
│ ├── PULL_REQUEST_TEMPLATE.md
│ ├── scripts/
│ │ └── convert_for_gitbook.py
│ └── workflows/
│ └── sync-gitbook.yml
├── .gitignore
├── .mergify.yml
├── LICENSE
├── README.md
├── SUMMARY.md
└── answers/
├── 1-statistics-math.md
├── 2-machine-learning.md
├── 3-deep-learning.md
├── 4-python.md
├── 5-network.md
├── 6-operating-system.md
├── 7-data-structure.md
├── 8-algorithm.md
└── statistics-math-distribution.md
================================================
FILE CONTENTS
================================================
================================================
FILE: .github/PULL_REQUEST_TEMPLATE.md
================================================
| **⚠ PR 템플릿은 수정하지 말아주세요!** <br/> **🔥 [PR 작성 규칙](https://github.com/boostcamp-ai-tech-4/ai-tech-interview/discussions/182#discussion-4321560)을 준수하지 않는 PR은 거절됩니다. 꼭 읽어주세요.**|
| :--- |
## 🔎 What is this PR?
### 분야
> **`필수` 수정하려는 답변의 분야를 선택해주세요. 이외 수정사항은 기타를 선택하시고 오른쪽에 추가 설명 부탁드립니다.**
- [ ] 통계/수학
- [ ] 머신러닝
- [ ] 딥러닝
- [ ] 파이썬
- [ ] 네트워크
- [ ] 운영체제
- [ ] 자료구조
- [ ] 알고리즘
- [ ] 기타:
### 수정 내용
> **`필수` 어떻게 수정하셨는지 자세히 작성 부탁드립니다.**
### 참고 자료
> **`선택` 수정 시 참고한 문서가 있다면 링크 작성 부탁드립니다.**
## ✅ PR Checklists
> **`필수` 아래 체크리스트 확인 부탁드립니다. 모두 체크된 PR만 확인 가능합니다.**
- [ ] [PR 작성 규칙](https://github.com/boostcamp-ai-tech-4/ai-tech-interview/discussions/182)을 준수하셨나요?
- [ ] **"1문제 1PR" 원칙**을 준수하셨나요?
- [ ] PR 템플릿에 맞춰서 PR을 작성하셨나요?
- [ ] PR 제목은 "[분야] 수정내용"로 되어있나요? (분야는 **한글 명칭**만 가능 ex. 딥러닝, 머신러닝)
- [ ] PR이 **①미적으로 나아졌을 경우 ②답변이 개선된 경우** 두 가지 중 하나에 해당되나요?
- [ ] LaTeX 문법을 준수하셨나요? (참고: [GitHub 수식 기능 공지](https://github.blog/2022-05-19-math-support-in-markdown/))
- [ ] upstream 레포의 최신 브랜치와 동일한 main 브랜치에서 분기하여 수정하셨나요?
================================================
FILE: .github/scripts/convert_for_gitbook.py
================================================
#!/usr/bin/env python3
"""Convert GitHub markdown syntax to GitBook-compatible syntax.
Transformations:
1. Inline math: $...$ → $$...$$
2. Callouts: > [!TIP/WARNING/...] → {% hint style="..." %}
3. TOC anchors: (#N) → (#id-N)
"""
import re
import os
def convert_inline_math(content):
"""Convert $...$ inline math to $$...$$ for GitBook.
Skips code blocks and already-converted $$...$$ expressions.
"""
# Split by fenced code blocks and inline code to avoid modifying them
parts = re.split(r'(```[\s\S]*?```|`[^`\n]+`)', content)
result = []
for i, part in enumerate(parts):
if i % 2 == 0: # Non-code section
part = re.sub(
r'(?<!\$)\$(?!\$)([^\n$]+?)(?<!\$)\$(?!\$)',
r'$$\1$$',
part
)
result.append(part)
return ''.join(result)
def convert_callouts(content):
"""Convert GitHub [!TYPE] callouts to GitBook hint blocks.
GitHub:
> [!TIP]
> content
GitBook:
{% hint style="info" %}
content
{% endhint %}
"""
style_map = {
'TIP': 'info',
'NOTE': 'info',
'WARNING': 'warning',
'IMPORTANT': 'warning',
'CAUTION': 'danger',
}
def replace_callout(match):
callout_type = match.group(1).upper()
body = match.group(2)
lines = re.sub(r'^> ?', '', body, flags=re.MULTILINE).strip()
style = style_map.get(callout_type, 'info')
return f'{{% hint style="{style}" %}}\n{lines}\n{{% endhint %}}\n'
pattern = r'> \[!(\w+)\]\s*\n((?:>[ \t]?[^\n]*\n)*)'
return re.sub(pattern, replace_callout, content)
def convert_toc_anchors(content):
"""Convert (#N) TOC links to (#id-N) for GitBook anchor compatibility.
GitBook generates 'id-N' anchors for headings like '## #N'.
"""
return re.sub(r'\(#(\d+)\)', r'(#id-\1)', content)
def convert_file(filepath):
with open(filepath, 'r', encoding='utf-8') as f:
content = f.read()
content = convert_inline_math(content)
content = convert_callouts(content)
content = convert_toc_anchors(content)
with open(filepath, 'w', encoding='utf-8') as f:
f.write(content)
print(f'Converted: {filepath}')
def main():
for root, dirs, files in os.walk('.'):
dirs[:] = [d for d in dirs if not d.startswith('.')]
for filename in files:
if filename.endswith('.md'):
convert_file(os.path.join(root, filename))
if __name__ == '__main__':
main()
================================================
FILE: .github/workflows/sync-gitbook.yml
================================================
name: Sync to GitBook
on:
push:
branches:
- main
jobs:
sync:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.x'
- name: Convert markdown for GitBook
run: python .github/scripts/convert_for_gitbook.py
- name: Push to gitbook branch
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git checkout -B gitbook
git add -A
git diff --cached --quiet || git commit -m "chore: sync from main [skip ci]"
git push origin gitbook --force
================================================
FILE: .gitignore
================================================
# Created by https://www.toptal.com/developers/gitignore/api/windows,macos,linux
# Edit at https://www.toptal.com/developers/gitignore?templates=windows,macos,linux
### Linux ###
*~
# temporary files which can be created if a process still has a handle open of a deleted file
.fuse_hidden*
# KDE directory preferences
.directory
# Linux trash folder which might appear on any partition or disk
.Trash-*
# .nfs files are created when an open file is removed but is still being accessed
.nfs*
### macOS ###
# General
.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
### macOS Patch ###
# iCloud generated files
*.icloud
### Windows ###
# Windows thumbnail cache files
Thumbs.db
Thumbs.db:encryptable
ehthumbs.db
ehthumbs_vista.db
# Dump file
*.stackdump
# Folder config file
[Dd]esktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Windows Installer files
*.cab
*.msi
*.msix
*.msm
*.msp
# Windows shortcuts
*.lnk
# End of https://www.toptal.com/developers/gitignore/api/windows,macos,linux
================================================
FILE: .mergify.yml
================================================
pull_request_rules:
- name: Assign yourself and request reviews automatically
conditions:
- -merged
- -closed
- base=main
actions:
assign:
add_users:
- CoodingPenguin
request_reviews:
users:
- CoodingPenguin
label:
add:
- "💬 feedback"
- name: Automatic merge on approval
conditions:
- -closed
- -merged
- "#approved-reviews-by>=1"
- "#changes-requested-reviews-by=0"
- base=main
actions:
merge:
method: merge
- name: Add conflict label
conditions:
- -closed
- -merged
- conflict
actions:
comment:
message: "@{{author}} Conflict 해결이 필요합니다!😥 cc. @CoodingPenguin"
label:
add:
- "❗ conflict"
- name: Remove conflict label
conditions:
- -closed
- -merged
- -conflict
actions:
label:
remove:
- "❗ conflict"
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2021 boost-devs
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: README.md
================================================

<div align="center">
<a href="https://hits.sh/github.com/boost-devs/ai-tech-interview/"><img alt="Hits" src="https://hits.sh/github.com/boost-devs/ai-tech-interview.svg?view=today-total&color=dfb317"/></a>
<img src="https://img.shields.io/github/forks/boostcamp-ai-tech-4/ai-tech-interview" alt="forks"/>
<img src="https://img.shields.io/github/stars/boostcamp-ai-tech-4/ai-tech-interview?color=yellow" alt="stars"/>
<img src="https://img.shields.io/github/issues-pr/boostcamp-ai-tech-4/ai-tech-interview?color=red" alt="pr"/>
<img src="https://img.shields.io/github/license/boostcamp-ai-tech-4/ai-tech-interview" alt="license"/>
</div>
---
## Notice
> [!TIP]
> 이동 중에도 면접 준비하고 싶다면, @LearningnRunning 님이 만든 [AI Tech Interview 연습하기](https://ai-tech-interview.streamlit.app/)를 이용해보세요!
> [!WARNING]
> PR 요청 시 [작성 규칙](https://github.com/boost-devs/ai-tech-interview/discussions/182)을 준수해주세요. **준수하지 않을 시 해당 PR은 거절될 수 있습니다.**
- 피드백은 [Pull Request를 통한 피드백 요청 방법](https://github.com/boost-devs/ai-tech-interview/discussions/181)을 참고하여 Pull Request로 보내주세요.
- Pull Request 작성 규칙은 [여기](https://github.com/boost-devs/ai-tech-interview/discussions/182)를 참고해주세요.
- GitHub 외에 [GitBook 사이트](https://boostdevs.gitbook.io/ai-tech-interview/)로도 보실 수 있습니다.
---
## Interview Questions
<details>
<summary><a href="./answers/1-statistics-math.md"><strong>📈 통계/수학</strong></a></summary>
- 고유값(eigen value)와 고유벡터(eigen vector)이 무엇이고 왜 중요한지 설명해주세요.
- 샘플링(Sampling)과 리샘플링(Resampling)이 무엇이고 리샘플링의 장점을 말씀해주세요.
- 확률 모형과 확률 변수는 무엇인가요?
- 누적 분포 함수와 확률 밀도 함수는 무엇인가요? 수식과 함께 표현해주세요.
- 조건부 확률은 무엇인가요?
- 공분산과 상관계수는 무엇일까요? 수식과 함께 표현해주세요.
- 신뢰 구간의 정의는 무엇인가요?
- p-value를 모르는 사람에게 설명한다면 어떻게 설명하실 건가요?
- R square의 의미는 무엇인가요?
- 평균(mean)과 중앙값(median)중에 어떤 케이스에서 뭐를 써야할까요?
- 중심극한정리는 왜 유용한걸까요?
- 엔트로피(entropy)에 대해 설명해주세요. 가능하면 Information Gain도요.
- 어떨 때 모수적 방법론을 쓸 수 있고, 어떨 때 비모수적 방법론을 쓸 수 있나요?
- “likelihood”와 “probability”의 차이는 무엇일까요?
- 통계에서 사용되는 bootstrap의 의미는 무엇인가요.
- 모수가 매우 적은 (수십개 이하) 케이스의 경우 어떤 방식으로 예측 모델을 수립할 수 있을까요?
- 베이지안과 프리퀀티스트 간의 입장차이를 설명해주실 수 있나요?
- 검정력(statistical power)은 무엇일까요?
- missing value가 있을 경우 채워야 할까요? 그 이유는 무엇인가요?
- 아웃라이어의 판단하는 기준은 무엇인가요?
- 필요한 표본의 크기를 어떻게 계산합니까?
- Bias를 통제하는 방법은 무엇입니까?
- 로그 함수는 어떤 경우 유용합니까? 사례를 들어 설명해주세요.
- 베르누이 분포 / 이항 분포 / 카테고리 분포 / 다항 분포 / 가우시안 정규 분포 / t 분포 / 카이제곱 분포 / F 분포 / 베타 분포 / 감마 분포에 대해 설명해주세요. 그리고 분포 간의 연관성도 설명해주세요.
- 출장을 위해 비행기를 타려고 합니다. 당신은 우산을 가져가야 하는지 알고 싶어 출장지에 사는 친구 3명에게 무작위로 전화를 하고 비가 오는 경우를 독립적으로 질문해주세요. 각 친구는 2/3로 진실을 말하고 1/3으로 거짓을 말합니다. 3명의 친구가 모두 “그렇습니다. 비가 내리고 있습니다”라고 말했습니다. 실제로 비가 내릴 확률은 얼마입니까?
</details>
<details>
<summary><a href="./answers/2-machine-learning.md"><strong>🤖 머신러닝</strong></a></summary>
- 알고 있는 metric에 대해 설명해주세요. (ex. RMSE, MAE, recall, precision ...)
- 정규화를 왜 해야할까요? 정규화의 방법은 무엇이 있나요?
- Local Minima와 Global Minimum에 대해 설명해주세요.
- 차원의 저주에 대해 설명해주세요.
- dimension reduction기법으로 보통 어떤 것들이 있나요?
- PCA는 차원 축소 기법이면서, 데이터 압축 기법이기도 하고, 노이즈 제거기법이기도 합니다. 왜 그런지 설명해주실 수 있나요?
- LSA, LDA, SVD 등의 약자들이 어떤 뜻이고 서로 어떤 관계를 가지는지 설명할 수 있나요?
- Markov Chain을 고등학생에게 설명하려면 어떤 방식이 제일 좋을까요?
- 텍스트 더미에서 주제를 추출해야 합니다. 어떤 방식으로 접근해 나가시겠나요?
- SVM은 왜 반대로 차원을 확장시키는 방식으로 동작할까요? SVM은 왜 좋을까요?
- 다른 좋은 머신 러닝 대비, 오래된 기법인 나이브 베이즈(naive bayes)의 장점을 옹호해보세요.
- 회귀 / 분류시 알맞은 metric은 무엇일까?
- Association Rule의 Support, Confidence, Lift에 대해 설명해주세요.
- 최적화 기법중 Newton’s Method와 Gradient Descent 방법에 대해 알고 있나요?
- 머신러닝(machine)적 접근방법과 통계(statistics)적 접근방법의 둘간에 차이에 대한 견해가 있나요?
- 인공신경망(deep learning이전의 전통적인)이 가지는 일반적인 문제점은 무엇일까요?
- 지금 나오고 있는 deep learning 계열의 혁신의 근간은 무엇이라고 생각하시나요?
- ROC 커브에 대해 설명해주실 수 있으신가요?
- 여러분이 서버를 100대 가지고 있습니다. 이때 인공신경망보다 Random Forest를 써야하는 이유는 뭘까요?
- K-means의 대표적 의미론적 단점은 무엇인가요? (계산량 많다는것 말고)
- L1, L2 정규화에 대해 설명해주세요.
- Cross Validation은 무엇이고 어떻게 해야하나요?
- XGBoost을 아시나요? 왜 이 모델이 캐글에서 유명할까요?
- 앙상블 방법엔 어떤 것들이 있나요?
- feature vector란 무엇일까요?
- 좋은 모델의 정의는 무엇일까요?
- 50개의 작은 의사결정 나무는 큰 의사결정 나무보다 괜찮을까요? 왜 그렇게 생각하나요?
- 스팸 필터에 로지스틱 리그레션을 많이 사용하는 이유는 무엇일까요?
- OLS(ordinary least squre) regression의 공식은 무엇인가요?
</details>
<details>
<summary><a href="./answers/3-deep-learning.md"><strong>🧠 딥러닝</strong></a></summary>
- 딥러닝은 무엇인가요? 딥러닝과 머신러닝의 차이는?
- Cost Function과 Activation Function은 무엇인가요?
- Tensorflow, PyTorch 특징과 차이가 뭘까요?
- Data Normalization은 무엇이고 왜 필요한가요?
- 알고있는 Activation Function에 대해 알려주세요. (Sigmoid, ReLU, LeakyReLU, Tanh 등)
- 오버피팅일 경우 어떻게 대처해야 할까요?
- 하이퍼 파라미터는 무엇인가요?
- Weight Initialization 방법에 대해 말해주세요. 그리고 무엇을 많이 사용하나요?
- 볼츠만 머신은 무엇인가요?
- TF, PyTorch 등을 사용할 때 디버깅 노하우는?
- 뉴럴넷의 가장 큰 단점은 무엇인가? 이를 위해 나온 One-Shot Learning은 무엇인가?
- 요즘 Sigmoid 보다 ReLU를 많이 쓰는데 그 이유는?
- Non-Linearity라는 말의 의미와 그 필요성은?
- ReLU로 어떻게 곡선 함수를 근사하나?
- ReLU의 문제점은?
- Bias는 왜 있는걸까?
- Gradient Descent에 대해서 쉽게 설명한다면?
- 왜 꼭 Gradient를 써야 할까? 그 그래프에서 가로축과 세로축 각각은 무엇인가? 실제 상황에서는 그 그래프가 어떻게 그려질까?
- GD 중에 때때로 Loss가 증가하는 이유는?
- Back Propagation에 대해서 쉽게 설명 한다면?
- Local Minima 문제에도 불구하고 딥러닝이 잘 되는 이유는?
- GD가 Local Minima 문제를 피하는 방법은?
- 찾은 해가 Global Minimum인지 아닌지 알 수 있는 방법은?
- Training 세트와 Test 세트를 분리하는 이유는?
- Validation 세트가 따로 있는 이유는?
- Test 세트가 오염되었다는 말의 뜻은?
- Regularization이란 무엇인가?
- Batch Normalization의 효과는?
- Dropout의 효과는?
- BN 적용해서 학습 이후 실제 사용시에 주의할 점은? 코드로는?
- GAN에서 Generator 쪽에도 BN을 적용해도 될까?
- SGD, RMSprop, Adam에 대해서 아는대로 설명한다면?
- SGD에서 Stochastic의 의미는?
- 미니배치를 작게 할때의 장단점은?
- 모멘텀의 수식을 적어 본다면?
- 간단한 MNIST 분류기를 MLP+CPU 버전으로 numpy로 만든다면 몇줄일까?
- 어느 정도 돌아가는 녀석을 작성하기까지 몇시간 정도 걸릴까?
- Back Propagation은 몇줄인가?
- CNN으로 바꾼다면 얼마나 추가될까?
- 간단한 MNIST 분류기를 TF, PyTorch 등으로 작성하는데 몇시간이 필요한가?
- CNN이 아닌 MLP로 해도 잘 될까?
- 마지막 레이어 부분에 대해서 설명 한다면?
- 학습은 BCE loss로 하되 상황을 MSE loss로 보고 싶다면?
- 딥러닝할 때 GPU를 쓰면 좋은 이유는?
- GPU를 두개 다 쓰고 싶다. 방법은?
- 학습시 필요한 GPU 메모리는 어떻게 계산하는가?
</details>
<details>
<summary><a href="./answers/4-python.md"><strong>🐍 파이썬</strong></a></summary>
- What is the difference between list and tuples in Python?
- What are the key features of Python?
- What type of language is python? Programming or scripting?
- Python an interpreted language. Explain.
- What is pep 8?
- How is memory managed in Python?
- What is namespace in Python?
- What is PYTHONPATH?
- What are python modules? Name some commonly used built-in modules in Python?
- What are local variables and global variables in Python?
- Is python case sensitive?
- What is type conversion in Python?
- How to install Python on Windows and set path variable?
- Is indentation required in python?
- What is the difference between Python Arrays and lists?
- What are functions in Python?
- What is `__init__`?
- What is a lambda function?
- What is self in Python?
- How does break, continue and pass work?
- What does `[::-1]` do?
- How can you randomize the items of a list in place in Python?
- What’s the difference between iterator and iterable?
- How can you generate random numbers in Python?
- What is the difference between range & xrange?
- How do you write comments in python?
- What is pickling and unpickling?
- What are the generators in python?
- How will you capitalize the first letter of string?
- How will you convert a string to all lowercase?
- How to comment multiple lines in python?
- What are docstrings in Python?
- What is the purpose of is, not and in operators?
- What is the usage of help() and dir() function in Python?
- Whenever Python exits, why isn’t all the memory de-allocated?
- What is a dictionary in Python?
- How can the ternary operators be used in python?
- What does this mean: `*args`, `**kwargs`? And why would we use it?
- What does len() do?
- Explain split(), sub(), subn() methods of “re” module in Python.
- What are negative indexes and why are they used?
- What are Python packages?
- How can files be deleted in Python?
- What are the built-in types of python?
- What advantages do NumPy arrays offer over (nested) Python lists?
- How to add values to a python array?
- How to remove values to a python array?
- Does Python have OOps concepts?
- What is the difference between deep and shallow copy?
- How is Multithreading achieved in Python?
- What is the process of compilation and linking in python?
- What are Python libraries? Name a few of them.
- What is split used for?
- How to import modules in python?
- Explain Inheritance in Python with an example.
- How are classes created in Python?
- What is monkey patching in Python?
- Does python support multiple inheritance?
- What is Polymorphism in Python?
- Define encapsulation in Python?
- How do you do data abstraction in Python?
- Does python make use of access specifiers?
- How to create an empty class in Python?
- What does an object() do?
- What is map function in Python?
- Is python numpy better than lists?
- What is GIL in Python language?
- What makes the CPython different from Python?
- What are Decorators in Python?
- What is object interning?
- What is @classmethod, @staticmethod, @property?
</details>
<details>
<summary><a href="./answers/5-network.md"><strong>🌐 네트워크</strong></a></summary>
- TCP/IP의 각 계층을 설명해주세요.
- OSI 7계층와 TCP/IP 계층의 차이를 설명해주세요.
- Frame, Packet, Segment, Datagram을 비교해주세요.
- TCP와 UDP의 차이를 설명해주세요.
- TCP와 UDP의 헤더를 비교해주세요.
- TCP의 3-way-handshake와 4-way-handshake를 비교 설명해주세요.
- TCP의 연결 설정 과정(3단계)과 연결 종료 과정(4단계)이 단계가 차이나는 이유가 무엇인가요?
- 만약 Server에서 FIN 플래그를 전송하기 전에 전송한 패킷이 Routing 지연이나 패킷 유실로 인한 재전송 등으로 인해 FIN 패킷보다 늦게 도착하는 상황이 발생하면 어떻게 될까요?
- 초기 Sequence Number인 ISN을 0부터 시작하지 않고 난수를 생성해서 설정하는 이유가 무엇인가요?
- HTTP와 HTTPS에 대해서 설명하고 차이점에 대해 설명해주세요.
- HTTP 요청/응답 헤더의 구조를 설명해주세요.
- HTTP와 HTTPS 동작 과정을 비교해주세요.
- CORS가 무엇인가요?
- HTTP GET과 POST 메서드를 비교/설명해주세요.
- 쿠키(Cookie)와 세션(Session)을 설명해주세요.
- DNS가 무엇인가요?
- REST와 RESTful의 개념을 설명하고 차이를 말해주세요.
- 소켓(Socket)이 무엇인가요? 자신 있는 언어로 간단히 소켓 생성 예시를 보여주세요.
- Socket.io와 WebSocket의 차이를 설명해주세요.
- IPv4와 IPv6 차이를 설명해주세요.
- MAC Address가 무엇인가요?
- 라우터와 스위치, 허브의 차이를 설명해주세요.
- SMTP가 무엇인가요?
- 노트북으로 `www.google.com`에 접속을 했습니다. 요청을 보내고 받기까지의 과정을 자세히 설명해주세요.
- 여러 네트워크 topology에 대해 간단히 소개해주세요.
- subnet mask에 대해서 설명해주세요.
- data encapsulation이 무엇인가요?
- DHCP를 설명해주세요.
- routing protocol을 몇 가지 설명해주세요. (ex. link state, distance vector)
- 이더넷(ethernet)이 무엇인가요?
- client와 server의 차이점을 설명해주세요.
- delay, timing(jitter), throughput 차이를 설명해주세요.
</details>
<details>
<summary><a href="./answers/6-operating-system.md"><strong>🖥️ 운영체제</strong></a></summary>
- 프로세스와 스레드의 차이(Process vs Thread)를 알려주세요.
- 멀티 프로세스 대신 멀티 스레드를 사용하는 이유를 설명해주세요.
- 캐시의 지역성에 대해 설명해주세요.
- Thread-safe에 대해 설명해주세요. (hint: critical section)
- 뮤텍스와 세마포어의 차이를 설명해주세요.
- 스케줄러가 무엇이고, 단기/중기/장기로 나누는 기준에 대해 설명해주세요.
- CPU 스케줄러인 FCFS, SJF, SRTF, Priority Scheduling, RR에 대해 간략히 설명해주세요.
- 동기와 비동기의 차이를 설명해주세요.
- 메모리 관리 전략에는 무엇이 있는지 간략히 설명해주세요.
- 가상 메모리에 대해 설명해주세요.
- 교착상태(데드락, Deadlock)의 개념과 조건을 설명해주세요.
- 사용자 수준 스레드와 커널 수준 스레드의 차이를 설명해주세요.
- 외부 단편화와 내부 단편화에 대해 설명해주세요.
- Context Switching이 무엇인지 설명하고 과정을 나열해주세요.
- Swapping에 대해 설명해주세요.
</details>
<details>
<summary><a href="./answers/7-data-structure.md"><strong>🗂 자료구조</strong></a></summary>
- linked list
- single linked list
- double linked list
- circular linked list
- hash table
- stack
- queue
- circular queue
- graph
- tree
- binary tree
- full binary tree
- complete binary tree
- bst(binary search tree)
- heap(binary heap)
- min heap
- max heap
- red-black tree
- b+ tree
</details>
<details>
<summary><a href="./answers/8-algorithm.md"><strong>🔻 알고리즘</strong></a></summary>
- 시간, 공간 복잡도
- Sort Algorithm
- Bubble Sort
- Selection Sort
- Insertion Sort
- Merge Sort
- Heap Sort
- Quick Sort
- Counting Sort
- Radix Sort
- Divide and Conquer
- Dynamic Programming
- Greedy Algorithm
- Graph
- Graph Traversal: BFS, DFS
- Shortest Path
- Dijkstra
- Floyd-Warshall
- Bellman-Ford
- Minimum Spanning Tree
- Prim
- Kruskal
- Union-find
- Topological sort
</details>
---
## Contributors
<a href="https://github.com/boostcamp-ai-tech-4/ai-tech-interview/graphs/contributors">
<img src="https://contrib.rocks/image?repo=boostcamp-ai-tech-4/ai-tech-interview" />
</a>
---
## References
- [zzsza님의 Datascience-Interview-Questions](https://github.com/zzsza/Datascience-Interview-Questions)
- [DopplerHQ님의 awesome-interview-questions](https://github.com/DopplerHQ/awesome-interview-questions)
- [JaeYeopHan님의 Interview_Question_for_Beginner](https://github.com/JaeYeopHan/Interview_Question_for_Beginner)
- [WeareSoft님의 tech-interview](https://github.com/WeareSoft/tech-interview)
================================================
FILE: SUMMARY.md
================================================
# Table of contents
- [Notice](README.md)
## 🧑💻 INTERVIEW
- [Statistics/Math](answers/1-statistics-math.md)
- [Machine Learning](answers/2-machine-learning.md)
- [Deep Learning](answers/3-deep-learning.md)
- [Python](answers/4-python.md)
- [Network](answers/5-network.md)
- [Operating System](answers/6-operating-system.md)
- [Data Structure](answers/7-data-structure.md)
- [Algorithm](answers/8-algorithm.md)
================================================
FILE: answers/1-statistics-math.md
================================================
> **📌 질문은 <strong>[zzsza님의 Datascience-Interview-Questions](https://github.com/zzsza/Datascience-Interview-Questions)</strong>를 참고하였습니다.**
## Table of Contents
- [고유값(eigen value)와 고유벡터(eigen vector)이 무엇이고 왜 중요한지 설명해주세요.](#1)
- [샘플링(Sampling)과 리샘플링(Resampling)이 무엇이고 리샘플링의 장점을 말씀해주세요.](#2)
- [확률 모형과 확률 변수는 무엇인가요?](#3)
- [누적 분포 함수와 확률 밀도 함수는 무엇인가요? 수식과 함께 표현해주세요.](#4)
- [조건부 확률은 무엇인가요?](#5)
- [공분산과 상관계수는 무엇일까요? 수식과 함께 표현해주세요.](#6)
- [신뢰 구간의 정의는 무엇인가요?](#7)
- [p-value를 모르는 사람에게 설명한다면 어떻게 설명하실 건가요?](#8)
- [R square의 의미는 무엇인가요?](#9)
- [평균(mean)과 중앙값(median)중에 어떤 케이스에서 뭐를 써야할까요?](#10)
- [중심극한정리는 왜 유용한걸까요?](#11)
- [엔트로피(entropy)에 대해 설명해주세요. 가능하면 Information Gain도요.](#12)
- [어떨 때 모수적 방법론을 쓸 수 있고, 어떨 때 비모수적 방법론을 쓸 수 있나요?](#13)
- [“likelihood”와 “probability”의 차이는 무엇일까요?](#14)
- [통계에서 사용되는 bootstrap의 의미는 무엇인가요.](#15)
- [모수가 매우 적은 (수십개 이하) 케이스의 경우 어떤 방식으로 예측 모델을 수립할 수 있을까요?](#16)
- [베이지안과 프리퀀티스트 간의 입장차이를 설명해주실 수 있나요?](#17)
- [검정력(statistical power)은 무엇일까요?](#18)
- [missing value가 있을 경우 채워야 할까요? 그 이유는 무엇인가요?](#19)
- [아웃라이어의 판단하는 기준은 무엇인가요?](#20)
- [필요한 표본의 크기를 어떻게 계산합니까?](#21)
- [Bias를 통제하는 방법은 무엇입니까?](#22)
- [로그 함수는 어떤 경우 유용합니까? 사례를 들어 설명해주세요.](#23)
- [베르누이 분포 / 이항 분포 / 카테고리 분포 / 다항 분포 / 가우시안 정규 분포 / t 분포 / 카이제곱 분포 / F 분포 / 베타 분포 / 감마 분포에 대해 설명해주세요.](#24)
- [출장을 위해 비행기를 타려고 합니다. 당신은 우산을 가져가야 하는지 알고 싶어 출장지에 사는 친구 3명에게 무작위로 전화를 하고 비가 오는 경우를 독립적으로 질문했습니다. 각 친구는 2/3로 진실을 말하고 1/3으로 거짓을 말합니다. 3명의 친구가 모두 “그렇습니다. 비가 내리고 있습니다”라고 말했습니다. 실제로 비가 내릴 확률은 얼마입니까?](#25)
---
## #1
### 고유값(eigen value)와 고유벡터(eigen vector)이 무엇이고 왜 중요한지 설명해주세요.
정방행렬 $(n \times n)$인 $A$는 임의의 벡터 $(n \times 1)$인 $x$의 방향과 크기를 변화시킬 수 있다.
수많은 벡터 $x$중 어떤 벡터들은 $A$에 의해 선형 변환되었을 때에도 원래 벡터와 평행한 경우가 있다. **이렇듯 $Ax$가 원래 $x$에 상수 $\lambda$를 곱한 것과 같을 때의 $x$를 고유 벡터, 람다를 고유값이라 한다.**
$$
Ax = \lambda x
$$
아래처럼 $x_1$은 $A$에 의해 변환되었음에도 $x_1$과 평행하다. 따라서 $x_1$은 고유벡터이다.

고유값과 고유벡터를 통해 $A$를 고유값과 고유벡터들로 분해하는 **고유값 분해(eigen decomposition)**, 정방행렬 뿐만 아닌 $m \times n$행렬도 분해할 수 있는 **특이값 분해(SVD)**, 데이터들을 차원 축소시킬 때 가장 원래 의미를 잘 보존시키는 **주성분 분석(PCA)** 등에 활용할 수 있으므로 중요하다.
#### References
- [고유값과 고유 벡터 - 러너게인](https://twlab.tistory.com/46)
- [머신러닝 - 19. 고유값(eigenvalue), 고유벡터(eigenvector), 고유값 분해(eigen decomposition) - 귀퉁이 서재](https://bkshin.tistory.com/entry/%EB%A8%B8%EC%8B%A0%EB%9F%AC%EB%8B%9D-19-%ED%96%89%EB%A0%AC)
- [[선형대수학 #4] 특이값 분해(Singular Value Decomposition, SVD)의 활용 - 다크 프로그래머](https://darkpgmr.tistory.com/106)
- [주성분 분석(PCA) - 공돌이의 수학정리노트](https://angeloyeo.github.io/2019/07/27/PCA.html)
---
## #2
### 샘플링(Sampling)과 리샘플링(Resampling)이 무엇이고 리샘플링의 장점을 말씀해주세요.
샘플링이란 **표본추출**을 의미하는 것으로, 모집단 전체에 대한 추정치(estimate)를 얻기 위해 임의의 sample을 뽑아내는 것이다.
모집단 전체에 대한 조사는 불가능하기 때문에 sample을 이용하여 모집단에 대한 추론(inference)을 하게되는 것이다.
하지만 표본은 모집단을 닮은 모집단의 mirror image 같은 존재이지만, 모집단 그 자체일수는 없다.
따라서 표본에는 반드시 모집단의 원래 패턴에서 놓친 부분, 즉 **noise가 존재할 수 밖에 없다.**
리샘플링은 **모집단의 분포 형태를 알 수 없을 때 주로 사용하는 방법**이다.
즉, 모분포를 알 수 없으므로 일반적인 통계적 공식들을 사용하기 힘들 때, 현재 갖고 있는 데이터를 이용하여 모분포와 비슷할 것으로 추정되는 분포를 만들어 보자는 것이다.
리샘플링은 **가지고 있는 샘플에서 다시 샘플 부분집합을 뽑아서 통계량의 변동성(variability of statistics)을 확인하는 것**이라고 할 수 있다.
즉, 같은 샘플을 여러 번 사용해서 성능을 측정하는 방식이다. 가장 많이 사용되는 방법이며 종류로는 K-fold 교차 검증, 부트스트래핑이 있다.
리샘플링은 표본을 추출하면서 원래 데이터 셋을 복원하기 때문에 이를 통해서 모집단의 분포에 어떤 가정도 필요 없이 표본만으로 추론이 가능하다는 장점이 있다.
#### References
- [(데이터과학 인터뷰 질문)(2) 샘플링과 리샘플링, 1편 - CHAOS & PATTERN : 데이터 사이언스 블로그](https://cnp-0717.tistory.com/7?category=838077)
- [샘플링과 리샘플링의 차이는 무엇일까? - 김감귤](https://kejdev.github.io/posts/sampling-resampling/)
- [resampling을 이용한 방법 (bootstrapping) - 진화하자 - 어디에도 소속되지 않기](https://adnoctum.tistory.com/296)
- [샘플링과 리샘플링 - Wriggling](https://trampled-worm.tistory.com/91)
---
## #3
### 확률 모형과 확률 변수는 무엇인가요?
**확률변수(Random Variable)** 란, 표본 공간의 각 단위 사건에 실수 값을 부여하는 변수이다. 확률변수는 어떠한 함수로 해석할 수 있으므로 `대문자 X`라고 표기한다.
무작위(Random) 실험을 했을 때, 특정 확률로 발생하는 각각의 결과를 수치적 값으로 표현하는 변수라고 할 수 있다.
또한 확률 변수에는 `이산확률변수`, `연속확률변수` 두가지 경우가 있다. `이산확률변수`는 확률변수 $X$가 취할 수 있는 값이 유한하기 떄문에 셀 수 있는 확률변수이다. 반면에 `연속확률변수`는 어떠한 두 수 사이에 반드시 다른 수가 존재하는, 셀 수 없는 범위의 확률변수를 가지는 경우에 사용된다.
주사위 굴리기 예제를 생각해보자.
```text
일단 주사위를 굴리는 상황은 어떤 수가 나올지 모르므로, 확률상황이다.
"주사위를 굴렸을 때 나오는 값"을 확률변수 X라고 할 수 있다.
1~6이 표본공간이 되고, 셀 수 있으므로 이산확률변수가 된다.
P(X=1)와 같은 식으로 표현하고, 이는 "주사위를 굴렸을 때, 1이라는 값이 나올 확률"로 해석할 수 있다.
```
**확률모형(Probability Model)** 이란 확률변수를 이용하여 데이터의 분포를 수학적으로 정의한 모형이다.
데이터 분포를 묘사하기 위해서 사용된다.
보통 **확률 분포 함수(probability distribution function)** 또는 <strong>확률 밀도 함수(probability density function)</strong>를 주로 사용하며, 이때 함수의 계수를 분포의 모수(parameter)라고 부른다.
**확률분포(Probability Distribution)** 란 표본공간에 정의된 확률을 이용하여 확률변수의 값 또는 영역에 대한 확률을 표현한 것이다.
예를 들어 가장 널리 쓰이는 확률 모형의 하나인 `가우시안 정규 분포(Gaussian normal distribution)`는 다음과 같은 수식으로 확률 밀도 함수를 정의한다.
$$
N(x ; \mu, \sigma) = \frac{1}{\sigma \sqrt{2 \pi}} e^{-\frac{(x- \mu)^2}{2 \sigma^2}}
$$
다음과 같은 함수들이 확률모형에 포함될 수 있다. (자세한 내용은 [확률통계 기초용어 - EG 공간](https://kongdols-room.tistory.com/131) 참고)
- 확률질량함수(PMF, Probability Mass Function) - 이산형
- 확률밀도함수(PDF, Probability Density Function) - 연속형
- 누적분포함수(CDF, Cumulative Distribution Function)
추가적으로 **확률 통계의 기초 용어**를 정리하면 다음과 같다. (주사위 굴리기 예제 사용)
```text
- 실험(Experiment)은 하나의 행위가 하나 이상의 결과를 도출하는 것에 대한 과정 혹은 절차를 나타낸다.
- 예시) 주사위를 던진다.
- 결과(Outcome)는 어떤 실험에 의해 발생 가능한 결과이다. 특정 실험의 가능한 결과들은 각각 유일(unique)하다. 한번의 실험을 시행했을 때, 단 하나의 outcome만을 나타낸다.
- 예시) 주사위의 눈 (ex. 3, 4, 6)
- 표본 공간(Sample space)은 확률 실험에서 발생할 수 있는 모든 결과로 구성된 집합(set)이다. 발생할 수 있는 모든 결과의 집합이므로, 중복된 원소를 가질 수 있다.
- 예시) 가능한 주사위의 모든 눈 집합 (ex. Ω = {1, 2, 3, 4, 5, 6})
- 사건(Event)은 우리가 관심있는 Sample space의 부분집합이다.
- 예시) 주사위 눈이 3이 나온다, 짝수/홀수가 나온다.
```
#### References
- [확률변수와 확률모형 - 숨니의 무작정 따라하기](https://sumniya.tistory.com/24)
- [확률변수와 확률함수 - 필로홍의 데이터 노트](https://drhongdatanote.tistory.com/49)
- [확률변수의 개념, 의미 - 로스카츠의 AI 머신러닝](https://losskatsu.github.io/statistics/random-variable/#%EC%9D%B4%EC%82%B0%ED%99%95%EB%A5%A0%EB%B6%84%ED%8F%AC)
- [확률모형이란 - notebook.community](https://notebook.community/zzsza/Datascience_School/09.%20%EA%B8%B0%EC%B4%88%20%ED%99%95%EB%A5%A0%EB%A1%A02%20-%20%ED%99%95%EB%A5%A0%20%EB%B3%80%EC%88%98/03.%20%ED%99%95%EB%A5%A0%20%EB%AA%A8%ED%98%95%EC%9D%B4%EB%9E%80)
- [확률통계 기초용어 - EG 공간](https://kongdols-room.tistory.com/131)
- [[통계학] 9. 확률변수와 확률분포- 러닝머신의 Train Data Set](https://m.blog.naver.com/nilsine11202/221378790554)
---
## #4
### 누적 분포 함수와 확률 밀도 함수는 무엇인가요? 수식과 함께 표현해주세요.
확률 변수 $X$가 임의의 실수 집합 $B$에 포함되는 사건의 확률이 다음과 같이 어떤 음이 아닌 함수 $f$의 적분으로 주어진다고 하자.
$$
P(X \in B) = \int_{B} f(x) dx
$$
이 때의 $X$를 연속확률변수라고 하며, 함수 $f(x)$를 <strong>확률 밀도 함수(Probability Density Function, PDF)</strong>라고 한다. 단, 실수 집합 $B$가 실수 전체일 경우 실수 전체에 대한 확률밀도함수의 적분은 1을 만족해야 한다.
$$
P(X \in R) = \int_{R} f(x) dx = 1
$$
<strong>누적 분포 함수(Cumulative Distribution Function, CDF)</strong>는 확률변수가 특정 값보다 작거나 같을 확률을 나타내는 함수이다. 특정 값을 $a$라고 할 때, 누적 분포 함수는 다음과 같이 나타낼 수 있다.
$$
F(a) = P(X ≤ a) = \int^a_{-\infty} f(x) dx
$$
확률 밀도 함수와 누적 분포 함수는 **미분과 적분의 관계**를 갖는다. 확률 밀도 함수를 음의 무한대에서 특정값 $a$까지 적분을 하면, $a$에 대한 누적 분포 함수를 얻을 수 있다. 반대로 누적 분포 함수를 미분하면 확률 밀도 함수를 얻을 수 있다.
#### References
- [확률및통계 강의노트 - 홍영훈 교수님](https://sites.google.com/site/hong0108/)
- [확률 분포 함수와 확률 밀도 함수의 의미 - groovallstar.log](https://velog.io/@groovallstar/%ED%99%95%EB%A5%A0-%EB%B6%84%ED%8F%AC-%ED%95%A8%EC%88%98%EC%99%80-%ED%99%95%EB%A5%A0-%EB%B0%80%EB%8F%84-%ED%95%A8%EC%88%98%EC%9D%98-%EC%9D%98%EB%AF%B8)
---
## #5
### 조건부 확률은 무엇인가요?
조건부 확률은 사건 $A$가 일어났다는 전제 하에 사건 $B$가 일어날 확률이다. 이는 $P(B|A) = P(B \cap A) / P(A)$로 표현 가능하다. 조건부 확률은 **베이즈 정리**와도 이어지며, 조건부 확률을 이용한 가장 유명한 문제는 [몬티홀 문제](https://terms.naver.com/entry.naver?docId=3569086&cid=58944&categoryId=58970)가 있다.
> **베이즈 정리**
베이즈 정리를 통해 가능도(Likelihood)와 증거(Evidence)를 바탕으로 사전확률을 사후확률로 업데이트한다.

- $D$: 새로 관찰되는 데이터
- $\theta$: 모델에서 계산하고 싶어하는 모수 (가설)
- 사후확률(Posterior): 데이터를 관찰했을 때, 이 가설이 성립할 확률 (데이터 관찰 이후 측정하기 때문에 사후확률)
- 사전확률(Prior): 가설에 대해 사전에 세운 확률 (데이터 관측 이후 사후확률이 사전확률이 된다.)
- 가능도(Likelihood): 현재 주어진 모수 (가정) 에서 이 데이터가 관찰될 가능성
- 증거(Evidence): 데이터 전체의 분포
#### References
- [조건부 확률 - Truth in Engineering](https://m.blog.naver.com/PostView.nhn?blogId=mykepzzang&logNo=220834864348&proxyReferer=https:%2F%2Fwww.google.com%2F)
- [통계학 맛보기 - Heath](https://velog.io/@dldydldy75/%EB%B2%A0%EC%9D%B4%EC%A6%88-%ED%86%B5%EA%B3%84%ED%95%99-%EB%A7%9B%EB%B3%B4%EA%B8%B0)
---
## #6
### 공분산과 상관계수는 무엇일까요? 수식과 함께 표현해주세요.
공분산은 확률변수 X의 편차(평균으로부터 얼마나 떨어져 있는지)와 확률변수 Y의 편차를 곱한 것의 평균값이다.
$$
Cov(X, Y) = E((X - \mu_X)(Y-\mu_Y))
$$
공분산은 두 변수 간에 양의 상관관계가 있는지, 음의 상관관계가 있는지 정도를 알려준다. 하지만 상관관계가 얼마나 큰지는 제대로 반영하지 못한다.
공분산의 문제는 확률변수의 단위 크기에 영향을 많이 받는다는 것이다. 이를 보완할 수 있는 것이 바로 상관계수이다.
상관계수는 확률변수의 절대적 크기에 영향을 받지 않도록 공분산을 단위화시킨 것이다. 즉, 공분산에 각 확률변수의 분산을 나눠주었다.
$$
\rho = \frac{Cov(X, Y)}{\sqrt{Var(X) \cdot Var(Y)}}, \quad -1 ≤ \rho≤ 1
$$
상관계수는 양의 상관관계가 있는지 음의 상관관계가 있는지 알려줄 뿐만 아니라, 그 상관성이 얼마나 큰지도 알려준다. 1 또는 -1에 가까울수록 상관성이 큰 것이고, 0에 가까울수록 상관성이 작은 것이다.
#### References
- [공분산과 상관계수의 이해.txt - bskyvision](https://bskyvision.com/398)
- [공분산(Covariance)과 상관계수(Correlation) - Serious Archive](https://destrudo.tistory.com/15)
---
## #7
### 신뢰 구간의 정의는 무엇인가요?
구간 추정에서 <strong>모수가 a 에서 b 사이에 있을 것으로 추정(신뢰구간)</strong>하고 <strong>그 확률(%, 신뢰수준)</strong>을 구한다.

**신뢰구간(Confidence Interval)** 은 모집단의 모수(parameter)가 위치해 있을 것으로 신뢰할 수 있는 구간이다.
모수가 어느 범위 안에 있는지를 확률적으로 보여주는 방법이라고 할 수 있다.
신뢰구간을 구하는 이유는 모수의 신뢰성을 가늠하기 위함이다.
추가적으로, 신뢰구간에 대한 정확한 해석은 모평균을 포함할 확률이 95%가 되는 구간이 아닌, 같은 방법으로 100번 표본을 추출했을 때, 함께 계산되는 100개의 신뢰구간 중 모평균을 포함한 신뢰구간들의 숫자가 95개정도 된다라고 해야한다. 왜냐면, 모평균은 이미 정해져 있는 값이므로 전자의 해석을 사용할 수 없기 때문이다.
**신뢰수준**은 방법의 정확도, 참값을 구하기 위한 작업을 많이 반복했을 때, 참값이 특정 범위에 있는 비율이다.
**모수(Parameter)** 는 모집단의 특성을 보여주는 값이다. 예를들어, 평균, 분산 등의 고정인 값이 있을 수 있다.
#### References
- [COMPUTATAIONAL PREDICTION - Minkoo Seo blog](http://mkseo.pe.kr/stats/?p=763)
- [신뢰구간 - 위키백과](https://ko.wikipedia.org/wiki/%EC%8B%A0%EB%A2%B0_%EA%B5%AC%EA%B0%84)
- [신뢰구간의 의미 - 공돌이의 수학정리노트](https://angeloyeo.github.io/2021/01/05/confidence_interval.html)
---
## #8
### p-value를 모르는 사람에게 설명한다면 어떻게 설명하실 건가요?
p-value를 알기 위해서는 먼저 1종 오류를 알아야 한다. 여기서 1종 오류란 **귀무가설이 참인데 기각한 경우**을 말한다. 귀무가설이란 기존의 주장을 말하며, 이와 반대로 새로운 주장을 대립가설이라고 한다.
예를 들어, 어느 제약회사에서 치료약 A를 개발했다. 기존에는 치료약 A가 없었으므로 귀무가설은 "치료약 A가 효과가 없다"라고 설정한다. 반대로 대립가설은 "치료약 A는 효과가 있다"로 설정한다. 회사에서는 검정을 한 결과, 귀무가설을 기각하고 대립가설을 채택했다. 치료약 A는 판매되었고 높은 매출을 기록했다. 그런데 알고보니 치료약 A가 효과가 없다는 것이 밝혀졌다. 참인 귀무가설을 기각했기에 이는 1종 오류가 일어났다고 볼 수 있다.
다시 돌아와서 p-value는 **1종 오류를 범할 확률**을 말한다. 예를 들어, p-value가 5%라면, 100번 중 5번 1종 오류가 발생한다는 말이다. 검정을 할 때는 유의 수준 $\alpha$를 정하는데, 이것이 1종 오류의 상한선이 된다. 그래서 유의 수준보다 p-value가 작다면 실험의 오류가 상한선보다 작으므로 귀무가설을 기각하고 대립가설을 채택한다. 만약 크다면 상한선을 넘었으므로 귀무가설을 채택한다.
#### References
- [p-value의 의미 - 공돌이의 수학정리노트](https://angeloyeo.github.io/2020/03/29/p_value.html)
- [p-value란 무엇인가 - 진화하자 어디에도 소속되지 않기](https://adnoctum.tistory.com/332)
- [통계, 기본 개념을 정리해보자 - 이지훈](https://brunch.co.kr/@jihoonleeh9l6/34)
- [유의수준(Significance Level)과 p값(p-value) - 통계학과 사색의 공간](https://m.blog.naver.com/vnf3751/220830413960)
---
## #9
### R square의 의미는 무엇인가요?
<strong>결정계수(R square)</strong>는 선형 회귀 모델에서 데이터에 대해 회귀선이 얼마나 잘 설명하는지에 대한 설명력을 의미한다. 결정계수는 0~1 의 값을 가질 수 있고, 만약 값이 1 이라면 회귀선으로 모든 데이터를 다 설명할 수 있다고 이해할 수 있다.
참고로 결정계수는 다음의 식으로 구할 수 있다.
$$
R^2 = SSE/SST = 1 - SSR/SST
$$
- SSE(**E**xplained **S**um of **S**quares) = $\sum(\text{추정값 - 관측값 평균})^2$
- SST(**T**otal **S**um of **S**quares) = $\sum(\text{관측값 - 관측값 평균})^2$
- SSR(**R**esidual **S**um of **S**quares) = $SSR = \sum(\text{관측값 - 추정값})^2$
관측값은 실제 데이터의 값을 말하며, 추정값은 회귀 모델을 통해 나온 값을 말한다. 회귀 모델의 성능을 평가하는 방법은 결정계수 외에도 MAE, MSE, RMSE 가 있다.
#### References
- [결정계수의 의미와 계산 방법](https://m.blog.naver.com/tlrror9496/222055889079)
- [회귀분석에서 R스퀘어의 정확한 의미](https://m.blog.naver.com/PostView.nhn?blogId=will84&logNo=220348748198&proxyReferer=https:%2F%2Fwww.google.com%2F)
- [모델 성능 평가](https://heung-bae-lee.github.io/2020/01/09/machine_learning_03/)
---
## #10
### 평균(mean)과 중앙값(median)중에 어떤 케이스에서 뭐를 써야할까요?
- `평균(mean)`: 모든 관측값의 합을 자료의 개수로 나눈 것
- `중앙값(median)`: 전체 관측값을 크기 순서로 배열했을 때 가운데 위치하는 값
평균은 전체 관측값이 골고루 반영되므로 대표값으로서 가치가 있다. 평균 근처에 **표본이 몰려 있는 상황에서 대표값으로 유용**하지만 극단적인 값에 영향을 많이 받는다.
중앙값에서는 관측값을 크기 순서로 배열할 때 관측값의 위치가 중요하고, 가운데 위치한 관측값 이외의 관측값들의 크기는 중요하지 않다. 따라서 평균과는 달리 중앙값은 관측값들의 변화에 민감하지 않고 특히 아주 큰 관측값이나 아주 작은 관측값(즉, outlier)에 영향을 받지 않는다. 중앙값이 유용한 경우는 **표본의 편차, 혹은 왜곡이 심하게 나타나는 경우**이다.
#### References
- [평균(average, mean) vs. 중간값(median) | 통계상의 오류가능성 - 슈퍼짱짱](https://leedakyeong.tistory.com/entry/%ED%8F%89%EA%B7%A0-%EC%A4%91%EC%95%99%EA%B0%92-%EC%B5%9C%EB%B9%88%EA%B0%92-%EB%B9%84%EA%B5%90-Mean-VS-Median-VS-Mode)
- [[기초통계] 평균 중앙값 최빈값 비교 (Mean VS Median VS Mode) - Peter Hwang](https://blog.naver.com/ricemankr/220796823014)
---
## #11
### 중심극한정리는 왜 유용한걸까요?
**중심극한정리**란 크기가 n인 표본추출(30개 이상)이 무수히 많이 수행되면(최소 100회 이상을 의미), 표본 평균의 분포가 정규분포에 수렴한다는 것이다. 중심극한정리가 유용한 이유는 **모집단의 형태가 어떻든지 간에 상관없이 표본 평균의 분포가 정규분포를 따르기 때문**이다.
#### References
- [중심극한정리의 의미 - 공돌이의 수학정리노트](https://angeloyeo.github.io/2020/09/15/CLT_meaning.html)
---
## #12
### 엔트로피(Entropy)에 대해 설명해주세요. 가능하면 정보이득(Information Gain)도요.
**엔트로피**는 주어진 데이터의 혼잡도를 의미하며, 엔트로피는 다음과 같이 데이터가 어떤 클래스에 속할 확률에 대한 기댓값으로 표현할 수 있다.
$$
E = - \sum^k_{i=1} p_i \log_2 (p_i)
$$
엔트로피는 데이터가 서로 다른 클래스에 속하면 높고, 같은 클래스에 속하면 낮다. 다시 말하면 각각의 데이터가 특정 클래스에 속할 확률이 높고 나머지 클래스에 속할 확률이 낮다면 엔트로피가 낮고, 모든 각각의 클래스에 속할 확률이 비슷하다면 엔트로피는 높다.
**정보이득**은 데이터가 어떤 클래스에 속할 확률이 커짐에 따라 정보를 잘 얻게되는 것을 말하며, 감소되는 엔트로피 양을 의미한다. 수식으로는 기존 시스템의 엔트로피에서 현재 엔트로피를 뺀 값으로 표현된다. 의사결정트리는 가지를 칠 때 이 값을 사용하여 가지를 친다. 이 때 어떤 데이터를 두 집합으로 나누었을 때 두 집합의 정보이득이 크도록, 엔트로피는 작아지도록 분할을 한다.
#### References
- [10.1 엔트로피 - 데이터 사이언스 스쿨](https://datascienceschool.net/02%20mathematics/10.01%20%EC%97%94%ED%8A%B8%EB%A1%9C%ED%94%BC.html)
- [[인공지능] 엔트로피(Entropy) 와 정보이득(Information Gain) 계산 - 꾸준희](https://eehoeskrap.tistory.com/13)
- [파이썬 머신러닝 완벽 가이드 - 권철민](http://www.yes24.com/Product/Goods/87044746?OzSrank=2)
---
## #13
### 어떨 때 모수적 방법론을 쓸 수 있고, 어떨 때 비모수적 방법론을 쓸 수 있나요?
표본의 통계량(평균, 표준편차 등)을 통해 모집단의 모수(모평균, 모표준편차 등)를 추정하는 방법을 통계적 추론이라고 한다.
모집단이 어떤 분포를 따른다는 가정 하에 통계적 추론을 하는 방법을 모수적 방법이라 하는데, 표본의 수가 30개 이상일 때 중심극한 정리에 의해 정규분포를 따르므로 **모수적 방법론**을 사용한다.
반대로, 모집단의 분포를 가정하지 않는 비모수적 방법은, 표본의 수가 30개 미만이거나 정규성 검정에서 정규 분포를 따르지 않는다고 증명되는 경우 **비모수적 방법론**을 사용한다.
#### References
- [어떨 때 모수적 방법론을 쓸 수 있고, 어떨 때 비모수적 방법론을 쓸 수 있나요? - 내가 보려고 만든 공간](https://astralworld58.tistory.com/80)
---
## #14
### “likelihood”와 “probability”의 차이는 무엇일까요?
<strong>확률(Probability)</strong>은 어떤 시행(trial)에서 특정 결과(sample)가 나올 가능성을 말한다. 즉, 시행 전 모든 경우의 수의 가능성은 정해져 있으며 그 총합은 1(100%)이다.
<strong>가능도(Likelihood)</strong>은 어떤 시행(trial)을 충분히 수행한 뒤 그 결과(sample)를 토대로 경우의 수의 가능성을 도출하는 것을 말한다. 아무리 충분히 수행해도 어디까지나 추론(inference)이기 때문에 가능성의 합이 1이 되지 않을수도 있다.
PDF(probability density function)에서는 **확률변수**를 변수로 보기 때문에 총합이 1이지만, likelihood function에서는 **분포의 모수**를 변수로 보기 때문에 총합이 1이 되지 않을수도 있다.
#### References
- [가능도(Likelihood)와 확률(Probability)의 차이 - JMAN's SW Lab.](https://swjman.tistory.com/104)
---
## #15
### 통계에서 사용되는 bootstrap의 의미는 무엇인가요.
**부트스트랩(Bootstrap)** 은 가설검증을 하거나 metric을 계산하기 전에 random sampling을 적용하는 방법이다. 모수의 분포를 추정하는 방법 중 하나는, 현재 가진 표본에서 추가적으로 표본을 복원추출하고 각 표본에 대한 통계량을 다시 계산하는 것이다.
부트스트랩이 여기에 해당하며, 여러번의 무작위 추출을 통해, 평균의 신뢰구간을 구할 수 있다.
200개로만 통계량을 구하는 것이 아니라 200개를 기준으로 복원 추출하여 새로운 통계량을 구하는 것을 예시로 들 수 있다.
> **머신러닝에서 부트스트램의 의미**
머신러닝에서 부트스트랩은 아래와 같이 해석될 수 있다.
- 랜덤 샘플링을 통해 학습 데이터를 늘리는 방법
- 여러 모델을 학습시켜 추론 결과의 평균을 사용하는 방법(=앙상블)
> **복원추출이란?**
복원추출(Sampling with replacement)이란 확률을 구할 때, 추출했던 것을 원래대로 돌려놓고 다시 추출하는 방법을 말한다.
#### References
- [부트스트랩에 대하여 - Learning Carrot](https://learningcarrot.wordpress.com/2015/11/12/%EB%B6%80%ED%8A%B8%EC%8A%A4%ED%8A%B8%EB%9E%A9%EC%97%90-%EB%8C%80%ED%95%98%EC%97%AC-bootstrapping/)
- [DATA - 12. 부트스트랩](https://bkshin.tistory.com/entry/DATA-12)
- [복원추출 - 사이언스올](https://www.scienceall.com/%EB%B3%B5%EC%9B%90-%EC%B6%94%EC%B6%9Csampling-with-replacement/)
---
## #16
### 모수가 매우 적은 (수십개 이하) 케이스의 경우 어떤 방식으로 예측 모델을 수립할 수 있을까요?
> _모수는 모집단의 수가 아닌, 평균, 표준편차 등의 모집단의 특징을 말합니다. 여기서는 모집단의 수로 잘못 쓰인 것으로 보이며, 데이터가 적은 경우라 가정하고 답변을 작성하였습니다._
표본이 매우 작은 경우 표본평균의 분포가 정규분포를 따른다고 가정할 수 없으므로 **비모수적 방법**을 채택하여 예측 모델을 수립할 수 있다. 하지만 중심극한정리에 의해 표본의 크기가 30보다 클 경우 표본평균이 정규분포를 따른다고 가정할 수 있으므로, 이 경우에는 모수적 방법을 사용한다.
#### References
- [모수, 큰 수의 법칙, 그리고 중심극한정리 - Kyoyoung Chu](https://chukycheese.github.io/data%20science/parameter-clt/)
- [퍼널에서 모수 용어 질문요? - 인프런, cco](https://www.inflearn.com/questions/34568)
- [[통계이론] 모수적 방법 vs 비모수적 방법](https://zzanhtt.tistory.com/18)
---
## #17
### 베이지안과 프리퀀티스트 간의 입장차이를 설명해주실 수 있나요?
베이지안은 사건의 확률을 바라볼 때, 사전 확률을 미리 염두해두고 사건의 발생에 따라 베이즈 정리로 사후 확률을 구해 다시 사전 확률을 업데이트시킨다. 즉, 베이지안은 **과거의 사건이 현재 사건에 영향을 끼친다는 입장**을 가지고 있다.
반면, 프리퀀티스트는 확률을 무한번 실험한 결과, 객관적으로 발생하는 현상의 빈도수로 바라본다. 즉, 프리퀀티스트는 **현재의 객관적인 확률에 의해서만 사건이 발생한다는 입장**을 가지고 있다.
#### References
- [베이지안(Bayesian)과 프리퀀티스트(Frequentist) 간의 입장 차이 - 내가 보려고 만든 공간](https://astralworld58.tistory.com/81)
---
## #18
### 검정력(statistical power)은 무엇일까요?
| | 귀무가설 H0 참 | 귀무가설 H0 거짓 |
| :--------------: | :------------: | :--------------------: |
| 귀무가설 H0 채택 | 옳은 결정(1-α) | 제 2종 오류(β) |
| 귀무가설 H0 기각 | 제 1종 오류(α) | 옳은 결정(1-β), 검정력 |
검정력은 대립가설 H1이 참인 경우 귀무가설 H0를 기각(대립가설 H1을 채택)할 확률이다.

#### References
- [검정력(power)의 의미 및 수식 -
Curycu's Box](https://m.blog.naver.com/PostView.nhn?blogId=hancury&logNo=220854934914&proxyReferer=https:%2F%2Fwww.google.com%2F)
- [통계적 검정: 검정력(power)과 Type 1, 2 Error(1, 2 종 오류) - 코딩하고, ](https://niceguy1575.tistory.com/entry/%ED%86%B5%EA%B3%84%EC%A0%81-%EA%B2%80%EC%A0%95-%EA%B2%80%EC%A0%95%EB%A0%A5power%EA%B3%BC-Type-1-2-Error1-2-%EC%A2%85-%EC%98%A4%EB%A5%98)
---
## #19
### missing value가 있을 경우 채워야 할까요? 그 이유는 무엇인가요?
missing value를 처리하는 방법에는 크게 4가지가 있다.
1. `그대로 놔두기`: 누락된 데이터를 그대로 놔두는 방법이다.
2. `삭제하기`: 누락된 데이터를 제거하는 방법이다. 그러나 중요한 정보를 가진 데이터를 잃을 위험이 있다.
3. `특정 값으로 채우기`: 0, 빈번한 값, 지정한 상수값으로 채우기
4. `예측하여 채우기`: K-means, 평균값, 중앙값으로 대체하는 것
1번 방법을 사용하여, 데이터가 누락된 채로 놔둔다고 가정하자.
일부 xgboost같은 알고리즘은 결측값을 고려하여 잘 학습한다.
그러나 **결측치를 처리하는 로직이 없는 알고리즘(ex. sklearn의 LinearRegression)은 누락된 데이터 때문에 엉망이 될 수 있다.**
따라서 결측치를 처리해주어야한다.
2번 방법을 사용하여, 누락된 데이터를 제거한다고 해보자. 제거하는 방법은 가장 쉬운 방법이다. 그러나 만약 100명 중 한명의 특징(feature)이 누락된 상태이므로, 해당 특징을 전부 삭제한다면 중요한 특성을 잃어버리는 결과를 초래하게 된다.
3번, 4번 방법을 사용하여 결측치를 채운다고 해보자. 결측치를 채움으로서, 중요한 정보를 잃지않고 특성을 유지할 수 있다. 그러나 만약 100명 중 99명의 특징이 누락된 상태라고 한다면, 해당 특징을 어떠한 값으로 채우는 행위가 무의미할 것이다.
따라서 **결측치 상태나 비율, 어떤 모델을 사용할 것인지**에 따라서 결측치 대응 방법이 달라질 수 있다.
#### References
- [누락 데이터(Missing value)를 처리하는 7가지 방법 - 밥먹는 개발자](https://dining-developer.tistory.com/19)
---
## #20
### 아웃라이어의 판단하는 기준은 무엇인가요?
<strong>이상치(outlier)</strong>는 전체 데이터의 패턴에서 벗어난 이상한 값을 가진 데이터를 말한다. 이상치는 모델의 성능에 영향을 미치므로 이를 탐지하는 것은 정말 중요하다.
이상치를 탐지하는 방법 중 하나로 **IQR(Inter Quantile Range) 기법**이 있다. IQR 기법을 사용하기 위해서는 우선 데이터를 오름차순으로 정렬하고 25%, 50%, 75%, 100%로 4등분을 한다. 이 75% 지점과 25% 지점의 값의 차이를 IQR이라고 한다. 이 IQR에 1.5를 곱한 값을 75% 지점의 값에 더하여 최대값을, 25% 지점의 값에서 빼서 최소값을 계산한다. 이 때 최소값보다 작거나 최대값보다 큰 값을 이상치라고 판단한다.
또 다른 탐지 방법으로는 **Z-score를 계산하는 방식**이 있다. Z-score는 데이터가 평균에서 얼마나 떨어져 있는지를 나타내는 지표로, 임계값을 설정하여 Z-score이 이 값보다 크다면 이상치로 판단한다. 하지만 Z-score 방식은 데이터가 가우시안 분포를 따른다고 가정하기 때문에 데이터가 가우시안 분포가 아닐 경우 별도의 변환이 필요하다.
#### References
- [A Brief Overview of Outlier Detection Techniques - Towards Data Science](https://towardsdatascience.com/a-brief-overview-of-outlier-detection-techniques-1e0b2c19e561)
- [IQR 방식을 이용한 이상치 데이터(Outlier) 제거 - Hwi's ML doc](https://hwi-doc.tistory.com/entry/IQR-%EB%B0%A9%EC%8B%9D%EC%9D%84-%EC%9D%B4%EC%9A%A9%ED%95%9C-%EC%9D%B4%EC%83%81%EC%B9%98-%EB%8D%B0%EC%9D%B4%ED%84%B0Outlier-%EC%A0%9C%EA%B1%B0)
- [[데이터전처리] Outlier(이상치/이상값/특이값/특이치 등) 탐지 방법(detection method) : 2. Z-score 방식 with - Clary K](https://claryk.tistory.com/5)
---
## #21
### 필요한 표본의 크기를 어떻게 계산합니까?
먼저 **모집단의 크기 $N$** 을 구하고, **신뢰수준 $z$** 와 **오차범위 $e$** 를 얼마로 할지 선정하여 표본의 크기를 구할 수 있다.
$$
\frac{\frac{z^2 \times p(1-p)}{e^2}}{1 + (\frac{z^2 \times p(1-p)}{e^2 N})}
$$
참고로 신뢰수준은 표본추출을 반복했을 때 얼마나 그 결과를 신뢰할 수 있는지에 대한 정도로 95% 를 주로 사용한다.
오차범위는 작을 수록 모집단의 특성에 대한 유용한 정보를 제공하지만 모집단에 대한 추론이 틀릴 가능성도 높아지므로 10% 를 넘지 않게 한다.
#### References
- [필요한 설문 응답자수(표본크기) 계산하기 - LearnX](https://learnx.tistory.com/entry/%ED%95%84%EC%9A%94%ED%95%9C-%EC%84%A4%EB%AC%B8-%EC%9D%91%EB%8B%B5%EC%9E%90%EC%88%98%ED%91%9C%EB%B3%B8%ED%81%AC%EA%B8%B0-%EA%B3%84%EC%82%B0%ED%95%98%EA%B8%B0)
- [표본크기의 결정 - Data Scream](https://datascream.co.kr/77)
---
## #22
### Bias를 통제하는 방법은 무엇입니까?

편향(Bias)는 데이터 내에 있는 모든 정보를 고려하지 않음으로 인해, 지속적으로 잘못된 것들을 학습하는 경향을 의미한다. 이는 언더피팅(Underfitting)과 관계되어 있다.
반대로 분산(Variance)는 데이터 내에 있는 에러나 노이즈까지 잘 잡아내는 highly flexible models에 데이터를 피팅시킴으로써, 실제 현상과 관계 없는 랜덤한 것들까지 학습하는 알고리즘의 경향을 의미한다. 이는 오버피팅(Overfitting)과 관계되어 있다.

편향(Bias)과 분산(Variance)은 한 쪽이 증가하면 다른 한 쪽이 감소하고, 한쪽이 감소하면 다른 한쪽이 증가하는 tradeoff 관계를 가진다.

**Bias를 통제하기 위한 방법**으로는 뉴런이나 계층의 개수가 같은 모델의 크기 증가, 오류평가시 얻은 지식을 기반으로 입력 특성 수정, 정규화, 모델 구조를 수정, 학습 데이터 추가 등의 방법이 있다.
#### References
- [쉽게 이해해보는 bias-variance tradeoff - 건빵의 블로그](https://bywords.tistory.com/entry/%EB%B2%88%EC%97%AD-%EC%9C%A0%EC%B9%98%EC%9B%90%EC%83%9D%EB%8F%84-%EC%9D%B4%ED%95%B4%ED%95%A0-%EC%88%98-%EC%9E%88%EB%8A%94-biasvariance-tradeoff)
- [Bias and Variance (편향과 분산) - 한 페이지 머신러닝](https://opentutorials.org/module/3653/22071)
- [[MLY] avoidable bias를 줄이는 방법들 - 생각많은 소심남](https://talkingaboutme.tistory.com/entry/MLY-avoidable-bias%EB%A5%BC-%EC%A4%84%EC%9D%B4%EB%8A%94-%EB%B0%A9%EB%B2%95%EB%93%A4?category=538748)
---
## #23
### 로그 함수는 어떤 경우 유용합니까? 사례를 들어 설명해주세요.
우선 **단위 수가 너무 큰 값들을 바로 회귀분석 할 경우 결과를 왜곡할 우려가 있으므로 이를 방지하기 위해 사용**된다.
예를들어, 나이와 재산보유액의 관계를 회귀분석으로 푼다고 했을 때, 재산보유액의 숫자가 굉장히 클 수 있다.
재산보유액에 로그를 취할 경우, 데이터의 왜도와 첨도를 줄일 수 있어 정규성이 높아지는 효과를 얻는다.
또한 **비선형관계의 데이터를 선형으로 만들기 위해** 사용된다.
예를들어, 기하급수적으로 늘어나는 제곱 형식의 그래프에 자연로그를 취하면 그 관계가 직선(선형)이 된다.
> **로그함수 주의사항**
로그 함수는 0~1 사이에서는 음수값을 가지므로, $log(1+x)$와 같은 방법으로 처리해주어야한다.
> **왜도(skewness)와 첨도(Kurtosis)**
- 왜도는 데이터가 한쪽으로 치우친 정도이다.
- 첨도는 분포가 얼마나 뾰족한지를 나타내는 정도이다.
#### References
- [로그함수를 취하는 이유 - 당도](https://dangdo.tistory.com/44)
---
## #24
### 베르누이 분포, 이항 분포, 카테고리 분포, 다항 분포, 가우시안 정규 분포, t 분포, 카이제곱 분포, F 분포, 베타 분포, 감마 분포에 대해 설명해주세요.
- [answer/statistics-math-distribution.md](./statistics-math-distribution.md) 참고
(TODO: 추후 수정)
---
## #25
### 출장을 위해 비행기를 타려고 합니다. 당신은 우산을 가져가야 하는지 알고 싶어 출장지에 사는 친구 3명에게 무작위로 전화를 하고 비가 오는 경우를 독립적으로 질문했습니다. 각 친구는 2/3로 진실을 말하고 1/3으로 거짓을 말합니다. 3명의 친구가 모두 “그렇습니다. 비가 내리고 있습니다”라고 말했습니다. 실제로 비가 내릴 확률은 얼마입니까?

출장지에 비가 내릴 때 $p$, 내리지 않을 때를 $1-p$라고 하자. 출장지에 비가 내리는데( $p$ ) 모든 친구가 비가 내린다라고 한다면 모든 친구가 진실을 말하는 것( $\frac{8}{27}$ )이다. 이 경우 확률은 $\frac{8p}{27}$이다.
출장지가 비가 내리지 않는데( $(1-p)$ ) 모든 친구가 비가 내린다라고 한다면 모든 친구가 거짓을 말하는 것( $\frac{1}{27}$ )이다. 이 경우 확률은 $\frac{(1-p)}{27}$이다.

위에서 계산한 확률을 위의 식에 대입하고 식을 정리하면 아래와 같다.
$$
Pr(raining | Yes) = \frac{\frac{8p}{27}}{\frac{8p}{27} + \frac{(1-p)}{27}} = \frac{8p}{8p + (1-p)} = \frac{8p}{7p+1}
$$
만약 출장지에 비가 올 확률이 25%라면 실제로 출장지에 비가 내릴 확률은 약 72.7%이다.
#### References
- [페이스북 데이터 사이언스 직무 인터뷰 - glassdoor](https://www.glassdoor.com/Interview/You-re-about-to-get-on-a-plane-to-Seattle-You-want-to-know-if-you-should-bring-an-umbrella-You-call-3-random-friends-of-y-QTN_519262.htm)
- [Solving Facebook's raining in Seattle interview question - Youtube](https://www.youtube.com/watch?v=NM91QI2uUqI)
================================================
FILE: answers/2-machine-learning.md
================================================
> **📌 질문은 <strong>[zzsza님의 Datascience-Interview-Questions](https://github.com/zzsza/Datascience-Interview-Questions)</strong>를 참고하였습니다.**
## Table of Contents
- [알고 있는 metric에 대해 설명해주세요. (ex. RMSE, MAE, recall, precision ...)](#1)
- [정규화를 왜 해야할까요? 정규화의 방법은 무엇이 있나요?](#2)
- [Local Minima와 Global Minimum에 대해 설명해주세요.](#3)
- [차원의 저주에 대해 설명해주세요.](#4)
- [dimension reduction 기법으로 보통 어떤 것들이 있나요?](#5)
- [PCA는 차원 축소 기법이면서, 데이터 압축 기법이기도 하고, 노이즈 제거기법이기도 합니다. 왜 그런지 설명해주실 수 있나요?](#6)
- [LSA, LDA, SVD 등의 약자들이 어떤 뜻이고 서로 어떤 관계를 가지는지 설명할 수 있나요?](#7)
- [Markov Chain을 고등학생에게 설명하려면 어떤 방식이 제일 좋을까요?](#8)
- [텍스트 더미에서 주제를 추출해야 합니다. 어떤 방식으로 접근해 나가시겠나요?](#9)
- [SVM은 왜 반대로 차원을 확장시키는 방식으로 동작할까요? SVM은 왜 좋을까요?](#10)
- [다른 좋은 머신 러닝 대비, 오래된 기법인 나이브 베이즈(naive bayes)의 장점을 옹호해보세요.](#11)
- [회귀 / 분류시 알맞은 metric은 무엇일까?](#12)
- [Association Rule의 Support, Confidence, Lift에 대해 설명해주세요.](#13)
- [최적화 기법중 Newton’s Method와 Gradient Descent 방법에 대해 알고 있나요?](#14)
- [머신러닝(machine)적 접근방법과 통계(statistics)적 접근방법의 둘간에 차이에 대한 견해가 있나요?](#15)
- [인공신경망(deep learning이전의 전통적인)이 가지는 일반적인 문제점은 무엇일까요?](#16)
- [지금 나오고 있는 deep learning 계열의 혁신의 근간은 무엇이라고 생각하시나요?](#17)
- [ROC 커브에 대해 설명해주실 수 있으신가요?](#18)
- [여러분이 서버를 100대 가지고 있습니다. 이때 인공신경망보다 Random Forest를 써야하는 이유는 뭘까요?](#19)
- [K-means의 대표적 의미론적 단점은 무엇인가요? (계산량 많다는것 말고)](#20)
- [L1, L2 정규화에 대해 설명해주세요.](#21)
- [Cross Validation은 무엇이고 어떻게 해야하나요?](#22)
- [XGBoost을 아시나요? 왜 이 모델이 캐글에서 유명할까요?](#23)
- [앙상블 방법엔 어떤 것들이 있나요?](#24)
- [feature vector란 무엇일까요?](#25)
- [좋은 모델의 정의는 무엇일까요?](#26)
- [50개의 작은 의사결정 나무는 큰 의사결정 나무보다 괜찮을까요? 왜 그렇게 생각하나요?](#27)
- [스팸 필터에 로지스틱 리그레션을 많이 사용하는 이유는 무엇일까요?](#28)
- [OLS(ordinary least squre) regression의 공식은 무엇인가요?](#29)
---
## #1
#### 알고 있는 metric에 대해 설명해주세요. (ex. RMSE, MAE, recall, precision ...)
평가지표(metric)을 크게 **분류를 위한 평가지표**와 **회귀를 위한 평가지표**로 나눌 수 있다.
---
우선 <strong>분류 작업(task)</strong>에 적용할 수 있는 평가지표를 살펴보자.
> **정확도(accuracy)**
정확도는 **모델의 예측이 얼마나 정확한지**를 의미한다. 정확도는 <strong>(예측 결과가 동일한 데이터 개수)/(전체 예측 데이터 개수)</strong>로 계산할 수 있다. 하지만 라벨 불균형이 있는 데이터에서 정확도를 사용하면 안 된다. 예를 들면, 0과 1의 비율이 9:1인 데이터가 있다고 했을 때, 모두 0으로 예측하면 정확도가 90%가 나올 것이다. 이는 잘못된 판단이므로 정확한 판단을 위해서는 다른 지표를 사용해야 한다.
> **오차 행렬(confusion matrix)**

오차 행렬은 **모델이 예측을 하면서 얼마나 헷갈리고 있는지를 보여주는 지표**이다. 주로 이진 분류에서 많이 사용하며 이진 분류에 대한 오차 행렬은 위의 그림처럼 같이 나타낼 수 있다. True Positive는 긍정으로 예측을 했는데 실제로 긍정인 경우를, False Positive는 긍정으로 예측했는데 실제로 부정인 경우를, False Negative는 부정으로 예측했는데 실제로 긍정인 경우를, True Negative는 부정으로 예측했는데 실제로 부정인 경우를 말한다. 위의 값을 바탕으로 모델이 어떤 오류를 발생시켰는지를 살펴볼 수 있다.
참고로 정확도는 <strong>(TN + TP) / (TN + FP + FN + TP)</strong>로 계산할 수 있다.
> **정밀도(precision), 재현율(recall)**
정밀도와 재현율은 **긍정 데이터 예측 성능에 초점을 맞춘 평가지표**이다. 정밀도란 **예측을 긍정으로 한 데이터 중 실제로 긍정인 비율**을 말하며, 재현율은 **실제로 긍정인 데이터 중 긍정으로 예측한 비율**을 말한다. 오차 행렬을 기준으로 정밀도는 <strong>TP / (FP + TP)</strong>으로, 재현율은 <strong>TP / (FN + TP)</strong>으로 계산할 수 있다.
정밀도와 재현율은 **트레이드오프 관계**를 갖는다. 정밀도는 FP를, 재현율은 FN을 낮춤으로써 긍정 예측의 성능을 높인다. 이 같은 특성 때문에 정밀도가 높아지면 재현율은 낮아지고 재현율이 높아지면 정밀도는 낮아진다. 가장 좋은 경우는 두 지표 다 적절히 높은 경우이다.
> **F1-Score**
**정밀도와 재현율 한 쪽에 치우치지 않고 둘 다 균형을 이루는 것**을 나타낸 것이 `F1-Score`이다. F1-Score는 정밀도와 재현율의 조화평균으로 계산할 수 있다.
$$
F1 = \frac{2}{\frac{1}{recall} + \frac{1}{precision}} = 2 * \frac{precision * recall}{precision + recall}
$$
> **ROC-AUC**

ROC는 **FPR(False Positive Rate)가 변할 때 TPR(True Positive Rate)가 어떻게 변하는지를 나타내는 곡선**을 말한다. 여기서 FPR이란 <strong>FP / (FP + TN)</strong>이고, TPR은 <strong>TP / (FN + TP)</strong>으로 재현율을 말한다. 그럼 어떻게 FPR을 움직일까? 바로 분류 결정 임계값을 변경함으로써 움직일 수 있다. FPR이 0이 되려면 임계값을 1로 설정하면 된다. 그럼 긍정의 기준이 높으니 모두 부정으로 예측될 것이다. 반대로 1이 되려면 임계값을 0으로 설정하여 모두 긍정으로 예측시키면 된다. 이렇게 임계값을 움직이면서 나오는 FPR과 TPR을 각각 x와 y 좌표로 두고 그린 곡선이 ROC이다.
AUC는 ROC 곡선의 넓이를 말한다. AUC가 높을수록 즉, AUC가 왼쪽 위로 휘어질수록 좋은 성능이 나온다고 판단한다. 즉, TPR이 높고 FPR이 낮을수록 예측 오류는 낮아지기 때문에 성능이 잘 나온다 볼 수 있다.
---
마지막으로 **회귀 작업**에 적용할 수 있는 평가지표를 살펴보자.
MAE(Mean Absolute Error)는 **예측값과 정답값 사이의 차이의 절대값의 평균**을 말한다.
$$
MAE = \frac{1}{N} \sum^N_{i=1} |y_i - \acute{y_i}|
$$
MSE(Mean Squared Error)는 **예측값과 정답값 사이의 차이의 제곱의 평균**을 말하며, MAE와 달리 제곱을 했기 때문에 이상치에 민감하다.
$$
MSE = \frac{1}{N} \sum^N_{i=1} (y_i - \acute{y_i})^2
$$
RMSE(Root Mean Squared Error)는 **MSE에 루트를 씌운 값**을 말한다.
$$
RMSE = \sqrt{MSE} = \sqrt{\frac{1}{N} \sum^N_{i=1} (y_i - \acute{y_i})^2}
$$
RMSLE(Root Mean Squared Logarithmic Error)는 RMSE와 비슷하나 **예측값과 정답값에 각각 로그를 씌워 계산**을 한다.
$$
RMSLE = \sqrt{\frac{1}{N} \sum^N_{i=1} (\log(y_i+1) - \log(\acute{y_i}+1))^2}
$$
R Squared는 **분산을 기반으로 예측 성능을 평가하는 지표**를 말한다. 정답값의 분산 대비 예측값의 분산 비율을 지표로 하며, 1에 가까울수록 정확도가 높다.
#### References
- [14 Popular Machine Learning Evaluation Metrics - RUBIK'S CODE](https://rubikscode.net/2020/10/19/14-popular-machine-learning-evaluation-metrics/)
- [Metrics to Evaluate your Machine Learning Algorithm - towards data science](https://towardsdatascience.com/metrics-to-evaluate-your-machine-learning-algorithm-f10ba6e38234)
- [머신러닝 용어집 - 구글 머신러닝 단기 집중과정](https://developers.google.com/machine-learning/glossary)
- [3. 평가 - 파이썬 머신러닝 완벽 가이드](http://www.yes24.com/Product/Goods/87044746?OzSrank=1)
- [Regression 모델 평가 : MSE, MAE, RMSE, RMSLE, R-Squared - Steadiness](https://steadiness-193.tistory.com/277)
---
## #2
#### 정규화를 왜 해야할까요? 정규화의 방법은 무엇이 있나요?
정규화는 **개별 피처의 크기를 모두 똑같은 단위로 변경하는 것**을 말한다. 정규화를 하는 이유는 **피처의 스케일이 심하게 차이가 나는 경우 값이 큰 피처가 더 중요하게 여겨질 수 있기 때문**이다. 이를 막기 위해 피처 모두 동일한 스케일로 반영되도록 하는 것이 정규화이다.
정규화하는 방법으로는 대표적으로 두 가지가 존재한다. 첫 번째 정규화 방법은 <strong>최소-최대 정규화(min-max normalization)</strong>으로 각 피처의 최소값을 0, 최대값을 1로 두고 변환하는 방법이다. 값을 $x$로, 최소값을 $min$, 최대값을 $max$로 둘 때, 정규화된 값은 $\frac{x - min}{max - min}$으로 계산할 수 있다. 두 번째 정규화 방법으로 <strong>Z-점수 정규화(z-score normalization)</strong>이 있다. 이 방법은 각 피처의 표준편차와 평균으로 값을 정규화시킨다. 정규화된 값은 $\frac{x - mean}{std}$로 계산할 수 있다.
#### References
- [정규화(Normalization) 쉽게 이해하기 - 아무튼 워라밸](http://hleecaster.com/ml-normalization-concept/)
- [2. 사이킷런으로 시작하는 머신러닝 - 파이썬 머신러닝 완벽 가이드](http://www.yes24.com/Product/Goods/87044746?OzSrank=1)
---
## #3
#### Local Minima와 Global Minimum에 대해 설명해주세요.

비용 함수(cost function)에서의 **Global Minimum**은 에러가 최소화되는 즉, 우리가 찾고자 하는 지점을 말하며, **Local Minima**는 에러가 최소가 될 수 있는 후보가 되는 지점 중 Global Minimum을 뺀 지점을 말한다. Local Minima는 자칫 에러가 **최소화되는 지점을 찾았다고 착각**할 수 있기에 함정에 비유할 수 있다. 이를 해결하기 위해 Momentum과 같은 최적화 알고리즘을 사용하거나 학습률(learning rate)를 잘 조절하여 Local Minima에서 벗어날 수 있다.
#### References
- [Local Minima 문제에 대한 새로운 시각 - 다크 프로그래머](https://darkpgmr.tistory.com/148)
- [Minima - Hong's](https://jihongl.github.io/2017/09/18/minima/)
---
## #4
#### 차원의 저주에 대해 설명해주세요.

차원의 저주란 **데이터 차원이 증가할수록 해당 공간의 크기가 기하급수적으로 증가하여 데이터 간 거리가 기하급수적으로 멀어지고 희소한 구조를 갖게 되는 현상**을 말한다. 이를 해결하기 위해서는 차원을 증가시킨만큼 더 많은 데이터를 추가하거나 PCA, LDA, LLE, MDS와 같은 차원 축소 알고리즘으로 차원을 줄여 해결할 수 있다.
#### References
- [차원의 저주(Curse of dimensionality) - BioinformaticsAndMe](https://bioinformaticsandme.tistory.com/197)
- [차원의 문제 - 다크 프로그래머](https://darkpgmr.tistory.com/145)
- [6. 차원 축소 - 파이썬 머신러닝 완벽 가이드](http://www.yes24.com/Product/Goods/87044746?OzSrank=1)
---
## #5
#### dimension reduction 기법으로 보통 어떤 것들이 있나요?
차원 축소는 <strong>피처 선택(feature selection)</strong>과 <strong>피처 추출(feature extraction)</strong>으로 나눌 수 있다. 우선 피처 선택은 특정 피처에 종속성이 강한 불필요한 피처는 제거하고 데이터의 특징을 잘 표현하는 주요 피처만 선택하는 것을 말한다. 반면 피처 추출은 기존 피처를 저차원의 피처로 압축하여, 피처를 함축적으로 잘 설명할 수 있도록 저차원으로 매핑하는 것을 말한다. 대표적인 피처 추출 알고리즘으로 PCA, SVD, NMF, LDA 등이 있다.
#### References
- [6. 차원 축소 - 파이썬 머신러닝 완벽 가이드](http://www.yes24.com/Product/Goods/87044746?OzSrank=1)
---
## #6
#### PCA는 차원 축소 기법이면서, 데이터 압축 기법이기도 하고, 노이즈 제거기법이기도 합니다. 왜 그런지 설명해주실 수 있나요?
PCA(Principle Component Analysis)는 **입력 데이터의 공분산 행렬을 기반으로 고유벡터를 생성하고 이렇게 구한 고유 벡터에 입력 데이터를 선형 변환하여 차원을 축소하는 방법**이다. 차원은 곧 입력 데이터의 피처를 뜻하므로 데이터 압축 기법으로 볼 수도 있다.
또한 PCA는 고유값이 가장 큰, 즉 데이터의 분산이 가장 큰 순으로 주성분 벡터를 추출하는데, 가장 나중에 뽑힌 벡터보다 가장 먼저 뽑힌 벡터가 데이터를 더 잘 설명할 수 있기 때문에 노이즈 제거 기법이라고도 불린다.
#### References
- [6. 차원 축소 - 파이썬 머신러닝 완벽 가이드](http://www.yes24.com/Product/Goods/87044746?OzSrank=1)
- [[기술면접] 차원축소, PCA, SVD, LSA, LDA, MF 간단정리 (day1 / 201009) - Hui_dea](https://huidea.tistory.com/126)
---
## #7
#### LSA, LDA, SVD 등의 약자들이 어떤 뜻이고 서로 어떤 관계를 가지는지 설명할 수 있나요?
`PCA`는 **Principle Component Analysis**의 약자로 데이터의 공분산 행렬을 기반으로 고유벡터를 생성하고 이렇게 구한 고유 벡터에 입력 데이터를 선형 변환하여 차원을 축소하는 방법이다. `SVD`는 **Singular Value Decomposition**의 약자로 PCA와 유사한 행렬 분해 기법을 사용하나 정방 행렬(square matrix)를 분해하는 PCA와 달리 행과 열의 크기가 다른 행렬에도 적용할 수 있다.
`LSA`는 **Latent Semantic Analysis**의 약자로 잠재 의미 분석을 말하며, 주로 토픽 모델링에 자주 사용되는 기법이다. LSA는 DTM(Document-Term Matrix)이나 TF-IDF(Term Frequency-Inverse Document Frequency) 행렬에 Truncated SVD를 적용하여 차원을 축소시키고, 단어들의 잠재적인 의미를 이끌어낸다. Truncated SVD는 SVD와 똑같으나 상위 n개의 특이값만 사용하는 축소 방법이다. 이 방법을 쓸 경우 원 행렬로 복원할 수 없다.
`LDA`는 **Latent Dirichlet Allocation** 혹은 **Linear Discriminant Analysis**의 약자이다. 전자는 토픽모델링에 사용되는 기법 중 하나로 LSA와는 달리 단어가 특정 토픽에 존재할 확률과 문서에 특정 토픽이 존재할 확률을 결합확률로 추정하여 토픽을 추정하는 기법을 말한다. 후자는 차원축소기법 중 하나로 분류하기 쉽도록 클래스 간 분산을 최대화하고 클래스 내부의 분산은 최소화하는 방식을 말한다.
> **Latent Dirichlet Allocation**와 관련된 자세한 내용은 [#9 텍스트 더미에서 주제를 추출해야 합니다. 어떤 방식으로 접근해 나가시겠나요?](#9)을 참고해주세요!
#### References
- [잠재 의미 분석(Latent Semantic Analysis, LSA) - 딥러닝을 이용한 자연어 처리 입문](https://wikidocs.net/24949)
- [잠재 디리클레 할당(Latent Dirichlet Allocation, LDA) - 딥러닝을 이용한 자연어 처리 입문](https://wikidocs.net/30708)
- [문서 단어 행렬(Document-Term Matrix, DTM) - 딥러닝을 이용한 자연어 처리 입문](https://wikidocs.net/24559)
- [TF-IDF(Term Frequency-Inverse Document Frequency) - 딥러닝을 이용한 자연어 처리 입문](https://wikidocs.net/31698)
- [6. 차원 축소 - 파이썬 머신러닝 완벽 가이드](http://www.yes24.com/Product/Goods/87044746?OzSrank=1)
---
## #8
#### Markov Chain을 고등학생에게 설명하려면 어떤 방식이 제일 좋을까요?
> **마코프 체인(Markov Chain)**
마코프 체인이란 <strong>마코프 성질을 지닌 이산 확률 과정(Discrete-time Stochastic Process)</strong>을 말한다.
> **마코프 성질(Markov Property)**
$n+1$회의 상태(state)는 오직 $n$회에서의 상태, 혹은 그 이전 일정 기간의 상태에만 영향을 받는 것을 의미한다. 예를 들면 동전 던지기는 독립 시행이기 때문에 $n$번째의 상태가 앞이던지 뒤이던지 간에 $n+1$번째 상태에 영향을 주지 않는다. 하지만 1차 마코프 체인은 $n$번째 상태가 $n+1$번째 상태를 결정하는데에 영향을 미친다. (시간 $t$에서의 관측은 단지 최근 $r$개의 관측에만 의존한다는 가정을 하고 그 가정하에서 성립한다.)

정리하면 마코프 체인은 **확률변수(random variable)가 어떤 상태(state)에 도달할 확률이 오직 바로 이전 시점의 상태(state)에 달려 있는 경우**를 가리킨다.
예를 들어, 오늘의 날씨가 어제의 날씨에만 의존하면 1차 마코프 체인, 이틀 전까지의 날씨에만 의존하면 2차 마코프 체인이다.
> **마코프 모델(Markov Model)**
마코프 **모델은 위의 가정하에 확률적 모델을 만든 것으로써 가장 먼저 각 상태를 정의**하게 된다. 상태(state)는 $V = v_1, ... , v_m$로 정의하고, m개의 상태가 존재하게 되는 것이다. 그 다음은 <strong>상태 전이 확률(State transition Probability)</strong>을 정의할 수 있다. 상태 전이 확률이란 각 상태에서 각 상태로 이동할 확률을 말한다. 상태 전이 확률 $a_{ij}$는 상태 $v_i$에서 상태 $v_j$로 이동할 확률을 의미한다. 아래의 식은 상태 전이 확률을 식으로 나타낸 것과 그 아래는 확률의 기본 정의에 의한 상태 전이 확률의 조건이다.

그리고 상태와 상태 전이 확률을 정리하여 <strong>상태 전이도(state transition diagram)</strong>으로도 표현할 수 있다.

#### References
- [Markov Chain - MLWiki](https://sites.google.com/site/machlearnwiki/RBM/markov-chain)
- [[기술면접] Markov Chain, Gibbs Sampling, 마르코프 체인, 깁스 샘플링 (day2 / 201010) - huidea](https://huidea.tistory.com/128?category=879541)
- [(Bayes 학습)(4)마르코프 연쇄-(1) - 정보사회학연구소](http://piramvill2.org/?p=905)
---
## #9
#### 텍스트 더미에서 주제를 추출해야 합니다. 어떤 방식으로 접근해 나가시겠나요?
> **잠재 디리클레 할당(Latent Dirichlet Allocation, LDA)**
잠재 디리클레 할당(LDA)이란 **문서의 집합에서 토픽을 찾아내는 프로세스를 뜻하는 토픽 모델링의 대표적인 알고리즘**을 말한다. LDA는 "문서들은 토픽들의 혼합으로 구성되어져 있으며, 토픽들은 확률 분포에 기반하여 단어들을 생성한다"고 가정하며, 데이터가 주어지면 LDA는 토픽을 문서가 생성되던 과정을 역추적한다.
예를 들어, 다음과 같은 예시 문장 3개가 있다고 가정하자.
```text
문서1 : 저는 사과랑 바나나를 먹어요
문서2 : 우리는 귀여운 강아지가 좋아요
문서3 : 저의 깜찍하고 귀여운 강아지가 바나나를 먹어요
```
LDA를 통해 각 문서의 **토픽 분포**와 **각 토픽 내의 단어 분포**를 추정할 수 있다.
- **각 문서의 토픽 분포**
- 문서1 : 토픽 A 100%
- 문서2 : 토픽 B 100%
- 문서3 : 토픽 B 60%, 토픽 A 40%
- **각 토픽의 단어 분포**
- 토픽A : 사과 20%, 바나나 40%, 먹어요 40%, 귀여운 0%, 강아지 0%, 깜찍하고 0%, 좋아요 0%
- 토픽B : 사과 0%, 바나나 0%, 먹어요 0%, 귀여운 33%, 강아지 33%, 깜찍하고 16%, 좋아요 16%
LDA는 토픽의 제목을 정해주지 않지만, 이 시점에서 알고리즘의 사용자는 위 결과로부터 두 토픽이 각각 과일에 대한 토픽과 강아지에 대한 토픽이라고 판단해볼 수 있다.
#### References
- [Topic Modeling, LDA - ratsgo's blog](https://ratsgo.github.io/from%20frequency%20to%20semantics/2017/06/01/LDA/)
- [[기술면접] 잠재디리클레할당 (day3 / 201012) - huidea](https://huidea.tistory.com/130?category=879541)
- [딥 러닝을 이용한 자연어 처리 입문](https://wikidocs.net/30708)
---
## #10
#### SVM은 왜 반대로 차원을 확장시키는 방식으로 동작할까요? SVM은 왜 좋을까요?
SVM(Support Vector Machine)은 데이터가 사상된 공간에서 **경계로 표현**되며, 공간상에 존재하는 **여러 경계 중 가장 큰 폭을 가진 경계를 찾는다.**

- $B_1$: 결정 경계
- $b_{11}$: plus-plane
- $b_{12}$: minus-plane
SVM의 장단점은 다음과 같다.
| 장점 | 단점 |
| ------------------------------------------------- | --------------------------------------------------------------------- |
| 분류와 회귀에 모두 사용할 수 있다. | 데이터 전처리와 매개변수 설정에 따라 정확도가 달라질 수 있다. |
| 신경망 기법에 비해 과적합 정도가 낮다. | 예측이 어떻게 이루어지는지에 대한 이해와 모델에 대한 해석이 어렵다. |
| 예측의 정확도가 높다. | 대용량 데이터에 대한 모델 구축 시 속도가 느리며,메모리 할당량이 크다. |
| 저차원과 고차원 데이터에 대해서 모두 잘 작동한다. | |
> **마진(Margin)**
마진(Margin)은 plus-plane과 minus-plane 사이의 거리를 의미하며, **최적의 결정 경계는 마진을 최대화**한다.
SVM은 선형 분류뿐만 아니라 **비선형 분류**에도 사용되는데, 비선형 분류에서는 입력자료를 다차원 공간상으로 맵핑할 때 <strong>커널 트릭(kernel trick)</strong>을 사용하기도 한다. 원공간(Input Space)의 데이터를 선형분류가 가능한 고차원 공간(Feature Space)으로 매핑한 뒤 두 범주를 분류하는 초평면을 찾는다. (Kernel-SVM)


> **커널 트릭(Kernel Trick)**
커널 함수를 이용하여 **차원 공간(low dimensional space)을 고차원 공간(high dimensional space)으로 매핑해주는 작업**을 커널트릭이라 한다.
커널 함수의 종류는 다음과 같다.

#### References
- [서포트 벡터 머신 (Support Vector Machine) - ratsgo's blog](https://ratsgo.github.io/machine%20learning/2017/05/23/SVM/)
- [Kernel-SVM - ratsgo's blog](https://ratsgo.github.io/machine%20learning/2017/05/30/SVM3/)
- [Support Vector Machine (SVM)의 개념 - butter_shower](https://butter-shower.tistory.com/7)
- [Support Vector Machine (SVM, 서포트 벡터 머신) - Excelsior-JH](https://excelsior-cjh.tistory.com/66)
- [서포트 벡터 머신(Support Vector Machine) 쉽게 이해하기 - 아무튼 워라벨](http://hleecaster.com/ml-svm-concept/)
- [ADP 필기 올패키지 데이터 분석 전문가](https://search.shopping.naver.com/search/all?where=all&frm=NVSCTAB&query=ADP+%ED%95%84%EA%B8%B0+%EC%98%AC%ED%8C%A8%ED%82%A4%EC%A7%80+%EB%8D%B0%EC%9D%B4%ED%84%B0+%EB%B6%84%EC%84%9D+%EC%A0%84%EB%AC%B8%EA%B0%80)
---
## #11
#### 다른 좋은 머신 러닝 대비, 오래된 기법인 나이브 베이즈(naive bayes)의 장점을 옹호해보세요.
데이터에서 변수들에 대한 **조건부 독립을 가정**하는 알고리즘으로 클래스에 대한 사전 정보와 데이터로부터 추출된 정보를 결합하고, <strong>베이즈 정리(Bayes Theorem)</strong>를 이용하여 어떤 데이터가 특정 클래스에 속하는지 분류하는 알고리즘이다.
나이브 베이즈의 장단점은 다음과 같다.
| 장점 | 단점 |
| -------------------------------------------------------------------------- | ---------------------------------------------------------------------- |
| 단순하고 빠르며 매우 효과적이다 | 모든 속성은 동등하게 중요하고 독립적이라는 알려진 결함 가정에 의존한다 |
| 노이즈와 결측 데이터가 있어도 잘 수행한다 | 수치 속성으로 구성된 많은 데이터셋에 대해 이상적이지 않다 |
| 훈련에 대한 상대적으로 적은 예제가 필요하지만 매우 많은 예제도 잘 수행한다 | 추정된 확률은 예측된 범주보다 덜 신뢰적이다 |
| 예측에 대한 추정된 확률을 얻기 쉽다 | |
#### References
- [쉽고 강력한 머신러닝, 나이브 베이즈 분류 (Naive Bayes Classification)- 자비스가 필요해](https://needjarvis.tistory.com/621)
- [나이브 베이즈 알고리즘의 장점과 단점 - 웹개발공작소](http://w3devlabs.net/wp/?p=17273)
- [ADP 필기 올패키지 데이터 분석 전문가](https://search.shopping.naver.com/search/all?where=all&frm=NVSCTAB&query=ADP+%ED%95%84%EA%B8%B0+%EC%98%AC%ED%8C%A8%ED%82%A4%EC%A7%80+%EB%8D%B0%EC%9D%B4%ED%84%B0+%EB%B6%84%EC%84%9D+%EC%A0%84%EB%AC%B8%EA%B0%80)
---
## #12
#### 회귀 / 분류시 알맞은 metric은 무엇일까?
[#1](#1) 답변을 참고해주세요. 해당 답변에서 서술하지 않은 지표만 추가로 설명합니다.
> **회귀**
$$
R^2 = \frac{\sum (\hat{y}_l - \bar{y})}{\sum (y_i - \bar{y})^2}
$$
결정계수(Coefficient of determination)는 (회귀선에 의해 설명되는 변동)/(전체 변동)을 말하며, 독립변수의 개수가 많아질수록 결정계수가 1에 가까워진다. 회귀모형이 높은 결정계수를 갖는다면 실제로 모형이 설명력이 높은 것인지 단순히 독립변수의 개수가 많은 것인지 알기 어려워 결정계수를 신뢰할 수 없게 되는 문제가 발생한다.
$$
adj R^2 = 1 - \frac{n - 1}{(n - p - 1)(1 - R^2)}
$$
수정된 결정계수는 결정계수의 문제를 해결하기 위해 표본의 크기(n)와 독립변수의 수(p)를 고려하여 수정된 결정계수를 계산한다.
> **분류**
$$ - (y - \log (p))) + (1 - y) \log (1-p) $$
Log Loss 혹은 Binary Crossentropy는 이진 분류에서의 지표로 사용된다.
$$
LogarithmicLoss = - \frac{1}{N} \sum^N_{i=1} \sum^M_{j=1} y_{ij} * \log (p_{ij})
$$
Categorical Crossentropy는 분류해야할 클래스가 3개 이상인 멀티 클래스 분류에서의 지표로 사용된다.
#### References
- [상관계수 & 결정계수 & 수정된 결정계수 - 모찌의 맛집 통계](https://mansoostat.tistory.com/76)
- [[결정계수] R square와 adjusted R square - specialscene](https://specialscene.tistory.com/63)
- [3 Best metrics to evaluate Regression Model?](https://towardsdatascience.com/what-are-the-best-metrics-to-evaluate-your-regression-model-418ca481755b)
- [The 5 Classification Evaluation metrics every Data Scientist must know](https://towardsdatascience.com/the-5-classification-evaluation-metrics-you-must-know-aa97784ff226)
---
## #13
#### Association Rule의 Support, Confidence, Lift에 대해 설명해주세요.
연관규칙분석(Association Analysis)은 흔히 장바구니 분석(Market Basket Analysis) 또는 서열분석(Sequence Analysis)이라고 불린다. 기업의 데이터베이스에서 상품의 구매, 서비스 등 **일련의 거래 또는 사건들 간의 규칙을 발견하기 위해 적용**하며, 연관성 분석의 평가 지표로는 Support, Confidence, Lift를 사용한다.
> **Support(지지도)**
전체 거래 중 항목 A와 항목 B를 동시에 포함하는 거래의 비율로 정의한다.
$$
지지도 = P(A \cap B) = \frac{A와 B가 동시에 포함된 거래수}{전체 거래수} = \frac{A \cap B}{전체}
$$
> **Confidence(신뢰도)**
항목 A를 포함한 거래 중에서 항목 A와 항목 B가 같이 포함될 확률이다. 연관성의 정도를 파악할 수 있다.
$$
신뢰도 = \frac{P(A \cap B)}{P(A)} = \frac{A와 B가 동시에 포함된 거래수}{A를 포함하는 거래수} = \frac{지지도}{P(A)}
$$
> **Lift(향상도)**
A가 구매되지 않았을 때 품목 B의 구매확률에 비해 A가 구매됐을 때 품목 B의 구매확률의 증가 비이다. 연관규칙 A→B는 품목 A와 품목 B의 구매가 서로 관련이 없는 경우에 향상도가 1이 된다.
$$
향상도 = \frac{P(B | A)}{P(B)} = \frac{P(A \cap B)}{P(A)P(B)} = \frac{A와 B가 동시에 포함된 거래수}{A를 포함하는 거래수 \times B를 포함하는 거래수} = \frac{신뢰도}{P(B)}
$$
---
에를 들어 어떤 슈퍼마켓에서 5명의 고객에 의해 발생된 5($N = 5$)건의 거래를 가지고, 연관규칙 X:{계란, 맥주} → Y:{기저귀}에 대해 살펴보자.
| Customer<br>ID | Transaction<br>ID | Items |
| :------------: | :---------------: | :------------------------------------: |
| 1131 | no.1 | 계란, 우유 |
| 2094 | no.2 | <U>계란, 기저귀, 맥주</U>, 사과 |
| 4122 | no.3 | 우유, 기저귀, 맥주, 콜라 |
| 4811 | no.4 | <U>계란</U>, 우유, <U>맥주, 기저귀</U> |
| 8091 | no.5 | 계란, 우유, 맥주, 콜라 |
$$ P(Y) = \frac{n(Y)}{N} = \frac{n \\{ no.2, no.3, no.4 \\} }{N} = \frac{3}{5} = 0.6 $$
- 지지도(Support) = $s(X→Y) = \frac{n(X\cup Y)}{N} = \frac{n \\{ no.2, no.4 \\} }{N} = \frac{2}{5} = 0.4$
- 신뢰도(Confidence) = $c(X→Y) = \frac{n(X\cup Y)}{n(X)} = \frac{n \\{ no.2, no.4 \\} }{n \\{ no.2, no.4, no.5 \\} } = \frac{2}{3} = 0.6667$
- 향상도(Lift) = $Lift(X→Y) = \frac{c(X→Y)}{s(Y)} = \frac{0.6667}{0.6} = 1.1111$
#### References
- [[R 연관규칙(Association Rule)] 지지도(support), 신뢰도(confidence), 향상도(lift), IS측도, 교차지지도 - R, Python 분석과 프로그래밍의 친구 (by R Friend)](https://rfriend.tistory.com/191)
- [ADP 필기 올패키지 데이터 분석 전문가](https://search.shopping.naver.com/search/all?where=all&frm=NVSCTAB&query=ADP+%ED%95%84%EA%B8%B0+%EC%98%AC%ED%8C%A8%ED%82%A4%EC%A7%80+%EB%8D%B0%EC%9D%B4%ED%84%B0+%EB%B6%84%EC%84%9D+%EC%A0%84%EB%AC%B8%EA%B0%80)
---
## #14
#### 최적화 기법중 Newton’s Method와 Gradient Descent 방법에 대해 알고 있나요?
> **Newton's Method**
함수 $f$의 2차 테일러 근사(quadratic approximation)은 다음과 같다.
$$
f(y)\approx f(x)+\nabla f(x)^T(y-x)+\frac{1}{2}(y-x)^T\nabla^2f(x)(y-x),
\\
f_{approx}(y)=f(x)+\nabla f(x)^T(y-x)+\frac{1}{2}(y-x)^T\nabla^2f(x)(y-x)
$$
여기서 $y$는 다음 스텝의 $x$ 값인 $x^+$이다. 또한 quadratic approximation을 $f_{approx}$로 정한다.
이 $f_{approx}$ 즉, quadratic approximation을 최소로 만드는 입력 $y$를 찾으려 한다. 이때 $f_{approx}$는 convex이므로 위 식의 gradient를 0으로 만드는 입력 $y$가 $f_{approx}$를 최소로 만들 것이다. 이 결과가 Newton’s method에서의 step update 식이 된다. 아래 식의 미분은 $y$에 대한 미분 임을 기억하자.
$$
\nabla f_{approx}(y)=\nabla f(x)+\frac{1}{2}\left((\nabla^2f(x))^T(y-x)+(y-x)^T\nabla^2f(x)\right)
\\
=\nabla f(x)+\nabla^2f(x)(y-x)\qquad\qquad\qquad
\\
= 0,\qquad\qquad\qquad\qquad\qquad\qquad\qquad\quad\;\,
\\
\Leftrightarrow y=x-(\nabla^2f(x))^{-1}\nabla f(x)\qquad\qquad\;
$$
> **Gradient Descent**
Gradient descent에서는 함수 $f$의 2차 테일러 근사항을 사용하고, 2차 항의 경우 실제 2차 미분 결과가 아닌, 정방행렬(identity matrix)과 이를 $t$로 나눈 값으로 가정한다.
$$
f(y)\approx f(x)+\nabla f(x)^T(y-x)+\frac{1}{2t}\parallel y-x\parallel^2_2,
\\
f_{approx}(y)=f(x)+\nabla f(x)^T(y-x)+\frac{1}{2t}\parallel y-x\parallel^2_2
$$
Newton’s method와 동일하게 위 근사식의 gradient가 0인 $y$ 값, 즉 $x^+$를 정할 수 있다.
$$
\nabla f(y)=\nabla f(x)+\frac{1}{t}(y-x),
\\
=0,\qquad\qquad\;
\\
\Leftrightarrow y=x-t\nabla f(x)
$$
> **Newton's method**와 **Gradient descent**의 step에 따른 수렴 방향 비교
<img src="https://convex-optimization-for-all.github.io/img/chapter_img/chapter14/gd.jpeg">
- 파랑: Newton's method
- 검정: Gradient descent
Gradient descent는 2차 미분항을 정방행렬에 상수가 곱해진 값으로 가정하고 gradient를 계산하기 때문에, 등고선(contour)의 접선 방향에 수직하게(perpendicular) 수렴함을 확인할 수 있고, Newton’s method에 비해 느린 수렴 속도를 보인다.
#### References
- [14-01-01 Newton's method interpretation - 모두를 위한 컨벡스 최적화](https://convex-optimization-for-all.github.io/contents/chapter14/2021/03/26/14_01_01_newton_method_interpretation/)
- [뉴턴법/뉴턴-랩슨법의 이해와 활용(Newton's method) - 다크 프로그래머](https://darkpgmr.tistory.com/58)
- [Gradient Descent 탐색 방법 - 다크 프로그래머](https://darkpgmr.tistory.com/133)
- [4주차\_#2. 최적화 기법중 Newton's Method와 Gradient Descent 방법을 설명하세요. - 내가 보려고 만든 공간](https://astralworld58.tistory.com/86)
---
## #15
#### 머신러닝(machine)적 접근방법과 통계(statistics)적 접근방법의 둘간에 차이에 대한 견해가 있나요?
머신러닝적 접근방법과 통계적 접근방법의 차이는 두 방법의 주 목적이 다르다는 것이다.
머신러닝적 접근방법은 모델의 **예측 성공률**을 높이는게 목적이다.
따라서 모델의 신뢰도나 정교한 가정보다는 다양한 피쳐를 사용하여 (오버피팅을 감안하더라도) 높은 예측률을 달성하고자 한다.
통계적 접근방법은 분포와 가정을 통해 **신뢰 가능하고 정교한** 모델을 만드는게 목적이다.
따라서 모형을 복잡하지 않고 단순하게 만들고, 어떤 피쳐가 어떤 원인을 주는지 알 수 있도록 한다.
#### References
- [머신러닝과 전통적 통계학의 차이 - Hyunseok Choi](https://medium.com/@hyunseok/%EB%A8%B8%EC%8B%A0%EB%9F%AC%EB%8B%9D%EA%B3%BC-%EC%A0%84%ED%86%B5%EC%A0%81-%ED%86%B5%EA%B3%84%ED%95%99%EC%9D%98-%EC%B0%A8%EC%9D%B4-a560f0708db0)
- [Machine Learning과 전통적 통계분석 방법의 차이](https://ek-koh.github.io/data%20analysis/ML-diff/)
---
## #16
#### 인공신경망(deep learning이전의 전통적인)이 가지는 일반적인 문제점은 무엇일까요?
딥러닝 이전의 인공신경망은 선형적으로만 회귀, 분류를 수행하기 때문에 레이어를 깊게 쌓지 못했고, 때문에 XOR 문제 같은 복잡한 문제를 풀지 못하는 문제점이 있었다.

하지만 시그모이드와 같은 비선형 함수를 선형 모델에 추가하여 XOR 문제를 해결하고, 편미분 체인룰을 사용한 오차역전파 방법으로 모델을 업데이트할 수 있게 되면서 레이어를 깊게 쌓은 딥러닝 인공신경망이 발전하였다.
#### References
- [1.2 딥러닝 이전: 머신 러닝의 간략한 역사 - 텐서 플로우 블로그](https://tensorflow.blog/%EC%BC%80%EB%9D%BC%EC%8A%A4-%EB%94%A5%EB%9F%AC%EB%8B%9D/1-2-%EB%94%A5%EB%9F%AC%EB%8B%9D-%EC%9D%B4%EC%A0%84-%EB%A8%B8%EC%8B%A0-%EB%9F%AC%EB%8B%9D%EC%9D%98-%EA%B0%84%EB%9E%B5%ED%95%9C-%EC%97%AD%EC%82%AC/)
- [모두를 위한 딥러닝 - Sung Kim](https://www.youtube.com/watch?v=n7DNueHGkqE&list=PLlMkM4tgfjnLSOjrEJN31gZATbcj_MpUm&index=22)
---
## #17
#### 지금 나오고 있는 deep learning 계열의 혁신의 근간은 무엇이라고 생각하시나요?
ImageNet 과 같은 **거대하고 높은 품질의 데이터셋**이 모두에게 공개되면서 딥러닝의 혁신적인 발전이 시작될 수 있었다. 현재는 더 다양한 태스크에 적합한 좋은 GLUE 같은 데이터들도 공개되어 더욱 딥러닝의 발전에 이바지하고 있다.
현재 좋은 성능을 내는 딥러닝 모델들은 모두 큰 규모의 모델들인데 **하드웨어의 발전**이 이를 가능하게 하였다.
또한 **end-to-end 모델**이 나타나면서 데이터 레이블링, 하이퍼파라미터 찾기, 최적 모델 찾기 등 모든 작업을 기계에게 맡기면서 딥러닝이 크게 발전하였다.
#### References
- [end-to-end 학습의 장단점 - 생각많은 소심남](https://talkingaboutme.tistory.com/entry/MLY-end-to-end-%ED%95%99%EC%8A%B5%EC%9D%98-%EC%9E%A5%EB%8B%A8%EC%A0%90)
---
## #18
#### ROC 커브에 대해 설명해주실 수 있으신가요?
ROC 커브는 **이진분류 모델의 성능**을 나타내는 지표이다.
모델이 참이라고 예측하는 경우는 **FPR** (False Positive Rate, 실제 값이 거짓일 때) 과 **TPR** (True Positive Rate, 실제 값이 참일 때) 두 경우로 나뉜다.
FPR 과 TPR 을 그래프에서 x 축, y 축으로 동시에 표현한 ROC 커브를 통해 모델이 얼마나 옳은 값을 잘 예측하는지 알 수 있게 된다.

ROC 커브가 좌상단과 가까운 경우 좋은 모델이라고 판단할 수 있다. 모델이 FPR 은 낮게, TPR 은 높게 예측하기 때문이다.
#### References
- [ROC curve - 공돌이의 수학 정리 노트](https://angeloyeo.github.io/2020/08/05/ROC.html)
---
## #19
#### 여러분이 서버를 100대 가지고 있습니다. 이때 인공신경망보다 Random Forest를 써야하는 이유는 뭘까요?
**랜덤 포레스트**는 여러 결정 트리를 앙상블하여 하나의 모델로 구성하는 방법이다. 랜덤 포레스트에서는 각 서버를 모델의 특성을 이해하는 단일 결정 트리 (Decision tree) 로 **병렬**적이게 구성할 수 있다.
반면, **인공신경망**은 하나의 서버 자체가 모델의 특성을 모두 이해하는 end-to-end 구조로 **직렬**적이게 구성된다.
따라서 서버가 100대 있을 때는, 이를 병렬적으로 활용할 수 있는 **랜덤 포레스트**를 사용한다.
#### References
- [Random Forest(랜덤 포레스트) 개념 정리 - Codesigner's Dev Story](https://eunsukimme.github.io/ml/2019/11/26/Random-Forest/)
- [의사결정나무 - ratsgo's blog](https://ratsgo.github.io/machine%20learning/2017/03/26/tree/)
- [출근 루틴, 하루 3문제 - Man-About-Town](https://yongwookha.github.io/MachineLearning/2021-01-29-interview-question)
---
## #20
#### K-means의 대표적 의미론적 단점은 무엇인가요? (계산량 많다는것 말고)
K-means 는 특성이 비슷한 데이터를 같은 그룹으로 묶어주는 클러스터링 알고리즘으로, k 개의 군집 개수를 정하고 군집의 중심점을 예측하여 각 데이터와 거리를 비교한 후 군집을 결정한다.
**K-means 알고리즘의 단점**은 다음과 같다.
- K 를 몇 개로 설정하냐에 따라 성능이 달라진다.
- K 개 군집의 중심점을 예측하여야 하는데, 어디를 중심점으로 두냐에 따라 성능이 달라진다.
- 데이터가 잘 모여있는 경우에 효과적이지, 노이즈가 많은 경우 효과적이지 않다.
#### References
- [머신러닝 - 7. K-평균 클러스터링(K-means Clustering) - 귀퉁이 서재](https://bkshin.tistory.com/entry/%EB%A8%B8%EC%8B%A0%EB%9F%AC%EB%8B%9D-7-K-%ED%8F%89%EA%B7%A0-%EA%B5%B0%EC%A7%91%ED%99%94-K-means-Clustering)
---
## #21
#### L1, L2 정규화에 대해 설명해주세요.
정규화(**일반화**)의 목적은 모델이 학습 데이터에 오버피팅되지 않고 처음 보는 테스트 데이터에도 좋은 성능을 내도록 만드는 것이다.
모델의 학습은 loss 함수를 최소화하는 방향으로 진행된다.
이 때, loss 함수에 L1, L2 정규화 항 (norm) 을 더함으로써 모델은 기존의 loss 도 줄이면서 정규화 항 (모델의 피쳐값과 관련) 도 줄이는 방향으로 학습된다.
모델의 피쳐값이 줄어듦에 따라 특정 피쳐가 너무 큰 값을 갖지 않게 되면서 오버피팅을 방지할 수 있게 된다.
> **L1 정규화 (라쏘 회귀)**
L1 정규화는 특정 피쳐의 값이 매우 낮은 경우 (아웃라이어) 0에 수렴되는 특징이 있다. 특정 피쳐가 0이 되어 사라지는 것은 **feature selection** 과 동일하다고 볼 수 있다.
$$
Cost = \sum^N_{i=0} (y_i - \sum^M_{j=0} x_{ij}W_j)^2 + \lambda \sum^M_{j=0} |W_j|
$$
> **L2 정규화 (릿지 회귀)**
L2 정규화는 특정 웨이트의 값이 매우 낮아도 0에 수렴되지는 않고 가까워지는 특징이 있다. 이는 L1 정규화에 비해 강하지 않게 정규화를 실행하여 항상 선형 모델에 일반화 효과를 줄 수 있다.
$$
Cost = \sum^N_{i=0} (y_i - \sum^M_{j=0} x_{ij}W_j)^2 + \lambda \sum^M_{j=0} W_j^2
$$
loss 식에 람다 모델의 웨이트에 대한 L1 or L2 norm 을 더해줌으로써 모델의 일반화가 가능해진다.
loss 는 데이터 값과 추정 값의 차이로 모델은 loss 를 최소화하는 방향으로 학습하는데, L1 or L2 정규화를 사용하면 loss 가 웨이트의 크기만큼 커지기 때문에 데이터 값에 예측 값이 fit 해지지 않기 때문이다.
> **Norm**
Norm은 벡터의 크기를 나타내는 것으로 L1 Norm은 벡터의 절댓값 크기를 나타내고, L2 Norm은 직선 거리 (제곱의 루트) 를 나타낸다.

위 그림에서 초록선은 L2 norm 을 의미하고, 나머지 선은 L1 norm 을 의미한다.
- **L1 loss**
$$
L1LossFunction = \sum^n_{i=1} |y_{true} - y_{predicted}|
$$
- L2 loss
$$
L2LossFunction = \sum^n_{i=1} (y_{true} - y_{predicted})^2
$$
#### References
- [딥러닝 용어 정리, L1 Regularization, L2 Regularization 의 이해, 용도와 차이 설명 - 빛나는 나무](https://light-tree.tistory.com/125)
- [L1, L2 Norm, Loss, Regularization? - 생각 정리](https://junklee.tistory.com/29)
- [릿지회귀, 라쏘회귀, 엘라스틱넷 - 대학원생이 쉽게 설명해보기](https://hwiyong.tistory.com/93)
---
## #22
#### Cross Validation은 무엇이고 어떻게 해야하나요?
**cross validation(교차검증)이란** train(학습) 데이터로 학습한 모델이, 학습에 사용되지 않은 validation(검증) 데이터를 기준으로 얼마나 잘 동작하는지 확인하는 것이다. 여기서 주의할 점은 train 데이터셋과 validation 데이터셋에는 test 데이터셋이 포함되면 안된다는 것이다.
교차검증을 통해 얻을 수 있는 **장단점**은 아래와 같다.
- 적은 데이터에 대한 validation 신뢰성을 높일 수 있다.
- 모든 데이터셋을 훈련에 활용할 수 있으므로 데이터 편중을 막을 수 있다. (k-fold 경우)
- 검증 결과에 따라 더 일반화된 모델을 만들 수 있다.
- 모델 학습에 오랜 시간이 소요된다.
교차검증 기법의 **종류**는 아래와 같다. (validation 데이터셋을 어떻게 지정하느냐에 따라 달라진다.)
- 홀드 아웃 교차검증(Holdout Cross Validation)
- K-겹 교차검증(K-fold Cross Validation)
- 계층별 k-겹 교차검증(Stratified K-Fold Cross Validation)
> **홀드 아웃 교차검증**
홀드아웃 교차검증방법은 일정한 비율의 validation 데이터셋 하나를 지정하여 검증 데이터셋으로 사용하는 것이다. 홀드아웃 교차검증을 사용하는 경우, 두가지 문제점이 존재한다.
1. validation 데이터셋으로 지정된 부분의 데이터가 학습셋으로 사용되지 않는다는 문제
2. validation 데이터셋에 편향되도록 모델을 조정하게 된다는 문제
이를 해결하기 위해 k-겹 교차검증이 등장했다.
> **k-겹 교차검증**
k-겹 교차검증 방법은 train 데이터를 k개의 fold로 나누어, 그 중 하나의 fold를 validation 데이터셋으로 삼아 검증하는 방법을 k번 반복하여, 그 평균을 결과로서 사용하는 방법이다. 세부적인 동작방법은 다음과 같다.
1. train 데이터셋을 k개의 fold로 나누고, 그 중 하나를 validation 데이터셋으로 지정한다.
2. validation 데이터셋을 제외한 나머지 폴드들을 train 데이터셋으로 사용하여 모델을 학습한다.
3. 학습한 모델을 1번에서 지정해둔 validation 데이터셋으로 검증하고, 그 검증 결과를 저장해둔다.
4. 모델을 초기화한 후, 기존 validation 데이터셋이 아닌 다른 fold를 validation 데이터셋으로 지정하고, 2번 과정부터 다시 수행한다.
5. 모든 fold들이 한번씩 validation 데이터셋으로 사용된 후에는, 저장해둔 검증결과의 평균을 내어, 그것을 최종 validation 결과로 사용한다.
그러나 k-겹 교차검증 방법은 랜덤하게 validation 데이터셋을 지정하게 되므로, 편향된 데이터로 이뤄진 폴드가 생성될 수 있다는 단점이 있다. 이를 해결하기 위해서 계층별 k-겹 교차검증 방법이 등장했다.
> **계층별 k-겹 교차검증**
계층별 k-겹 교차검증 방법은 k-겹 교차검증 방법에서 fold를 나눌때, 랜덤하게 fold를 지정하는 것이 아닌, 각 클래스별 비율을 고려하여 fold를 구성하는 방법이다.

> **💡 왜 test 데이터셋 만으로 검증하면 안될까?**
> 모든 train 데이터셋을 학습하고, test 데이터셋으로 검증한 결과를 확인한다고 하자. 개발자는 test 데이터셋 점수를 높이기 위해, test 데이터셋에 편향되도록 모델을 튜닝하게 될 것이다. 그러나 중요한 것은 test 데이터셋에 대한 정확도를 높이는 것 뿐만아니라, 모델의 일반적인 정확도를 높이는 것이다. 어떤 데이터가 들어와도 일정하게 높은 정확도를 보여주는 모델이 좋은 모델이라 할 수 있으므로, validation 데이터셋과 test 데이터셋을 분리하여 검증하는 과정을 통해, 모델을 일반화시켜야 한다.
#### References
- [딥러닝기초 Optimization - Sally](https://bsm8734.github.io/posts/bc-d012-1-dlbasic-optimization/)
- [교차검증(CV, Cross Validation)이란? - unhochoi](https://wooono.tistory.com/105)
---
## #23
#### XGBoost을 아시나요? 왜 이 모델이 캐글에서 유명할까요?
**XGBoost(eXtreme Gradient Boosting)** 이란, 트리 기반의 앙상블 학습에서 가장 각광받고 있는 알고리즘 중 하나이다. Kaggle 경연대회에서 상위를 차지한 많은 과학자들이 XGBoost를 이용하면서 널리 알려졌다. GBM에 기반하고 있지만, GBM의 단점인 느린 수행시간 및 과적합 규제(Regularization) 부재 등의 문제를 해결해서 각광받고 있다.
XGBoost의 장점은 다음과 같다.
- 분류와 회귀영역에서 **뛰어난 예측 성능**을 발휘한다.
- XGBoost는 병렬처리를 사용하여, GBM 대비 **빠른 수행시간**을 보인다.
- **Regularization, Early Stopping** 기능을 통해 오버피팅을 방지할 수 있다.
- Tree Pruning(가지치기) 제공한다. 미리 정해둔 max_depth까지만 split하고 pruning을 하고, 거꾸로 올라가면서 positive gain이 없는 노드를 삭제한다.
- 자체적으로 결측치를 처리해준다.
- 매 iteration마다 교차검증을 수행한다.
**GBM(Gradient Boosting Algorithm)** 이란 회귀분석 또는 분류 분석을 수행할 수 있는 **예측모형**이며 예측모형의 **앙상블 방법론** 중 **부스팅** 계열에 속하는 알고리즘이다. LightGBM, CatBoost, XGBoost는 모두 GBM을 기반으로 만들어졌다. (자세한 내용은 [Gradient Boosting Algorithm의 직관적인 이해 - DeepPlay](https://3months.tistory.com/368) 참고)
> **💡 boosting 이라는 테크닉 자체가 sequential 한데 어떻게 병렬처리를 할까?**
> 세가지 가능성이 제기된다. 나뉜 분기마다 각각 병렬처리하거나, 분기가 나뉘는 지점 계산을 병렬처리 하거나, 처음부터 feature별 정렬을 통해 병렬처리를 할 수 있다. (자세한 내용은 [XGBoost의 병렬처리가 어떻게 가능할까? - GoLab](http://machinelearningkorea.com/2019/07/25/xgboost-%EC%9D%98-%EB%B3%91%EB%A0%AC%EC%B2%98%EB%A6%AC%EA%B0%80-%EC%96%B4%EB%96%BB%EA%B2%8C-%EA%B0%80%EB%8A%A5%ED%95%A0%EA%B9%8C/) 참고)
#### References
- [머신러닝 알고리즘-XGBoost - RosyPark](https://rosypark.tistory.com/59)
- [Gradient Boosting Algorithm의 직관적인 이해 - DeepPlay](https://3months.tistory.com/368)
---
## #24
#### 앙상블 방법엔 어떤 것들이 있나요?

**앙상블(Ensemble)** 은 여러개의 모델을 조합해서 그 결과를 뽑아 내는 방법이다. "정확도가 높은 강한 모델을 하나 사용하는 것보다, 정확도가 낮은 약한 모델을 여러개 조합 하는 방식의 정확도가 높다"는 개념에서 비롯한 방법이다. `Bagging`, `Boosting`, `Stacking` 등의 방법이 있다.
**배깅(Bagging, Bootstrap Aggregation)** 이란 샘플을 여러번 뽑아(Bootstrap = 복원 랜덤 샘플링) 각 모델을 학습시켜 결과물을 집계(Aggregation)하는 방법이다. 카테고리 데이터는 투표 방식(Voting)으로 결과를 집계하며, 연속형 데이터는 평균으로 집계한다. Bagging을 사용한 대표적인 기법에는 `Random Forest` 방법이 있다. 학습 데이터가 충분하지 않더라도 충분한 학습효과를 주어 높은 bias의 underfitting 문제나, 높은 variance로 인한 overfitting 문제를 해결하는데 도움을 준다.
**부스팅(Boosting)** 이란 이전 모델의 오답에 가중치를 높게 부여하여 다음 모델을 학습하는 방법이다. 오답을 정답으로 맞추기 위해 오답에 더 집중하여 학습시키기 떄문에 일반적으로 배깅에 비해 정확도가 높다. 그러나 틀렸던 부분에 대해 반복적으로 학습하므로 오버피팅의 문제가 있으며, outlier에 취약하고, 속도가 느리다는 단점도 가지고 있다. `GBM(Gradient Boosting)` 방법이 대표적이고, `XGBoost, AdaBoost, GradientBoost` 등의 알고리즘이 존재한다.
**스태킹(Stacking)** 이란 여러 개별 모델이 예측한 결과값을 다시 학습 데이터셋으로 사용해서 모델을 만드는 방법이다. 그러나 위의 그림과 같은 기본적인 스태킹 방법은 `같은 데이터셋을 통해 예측한 결과를 기반으로 다시 학습`하므로 `오버피팅` 문제점이 있다. 따라서 스태킹에 Cross Validation 방식을 도입하여 이 문제를 해결할 수 있다. 데이터를 쪼개고 이들 중 일부만을 가지고 학습한 모델을 여러개 만들어, 그 결과들을 `메타 학습 데이터셋(meta train dataset)` 으로 사용하여 다시 학습하는 것이다. 이 방법은 많은 개별 모델의 결과를 결합하여 예측 성능을 높일 수 있다는 장점이 있다.
> **💡 배깅 vs 부스팅**
> **배깅**은 랜덤 복원추출(부트스트랩)을 여러번 반복하여 모델을 **병렬적**으로 여러개 학습을 시킨 다음, 평균을 내는 방식이다. 반면, **부스팅**은 모든 데이터를 학습에 사용하되, 오답에 더 큰 가중치를 두어 다음 회차를 학습시키는 **순차적**인 방법이다.
#### References
- [머신러닝-11.앙상블학습: 배깅과 부스팅 - BaekKyunShin](https://bkshin.tistory.com/entry/%EB%A8%B8%EC%8B%A0%EB%9F%AC%EB%8B%9D-11-%EC%95%99%EC%83%81%EB%B8%94-%ED%95%99%EC%8A%B5-Ensemble-Learning-%EB%B0%B0%EA%B9%85Bagging%EA%B3%BC-%EB%B6%80%EC%8A%A4%ED%8C%85Boosting)
- [1.앙상블 기법과 배깅, 부스팅, 스태킹 - 데이터 맛집](https://data-matzip.tistory.com/entry/%EC%95%99%EC%83%81%EB%B8%94-%EA%B8%B0%EB%B2%95-%EC%A0%95%EB%A6%AC-1-%EC%95%99%EC%83%81%EB%B8%94Ensemble-%EA%B8%B0%EB%B2%95%EA%B3%BC-%EB%B0%B0%EA%B9%85Bagging-%EB%B6%80%EC%8A%A4%ED%8C%85Boosting-%EC%8A%A4%ED%85%8C%EC%9D%B4%ED%82%B9Stacking)
---
## #25
#### feature vector란 무엇일까요?
**특징(feature)** 이란, 샘플(데이터)을 잘 설명하는 측정가능한 속성이다. 특징을 통해 특정 샘플을 수치화하여 나타낼 수 있다.
**특징벡터(feature vector)** 란 피쳐(feature)들의 집합이다. 굳이 벡터로 표시하는 이유는 수학적으로 다루기 편하기 때문이다.
데이터별로 어떤 특징을 가지고 있는지 찾아내고, 그것을 토대로 데이터를 벡터로 변환하는 작업을 **특징추출(feature extraction)** 이라고 한다.
**특징 공간(feature space)** 이란 관측값들이 있는 공간을 의미한다. 이 특징 공간은 여러 차원으로 구성될 수 있다. 어떤 데이터를 특징공간의 하나의 벡터로 표현하는 경우, 여러 특징 변수가 특징벡터에 영향을 줄 수 있다. 예를들어, 특징 변수가 하나인 데이터는 1차원 특징 공간에 나타나고, 특징 변수가 N개라면 N차원의 특징 공간에 나타낼 수 있다.
d-차원 데이터의 특징 벡터는 다음과 같이 표시된다.
$$
x = (x_1, x_2, ..., x_d)^T
$$
> **💡 분야에 따른 피처벡터의 의미**
>
> - <strong>컴퓨터비전(이미지)</strong>에서의 특징은 edge, corner 등을 의미한다. 픽셀 값이 급격히 변화하는 곳, 밝기의 변화, 색상의 변화, 그래디언트의 방향 등의 매칭 정보등을 특징으로 삼는다. SIFT, SURF 등의 방법이 존재한다.
> - **자연어처리(텍스트)** 에서의 특징은 단어, 형태소, 서브워드, 토큰 등으로 표현될 수 있으며, BOW(Bag-of-Words)는 문서에서 단어의 발생을 설명하는 텍스트의 벡터 표현이다. 만약 8개의 단어로 이루어진 문장을 BoW로 만들면, 8차원(dimension)의 vector로서 하나의 단어를 표현할 수 있다.
> - **정형데이터**에서의 특징은 각 attribute(열)를 의미한다. 키, 나이, 국적 등이 특징으로 사용될 수 있다.
#### References
- [피쳐(기계학습) - 위키백과](<https://ko.wikipedia.org/wiki/%ED%94%BC%EC%B3%90_(%EA%B8%B0%EA%B3%84_%ED%95%99%EC%8A%B5)>)
- [4)머신러닝이란? - TCPschool.com](http://www.tcpschool.com/deep2018/deep2018_machine_learning)
- [머신러닝-다차원 특징공간과 차원의 저주 - 예비 개발자](http://blog.naver.com/PostView.nhn?blogId=qbxlvnf11&logNo=221323034856)
- [OpenCV-특징검출, 디스크립터, 매칭 - JeongYongHwang](<https://wjddyd66.github.io/opencv/OpenCV(8)/>)
- [자연어처리 Bag of Words](https://bsm8734.github.io/posts/bc-d016-2-nlp-bag-of-words/)
- [자연어의 피처와 전처리 - GeumjaeLee](https://brunch.co.kr/@geumjaelee/4)
---
## #26
#### 좋은 모델의 정의는 무엇일까요?
한 줄로 요약하자면, 좋은 모델은 **데이터의 패턴을 잘 학습한 모델**로서, **한번도 본적 없는 데이터에 대해 옳은 판단을 내리는 모델**이 좋은 모델이라고 할 수 있다.
머신러닝, 딥러닝 등을 사용하여 모델을 생성하는 이유는 `기계가 사람 대신 어떠한 결정을 내리기 위함`이다. 따라서 모델은 `결정을 대신하는 기계, 결정기`라고 볼 수 있다.
이 관점에서, 좋은 결정(옳은 결정)을 내리는 모델이 좋은 모델이다. 주어진 학습 데이터에 과적합된 모델의 경우, 주어진 데이터와 조금만 다른 데이터가 들어오면 제대로 분류하지 못하는 상황이 발생된다.
그러므로 **모델의 일반화**가 이루어져, 새로운 데이터에 대해서도 적정한 수준의 성능을 보이는 모델이 좋은 모델이라고 할 수 있다.
예를들어, 예측이 목적이라면, 실제 정답과 예측 값의 차이(loss, cost, error)를 최소화 하는 모델이 가장 좋은 모델이다. 또한 확률을 추정하는 경우에는 가능성(likelihood)을 최대화하는 모델이 좋은 모델이라고 할 수 있다.
#### References
- [머신러닝의 모델평가와 모델선택, 알고리즘 선택 - 텐서플로우 블로그](https://tensorflow.blog/%EB%A8%B8%EC%8B%A0-%EB%9F%AC%EB%8B%9D%EC%9D%98-%EB%AA%A8%EB%8D%B8-%ED%8F%89%EA%B0%80%EC%99%80-%EB%AA%A8%EB%8D%B8-%EC%84%A0%ED%83%9D-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EC%84%A0%ED%83%9D-1/)
- [3.머신러닝의 주요 개념-모델 - Aiden](https://isme2n.github.io/devlog/2017/10/27/machine-learning-3/)
- [모델 학습 방법과 일반화 성능 - 인생의 굴레에서1](https://dragsoseumon.tistory.com/34)
---
## #27
#### 50개의 작은 의사결정 나무는 큰 의사결정 나무보다 괜찮을까요? 왜 그렇게 생각하나요?
50개의 작은 의사결정 나무는 앙상블에서 `Bagging` 기법을 사용한 모델로 볼 수 있다. 따라서 Bagging의 대표적인 방법인 `Random Forest` 방법이 왜 좋은지 설명하는 것으로, 왜 50개의 작은 의사결정 나무가 더 나은지 설명하고자 한다.

큰 트리는 작은 편향(bias)와 큰 분산(variance)를 갖기 때문에, 매우 깊이 성장한 트리는 훈련데이터에 대해 과적합(overfitting)하게 된다. Random Forest 방식으로 학습하면, 트리들의 편향은 그대로 유지하면서, **여러 데이터셋/여러 경우에 대해 학습하기 떄문에 분산을 감소**시킬 수 있다. 또한 한 개의 결정트리의 경우, train 데이터에 있는 노이즈에 대해 매우 민감하지만, 여러 트리들을 만들면서 평균을 내면, **노이즈에 대해 강인**해질 수 있다. 따라서 하나의 깊은/큰 의사결정 나무보다 50개의 작은 의사결정 나무가 더 좋은 모델을 완성시킨다고 할 수 있다.
> **Bagging(Bootstrap Aggregating)**
Bagging은 Bootstrap(반복, 복원추출)하고, 이를 Aggregation(집계)하는 방법이다. 원래 데이터셋에 대해서 여러개의 작은 데이터셋 N개를 샘플링해서 만든다음, 각각의 데이터를 작은 모델 N개로 학습을 시킨다. 그 다음 학습된 N개의 모델을 모두 하나로 합쳐서 최종적인 모델로 사용하는 방법론을 의미한다. 결국, 병렬적으로 데이터를 나누어 여러 개의 모델을 동시에 학습시키는 방법이다.
> **Random Forest**
Random Forest는 여러 의사 결정 나무를 생성한 후에 다수결(hard voting) 또는 평균(soft voting)에 따라 출력을 예측하는 알고리즘이다. 즉 의사 결정 나무와 bagging을 혼합한 형태라고 볼 수 있다. Random Forest의 특징은 bootstrap을 이용하여 학습 데이터셋에서 다양한 샘플을 추출하여 일부만 한번의 학습에 사용한다는 것이다. 데이터 샘플링 및 변수 선택을 통해 의사 결정 나무의 다양성을 확보할 수 있다. 이를 통해 예측의 변동성이 줄어들고, 과적합을 방지할 수 있어 결측치에 대해 강건하다는 장점을 가진다. 그러나 데이터의 수가 많아지면 의사결정나무에 비해 속도가 크게 떨어지고, 결과에 대한 해석이 어렵다는 단점이 있다.
#### References
- [Bagging, Boosting, Bootstrapping - 곽동현, New Sight](https://newsight.tistory.com/247)
- [Bagging(Bootstrap aggregating, 배깅)알고리즘 - InCastle](https://m.blog.naver.com/PostView.nhn?blogId=ysd2876&logNo=221219689884&proxyReferer=https:%2F%2Fwww.google.com%2F)
- [머신러닝: Random Forest 특징, 개념, 장점, 단점](https://jjeongil.tistory.com/908)
---
## #28
#### 스팸 필터에 Logistic Regression을 많이 사용하는 이유는 무엇일까요?
스팸 필터는 메일이 스팸 메일인지 아닌지에 대한 확률을 계산하여, 메일을 **분류(Classification)** 하는 문제이다. 로지스틱 회귀는 회귀를 바탕으로 데이터가 어떤 범주에 속할 확률을 0과 1 사이의 값으로 예측하고 그 확률에 따라 가능성이 더 높은 범주에 속하는 것으로 분류(Classification)해주는 지도 학습 알고리즘이다. 특히 **입력값이 아무리 크거나 작아도 0에서 1 사이의 값으로 맵핑**시킨다는 점에서 분류문제에 적합하다. 따라서 로지스틱 회귀가 스팸필터에 많이 사용된다.

> **분류문제에서 로지스틱 회귀가 적절한 이유**
로지스틱 회귀는 **시그모이드 함수(sigmoid function)** 를 통해 선형함수를 0과 1 사이의 함수로 바꾼 것이며, S자 형태를 보인다.
시그모이드 함수의 정의는 아래와 같다.
$$
S(x) = \frac{1}{1 + e^{-x}} = \frac{e^x}{e^x+1}
$$
로지스틱 회귀의 가설함수는 다음과 같다.
$$
H(X) = \frac{1}{1 + e^{-(Wx+b)}} = sigmoid(Wx+b) = \sigma (Wx+b)
$$
x값이 아무리 +, -로 작아지거나 커져도 항상 0과 1 사이의 값을 반환한다. 확률은 **0에서 1사이의 범위 내에 들어와야하므로** 이러한 형태가 적합하다.
이렇게 H(x)의 값이 0과 1사이로 나오면, 위의 Hypothesis 함수로 regression을 한 결과값이 threshold(ex.0.5) 이상인 경우엔 1로 분류하고, threshold 보다 작으면 0으로 분류하면 되기 떄문이다.
> **분류문제에서 선형회귀가 적합하지 않은 이유**
`그림1`과 같이 주어진 데이터를 표현하는 그래프를 그려, 적절한 지점을 기준으로 두 그룹으로 분류할 수 있다.
이때 `그림2`의 `new` 데이터가 새로 들어왔다고 해보자. 그래프는 새로운 데이터 `new`의 영향을 받아, 아래로 기울어진 형태로 업데이트되어, `그림3`의 붉은색 그래프 형태가 된다.
이렇게 되면, 원래는 1로 잘 분류되던 것들의 예측값이 기존 threshold 아래로 내려가게되어, 0으로 분류되어버리는 문제가 발생한다.

선형회귀 함수는 어떤 입력값이 들어오느냐에 따라 **0과 1 사이의 범위를 벗어나기도** 한다.
또한, `H(x) = 100x`라는 가설함수(Hypothesis function)이 있다고 하자. x가 0.01 이상인 경우는 모두 1로 x가 0 이하인 경우는 모두 0으로 분류하게 된다. 이처럼 **x값에 너무 민감하게 반응**하는 모델이 만들어질 수 있다. 연산상으로는 매우 작은 값만 바뀌어도 아예 분류자체가 바뀌어버린다.
더 나아가, 선형모델은 확률이 아닌, 점들의 보간(interpolate)만으로 이루어지므로 확률로 해석할 수 없다. 예측값이 확률이 아니기 때문에 한 클래스와 다른 **클래스를 구분할 수 있는 의미 있는 임계값이 없다.** 또한 다중 클래스를 가지는 분류문제로 확장할 수 없다는 문제점도 있다. 이러한 문제점들 때문에, 분류문제에서 선형 회귀 모델은 적합하지 못하다.
#### References
- [4.2 Logistic Regression - TooTouch](https://tootouch.github.io/IML/logistic_regression/)
- [5)로지스틱회귀 - 딥러닝을 이용한 자연어 처리 입문](https://wikidocs.net/22881)
- [모두를 위한 딥러닝(sung kim)lec5-Logistic Classification - cdjs의 코딩 공부방](https://cding.tistory.com/55)
---
## #29
#### OLS(ordinary least square) Regression의 공식은 무엇인가요?
**최소자승법(OLS, Ordinary Least Squares)** 이란, 산점도를 통해 데이터의 분포 그래프를 그릴때, 이 데이터들의 경향을 알기 위한 최적의 추세선을 그리기 위한 방법 중 하나이다. OLS는 근사적으로 구하려는 해와 실제 해의 오차의 제곱의 합이 최소가 되는 해를 구하는 방법이다.
OLS Regression은 회귀를 통해서 방정식의 상수 값들을 추정하는 데에 사용된다. n개의 입력값과 그에 대응하는 출력값 $(x_i, y_i)(1\leq i\leq n)$이 있고, 이 계의 방정식이 변수 $x$와 $\beta=(\beta_0, \beta_1, \cdots , \beta_k )$인 상수 $\beta$에 대한 식 $f(x, \beta)$으로 주어질 때, $\sum_i(y_i - f(x_i, \beta))^{2}$ 의 값을 최소로 만드는 $\beta$를 구하는 것이 문제의 목표이다.
추정하고자 하는 파라미터 β에 대한 표현식을 다음과 같이 구할 수 있다.
$$
{\hat {\beta}}=(\mathbf {X}^{\rm {T}}\mathbf {X})^{-1}\mathbf {X}^{\rm {T}}\mathbf {y} = {\big (} ~ {\textstyle \sum }\mathbf x_i \mathbf x_i^{\rm {T}}\,{\big )}^{-1}{\big (} ~ {\textstyle \sum }\mathbf x_i y_i ~ {\big)}
$$

예를들어, 7개 데이터의 경향을 나타내는 추세선을 `그림2`와 같이 그렸다고 하자.
이때 실제 데이터의 y값(실제값)과 추세선의 y값(예측값)의 차를 **잔차(Residual)** 라고 한다. (아래 그래프에서 잔차는 점선으로 표시)
최소자승법은 이 **잔차의 제곱의 합(RSS, Residual Sum of Squares)을 최소로 하는 (가중치 벡터를 구하는) 방법**이다.
잔차 제곱의 합은 `그림3`의 `TOTAL AREA`에 해당하는 넓이와 같다.
잔차 제곱의 합을 구하는 식은 아래와 같다.

파란색 추세선보다 보라색 추세선의 잔차제곱의 합이 더 작다. 따라서 파란색 추세선보다 보라색 추세선이 위 7개의 데이터를 더 잘 표현해주는 추세선임을 알 수 있다.
이렇게 잔차 제곱의 합을 최소로 하는 방법이 최소자승법이며, 최소자승법을 활용하여 데이터를 가장 잘 표현하는 선형 회귀선을 그릴 수 있다.
> **💡 OLS vs. MSE**
>
> - OLS(Ordinary Least Square): 선형 회귀 모델을 만들기 위한 선횡 최소 제곱법, 모델을 만들때 사용한다.
> - MSE(Mean Square Error): 모델 성능 평가 지표, 모델을 평가할 때 사용한다.
#### References
- [DATA-17.최소자승법(OLS)을 활용한 단순 선형 회귀 - 귀퉁이 서재](https://bkshin.tistory.com/entry/DATA-17-Regression)
- [선형회귀 - 위키백과](https://ko.wikipedia.org/wiki/%EC%84%A0%ED%98%95_%ED%9A%8C%EA%B7%80#Ordinary_least_squares)
- [최소제곱법 - 위키백과](https://ko.wikipedia.org/wiki/%EC%B5%9C%EC%86%8C%EC%A0%9C%EA%B3%B1%EB%B2%95)
- [데이터분석 9.회귀모형 - 집밖은 위험해 OTL](https://throwexception.tistory.com/943)
---
================================================
FILE: answers/3-deep-learning.md
================================================
> **📌 질문은 <strong>[zzsza님의 Datascience-Interview-Questions](https://github.com/zzsza/Datascience-Interview-Questions)</strong>를 참고하였습니다.**
## Table of Contents
- [딥러닝은 무엇인가요? 딥러닝과 머신러닝의 차이는?](#1)
- [Cost Function과 Activation Function은 무엇인가요?](#2)
- [Tensorflow, PyTorch 특징과 차이가 뭘까요?](#3)
- [Data Normalization은 무엇이고 왜 필요한가요?](#4)
- [알고있는 Activation Function에 대해 알려주세요. (Sigmoid, ReLU, LeakyReLU, Tanh 등)](#5)
- [오버피팅일 경우 어떻게 대처해야 할까요?](#6)
- [하이퍼 파라미터는 무엇인가요?](#7)
- [Weight Initialization 방법에 대해 말해주세요. 그리고 무엇을 많이 사용하나요?](#8)
- [볼츠만 머신은 무엇인가요?](#9)
- [TF, PyTorch 등을 사용할 때 디버깅 노하우는?](#10)
- [뉴럴넷의 가장 큰 단점은 무엇인가? 이를 위해 나온 One-Shot Learning은 무엇인가?](#11)
- [요즘 Sigmoid 보다 ReLU를 많이 쓰는데 그 이유는?](#12)
- [Non-Linearity라는 말의 의미와 그 필요성은?](#12-1)
- [ReLU로 어떻게 곡선 함수를 근사하나?](#12-2)
- [ReLU의 문제점은?](#12-3)
- [Bias는 왜 있는걸까?](#12-4)
- [Gradient Descent에 대해서 쉽게 설명한다면?](#13)
- [왜 꼭 Gradient를 써야 할까? 그 그래프에서 가로축과 세로축 각각은 무엇인가? 실제 상황에서는 그 그래프가 어떻게 그려질까?](#13-1)
- [GD 중에 때때로 Loss가 증가하는 이유는?](#13-2)
- [Back Propagation에 대해서 쉽게 설명 한다면?](#13-3)
- [Local Minima 문제에도 불구하고 딥러닝이 잘 되는 이유는?](#14)
- [GD가 Local Minima 문제를 피하는 방법은?](#14-1)
- [찾은 해가 Global Minimum인지 아닌지 알 수 있는 방법은?](#14-2)
- [Training 세트와 Test 세트를 분리하는 이유는?](#15)
- [Validation 세트가 따로 있는 이유는?](#15-1)
- [Test 세트가 오염되었다는 말의 뜻은?](#15-2)
- [Regularization이란 무엇인가?](#15-3)
- [Batch Normalization의 효과는?](#16)
- [Dropout의 효과는?](#16-1)
- [BN 적용해서 학습 이후 실제 사용시에 주의할 점은? 코드로는?](#16-2)
- [GAN에서 Generator 쪽에도 BN을 적용해도 될까?](#16-3)
- [SGD, RMSprop, Adam에 대해서 아는대로 설명한다면?](#17)
- [SGD에서 Stochastic의 의미는?](#17-1)
- [미니배치를 작게 할때의 장단점은?](#17-2)
- [모멘텀의 수식을 적어 본다면?](#17-3)
- [간단한 MNIST 분류기를 MLP+CPU 버전으로 numpy로 만든다면 몇줄일까?](#18)
- [어느 정도 돌아가는 녀석을 작성하기까지 몇시간 정도 걸릴까?](#18-1)
- [Back Propagation은 몇줄인가?](#18-2)
- [CNN으로 바꾼다면 얼마나 추가될까?](#18-3)
- [간단한 MNIST 분류기를 TF, PyTorch 등으로 작성하는데 몇시간이 필요한가?](#19)
- [CNN이 아닌 MLP로 해도 잘 될까?](#19-1)
- [마지막 레이어 부분에 대해서 설명 한다면?](#19-2)
- [학습은 BCE loss로 하되 상황을 MSE loss로 보고 싶다면?](#19-3)
- [딥러닝할 때 GPU를 쓰면 좋은 이유는?](#20)
- [GPU를 두개 다 쓰고 싶다. 방법은?](#20-1)
- [학습시 필요한 GPU 메모리는 어떻게 계산하는가?](#20-2)
---
## #1
#### 딥러닝은 무엇인가요? 딥러닝과 머신러닝의 차이는?
딥러닝이란 **여러 층을 가진 인공신경망(Artificial Neural Network, ANN)을 사용하여 머신러닝 학습을 수행하는 것**으로, 심층학습이라고도 부른다.
딥러닝은 엄밀히 말하자면 머신러닝에 포함되는 개념이다. 따라서 전통적인 머신러닝 기법과 딥러닝 기법의 차이를 설명하고자 한다.
(인공신경망, 퍼셉트론에 대한 내용은 [reference](http://tcpschool.com/deep2018/deep2018_deeplearning_intro)를 참고)
머신러닝과 딥러닝의 가장 큰 차이점은 다음과 같다. 기존 머신러닝에서는 학습하려는 데이터의 여러 특징 중에서 **어떤 특징을 추출할지 사람이 직접 분석하고 판단**해야하는 반면, 딥러닝에서는 기계가 **자동으로 학습하려는 데이터에서 특징을 추출**하여 학습하게 된다. 따라서 특징 추출에 사람이 개입(feature engineering)하면 머신러닝, 개입하지 않으면 딥러닝이다.
또한, 딥러닝은 머신러닝보다 큰 데이터셋과 긴 학습시간이 필요하다. 정형데이터는 주로 머신러닝, 비정형데이터는 주로 딥러닝 방식을 사용한다.
> **AI, ML, DL**

**인공지능이란** 인간이 가지고 있는 인식, 판단 등의 지적 능력을 모델링하여 컴퓨터에서 구현하는 것이다. 머신러닝, 딥러닝 외에도 다양한 분야가 인공지능 내에 포함된다.
**머신러닝이란** 데이터를 기반으로 패턴을 학습하고 결과를 예측하는 알고리즘 기법이다. 머신러닝은 조건이 복잡하고 규칙이 다양한 경우에, 데이터를 기반으로 일정한/숨겨진 패턴을 찾아내서 문제를 해결한다. 머신러닝의 단점은 데이터에 매우 의존적이라는 것이다. 즉, 좋은 품질의 데이터를 갖추지 못하면 머신러닝 수행결과도 좋지 않다는 것이다.
머신러닝은 아래와 같이 분류된다.
| 지도 학습 | 비지도 학습 |
| :---------------------------------------------------------------: | :----------------------------: |
| 분류, 회귀, 추천시스템<br/>시각/음성 인지(DL), 텍스트분석/NLP(DL) | 클러스터링, 차원축소, 강화학습 |
#### References
- [딥러닝, 데이터로 세상을 파악하다(1) - LG CNS](https://blog.lgcns.com/2212)
- [CH01)01.머신러닝의 개념 - 파이썬 머신러닝 완벽가이드(도서)](http://m.yes24.com/goods/detail/69752484)
- [9)딥러닝이란? - TCP SCHOOLS.com](http://tcpschool.com/deep2018/deep2018_deeplearning_intro)
---
## #2
#### Cost Function과 Activation Function은 무엇인가요?
> **cost function**
모델은 데이터에 대해 현재 예측을 얼마나 잘하고 있는지 알아야 학습 방향을 어느 방향으로, 얼마나 개선할지 판단할 수 있다.
이 때, 예측 값과 데이터 값의 차이에 대한 함수를 **cost function**(MSE, CrossEntropy 등) 이라고 한다.
**cost function** 을 최소화함으로써 모델을 적절한 표현력을 갖추도록 학습시킬 수 있다.
> **activation function**
데이터를 예측하기 위해 선형 모델을 사용할 수 있다. 하지만 선형 모델의 경우 복잡한 데이터에 대해서는 적절한 예측을 못한다. 따라서 이를 처리하기 위해 **비선형 모델**이 필요하다.
선형 모델을 비선형 모델로 만들어주는 역할을 하는 함수가 바로 활성화 함수 **activation function**(Sigmoid, ReLU 등) 이다.
비선형 함수인 활성화 함수가 선형 함수와 결합됨으로써 선형 모델은 비선형 모델이 된다.
선형 모델은 깊게 쌓을 수 없다. 깊게 쌓아도 하나의 층을 잘 튜닝한 것과 다르지 않기 때문이다.
비선형 모델은 깊게 쌓을 수 있다. 선형으로 만들었다가 비선형으로 만드는 작업을 계속 반복할 수 있기 때문이다. 이로 인해 모델은 복잡한 데이터에 대해 더 표현력이 좋아질 수 있다.
활성화 함수는 입력 값에 대해 더 높게 혹은 더 낮게 만들 수 있기 때문에 활성화 함수라고 불린다.
#### References
- [5. 결과 값을 비교하는 방식(Cost function) - 대소니](https://daeson.tistory.com/166)
- [Activation Functions에 대해 알아보자 - Steve-Lee's Deep Insight](https://deepinsight.tistory.com/113)
- [활성화 함수(activation function)을 사용하는 이유 - 프라이데이](https://ganghee-lee.tistory.com/30)
---
## #3
#### Tensorflow, PyTorch 특징과 차이가 뭘까요?
| 구분 | Tensorflow | PyTorch |
| :---------: | :----------------: | :-----------------: |
| 패러다임 | Define and Run | Define by Run |
| 그래프 형태 | Static graph(정적) | Dynamic graph(동적) |
Tensorflow와 Pytorch의 가장 큰 차이점은 딥러닝을 구현하는 패러다임이 다르다는 것이다. Tensorflow는 **Define-and-Run**인 반면에, Pytorch는 **Define-by-Run**이다.
<strong>Define and Run (Tensorflow)</strong>은 코드를 직접 돌리는 환경인 세션을 만들고, placeholder를 선언하고 이것으로 계산 그래프를 만들고(Define), 코드를 실행하는 시점에 데이터를 넣어 실행하는(Run) 방식이다. 이는 계산 그래프를 명확히 보여주면서 실행시점에 데이터만 바꿔줘도 되는 유연함을 장점으로 갖지만, 그 자체로 비직관적이다.
<strong>Define by Run (PyTorch)</strong>은 선언과 동시에 데이터를 집어넣고 세션도 필요없이 돌리면 되기때문에 코드가 간결하고 난이도가 낮은 편이다.
두 프레임워크 모두 계산 그래프를 정의하고 자동으로 그래디언트를 계산하는 기능이 있다. 하지만 Tensorflow의 계산 그래프는 정적이고 Pytorch는 동적이다.
즉 Tensorflow에서는 계산 그래프를 한 번 정의하고 나면 그래프에 들어가는 입력 데이터만 다르게 할 수 있을 뿐 같은 그래프만을 실행할 수 있다. 하지만 PyTorch는 각 순전파마다 새로운 계산 그래프를 정의하여 이용한다.

#### References
- [PyTorch - 위키백과](https://ko.wikipedia.org/wiki/PyTorch)
- [3. PyTorch VS TensorFlow - Dev](https://dev-jm.tistory.com/4)
---
## #4
#### Data Normalization은 무엇이고 왜 필요한가요?
**Data Normalization(데이터 정규화)이란** feature들의 분포(scale)을 조절하여 균일하게 만드는 방법이다. 데이터 정규화가 필요한 이유는 데이터 feature 간 scale 차이가 심하게 날 때, 큰 범위를 가지는 feature(ex. 가격)가 작은 범위를 가지는 feature(ex. 나이)보다 더 강하게 모델에 반영될 수 있기 때문이다.
즉, 데이터 정규화는 모든 데이터 포인트가 동일한 정도의 스케일(중요도)로 반영되도록 하는 역할을 수행하며, 아래와 같은 장점을 얻을 수 있다.
- 학습속도가 개선된다.
- 노이즈가 작아지므로 오버피팅을 억제시킨다.
- 데이터를 덜 치우치게 만드므로, 좋은 성능을 보인다.

> **Regularization, Normalization, Standardization**
**Regularization(정규화, 규제)** 란 모델에 제약(penalty)를 주어 모델의 복잡성을 낮추고, 이를 통해 오버피팅을 방지하는 방법이다. 제약을 사용하면 학습 정확도(train accuracy)는 조금 낮아질 수 있지만, 테스트 정확도(test accuracy)를 높일 수 있다. 정규화에는 `Drop out, Early Stopping, Weight decay(Parameter Norm Penalty)`와 같은 방법이 존재한다.
(자세한 Regularization 방법은 [reference](https://bsm8734.github.io/posts/bc-d012-3-dlbasic-optimization-regularization/) 참고)
**Normalization, Standardization**은 모두 데이터의 범위(scale)을 축소하는 방법이다.(re-scaling) 데이터의 범위 재조정이 필요한 이유는 `데이터의 범위가 너무 넓은 곳에 퍼져있을 때(scale이 크다면), 데이터셋이 outlier를 지나치게 반영`하여 오버피팅이 될 가능성이 높기 때문이다. 두 방법은 scale 조절 방식에 차이가 존재한다.
**Normalization(정규화)** 방법에는 Batch Normalization, Min-Max Normalization 등이 있다.
- `Batch Normalization`: 적용시키려는 레이어의 통계량, 분포를 정규화시키는 방법이다.
- `Min-Max Normalization`: 모든 데이터 중에서 가장 작은 값을 0, 가장 큰 값을 1로 두고, 나머지 값들은 비율을 맞춰서 모두 0과 1 사이의 값으로 스케일링하는 방법이다. 모든 feature들의 스케일이 동일하지만, 이상치(outlier)를 잘 처리하지 못한다. 식은 아래와 같다.
$$
x= {{x - x_{min}} \over {x_{max} - x_{min}}}
$$
**Standardization(표준화)** 란 표준화 확률변수를 구하는 방법이다. 이는 `z-score를 구하는 방법`을 의미한다. z-score normalization이라 불리기도 한다.
- `Z-score`: 관측값이 평균 기준으로 얼마나 떨어져있는지 나타낼 때 사용한다. 각 데이터에서 데이터 전체의 평균을 빼고, 이를 표준편차로 나누는 방식이다. 이상치(outlier)를 잘 처리하지만, 정확히 동일한 척도로 정규화 된 데이터를 생성하지는 않는다. 식은 아래와 같다.
$$
z-score = {{x-{\mu}} \over {\sigma}}
$$
#### References
- [딥러닝 기초 Optimization_Regularization - Sally blog](https://bsm8734.github.io/posts/bc-d012-3-dlbasic-optimization-regularization/)
- [머신 러닝\_Normalization, Standardization, Regularization 비교 - 프로그래밍 학습 블로그](https://m.blog.naver.com/qbxlvnf11/221476122182)
- [정규화(Normalization) 쉽게 이해하기 - 아무튼 워라벨](http://hleecaster.com/ml-normalization-concept/)
- [정규화(Normalization)의 목적과 방법들 - Deep Learning with Writing](https://mole-starseeker.tistory.com/31)
- [데이터 일반화 vs 표준화 (Normalization and Standardization of Data) - 컴퓨터와 수학, 몽상 조금](https://skyil.tistory.com/50)
---
## #5
#### 알고있는 Activation Function에 대해 알려주세요. (Sigmoid, ReLU, LeakyReLU, Tanh 등)
> **Sigmoid**

sigmoid 함수는 $s(z) = \frac{1}{1 + e^{-z}}$로, 입력을 0~1 사이의 값으로 바꿔준다.
입력 값이 크거나 작을 때 기울기가 0에 가까워지는 `saturation` 문제가 있다. 이는 `gradient vanishing` 문제를 야기하므로 요즘에는 활성화 함수로서 잘 사용되지 않는다.
또한 값이 `zero-centered` 가 아니기 때문에 입력값의 부호에 그대로 영향을 받으므로 경사하강법 과정에서 정확한 방향으로 가지 못하고 지그재그로 움직이는 문제가 있다. ([12-3 참고](#12-3))
> **Tanh**

tanh 함수는 입력을 -1~1 사이의 값으로 바꿔준다. sigmoid 함수와 마찬가지로 `saturation` 문제가 있다.
**> ReLU**

ReLU 함수는 $f(x) = max(0, x)$으로, 입력이 양수면 그대로, 음수면 0을 출력한다. 계산 효율과 성능에서 뛰어난 성능을 보여 가장 많이 사용되는 활성화 함수이다. 양의 입력에 대해서는 `saturation` 문제가 발생하지 않는다. 음의 입력 값에 대해서는 어떤 업데이트도 되지 않는 `Dead ReLU` 문제가 발생한다.
> **Leaky ReLU**

>
Leaky ReLU는 $f(x) = max(0.01x, x)$으로, ReLU 와 마찬가지로 좋은 성능을 유지하면서 음수 입력이 0이 아니게 됨에 따라 `Dead ReLU` 문제를 해결하였다.
#### References
- [Activation Functions에 대해 알아보자 - Steve-Lee's Deep Insight](https://deepinsight.tistory.com/113)
- [[신경망] 6. 활성화 함수 (Activation Function) - 분석벌레의 공부방](https://analysisbugs.tistory.com/55)
---
## #6
#### 오버피팅일 경우 어떻게 대처해야 할까요?
> **Early Stopping**
training loss는 계속 낮아지더라도 validation loss는 올라가는 시점을 overfitting으로 간주하여 학습을 종료하는 방법이다.

> **Parameter Norm Penalty / Weight Decay**
비용함수에 제곱을 더하거나($L_2 Regularization$) 절댓값을 더해서($L_1 Regularization$) weight의 크기에 페널티를 부과하는 방법을 말한다.
$$
total cost = loss(D ; W) + \frac{\alpha}{2} \lVert W \rVert^2_2
$$
> **Data augmentation**
훈련 데이터의 개수가 적을 때, 데이터에 인위적으로 변화를 주어 훈련 데이터의 수를 늘리는 방법이다.

> **Noise robustness**
노이즈나 이상치같은 엉뚱한 데이터가 들어와도 흔들리지 않는(robust 한) 모델을 만들기 위해 input data나 weight에 일부러 노이즈를 주는 방법을 말한다.

> **Label smoothing**
모델이 Ground Truth를 정확하게 예측하지 않아도 되게 만들어 주어 정확하지 않은 학습 데이터셋에 치중되는 경향(overconfident)을 막아주는 방법이다.
> **Dropout**
각 계층 마다 일정 비율의 뉴런을 임의로 정해 drop 시키고 나머지 뉴런만 학습하도록 하는 방법을 말한다. 매 학습마다 drop 되는 뉴런이 달라지기 때문에 서로 다른 모델들을 앙상블 하는 것과 같은 효과가 있다. dropout은 **학습 시에만 적용**하고, 추론 시에는 적용하지 않는다.

> **Batch normalization**
활성화함수의 활성화값 또는 출력값을 정규화하는 방법이다. 각 hidden layer에서 정규화를 하면서 입력분포가 일정하게 되고, 이에 따라 Learning rate을 크게 설정해도 괜찮아진다. 결과적으로 학습속도가 빨라지는 효과가 있다.

#### References
- [인공신경망 ( ANN ) #6-3 최적화 : 오버피팅 방지( weight decay, droupout ) / 하이퍼파라미터 최적화 - 엄범](https://umbum.dev/222)
- [딥러닝6. Dropout & Early stopping을 통한 최적화 - 살아가는동안](https://m.blog.naver.com/jeonghj66/222004874975)
- [[딥러닝개념] 딥러닝 효과적으로 학습하기(2) (ft. regularization) - WE GONNA MAKE IT](https://wegonnamakeit.tistory.com/9)
- [[Label Smoothing] 요약 정리 - Computer Vision :)](https://cvml.tistory.com/9)
- [문과생도 이해하는 딥러닝 (10) - 배치 정규화 - 데이터 분석하는 문과생, 싸코](https://sacko.tistory.com/44)
---
## #7
#### 하이퍼 파라미터는 무엇인가요?
하이퍼 파라미터(Hyper-parameter)는 모델링할 때, **사용자가 직접 세팅해주는 값**을 뜻한다. 하이퍼 파라미터는 정해진 최적의 값이 없으며, 사용자의 선험적 지식을 기반으로 설정(휴리스틱)한다. 예를들어 딥러닝의 하이퍼 파라미터에는 학습률, 배치 사이즈 등이 있고, 가중치는 학습 과정에서 바뀌는 값이며 이는 파라미터에 속한다. 하이퍼 파라미터 튜닝 기법에는 Manual Search, Grid Search, Random Search, Bayesian Optimization 등이 있다. 딥러닝에서의 하이퍼 파라미터는 아래의 그림을 참고한다.

> **파라미터 vs 하이퍼 파라미터**
파라미터와 하이퍼 파라미터를 구분하는 기준은 사용자가 직접 설정하느냐 아니냐이다. **사용자가 직접 설정하면 하이퍼 파라미터, 모델 혹은 데이터에 의해 결정되면 파라미터**이다.
딥러닝에서 하이퍼 파라미터는 `학습률, 배치 크기, 은닉층의 개수` 등이 있고, 파라미터는 `가중치, 편향` 등이 있다.

> **용어 정리**
- 선험적 지식: 경험하지 않아도 알 수 있는 것을 말한다.
- 휴리스틱: 체계적이면서 합리적인 판단이 굳이 필요하지 않은 상황에서 사람들이 빠르게 사용할 수 있도록, 보다 용이하게 구성된 간편추론의 방법이다. '대충 어림짐작하기', '눈대중으로 맞추기' 등의 방법을 일컫는다.
#### References
- [13.파라미터(Parameter)와 하이퍼 파라미터(Hyper parameter) - 귀퉁이 서재](https://bkshin.tistory.com/entry/%EB%A8%B8%EC%8B%A0%EB%9F%AC%EB%8B%9D-13-%ED%8C%8C%EB%9D%BC%EB%AF%B8%ED%84%B0Parameter%EC%99%80-%ED%95%98%EC%9D%B4%ED%8D%BC-%ED%8C%8C%EB%9D%BC%EB%AF%B8%ED%84%B0Hyper-parameter)
- [하이퍼파라미터(Hyperparameter) - 도리의 디지털라이프](http://blog.skby.net/%ED%95%98%EC%9D%B4%ED%8D%BC%ED%8C%8C%EB%9D%BC%EB%AF%B8%ED%84%B0-hyperparameter/)
---
## #8
#### Weight Initialization 방법에 대해 말해주세요. 그리고 무엇을 많이 사용하나요?
딥러닝에서 가중치를 잘 초기화하는 것은 기울기 소실이나 local minima 등의 문제를 야기할 수 있기 때문에 중요하다.
> **LeCun Initialization**
딥러닝의 대가 LeCun 교수님이 제시한 초기화 방법으로 들어오는 노드 수에 대해 정규 분포와 균등 분포를 따르는 방법이 있다.
- **정규 분포를 따르는 방법**
$$
W \sim N(0, Var(W)), \quad Var(W) = \sqrt{\frac{1}{n_{in}}}
$$
- **균등 분포를 따르는 방법**
$$
W \sim U(- \sqrt{\frac{1}{n_{in}}}, + \sqrt{\frac{1}{n_{in}}})
$$
> **Xavier Initialization**
LeCun 방법과 비슷하지만 들어오는 노드 수와 나가는 노드 수에 의존하고, 적절한 상수값도 발견하여 사용한 방법이다.
- **정규 분포를 따르는 방법**
$$
W \sim N(0, Var(W)), \quad Var(W) = \sqrt{\frac{2}{n_{in} + n_{out}}}
$$
- **균등 분포를 따르는 방법**
$$
W \sim U(- \sqrt{\frac{6}{n_{in} + n_{out}}}, + \sqrt{\frac{6}{n_{in} + n_{out}}})
$$
sigmoid 나 tanh 함수와는 좋은 결과를 보여주지만 ReLU 함수와 사용할 경우 0에 수렴하는 문제가 발생한다.
따라서 `sigmoid` 나 `tanh` 함수와 주로 많이 사용한다.
> **He Initialization**
`ReLU` 와 함께 많이 사용되는 방법으로, LeCun 방법과 같지만 상수를 다르게 하였다. 들어오는 노드만 고려한다.
- **정규 분포를 따르는 방법**
$$
W \sim N(0, Var(W)), \quad Var(W) = \sqrt{\frac{2}{n_{in}}}
$$
- **균등 분포를 따르는 방법**
$$
W \sim U(- \sqrt{\frac{6}{n_{in}}}, + \sqrt{\frac{6}{n_{in}}})
$$
#### References
- [가중치 초기화 (Weight Initialization) - reniew's blog](https://reniew.github.io/13/)
---
## #9
#### 볼츠만 머신은 무엇인가요?
볼츠만 머신은 가시층(Visible Layer)와 은닉층(Hidden Layer), 총 두 개의 층으로 신경망을 구성하는 방법이다.
볼츠만 머신은 모든 뉴런이 연결되어 있는 완전 그래프 형태이며, 제한된 볼츠만 머신(RBM)에서는 같은 층의 뉴런들은 연결되어 있지 않은 모양이다.
기본적으로 단층구조이며, 확률 모델이다. 분류나 선형 회귀 분석 등에 사용될 수 있다.
특히 DBN(Deep Belief Network)에서는 RBM들을 쌓아올려, 각 볼츠만 머신을 순차적으로 학습시킨다.

<div align='center'>
<img src="">
</div>
<br/>
색깔 별 cell의 역할은 아래와 같다.

#### References
- [Interview Question & Answer 출근 루틴, 하루 3문제 - YongWook](https://yongwookha.github.io/MachineLearning/2021-01-29-interview-question)
- [Restricted Boltzmann Machine - 공돌이의 수학정리노트](https://angeloyeo.github.io/2020/10/02/RBM.html)
---
## #10
#### TF, PyTorch 등을 사용할 때 디버깅 노하우는?
오류가 발생하는 곳, 중요한 데이터가 바뀌는 지점을 디버깅 포인트로 두고, 확인하는 방법이 있다. 또, IDE에서 다양한 디버깅 extension을 지원하기 때문에 이를 잘 활용하면 좋은 인사이트를 얻을 수 있다. 예를들어, vs code의 jupyter extension을 사용하면 데이터 프레임, 변수값등을 보기 쉽게 정렬하여 확인할 수 있다.
디버깅 노하우도 중요하지만, 오류에 대한 대처방식을 익히면 좋다. 디버깅 하지 않고 오류에 대처할 수 있으므로, 디버깅 시간을 아껴준다. 예를들어, 딥러닝 학습을 위한 코드를 작성할 때, 가장 많이 발생하는 오류는 CUDA out of memory와 shape 오류이다.(개인적인 의견) out of memory와 같은 오류는 배치 사이즈를 줄인다거나, 입력 데이터의 사이즈를 줄이는 방식으로 해결할 수 있다. shape 오류는 디버깅을 통해서 현재 입력 데이터의 shape, type등을 확인하고, 함수의 파라미터가 요구하는 shape, type에 맞게 변형하는 과정이 필요하다.
추가적으로 딥러닝 디버깅 툴은 아니지만, logging tool로서 tensorboard, wandb 등이 매우 유용하게 사용될 수 있다.
---
## #11
#### 뉴럴넷의 가장 큰 단점은 무엇인가? 이를 위해 나온 One-Shot Learning은 무엇인가?
사람은 처음 보는 물건 (새 레이블) 에 대해 조금만 봐도 다른 것과 이 물건을 구분해낼 수 있다. 하지만 뉴럴넷은 이 물건을 구분해내기 위해서는 이 물건에 대한 많은 데이터를 학습해야한다.
**One-shot Learning** 은 뉴럴넷도 새로운 레이블을 지닌 데이터가 적을 때 (one-shot 에서는 한 개) 에도 모델이 좋은 성능을 내도록 사용되는 방법이다.
이를 위해서는 기존에 다른 레이블의 많은 데이터를 학습하여 데이터의 특성을 잘 이해하는 **pretrained** 모델이 필요하다.
학습된 모델에 새로운 레이블의 데이터 하나 던져 주면 모델은 데이터의 특성에 대한 이해를 바탕으로 이 레이블에 대해서도 이해를 하게 된다.
#### References
- [One-shot learning (siamese network) - sji](https://aimaster.tistory.com/48)
- [One shot learning, Siamese Network 이해 - Deep Play](https://3months.tistory.com/507)
---
## #12
#### 요즘 sigmoid 보다 ReLU를 많이 쓰는데 그 이유는?

우선 sigmoid와 ReLU 함수의 모양을 보자. sigmoid는 값이 큰 양수일수록 1에, 큰 음수일수록 0에 가까워진다. 반면 ReLU는 값이 양수이면 원래 값을 그대로 가져가고, 음수이면 0이다.
요즘 sigmoid보다 ReLU를 많이 쓰는 가장 큰 이유는 **기울기 소실 문제(Gradient Vanishing)** 때문이다. 기울기는 연쇄 법칙(Chain Rule)에 의해 국소적 미분값을 누적 곱을 시키는데, sigmoid의 경우 기울기가 항상 0과 1사이의 값이므로 이 값을 연쇄적으로 곱하게 되면 0에 수렴할 수 밖에 없다. 반면 ReLU는 값이 양수일 때, 기울기가 1이므로 연쇄 곱이 1보다 작아지는 것을 어느 정도 막아줄 수 있다.
다만, ReLU는 값이 음수이면, 기울기가 0이기 때문에 일부 뉴런이 죽을 수 있다는 단점이 존재한다. 이를 보완한 활성화 함수로 Leaky ReLU가 있다.
#### References
- [ML — sigmoid 대신 ReLU? 상황에 맞는 활성화 함수 사용하기 - Minkyeong Kim](https://medium.com/@kmkgabia/ml-sigmoid-%EB%8C%80%EC%8B%A0-relu-%EC%83%81%ED%99%A9%EC%97%90-%EB%A7%9E%EB%8A%94-%ED%99%9C%EC%84%B1%ED%99%94-%ED%95%A8%EC%88%98-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0-c65f620ad6fd)
- [[히스] Gradient Vanishing 해결을 위한 ReLU 와 ResNet - boostcamp-ai-tech-4/peer-session](https://github.com/boostcamp-ai-tech-4/peer-session/issues/52)
- [딥러닝에서 사용하는 활성화함수 - reniew's blog](https://reniew.github.io/12/)
---
## #12-1
#### Non-Linearity라는 말의 의미와 그 필요성은?
비선형(non-linearity)의 뜻을 알기 위해서는 우선 선형(linearity)가 무엇인지 알아야 한다. 어떤 모델이 선형적(linearity)라고 한다면 그 모델은 변수 $x_1, x_2, ... , x_n$과 가중치 $w_1, w_2, ... , w_n$으로 $y = w_1 * x_1 + w_2 * x_2 + ... + w_n * x_n$으로 표현할 수 있으며, 가산성(Additreivityly)과 동차성(Homogeneity)을 만족해야 한다.
- **가산성**: 임의의 수 $x, y$에 대해 $f(x+y) = f(x) + f(y)$가 성립
- **동차성**: 임의의 수 $x, \alpha$에 대해 $f(\alpha x) = \alpha f(x)$가 성립
이를 만족하지 못하는 모델을 비선형 관계에 있는 모델이라고 한다.
딥러닝에서 이런 비선형 관계는 활성화 함수(activation function)을 도입함으로써 표현할 수 있다. 그럼 비선형 관계 즉, 활성화 함수가 왜 필요할까? 바로 **활성화 함수를 사용해 여러 층을 쌓아서 더 복잡한 표현을 하기 위해서**이다. 활성화 함수가 $h(x) = cx$인 선형 함수라고 생각해보자. 이 때 $n$개의 층을 쌓았다고 할 때, 모델은 $y = h^n(x) = c^nx$로 나타낼 수 있다. $c^n=k$라는 상수로 치환하면 결국 1층을 가진 신경망과 동일하다. 그렇기 때문에 비선형인 활성화 함수가 필요한 것이다.
#### References
- [[밑바닥 딥러닝] 신경망 - 코딩하는펭귄의 저장소](https://cooding-penguin.netlify.app/dl-from-scratch/neural-network/#%EB%B9%84%EC%84%A0%ED%98%95-%ED%95%A8%EC%88%98)
- [선형성 - 위키백과](https://ko.wikipedia.org/wiki/%EC%84%A0%ED%98%95%EC%84%B1)
---
## #12-2
#### ReLU로 어떻게 곡선 함수를 근사하나?
ReLU는 양수일 때 <!-- $y=x$ --> <img style="transform: translateY(0.1em); background: white;" src="https://render.githubusercontent.com/render/math?math=y%3Dx">인 선형 함수와 음수일 때 <!-- $y=0$ --> <img style="transform: translateY(0.1em); background: white;" src="https://render.githubusercontent.com/render/math?math=y%3D0">인 선형 함수 두 개를 결합된 형태이다. 그렇지만 ReLU는 선형 함수가 갖는 가산성을 만족하지 못하기 때문에 비선형 함수로 볼 수 있다. 하지만 ReLU가 어떻게 곡선 함수를 근사할 수 있을까?

ReLU를 여러 개 결합하면, 특정 지점에서 특정 각도만큼 선형 함수를 구부릴 수 있다. 이 성질을 이용하여 곡선 함수 뿐만 아니라 모든 함수에 근사를 할 수 있게 된다.
#### References
- [활성화 함수(Activation function) 설명 (Sigmoid, ReLU, LeakyReLU, tanh) - 별보는두더지](https://mole-starseeker.tistory.com/m/39)
- [Q2) Sigmoid 보다 ReLu를 많이 쓰는 이유? - JINSOL KIM](https://gaussian37.github.io/math-question-q2/)
- [How do ReLU Neural Networks approximate any continuous function? - towards data science](https://towardsdatascience.com/how-do-relu-neural-networks-approximate-any-continuous-function-f59ca3cf2c39)
- [Finally, an intuitive explanation of why ReLU works](https://towardsdatascience.com/if-rectified-linear-units-are-linear-how-do-they-add-nonlinearity-40247d3e4792)
---
## #12-3
#### ReLU의 문제점은?
ReLU의 가장 큰 문제점은 바로 <strong>죽은 뉴런(Dead Neurons)</strong>이다. ReLU는 결과값이 음수인 경우 모두 0으로 취급하는데, back propagation시 기울기에 0이 곱해져 해당 부분의 뉴런은 죽고 그 이후의 뉴런 모두 죽게 된다. 이를 해결한 Leaky ReLU는 값이 음수일 때 조금의 음의 기울기를 갖도록 하여 뉴런이 조금이라도 기울기를 갖도록 한다. 또 다른 방법으로는 입력값에 아주 조금의 편향(bias)를 주어 ReLU를 왼쪽으로 조금 이동시키는 방법이 있다. 이렇게 되면 입력값은 모두 양수이므로 뉴런이 모두 활성화가 되어 뉴런이 죽지 않는다. 관련 내용은 [CS231n 6강 16:45](https://youtu.be/wEoyxE0GP2M?t=1005)를 참고!
두 번째 문제는 <strong>편향 이동(Bias Shift)</strong>이다. ReLU는 항상 0이상의 값을 출력하기 때문에 활성화값의 평균이 0보다 커 zero-centered하지 않다. 활성화값이 zero-centered되지 않으면 가중치 업데이트가 동일한 방향으로만 업데이트가 돼서 학습 속도가 느려질 수가 있다. 관련 내용은 [CS231n 6강 8:46](https://youtu.be/wEoyxE0GP2M?t=526)을 참고!

이를 해결하기 위해 배치 정규화(Batch Normalization)을 사용하거나 zero-centered된 ELU, SeLU와 같은 활성화 함수를 사용한다.
#### References
- [Neural Network - Machine Learning Blog](https://nmhkahn.github.io/NN)
- [What are the disadvantages of using the ReLu when using Neural Networks? - Quora](https://www.quora.com/What-are-the-disadvantages-of-using-the-ReLu-when-using-Neural-Networks)
- [05-1. 심층 신경망 학습 - 활성화 함수, 가중치 초기화 EXCELSIOR](https://excelsior-cjh.tistory.com/177)
- [computer-vision-study-2020s/week3/week3.md - CoodingPenguin/computer-vision-study-2020s](https://github.com/CoodingPenguin/computer-vision-study-2020s/blob/master/week3/week3.md#lecture-6)
- [Activation Functions in Neural Networks - Kshitij Khurana](https://medium.com/@kshitijkhurana3010/activation-functions-in-neural-networks-ed88c56b611b)
- [A Gentle Introduction to the Rectified Linear Unit (ReLU)](https://machinelearningmastery.com/rectified-linear-activation-function-for-deep-learning-neural-networks/)
---
## #12-4
#### 편향(bias)는 왜 있는걸까?

편향(bias)는 활성화 함수가 왼쪽 혹은 오른쪽으로 이동한다. 가중치(weight)는 활성화 함수의 가파른 정도 즉, 기울기를 조절하는 반면, 편향(bias)는 **활성화 함수를 움직임으로써 데이터에 더 잘 맞도록 한다.**
#### References
- [Glossary of Deep Learning: Bias - Jaron Collis](https://medium.com/deeper-learning/glossary-of-deep-learning-bias-cf49d9c895e2)
- [What is the role of the bias in neural networks? - stackoverflow](https://stackoverflow.com/questions/2480650/what-is-the-role-of-the-bias-in-neural-networks)
---
## #13
#### Gradient Descent에 대해서 쉽게 설명한다면?
Gradient Descent는 어떤 함수의 극소점을 찾기 위해 gradient 반대 방향으로 이동해 가는 방법이다.

딥러닝에서는 Loss function을 최소화시키기 위해 파라미터에 대해 Loss function을 미분하여 그 기울기값(gradient)을 구하고, 경사가 하강하는 방향으로 파라미터 값을 점진적으로 찾기위해 사용된다.
Gradient Descent를 수식으로 표현하면 아래와 같다.
$$
W_{t+1} \leftarrow W_t - \eta g_t
$$
Gradient Descent의 문제점으로는 크게 두 가지가 있다.
첫 번째로 적절한 <strong>step size(learning rate)</strong>가 필요하다. step size가 큰 경우 한 번 이동하는 거리가 커지므로 빠르게 수렴할 수 있다는 장점이 있다. 하지만, step size를 너무 크게 설정해버리면 최소값을 계산하도록 수렴하지 못하고 함수 값이 계속 커지는 방향으로 최적화가 진행될 수 있다.
한편 step size가 너무 작은 경우 발산하지는 않을 수 있지만 최적의 x를 구하는데 소요되는 시간이 오래 걸린다는 단점이 있다.

두 번째로 **local minima 문제**이다. gradient descent 알고리즘을 시작하는 위치는 매번 랜덤하기 때문에 어떤 경우에는 local minima에 빠져 계속 헤어나오지 못하는 경우도 생긴다. (자세한 내용은 [#14-1. GD가 Local Minima 문제를 피하는 방법은?](#14-1) 참고)

#### References
- [경사하강법(gradient descent) - 공돌이의 수학정리노트](https://angeloyeo.github.io/2020/08/16/gradient_descent.html)
- [Gradient Descent 탐색 방법 - 다크 프로그래머](https://darkpgmr.tistory.com/133)
---
## #13-1
#### 왜 꼭 Gradient를 써야 할까? 그 그래프에서 가로축과 세로축 각각은 무엇인가? 실제 상황에서는 그 그래프가 어떻게 그려질까?

Gradient가 양수이면 올라가는 방향이며 음수이면 내려가는 방향이다. 실제 상황에서는 Gradient 그래프가 0을 중심으로 진동하는 모양이 될 것이다.
#### References
- [Interview Question & Answer 출근 루틴, 하루 3문제 - YongWook](https://yongwookha.github.io/MachineLearning/2021-01-29-interview-question)
---
## #13-2
#### GD 중에 때때로 Loss가 증가하는 이유는?

minima에 들어갔다가 나오는 경우일 것이다. 실제로 사용되는 GD에서는 local minima 문제를 피하기 위해 Momentum 등의 개념을 도입한 RMSprop, Adam 등의 optimization 전략을 사용한다.
각 optimization 전략에 따라 gradient가 양수인 방향으로도 parameter update step을 가져가는 경우가 생길 수 있으며, 이 경우에는 Loss가 일시적으로 증가할 수 있다.
(자세한 내용은 [#17. SGD, RMSprop, Adam에 대해서 아는대로 설명한다면?](#17) 참고)
#### References
- [Interview Question & Answer 출근 루틴, 하루 3문제 - YongWook](https://yongwookha.github.io/MachineLearning/2021-01-29-interview-question)
---
## #13-3
#### Back Propagation에 대해서 쉽게 설명 한다면?
역전파 알고리즘은 Loss에 대한 입력값의 기울기(미분값)를 출력층 layer에서부터 계산하여 거꾸로 전파시키는 것이다.
이렇게 거꾸로 전파시켜서 최종적으로 출력층에서의 output값에 대한 입력층에서의 input data의 기울기 값을 구할 수 있다.
이 과정에서 **chain rule**이 이용된다.
출력층 바로 전 layer에서부터 기울기(미분값)을 계산하고 이를 점점 거꾸로 전파시키면서 전 layer들에서의 기울기와 서로 곱하는 형식으로 나아가면 최종적으로 출력층의 output에 대한 입력층에서의 input의 기울기(미분값)을 구할 수가 있다. 이를 그림으로 나타내면 아래와 같다.

역전파 알고리즘이 해결한 문제가 바로 파라미터가 매우 많고 layer가 여러개 있을때 가중치w와 b를 학습시키기 어려웠다는 문제이다.
이는 역전파 알고리즘으로 각 layer에서 기울기 값을 구하고 그 기울기 값을 이용하여 Gradient descent 방법으로 가중치w와 b를 update시키면서 해결되었다.
#### References
- [딥러닝 역전파 backpropagation이란? - 프라이데이](https://ganghee-lee.tistory.com/31)
- [3.14. 순전파(forward propagation), 역전파(back propagation), 연산 그래프 - Dive into Deep Learning](https://ko.d2l.ai/chapter_deep-learning-basics/backprop.html)
---
## #14
#### Local Minima 문제에도 불구하고 딥러닝이 잘 되는 이유는?
local minima 문제가 사실은 고차원(High Dimensional)의 공간에서는 발생하기 힘든, 매우 희귀한 경우이기 때문이다. 실제 딥러닝 모델에서는 weight가 수도없이 많으며, 그 수많은 weight가 모두 local minima에 빠져야 weight update가 정지되기 때문에 local minima는 큰 문제가 되지 않는다.
> **Local Minima 문제에도 불구하고 딥러닝이 잘 되는, 더 구체적인 이유**
고차원의 공간에서 모든 축의 방향으로 오목한 형태가 형성될 확률은 거의 0에 가깝다. 따라서, 고차원의 공간에서 대부분의 critical point는 local minima가 아니라 saddle point다. 그리고, 고차원의 공간에서 설령 local minima가 발생한다 하더라도 이는 global minimum이거나 또는 global minimum과 거의 유사한 수준의 에러 값을 갖는다. 왜냐하면, critical point에 포함된 위로 볼록인 방향 축의 비율이 크면 클수록 높은 에러를 가지기 때문이다.(실험적 결과) local minima는 위로 볼록인 경우가 하나도 없는 경우이기 때문에 결과적으로 매우 낮은 에러를 갖게 될 것이다.

> **Critical point, Saddle point, Local minimum**

- `critical point`: 일차 미분이 0인 지점이다. (local/global)minima, (local/global)maxima, saddle point를 가리킴
- `local minimum`: 모든 방향에서 극소값을 만족하는 점
- `global minimum`: 모든 방향에서 극소값을 만족하는 점 중에 가장 값이 작은 점(정답)
- `saddle point`: 어느 방향에서 보면 극대값이지만 다른 방향에서 보면 극소값이 되는 점
#### References
- [NeuralNetwork (3) Optimazation2 - Cornor's Blog](<https://wjddyd66.github.io/dl/NeuralNetwork-(3)-Optimazation2/>)
- [Local Minima 문제에 대한 새로운 시각 - 다크 프로그래머](https://darkpgmr.tistory.com/148)
- [05-1.심층 신경망 학습-활성화 함수, 가중치 초기화 - EXCELSIOR](https://excelsior-cjh.tistory.com/177)
---
## #14-1
#### GD(Gradient Descent)가 Local Minima 문제를 피하는 방법은?
Local minima 문제를 피하는 방법으로는 **Momentum, Nesterov Accelerated Gradient(NAG), Adagrad, Adadelta, RMSprop, Adam** 등이 있다.
**SGD**는 Stochastic Gradient Descent으로, 하나 혹은 여러개의 데이터를 확인한 후에 어느 방향으로 갈 지 정하는 가장 기초적인 방식이다.
**Momentum**이란 관성을 의미하며, 이전 gradient의 방향성을 담고있는 `momentum` 인자를 통해 흐르던 방향을 어느 정도 유지시켜 local minima에 빠지지 않게 만든다. 즉, 관성을 이용하여, 학습 속도를 더 빠르게 하고, 변곡점을 잘 넘어갈 수 있도록 해주는 역할을 수행한다.

**Nesterov Accelerated Gradient(NAG)** 는 모멘텀과 비슷한 역할을 수행하는 `Look-ahead gradient `인자를 포함하여, $a$ 라는 `accumulate gradient`가 gradient를 감소시키는 역할을 한다. 모멘텀과 다른 점은, 미리 한 스텝을 옮겨가본 후에 어느 방향으로 갈지 정한다는 것이다.
**Adagrad**란 뉴럴넷의 파라미터가 많이 바뀌었는지 적게 바뀌었는지 확인하고, 적게 변한건 더 크게 변하게 하고, 크게 변한건 더 작게 변화시키는 방법이다. Adagrad는 `sum of gradient squares`($G_t$)를 사용하는데, 이는 그래디언트가 얼만큼 변했는지를 제곱해서 더하는 것이므로 계속 커진다는 문제가 발생한다. $G_t$가 계속 커지면 분모가 점점 무한대에 가까워지게 되어, $W$ 업데이트가 되지 않게 되어, 뒤로 갈수록 학습이 점점 안되는 문제점이 발생한다.

**Adadelta**는 `Exponential Moving Average(EMA)`를 사용하여, Adagrad의 $G_t$가 계속 커지는 현상을 막을 수 있다. EMA는 현재 타임스텝으로부터 `윈도우 사이즈만큼의 파라미터 변화(그래디언트 제곱의 변화)를 반영`하는 역할을 하는데, 이전의 값을 모두 저장하는 것이 아닌, `이전 변화량에 특정 비율을 곱해 더한 인자`를 따로 두는 방식이다. Adadelta는 learning rate가 없다.

(**Momentum**의 더 자세한 내용은 [모멘텀의 수식을 적어 본다면?](#17-3) 참고)
(**SGD, RMSprop, Adam**에 대한 설명은 [SGD, RMSprop, Adam에 대해서 아는대로 설명한다면?](#17) 참고)
#### References
- [딥러닝 기초 Optimization-Gradient Descent Methods - Sally blog](https://bsm8734.github.io/posts/bc-d012-2-dlbasic-optimization-gradient-descent-methods/)
- [NeuralNetwork (3) Optimazation2 - Cornor's Blog](<https://wjddyd66.github.io/dl/NeuralNetwork-(3)-Optimazation2/>)
---
## #14-2
#### 찾은 해가 Global Minimum인지 아닌지 알 수 있는 방법은?
Gradient Descent 방식에서 local minima에 도달함은 증명되어있으나, global minima에 도달하는 것은 보장되지 않았다. 또한, 현재 지점이 global minima인지도 알 수 없다. 딥러닝에서 다루는 문제가 convexity를 만족하지 않기 때문이다. 대신, local minima를 찾는다면, 그 지점이 곧 global minima일 가능성이 크다. [Local Minima 문제에도 불구하고 딥러닝이 잘 되는 이유는?](#14)에서 언급했듯, saddle point가 아닌 완전한 local minimum이 발생하는 경우는 희귀하다. 따라서 모든 방향에서 아래로 볼록인 local minima를 발견한다면, 그 지점이 바로 global minima일 가능성이 높다.
#### References
- [Local Minima 문제에 대한 새로운 시각 - 다크 프로그래머](https://darkpgmr.tistory.com/148)
- [0021 Gradient Descent & Momentum - Deepest Documentation](https://deepestdocs.readthedocs.io/en/latest/002_deep_learning_part_1/0021/)
---
## #15
#### Training 세트와 Test 세트를 분리하는 이유는?
모델은 데이터에 대해 예측값을 만들고 정답과 비교하며 업데이트되면서 학습이 된다. 그런데 학습 데이터에 대해서는 좋은 성능을 낸다 하더라도 본 적 없는 데이터에 대해서는 잘 대응하지 못하는 **오버피팅** 문제가 생긴다면 좋은 모델이 아니다.
이를 막기 위해 학습된 모델이 처음 보는 데이터에도 강건하게 성능을 내는지 판단하기 위한 수단으로 test 세트를 따로 만든다.
#### References
- [test와 validation - ML Basics](https://wikidocs.net/31019)
---
## #15-1
#### Validation 세트가 따로 있는 이유는?
모델을 학습시키고 test 데이터를 통해 모델의 일반화 성능을 파악하고, 다시 모델에 새로운 시도를 하고 test 데이터를 통해 모델의 성능을 파악한다고 생각해보자.
이 경우, 모델은 결국 test 데이터에도 오버피팅이 되어 다시 처음 보는 데이터를 주면 좋은 성능을 보장할 수 없게 된다.
이 문제를 막기 위해 validation 세트를 사용한다. validation 세트를 통해 모델의 성능을 평가하고 하이퍼파라미터 등을 수정하는 것이다.
즉, train 데이터로 모델을 학습시키고 valid 데이터로 학습된 모델의 성능 평가를 하고 더 좋은 방향으로 모델을 수정한다. 그리고 최종적으로 만들어진 모델로 test 데이터를 통해 최종 성능을 평가한다.
#### References
- [test와 validation - ML Basics](https://wikidocs.net/31019)
---
## #15-2
#### Test 세트가 오염되었다는 말의 뜻은?
test 데이터는 한 번도 학습에서 본 적 없는 데이터여야 한다. 그런데 train 데이터가 test 데이터와 흡사하거나 포함되기까지한다면 test 데이터는 더이상 학습된 모델의 성능 평가를 객관적으로 하지 못한다.
이렇듯 test 데이터가 train 데이터와 유사하거나 포함된 경우에 test 세트가 오염되었다고 말한다.
#### References
- [7. Data Leakage - 분리수거장](https://m.blog.naver.com/hongjg3229/221811766581)
---
## #15-3
#### Regularization이란 무엇인가?
모델의 오버피팅을 막고 처음 보는 데이터에도 잘 예측하도록 만드는 방법을 Regularization(일반화)라고 한다.
대표적인 방법으로 [Dropout](https://github.com/boostcamp-ai-tech-4/ai-tech-interview/blob/main/answers/3-deep-learning.md#16-1), [L1, L2 Regularization](https://github.com/boostcamp-ai-tech-4/ai-tech-interview/blob/main/answers/2-machine-learning.md#21) 등이 존재한다.
#### References
- [L1 and L2 regularization for Deep Learning - Ujwal Tewari's Medium](https://medium.com/analytics-vidhya/regularization-understanding-l1-and-l2-regularization-for-deep-learning-a7b9e4a409bf)
---
## #16
#### Batch Normalization의 효과는?

배치 정규화(Batch Normalization)은 학습 시 **미니배치 단위로 입력의 분포가 평균이 0, 분산이 1이 되도록 정규화**한다. 더불어 $\gamma$로 스케일과 $\beta$로 이동 변환을 수행한다. 이렇게 배치 정규화를 사용하면 다음과 같은 효과를 얻을 수 있다.
- `장점 1` 기울기 소실/폭발 문제가 해결되어 큰 학습률을 설정할 수 있어 학습속도가 빨라진다.
- `장점 2` 항상 입력을 정규화시키기 때문에 가중치 초깃값에 크게 의존하지 않아도 된다.
- `장점 3` 자체적인 규제(Regularization) 효과가 있어 Dropout이나 Weight Decay와 같은 규제 방법을 사용하지 않아도 된다.
#### References
- [Batch Normalization - Steve-Lee's Deep Insight](https://deepinsight.tistory.com/116)
- [Understanding Batch Normalization for Neural Networks - towards data science](https://towardsdatascience.com/understanding-batch-normalization-for-neural-networks-1cd269786fa6)
- [Batch Normalization - 라온 피플](https://m.blog.naver.com/laonple/220808903260)
- [[Deep Learning] Batch Normalization (배치 정규화) - 꾸준희](https://eehoeskrap.tistory.com/430)
---
## #16-1
#### Dropout의 효과는?

드롭아웃(Dropout)은 <strong>설정된 확률 $p$만큼 은닉층(hidden layer)에 있는 뉴런을 무작위로 제거하는 방법</strong>으로, 오버피팅을 방지하기 위한 방법 중 하나이다. (정확히는 출력을 0으로 만들어 더이상의 전파가 되지 않도록 한다.) 드롭아웃(Dropout)은 학습 때마다 무작위로 뉴런을 제거하므로 매번 다른 모델을 학습시키는 것으로 해석할 수 있다. 그리고 추론 시 출력에 제거 확률 $p$를 곱함으로써 앙상블 학습에서 여러 모델의 평균을 내는 효과를 얻을 수 있다.
#### References
- [3.13. 드롭아웃(dropout) - Dive into Deep Learning](https://ko.d2l.ai/chapter_deep-learning-basics/dropout.html)
- [An Intuitive Explanation to Dropout - towards data science](https://towardsdatascience.com/an-intuitive-explanation-to-dropout-749c7fb5395c)
---
## #16-2
#### BN 적용해서 학습 이후 실제 사용시에 주의할 점은? 코드로는?
학습 과정에서는 미니 배치의 평균과 분산을 계산하여 배치 정규화를 적용하지만, 추론 시에는 학습 데이터 전체에 대한 평균과 분산을 계산하여 적용을 해야 한다. 왜냐하면 사용자가 설정한 배치의 크기에 따라 추론 결과가 변할 수도 있기 때문이다.
#### References
- [Batch Normalization (ICML 2015) - SanghyukChun's Blog](http://sanghyukchun.github.io/88/)
---
## #16-3
#### GAN에서 Generator 쪽에도 BN을 적용해도 될까?
일반적으로 GAN에서는 생성기(Generator)의 출력층(Output Layer)에만 BN(Batch Normalization)을 적용하지 않는다. 왜냐하면 생성기가 만든 이미지가 BN을 지나면 실제 이미지와는 값의 범위가 달라지기 때문이다.
#### References
- [초짜 대학원생의 입장에서 이해하는 Deep Convolutional Generative Adversarial Network (DCGAN) (1) - Jaejun Yoo's Playground](http://jaejunyoo.blogspot.com/2017/02/deep-convolutional-gan-dcgan-1.html)
---
## #17
#### SGD, RMSprop, Adam에 대해서 아는대로 설명한다면?
> **SGD**
Loss Function을 계산할 때 전체 train set을 사용하는 것을 Batch Gradient Descent 라고 한다. 그러나 이렇게 계산을 할 경우 한번 step을 내딛을 때 전체 데이터에 대해 Loss Function을 계산해야 하므로 너무 많은 계산량이 필요하다.
이를 방지하기 위해 보통은 Stochastic Gradient Descent(SGD)라는 방법을 사용한다. 이 방법에서는 loss function을 계산할 때 전체 데이터(batch) 대신 데이터 한 개 또는 일부 조그마한 데이터의 모음(mini-batch)에 대해서만 loss function을 계산한다.
**데이터 한 개**를 사용하는 경우를 <strong>Stochastic Gradient Descent(SGD)</strong>, <strong>데이터의 일부(mini-batch)</strong>를 사용하는 경우를 <strong>mini-batch Stochastic Gradient Descent(mini-batch SGD)</strong>라고 하지만 **오늘날의 딥러닝에서 일반적으로 통용되는 SGD는 mini-batch SGD이다.**
이 방법은 batch gradient descent 보다 다소 부정확할 수는 있지만, 훨씬 계산 속도가 빠르기 때문에 같은 시간에 더 많은 step을 갈 수 있으며 여러 번 반복할 경우 보통 batch의 결과와 유사한 결과로 수렴한다.
또한, SGD를 사용할 경우 Batch Gradient Descent에서 빠질 local minima에 빠지지 않고 더 좋은 방향으로 수렴할 가능성도 있다.
> **RMSprop**
RMSProp은 딥러닝의 대가 제프리 힌톤이 제안한 방법으로서, Adagrad의 단점을 해결하기 위한 방법이다.
Adagrad의 식에서 gradient의 제곱값을 더해나가면서 구한 $G_t$부분을 합이 아니라 지수평균으로 바꾸어서 대체한 방법이다.
이렇게 대체를 할 경우 Adagrad처럼 $G_t$가 무한정 커지지는 않으면서 최근 변화량의 변수간 상대적인 크기 차이는 유지할 수 있다.
식으로 나타내면 다음과 같다.

> **Adam**
Adam(Adaptive Moment Estimation)은 RMSProp과 Momentum 방식을 합친 것 같은 알고리즘이다.
이 방식에서는 Momentum 방식과 유사하게 지금까지 계산해온 기울기의 지수평균을 저장하며, RMSProp과 유사하게 기울기의 제곱값의 지수평균을 저장한다.

다만, Adam에서는 m과 v가 처음에 0으로 초기화되어 있기 때문에 학습의 초반부에서는 $m_t, v_t$가 0에 가깝게 bias 되어있을 것이라고 판단하여 이를 unbiased 하게 만들어주는 작업을 거친다.
$m_t, v_t$의 식을 ∑ 형태로 펼친 후 양변에 expectation을 씌워서 정리해보면, 다음과 같은 보정을 통해 unbiased 된 expectation을 얻을 수 있다.
이 보정된 expectation들을 가지고 gradient가 들어갈 자리에 $\widehat{m_t}, G_t$가 들어갈 자리에 $\widehat{v_t}$를 넣어 계산을 진행한다.

#### References
- [Gradient Descent Optimization Algorithms 정리 - Beomsu Kim's Blog](http://shuuki4.github.io/deep%20learning/2016/05/20/Gradient-Descent-Algorithm-Overview.html)
- [딥러닝 Optimization 함수 정리 - rueki](https://rueki.tistory.com/187)
---
## #17-1
#### SGD에서 Stochastic의 의미는?
SGD는 Loss Function을 계산할 때 전체 train dataset을 사용하는 Batch Gradient Descent와 다르게 일부 조그마한 데이터의 모음(mini-batch)에 대해서만 loss function을 계산한다.
`Stochastic`은 **mini-batch가 전체 train dataset에서 무작위로 선택된다**는 것을 의미한다.
#### References
- [Gradient Descent Optimization Algorithms 정리 - Beomsu Kim's Blog](http://shuuki4.github.io/deep%20learning/2016/05/20/Gradient-Descent-Algorithm-Overview.html)
---
## #17-2
#### 미니배치를 작게 할때의 장단점은?
> **장점**
- 한 iteration의 계산량이 적어지기 때문에 step 당 속도가 빨라진다.
- 적은 Graphic Ram으로도 학습이 가능하다.
> **단점**
- 데이터 전체의 경향을 반영하기 힘들다. 업데이트를 항상 좋은 방향으로 하지만은 않는다.
(batch size에 관련된 논문은 [Batch Size in Deep Learning - hyeonseob](https://blog.lunit.io/2018/08/03/batch-size-in-deep-learning/) 참고)
#### References
- [[호기심] mini-batch는 왜 사용하는가? - 담백한오늘](https://dambaekday.tistory.com/1)
---
## #17-3
#### 모멘텀의 수식을 적어 본다면?
Momentum 방식은 말 그대로 Gradient Descent를 통해 이동하는 과정에 일종의 `관성`을 주는 것이다.
현재 Gradient를 통해 이동하는 방향과는 별개로, 과거에 이동했던 방식을 기억하면서 그 방향으로 일정 정도를 추가적으로 이동하는 방식이다.
$$
v_t = \gamma v_{t-1} + \eta\nabla_{\theta}J(\theta)
$$
$$
\theta = \theta - v_t
$$
이 때, $v_t$는 time step t에서의 이동 벡터이며, $\gamma$는 얼마나 momentum을 줄 것인지에 대한 momentum term이다.
#### References
- [Gradient Descent Optimization Algorithms 정리 - Beomsu Kim's Blog](http://shuuki4.github.io/deep%20learning/2016/05/20/Gradient-Descent-Algorithm-Overview.html)
---
## #18
#### 간단한 MNIST 분류기를 MLP+CPU 버전으로 numpy로 만든다면 몇줄일까?
2-layer 신경망을 구현한다고 했을 때, 100줄 이내로 만들 수 있다.
#### References
- [deeplearning_from_scratch - youbeebee](https://github.com/youbeebee/deeplearning_from_scratch/blob/master/ch4.%EC%8B%A0%EA%B2%BD%EB%A7%9D%20%ED%95%99%EC%8A%B5/4.5.%ED%95%99%EC%8A%B5%20%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98%20%EA%B5%AC%ED%98%84%ED%95%98%EA%B8%B0.py)
- [4장.신경망 학습 - 밑바닥부터 시작하는 딥러닝(도서)](http://m.yes24.com/Goods/Detail/34970929)
---
## #18-1
#### 어느 정도 돌아가는 녀석을 작성하기까지 몇시간 정도 걸릴까?
간단한 MNIST 분류기를 MLP+CPU 버전으로 numpy로 만든, 참고 코드([deeplearning_from_scratch - youbeebee](https://github.com/youbeebee/deeplearning_from_scratch/blob/master/ch4.%EC%8B%A0%EA%B2%BD%EB%A7%9D%20%ED%95%99%EC%8A%B5/4.5.%ED%95%99%EC%8A%B5%20%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98%20%EA%B5%AC%ED%98%84%ED%95%98%EA%B8%B0.py))의 경우, 15 에폭 기준 0.9 이상의 정확도가 나온다고 한다. 이 100줄 가량의 코드를 작성하는데 걸리는 시간은 사람마다 다르겠지만, 구조를 정확히 알고있다면 오래걸려도 30분 내에는 작성할 수 있을 것이라 생각한다. 그러나 pretrain되지 않은 모델의 경우, 학습시간이 꽤 오래걸린다고 한다.
#### References
- [3.6.2.신경망의 추론 처리 - 밑바닥부터 시작하는 딥러닝(도서)](http://m.yes24.com/Goods/Detail/34970929)
---
## #18-2
#### Back Propagation은 몇줄인가?
참고 코드(경사하강법 적용) 기준으로 10줄이면 구현할 수 있다. `gradient_descent` 함수를 각 레이어별로 적용하면 미분값을 적용시킬 수 있다.
```python
# 가중치 매개변수의 기울기를 구함
def numerical_gradient(f, x):
h = 1e-4
grad = np.zeros_like(x) # x와 형상이 같은 배열을 생성
for idx in range(x.size):
tmp_val = x[idx]
# f(x+h) 계산
x[idx] = tmp_val + h
fxh1 = f(x)
# f(x-h) 계산
x[idx] = tmp_val - h
fxh2 = f(x)
grad[idx] = (fxh1 - fxh2) / (2 * h)
x[idx] = tmp_val # 값 복원
return grad
for key in ('W1', 'b1', 'W2', 'b2'):
network.params[key] -= learning_rate * grad[key]
```
#### References
- [deeplearning_from_scratch - youbeebee](https://github.com/youbeebee/deeplearning_from_scratch/blob/master/ch4.%EC%8B%A0%EA%B2%BD%EB%A7%9D%20%ED%95%99%EC%8A%B5/4.4.%EA%B8%B0%EC%9A%B8%EA%B8%B0.py)
- [4.5.신경망학습\_학습 알고리즘 구현하기 - 밑바닥부터 시작하는 딥러닝(도서)](http://m.yes24.com/Goods/Detail/34970929)
---
## #18-3
#### CNN으로 바꾼다면 얼마나 추가될까?
filter의 수, 크기, padding, stride 등에 대한 내용과 pooling layer등 레이어에 관한 정의가 추가되므로 약 50줄 정도 추가된다.
MLP 버전과 CNN 버전의 참고코드는 아래와 같다.
- [MLP 참고 코드](https://github.com/youbeebee/deeplearning_from_scratch/blob/master/ch4.%EC%8B%A0%EA%B2%BD%EB%A7%9D%20%ED%95%99%EC%8A%B5/4.5.%ED%95%99%EC%8A%B5%20%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98%20%EA%B5%AC%ED%98%84%ED%95%98%EA%B8%B0.py)
- [CNN 참고 코드](https://github.com/youbeebee/deeplearning_from_scratch/blob/master/ch7.CNN/7.5.CNN%20%EA%B5%AC%ED%98%84%ED%95%98%EA%B8%B0.py)
#### References
- [deeplearning_from_scratch - youbeebee](https://github.com/youbeebee/deeplearning_from_scratch/blob/master/ch7.CNN/7.5.CNN%20%EA%B5%AC%ED%98%84%ED%95%98%EA%B8%B0.py)
- [4.5.신경망학습\_학습 알고리즘 구현하기 - 밑바닥부터 시작하는 딥러닝(도서)](http://m.yes24.com/Goods/Detail/34970929)
---
## #19
#### 간단한 MNIST 분류기를 TF, PyTorch 등으로 작성하는데 몇시간이 필요한가?
TF 나 Pytorch 를 몇 번 사용해본 사람이라면 도큐먼트 참고도 하고 적당히 구글링도 하면, MNIST 분류기의 `데이터 다운로드, 데이터셋, 데이터로더, 모델 세팅, 학습, 추론` 를 구현하는데 2시간이 걸리지 않을 것이라 생각한다.
강력한 성능을 내는 모델도 이러한 프레임워크를 사용하면 빠른 시간 내에 구현해낼 수 있음에 감사하고, 추상화가 잘 된 함수들일지라도 안에서는 어떤 동작을 하는지 알고 사용해야한다.
---
## #19-1
#### CNN이 아닌 MLP로 해도 잘 될까?
Convolution 레이어는 receptive field 를 통해 이미지의 위치 정보까지 고려할 수 있다는 장점이 있다.
반면 MLP 는 모두 Fully connected 구조이므로 이미지의 특징을 이해하는데 픽셀마다 위치를 고려할 수 없게된다.
따라서 MNIST 분류기에서 MLP 를 사용하면 CNN 을 사용했을 때보다 성능이 낮다.
---
## #19-2
#### 마지막 레이어 부분에 대해서 설명 한다면?
MNIST 분류기는 Convolution 레이어를 깊게 쌓으며 숫자 이미지의 작은 특징부터 큰 특징까지 파악한다.
마지막 레이어, `Fully connected 레이어`는 이미지 데이터의 특징을 취합하여 10개의 숫자 중 적절한 숫자로 분류하는 역할을 한다.
만약 더 많은 레이블에 대해 분류해야 한다면 마지막 레이어의 out dimension 을 그에 맞게 설정하면 된다.
---
## #19-3
#### 학습은 BCE loss로 하되 상황을 MSE loss로 보고 싶다면?
train 과정에서 criterion 은 BinaryCrossEntropy 를 사용하고, valid 데이터를 이용한 valid loss 를 구하는 과정에서는 MeanSquaredLoss 를 사용한다.
---
## #20
#### 딥러닝할 때 GPU를 쓰면 좋은 이유는?
GPU(Graphics Processing Unit)은 부동 소수점 연산을 수행하는 많은 코어가 있어 수 많은 연산을 **병렬처리**할 수 있다. 또한 CPU보다 더 큰 메모리 대역폭을 가지고 있기 때문에 **큰 데이터를 더 효율적으로 빠르게 처리**할 수 있다.
> 메모리 대역폭(Memory Bandwidth)란 메모리가 처리할 수 있는 초당 데이터양을 뜻한다.
#### References
- [What is a GPU and do you need one in Deep Learning? - towards data science](https://towardsdatascience.com/what-is-a-gpu-and-do-you-need-one-in-deep-learning-718b9597aa0d)
---
## #20-1
#### GPU를 두개 다 쓰고 싶다. 방법은?
Pytorch의 경우 `torch.nn.DataParallel`을 사용하여 여러 개의 GPU를 사용할 수 있다.
- `torch.device`를 **cuda**로 설정한다.
- `nn.DataParallel`을 사용하여 모델을 감싼다.
- 모델을 `model.to(device)`를 사용하여 GPU로 보낸다.
#### References
- [OPTIONAL: DATA PARALLELISM - Pytorch Tutorials](https://pytorch.org/tutorials/beginner/blitz/data_parallel_tutorial.html)
---
## #20-2
#### 학습시 필요한 GPU 메모리는 어떻게 계산하는가?
Pytorch를 기준으로 볼 때 `something.to('cuda')`로 변환하는 모든 것들을 생각해보면 된다. 보통 GPU로 올리는 것은 모델과 데이터셋이므로, <strong>(모델의 크기 + 데이터의 크기 × 배치 크기)</strong>로 학습시 필요한 메모리 크기를 계산할 수 있다.
---
================================================
FILE: answers/4-python.md
================================================
> **질문은 <strong>[Top 100 Python Interview Questions You Must Prepare In 2021 - edureka!](https://www.edureka.co/blog/interview-questions/python-interview-questions/)</strong>을 참고하였습니다.**
## Table of Contents
- [What is the difference between list and tuples in Python?](#1)
- [What are the key features of Python?](#2)
- [What type of language is python? Programming or scripting?](#3)
- [Python an interpreted language. Explain.](#4)
- [What is pep 8?](#5)
- [How is memory managed in Python?](#6)
- [What is namespace in Python?](#7)
- [What is PYTHONPATH?](#8)
- [What are python modules? Name some commonly used built-in modules in Python?](#9)
- [What are local variables and global variables in Python?](#10)
- [Is python case sensitive?](#11)
- [What is type conversion in Python?](#12)
- [How to install Python on Windows and set path variable?](#13)
- [Is indentation required in python?](#14)
- [What is the difference between Python Arrays and lists?](#15)
- [What are functions in Python?](#16)
- [What is `__init__`?](#17)
- [What is a lambda function?](#18)
- [What is self in Python?](#19)
- [How does break, continue and pass work?](#20)
- [What does `[::-1]` do?](#21)
- [How can you randomize the items of a list in place in Python?](#22)
- [What’s the difference between iterator and iterable?](#23)
- [How can you generate random numbers in Python?](#24)
- [What is the difference between range & xrange?](#25)
- [How do you write comments in python?](#26)
- [What is pickling and unpickling?](#27)
- [What are the generators in python?](#28)
- [How will you capitalize the first letter of string?](#29)
- [How will you convert a string to all lowercase?](#30)
- [How to comment multiple lines in python?](#31)
- [What are docstrings in Python?](#32)
- [What is the purpose of is, not and in operators?](#33)
- [What is the usage of help() and dir() function in Python?](#34)
- [Whenever Python exits, why isn’t all the memory de-allocated?](#35)
- [What is a dictionary in Python?](#36)
- [How can the ternary operators be used in python?](#37)
- [What does this mean: `*args`, `**kwargs`? And why would we use it?](#38)
- [What does len() do?](#39)
- [Explain split(), sub(), subn() methods of “re” module in Python.](#40)
- [What are negative indexes and why are they used?](#41)
- [What are Python packages?](#42)
- [How can files be deleted in Python?](#43)
- [What are the built-in types of python?](#44)
- [What advantages do NumPy arrays offer over (nested) Python lists?](#45)
- [How to add values to a python array?](#46)
- [How to remove values to a python array?](#47)
- [Does Python have OOps concepts?](#48)
- [What is the difference between deep and shallow copy?](#49)
- [How is Multithreading achieved in Python?](#50)
- [What is the process of compilation and linking in python?](#51)
- [What are Python libraries? Name a few of them.](#52)
- [What is split used for?](#53)
- [How to import modules in python?](#54)
- [Explain Inheritance in Python with an example.](#55)
- [How are classes created in Python?](#56)
- [What is monkey patching in Python?](#57)
- [Does python support multiple inheritance?](#58)
- [What is Polymorphism in Python?](#59)
- [Define encapsulation in Python?](#60)
- [How do you do data abstraction in Python?](#61)
- [Does python make use of access specifiers?](#62)
- [How to create an empty class in Python?](#63)
- [What does an object() do?](#64)
- [What is map function in Python?](#65)
- [Is python numpy better than lists?](#66)
- [What is GIL in Python language?](#67)
- [What makes the CPython different from Python?](#68)
- [What are Decorators in Python?](#69)
- [What is object interning?](#70)
- [What is @classmethod, @staticmethod, @property?](#71)
---
## #1
#### What is the difference between list and tuples in Python?
리스트는 mutable(변경 가능), 튜플은 immutable(변경 불가능)이라는 특징을 가지고 있다. 따라서 리스트는 선언 후에도 값에 대한 변경, 삭제가 가능하지만, 튜플은 선언 후에 값을 변경하거나 삭제하는 것이 불가능하다. 또한 리스트는 튜플보다 느리다는 단점을 가지고 있으며, 하나의 튜플/리스트에 다른 타입의 값을 함께 저장할 수 있다는 공통점이 있다. 리스트는 대괄호 `[ ]`를, 튜플은 소괄호 `( )`를 사용해서 나타낸다.
#### References
- [[Python] 튜플(tuple), 리스트(list), 셋(set), 딕셔너리(dict) 비교 - specialscene](https://specialscene.tistory.com/142)
---
## #2
#### What are the key features of Python?
파이썬이 주요 특징은 아래와 같다.
- **인터프리터 언어(Interpreter Language)**
- 파이썬은 인터프리터 언어이므로, 실행하기 전에 컴파일을 할 필요가 없다.
- 자세한 내용은 [Python an interpreted language. Explain.](#4) 참고
- **동적타이핑(Dynamic Typing)**
- 파이썬은 실행시간에 자료형을 검사하므로, 선언할 때 변수 유형(ex.int, double, ...)을 명시할 필요가 없다.
- `typing`이란 프로그램 내에서 변수의 데이터 타입을 정하는 것을 말한다. 데이터 타입 지정(assign)은 정적 또는 동적 타이핑으로 분류되는데, 프로그램 컴파일 시에 변수의 타입을 체크하는 C, C++과 같은 언어는 정적 타입(static typed) 언어라고 하고, 프로그램 실행 시에 타입을 체크하는 python은 동적 타입(dynamic typed) 언어이다.
- **객체 지향 프로그래밍(OOP)**
- 파이썬은 클래스와 구성 및 상속을 함께 정의할 수 있다는 점에서 객체 지향 프로그래밍에 매우 적합하다.
- **일급객체(First-class citizen)**
- 파이썬에서 함수와 클래스는 일급 객체이다. 일급객체는 변수나 데이터 구조 안에 담을 수 있고, 매개변수로 전달이 가능하며, 리턴값으로 사용될 수 있다는 특징을 가지고 있다.
> 이 외 특징
- 파이썬은 **들여쓰기(indentation)** 와 간결하고 쉬운 문법을 통해 빠르게 코드를 작성할 수 있다는 장점을 가지고있다.
- 변수, 인수(argument)를 미리 선언하지 않아도 **자동으로 메모리 공간 할당**되어 편리하다.
- 함수(function) 또는 **모듈**(module) 추가가 용이하여 **확장성과 이식성**이 좋다.
- 파이썬은 인터프리터로 동작하는 **스크립트 언어**이므로 다른 컴파일 언어에 비해 다소 느리다.
- 컴파일러가 코드를 기계어로 번역해서 실행가능 파일을 만드는 것에 비해, 인터프리터는 코드를 한줄씩 실행시간마다 번역해서 실행하기 때문이다.
#### References
- [Python 시작하기 - crystalcube](https://crystalcube.co.kr/44)
- [파이썬 동적 타이핑과 캐스팅 - 스스로 배우는 코딩](https://blog.naver.com/PostView.nhn?blogId=youndok&logNo=222057656966)
- [python 리스트, 튜플, 딕셔너리 비교 - bskyvision](https://bskyvision.com/854)
- [Python 일급객체(FIRST-CLASS CITIZEN)- 홍찬기](https://hckcksrl.medium.com/python-%EC%9D%BC%EA%B8%89%EA%B0%9D%EC%B2%B4-1735746a8229)
- [인터프리터 언어와 컴파일 언어의 차이 - jhkang-dev](https://jhkang-tech.tistory.com/136)
---
## #3
#### What type of language is python? Programming or scripting?
파이썬은 정확하게는, 스크립트 언어이다. 모든 스크립트 언어는 프로그래밍 언어로 볼 수 있으나, 모든 프로그래밍 언어가 스크립트 언어로 분류되는 것은 아니다. 따라서 파이썬은 스크립트 언어이자, 프로그래밍 언어이다. 그러나 사람들은 일반적인 경우에 파이썬을 프로그래밍 언어의 목적으로 분류하고, 프로그래밍 목적으로 많이 사용한다.
> **💡 스크립팅(scripting/Scripting Language)**
> 스크립트 언어란 컴파일이 필요없이 실행될 수 있는 명령어의 집합이다. 스크립트 언어는 인터프리터를 사용하는데, 인터프리터는 컴파일 과정이 필요하지 않으며, 소스코드로 부터 바로 명령어를 해석할 수 있다.
#### References
- [What Is a Scripting Language? - CAREER KARMA](https://careerkarma.com/blog/what-is-a-scripting-language/)
---
## #4
#### Python an interpreted language. Explain.
인터프리터는 고급 언어로 작성된 원시코드 명령어들을 한번에 한 줄씩 읽어들여서 실행하는 프로그램이다. 인터프리터 언어는 실행시간(runtime) 전에 기계 레벨 코드(machine-level code)를 만드는 컴파일 언어와 다르게 소스코드를 바로 실행하는 언어이며, 파이썬은 인터프리터 언어에 해당한다.
인터프리터 언어는 스크립트 언어와 동일한 의미이다. 스크립팅/스크립트 언어에 대한 질문과 답변은 [What type of language is python? Programming or scripting?](#3)을 참고한다.
#### References
- [인터프리터 - 위키백과](https://ko.wikipedia.org/wiki/%EC%9D%B8%ED%84%B0%ED%94%84%EB%A6%AC%ED%84%B0)
---
## #5
#### What is pep 8?
PEP(Python Enhancement Proposal)는 Python 코드를 포맷하는 방법을 지정하는 규칙 집합이다. 다른 사람과 원활하게 협업하려면 공통된 스타일 공유가 필요하며, 일관성 있는 스타일은 나중에 수정하기도 쉽다. PEP8은 파이썬 코드를 어떻게 구성할 지 알려주는 스타일 가이드로서의 역할을 한다. Python formatting tool에는 `black`, `flake8`, `autopep8`, `yamf` 등이 있다.
> **PEP8 스타일 가이드 예시**
- whitespace
- 한 줄의 문자 길이가 79자 이하여야 한다.
- 함수와 클래스는 빈 줄 두개로 구분한다.
- naming
- 함수, 변수, 속성 : `lowercase_underscore`
- 보호(protected) 인스턴스 속성 : `_leading_underscore`
- 비공개(private) 인스턴스 속성 : `__double_leading_undersocre`
#### References
- [파이썬 PEP8 스타일 가이드 - 초보몽키의 개발공부로그](https://wayhome25.github.io/python/2017/05/04/pep8/)
---
## #6
#### How is memory managed in Python?
Python은 모든 것을 객체로 관리한다. 객체가 더이상 필요하지 않으면 파이썬 메모리 관리자가 자동으로 객체에서 메모리를 회수하는 방식을 사용하므로, 파이썬은 **동적 메모리 할당** 방식을 사용한다고 말할 수 있다. <strong>힙(heap)</strong>은 동적할당을 구현하는데 사용된다. 힙을 사용하여 동적으로 메모리를 관리하면, 필요하지 않은 메모리를 비우고 재사용할 수 있다는 장점이 있다. 모든 파이썬 객체 또는 자료구조는 **python private heap** 공간에서 관리되며, 프로그래머는 이 공간에 접근할 수 없고, 대신 파이썬 인터프리터가 대신해서 관리한다.
> **더 자세히보기**
파이썬 객체에 대한 힙 공간 할당을 담당하는 것을 **파이썬 메모리 관리자(Python Memory Manager)** 라고 부른다. Python 메모리 관리자에는 객체별 할당자가있기 때문에 int, string 등과 같은 특정 객체에 대해 메모리를 명확하게 할당 할 수 있다. 또한, 사용되지 않는 모든 메모리를 재활용하고 힙 공간에서 사용할 수 있도록 하는 **내장 Garbage Collector(GC)** 를 가지고 있다.
#### References
- [[메모리 관리] 파이썬(Python)에서 메모리 관리하기 - DEVLOG/개발일기](https://deepwelloper.tistory.com/130)
- [파이썬 런타임과 메모리 관리 - muchogusto](https://velog.io/@muchogusto/%ED%8C%8C%EC%9D%B4%EC%8D%AC-%EB%9F%B0%ED%83%80%EC%9E%84%EA%B3%BC-%EB%A9%94%EB%AA%A8%EB%A6%AC-%EA%B4%80%EB%A6%AC)
---
## #7
#### What is namespace in Python?
namespace는 이름 지정 충돌(naming conflicts)을 피하기 위해 이름이 고유한지 확인하는 데 사용되는 이름 지정 시스템(naming system)이다. 네임스페이스(namespace, 이름공간)란 프로그래밍 언어에서 특정한 객체(Object)를 이름(Name)에 따라 구분할 수 있는 범위를 의미한다. 파이썬 내부의 모든것은 객체로 구성되며 이들 각각은 특정 이름과의 매핑 관계를 갖게 되는데 이 매핑을 포함하고 있는 공간을 네임스페이스라고 한다.
네임스페이스가 필요한 이유는 다음과 같다. 프로그래밍을 수행하다보면 모든 변수 이름과 함수 이름을 정하는 것이 중요한데 이들 모두를 겹치지 않게 정하는 것은 사실상 불가능하다. 따라서 프로그래밍언어에서는 네임스페이스라는 개념을 도입하여, 특정한 하나의 이름이 통용될 수 있는 범위를 제한한다. 즉, **소속된 네임스페이스가 다르다면 같은 이름이 다른 개체를 가리키도록 하는 것이 가능**하다.
> **파이썬 네임스페이스의 특징**
- 네임스페이스는 딕셔너리 형태로 구현된다.
- 모든 이름 자체는 문자열로 되어있고 각각은 해당 네임스페이스의 범위에서 실제 객체를 가리킨다.
- 이름과 실제 객체 사이의 매핑은 가변적(Mutable)이므로 런타임동안 새로운 이름이 추가될 수 있다.
- 빌트인 네임스페이스는 함부로 추가하거나 삭제할 수 없다.
> **파이썬 네임스페이스의 3가지 분류**
- `빌트인 네임스페이스(build-in namespace)`: 기본 내장 함수 및 기본 예외들의 이름들이 소속된다. 파이썬으로 작성된 모든 코드 범위가 포함된다.
- `전역 네임스페이스(global namespace)`: 모듈별로 존재하며, 모듈 전체에서 통용될 수 있는 이름들이 소속된다.
- `지역 네임스페이스(local namespace)`: 함수 및 메서드 별로 존재하며, 함수 내의 지역 변수들의 이름들이 소속된다.

#### References
- [[Python] 네임스페이스 개념 정리 - Hyungcheol Noh's Blog](https://hcnoh.github.io/2019-01-30-python-namespace)
---
## #8
#### What is PYTHONPATH?
모듈을 import할 때 사용되는 환경변수이다. 모듈을 import할 때마다 PYTONPATH를 조회하여 가져온 모듈이 디렉토리에 있는지 확인한다. 인터프리터는 이를 사용하여 로드할 모듈을 결정한다.
PYTHONPATH 환경 변수에 경로를 추가하면, 파이썬은 이 경로들을 `sys.path`에 추가한다. 이를 통해 파이썬 코드 내부에서 뿐만 아니라 파이썬 코드 밖에서도 `sys.path`를 조작할 수 있다. PYTHONPATH에는 `sys.path`에 추가할 여러 경로들이 들어간다. 리눅스에서는 `/foo:/bar`처럼 `:`로 두 경로를 구분하고, 윈도우에서는 `/foo;/bar`처럼 `;`로 두 경로를 구분한다. 이외에도 sys.path에는 파이썬에 포함된 여러 내장 모듈 등을 탐색하기 위한 기본 경로가 들어간다.
> **`sys.path`의 순서**
import는 `sys.path` 리스트에 들어있는 경로들을 탐색하며 불러올 파이썬 파일을 찾는다. 리스트에 들어있는 맨 처음 경로부터 탐색을 시작하여, 특정 경로에서 불러올 파일을 찾았다면 남은 경로를 더 찾아보지 않고 탐색을 중지한다.
`sys.path`의 기본값은 아래의 순서대로 추가된다.
- `.py` 파일이 속한 디렉터리의 절대 경로
- PYTHONPATH 환경 변수
- 기타 기본 경로
아래의 코드를 통해서 `sys.path`를 직접 확인할 수 있다.
```python
import sys
print(sys.path)
```
#### References
- [sys.path, PYTHONPATH: 파이썬 파일 탐색 경로 - 방성범 (Bang Seongbeom)](https://www.bangseongbeom.com/sys-path-pythonpath.html#fn:ahead)
- [Python sys module, path 정리 - 일류도 삼류에서 부터](https://smartkuma.tistory.com/entry/Python-sys-module-path-%EC%A0%95%EB%A6%AC)
---
## #9
#### What are python modules? Name some commonly used built-in modules in Python?
모듈이란 Python 코드를 포함하는 파일로써, 함수나 변수 또는 클래스를 모아 놓은 파일이다. 모듈은 다른 파이썬 프로그램에서 불러와 사용할 수 있게끔 만든 파이썬 파일이라고도 할 수 있다. 실행 가능한 코드를 포함하는, 파이썬 확장자 `.py`로 만든 파이썬 파일은 모두 모듈이다. 모듈을 사용하면, 다른 코드에 적용하기가 쉬워지므로 이식성이 좋아진다.
자주 사용되는 빌트인 모듈(built-in module)의 예시는 다음과 같다.
- `os`
- `sys`
- `math`
- `random`
- `datetime`
- `JSON`
#### References
- [05-2 모듈 - 점프 투 파이썬](https://wikidocs.net/29)
---
## #10
#### What are local variables and global variables in Python?
**전역 변수(Global Variable)**는 함수 외부 또는 전역 공간에 선언된 변수이다. 프로그램의 모든 함수에서 전역변수에 접근할 수 있다. ([Whenever Python exits, why isn’t all the memory de-allocated?](#35) 참고)
**로컬 변수(Local Variable)**는 함수 내부에 선언된 변수를 말한다. 로컬 변수는 전역 공간이 아닌 로컬 공간에 있다.
```python
a=2
def add():
b=3
c=a+b
print(c)
add()
# 출력: 5
# global var: a
# local var: b, c
```
`add()` 함수의 외부에서 `add()` 함수의 로컬 변수에 액세스하려고 하면 오류가 발생한다.
---
## #11
#### Is python case sensitive?
파이썬은 대소문자를 구분하는 언어이다. 예를들어, `a`와 `A`는 다른 변수이다.
---
## #12
#### What is type conversion in Python?
type conversion은 타입 캐스팅(type casting)과 동일한 의미를 가지며, 이는 어떤 데이터 타입을 다른 데이터 타입으로 변환하는 것을 말한다.
> **타입 캐스팅 함수의 종류**
- `int()`: 정수형으로 변환한다.
- `float()`: 실수형으로 변환한다.
- `ord()`: 문자형을 정수형으로 변환한다.
- `hex()`: 정수형을 10진수로 변환한다.
- `oct()`: 정수형을 8진수로 변환한다.
- `tuple()`: 튜플형으로 변환한다.
- `set()`: set으로 변환한다.
- `list()`: list로 변환한다.
- `dict()`: (key,value) 순서로 이뤄진 튜플을 딕셔너리형으로 변환한다.
- `str()`: 정수형을 문자형으로 변환한다.
- `complex(real, image)`: 실수를 복소수로 변환한다.
---
## #13
#### How to install Python on Windows and set path variable?
Windows에 Python을 설치하려면 다음 단계를 거쳐야한다.
1. [링크](https://www.python.org/downloads/)에서 python을 설치한다.
2. PC에 다운로드 받은 python을 설치하면서, `Add Python 3.6 to PATH`에 체크하고, 안내에 따라 설치하며 python을 설치한 위치를 저장해둔다.
3. `시스템 > 시스템 정보 > 고급 시스템 설정 > 환경변수`으로 이동하여 시스템 변수를 편집하여 2번에서 저장해둔 python.exe 실행파일이 있는 경로를 추가해주면 된다.
#### References
- [Python / 설치 / 윈도우에 설치하기 - CODING FACTORY](https://www.codingfactory.net/10023)
---
## #14
#### Is indentation required in python?
Python은 Indentation(들여쓰기)이 필요하다. 파이썬은 `{}`을 사용하여 영역을 지정하지 않고, 들여쓰기를 사용하여 코드블록을 지정하기 때문에 파이썬에서 들여쓰기는 문법적인 강제사항이다. `if, for, class, def` 등의 모든 코드는 들여쓰기 블록 내에서 지정된다. 들여쓰기의 방법은 1칸, 2칸, 4칸, 탭 등 여러가지 방식이 있다. 일반적으로 파이썬은 네 개의 공백 문자를 사용하여 들여쓰기를 수행한다.
코드가 정확하게 들여쓰여지지 않으면 실행되지 않고 오류도 발생한다. 중요한 것은 같은 블록 내에서는 들여쓰기 칸 수가 같아야한다는 것이다. 들여쓰기 규칙 위반시에는 `IndentationError: unexpected indent` 에러를 출력한다.
#### References
- [제 01장 첫번째 계단밟기 02. 들여쓰기(indent) - Python 계단밟기](https://wikidocs.net/20368)
---
## #15
#### What is the difference between Python Arrays and lists?
Python에서는 array과 list가 동일한 방식으로 데이터를 저장한다. 차이점은, 배열은 단일 데이터 타입 요소만 포함할 수 있는 반면, 리스트에는 다양한 타입의 요소들이 들어갈 수 있다는 것이다. array의 선언 방법은 `arrayName = array(type, [Values])`처럼 자료형을 정하고, 지정한/동일한 자료형만을 넣을 수 있도록 되어있다. list은 변수에 `[]`로 여러 타입의 변수를 묶어서 선언할 수 있다.
array에서 사용할 수 있는 타입은 아래와 같다.

```python
import array as arr
My_Array=arr.array('i',[1,2,3,4])
My_list=[1,'abc',1.20]
print(My_Array)
print(My_list)
# Output: array(‘i’, [1, 2, 3, 4]) [1, ‘abc’, 1.2]
```
#### References
- [파이썬[Python] 036 Array(배열) 사용하기 - SmartLeader 끔손](https://appia.tistory.com/125)
---
## #16
#### What are functions in Python?
함수는 호출될 때만 실행되는 코드 블록이다. Python 함수를 정의하기 위해 def 키워드가 사용된다. 반복되는 부분을 함수로 만들어서 사용하면, 똑같은 코드를 여러번 반복하여 쓰지 않아도 되고, 프로그램의 흐름을 쉽게 파악할 수 있다는 장점이 있다.
```python
def new_func():
print("Hi, Welcome to Edureka")
new_func(); # 함수 호출
# Output: Hi, Welcome to Edureka
```
#### References
- [04-1 함수 - 점프 투 파이썬](https://wikidocs.net/24)
---
## #17
#### What is `__init__`?
`__init__`는 파이썬에서 특별하게 약속된 메서드 가운데 하나로, 초기화 메서드 혹은 생성자라고도 한다. 이 메서드는 클래스의 새 개체/인스턴스가 생성될 때 메모리를 할당하기 위해 자동으로 호출되며, 그 객체가 갖게 될 여러 가지 성질을 정해준다. 모든 클래스에는 `__init__` 메서드가 있다.
```python
class Employee:
def __init__(self, name, age,salary):
self.name = name
self.age = age
self.salary = 20000
E1 = Employee("XYZ", 23, 20000)
# E1은 Employee 클래스의 객체
# __init__ 는 E1에 메모리를 할당함
print(E1.name)
print(E1.age)
print(E1.salary)
'''
출력:
XYZ
23
20000
'''
```
> **💡 `__init__.py`은 무엇인가?**
> python 3.3 이하 버전에서, package import하기 위해서 사용되는 규칙이다. 3.3 이후의 버전에서는 이 제약사항이 해제되었다. `__init__.py`는 python 프로그램이 디렉토리를 처음 가져올 때 자동으로 실행되는 **패키지 초기화 파일** 역할을 하고, **모듈의 네임스페이스 초기화** 역할을 한다.
#### References
- [7.5. 특별한 메서드들 - 왕초보를 위한 Python](https://wikidocs.net/89)
- [패키지 **init**.py 파일들 - 그것으로 말미암아,](https://m.blog.naver.com/jodi999/221609408266)
---
## #18
#### What is a lambda function?
익명 함수(이름이 없는 함수)를 람다 함수라고 한다. 람다 함수는 `def` 키워드를 통해서 함수를 생성하는 리터럴 표기법을 **딱 한 줄의 코드로 표현**할 수 있게 해주며, `lambda 인자 : 표현식`의 형식으로 표현한다. 람다함수는 결과 부분을 return 키워드 없이 자동으로 return한다. 람다함수를 사용하면 코드가 간결해지고 메모리가 절약된다는 장점이 있다. 그러나 함수에 이름이 없고, 저장된 변수가 없기 때문에 다시 사용하기 위해서는 다시 코드를 적어주거나, 람다함수를 변수에 담아주어야한다. 따라서, 재사용할 이유가 없다면 lambda 함수를 생성하여 넘겨주는 편이 좋다.
람다함수의 표현법을 그림으로 표현하면 아래와 같다.

```python
a = lambda x, y : x + y
print(a(5, 6))
# Output: 11
```
#### References
- [3.5 람다(lambda) - 왕초보를 위한 Python - WikiDocs](https://wikidocs.net/64)
- [4) 람다함수(익명함수) - 제대로 파이썬 - WikiDocs](https://wikidocs.net/22804)
---
## #19
#### What is self in Python?
```python
class MyClass:
def method(self):
return 'instance method', self
obj = MyClass
print(obj.method())
# >> ('instance method', <__main__.MyClass object at 0x7f10aa8e68b0>)
```
우선 `self`가 어디에서 쓰이는지 알아야 한다. `self`는 인스턴스 메서드(instance method)의 첫 번째 인자이다. 메서드가 호출될 때, 파이썬은 `self`에 인스턴스를 넣고 이 인스턴스를 참조하여 인스턴스 메서드를 실행할 수 있게 된다.
#### References
- [self 이해하기 - 파이썬으로 배우는 알고리즘 트레이딩](https://wikidocs.net/1742)
- [Python's Instance, Class, and Static Methods Demystified - Real Python](https://realpython.com/instance-class-and-static-methods-demystified/)
- [Why must ‘self’ be used explicitly in method definitions and calls? - Python Documentation](https://docs.python.org/3/faq/design.html?highlight=self#why-must-self-be-used-explicitly-in-method-definitions-and-calls)
---
## #20
#### How does break, continue and pass work?
`break`는 가장 가까운 for문이나 while문의 루프에서 빠져나가도록 한다.
```python
for i in range(10):
if i == 5:
break
print(i, end=' ')
# >> 0 1 2 3 4
```
`continue`는 이번 이터레이션(iteration)을 건너뛰고 다음 이터레이션을 이어나가도록 한다.
```python
for i in range(10):
if i == 5:
continue
print(i, end=' ')
# >> 0 1 2 3 4 6 7 8 9
```
`pass`는 문법적으로 필요하지만, 아무 것도 하지 않게 하고 싶을 때 사용한다. 주로 함수나 클래스의 구조부터 세우고 나중에 구현을 하고 싶을 때 사용한다.
```python
class MyClass:
def not_implemented_method(self):
pass
```
#### References
- [루프의 break 와 continue 문, 그리고 else 절 - Python Documentation](https://docs.python.org/ko/3/tutorial/controlflow.html?highlight=break)
- [pass 문 - Python Documentation](https://docs.python.org/ko/3/tutorial/controlflow.html?highlight=break#pass-statements)
---
## #21
#### What does `[::-1]` do?
파이썬 시퀀스 자료형은 값이 연속적으로 이어진 자료형으로, **리스트, 튜플, range, 문자열**이 있다. 시퀀스 자료형은 시퀀스 객체의 일부를 잘라낼 수 있는 **슬라이싱(slicing)**이라는 기능을 쓸 수 있다. 슬라이싱은 `seq[start:end:step]`처럼 쓸 수 있으며, `start`는 시작 인덱스, `end`는 끝 인덱스(범위에 포함하지는 않음), `step`은 인덱스 증감폭을 말한다. `step`이 양수이면 증가하고, 음수이면 감소한다.
다시 돌아와 `seq[::-1]`은 `start`와 `end`는 시작 인덱스와 끝 인덱스를 생략하였는데, 이럴 경우 전체 시퀀스를 가져오며, 증감폭이 -1이므로 `end-1`부터 시작해 `start`순으로 요소를 가져온다. 즉, `seq[::-1]`은 시퀀스를 역전(reverse)시킨다.
#### References
- [시퀀스 자료형 활용하기 - 파이썬 코딩 도장](https://dojang.io/mod/page/view.php?id=2205)
- [슬라이스 사용하기 - 파이썬 코딩 도장](https://dojang.io/mod/page/view.php?id=2208)
---
## #22
#### How can you randomize the items of a list in place in Python?
**random 모듈의 `shuffle` 메서드**를 사용하면 구현할 수 있다. `random.shuffle`은 시퀀스 객체의 요소를 임의로 섞어서 해당 시퀀스를 반환한다.
```python
import random
random.seed(2021) # 시드 고정
lst = list(range(10))
print(lst) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
random.shuffle(lst)
print(lst) # [2, 7, 9, 3, 0, 5, 1, 4, 8, 6]
```
#### References
- [Shuffle a list, string, tuple in Python (random.shuffle, sample) - note.nkmk.me](https://note.nkmk.me/en/python-random-shuffle/)
- [random - Python Documentation](https://docs.python.org/ko/3/library/random.html)
---
## #23
#### What’s the difference between iterator and iterable?
```python
lst = [1, 2] # iterable 객체 : 리스트
lst_iter = iter(lst) # iterator 객체
print(next(lst_iter)) # 1
print(next(lst_iter)) # 2
print(next(lst_iter)) # StopIteration 예외 발생
```
iterable 객체는 `iter` 함수에 인자로 전달 가능한, 반복 가능한 객체를 말한다. 예를 들면, 리스트(list), 딕셔너리(dictionary), 집합(set), 문자열(string) 등이 있다.
iterable 객체를 `iter` 함수의 인자로 넣으면 iterable 객체를 순회할 수 있는 객체를 반환하는데, 이것이 iterator 객체이다. iterator 객체를 `next` 함수의 인자로 주면 iterable 객체의 요소의 값을 차례대로 반환한다. 만약 iterable 객체를 모두 순회했다면, _StopIteration_ 예외를 발생시킨다. 만약 다시 순회를 하고 싶다면 `iter` 함수로 새로운 iterator 객체를 생성해주면 된다.
#### References
- [🐍 제너레이터(Generator) - 코딩하는펭귄의 저장소](https://cooding-penguin.netlify.app/python/generator/)
- [Iterable 과 Iterator - 파이썬 - 기본을 갈고 닦자!](https://wikidocs.net/16068)
---
## #24
#### How can you generate random numbers in Python?
random 모듈로 간단히 생성할 수 있다. 편의를 위해 다음과 같이 random 모듈을 import하고 시드값을 2021로 고정하자.
```python
import random
random.seed(2021)
```
- 0과 1사이의 임의의 수를 생성하고 싶은 경우
```python
print(random.random()) # 0.8363375023320742
```
- 특정 범위 내의 임의의 정수를 생성하고 싶은 경우
```python
print(random.randint(0, 10)) # 10
```
- 특정 범위 내의 n개의 정수를 생성하고 싶은 경우
```python
n = 5
lst = range(1, 101)
print(random.sample(lst, 5)) # [70, 36, 32, 82, 5]
```
#### References
- [Generating random number list in Python - tutorialspoint](https://www.tutorialspoint.com/generating-random-number-list-in-python)
---
## #25
#### What is the difference between range & xrange?
> _파이썬2에서는 `range`와 `xrange` 모두 존재하지만, 파이썬3부터는 `range`가 내부적으로 `xrange`로 동작하도록 바뀌어서 `range`만 존재한다. 그러므로 **파이썬2**를 기준으로 `range`와 `xrange`를 설명한다._
`range` 객체는 입력으로 받은 정수 범위의 값을 요소로 같는 리스트를 말한다. 그러므로 `range(3)`과 ` [0, 1, 2]`는 완전히 동일하다.
```python
# python2
r = range(5)
print(r) # [0, 1, 2, 3, 4]
print(type(r)) # <type 'list'>
```
`xrange`는 제너레이터 객체로, 오직 루프를 돌때만 해당 범위의 정수를 하나씩 반환한다. 제너레이터에 관한 설명은 [여기](#28)에서!
```python
#python2
r = xrange(5)
print(r) # xrange(5)
print(type(r)) # <type 'xrange'>
for i in r:
print i,
# >> 0 1 2 3 4
```
#### References
- [python range() 와 xrange() 차이 - ㅍㅍㅋㄷ](https://bluese05.tistory.com/57)
- [[python] range, xrange 차이 - 코딩장이](https://itholic.github.io/python-range-xrange/)
- [range() vs xrange() in Python - GeeksforGeeks](https://www.geeksforgeeks.org/range-vs-xrange-python/)
---
## #26
#### How do you write comments in python?
`#`을 사용하여 주석을 달 수 있다.
```python
# this is my comment
```
따옴표를 이용한 주석은 Docstring 형식으로 자세한 내용은 [#32](#32)를 참고!
#### References
- [Documenting Python Code: A Complete Guide - Real Python](https://realpython.com/documenting-python-code/)
---
## #27
#### What is pickling and unpickling?
우선 `직렬화(Serialization)`와 `역 직렬화(Deserialization)`의 개념을 알아야 한다. `직렬화`란 객체를 바이트 스트림(byte stream)으로 변환하여 디스크에 저장하거나 네트워크로 보낼 수 있도록 만들어주는 것을 말한다. 반대로 바이트 스트림을 파이썬 객체로 변환하는 것을 `역 직렬화`라고 한다.
**pickle 모듈**은 파이썬 객체의 직렬화와 역 직렬화를 수행하는 모듈이다. 이 때 파이썬 객체를 직렬화할 때를 `pickling`이라고 하며, 바이트 스트림을 역 직렬화할 때를 `unpickling`이라고 한다.
#### References
- [pickle — 파이썬 객체 직렬화 - Python Documentation](https://docs.python.org/ko/3/library/pickle.html)
- [The Python pickle Module: How to Persist Objects in Python - Real Python](https://realpython.com/python-pickle-module/)
---
## #28
#### What are the generators in python?
제너레이터(Generator)란 Iterator 객체를 간단히 만들 수 있는 함수를 말한다. 제너레이터는 다음과 같이 1) yield문과 함수, 2) 표현식 형태로 만들 수 있다.
> **방법 1. yield문과 함수**
- 제너레이터 함수 정의
```python
def generator_list(value):
for i in range(value):
# 값을 반환하고 여기를 기억
yield i
```
- 제너레이터 객체 생성 및 next 함수로 호출
```python
gen = generator_list(2)
print(next(gen)) # 0
print(next(gen)) # 1
print(next(gen)) # StopIteration 에러 발생
```
> **방법 2. 표현문**
```python
value = 2
gen = (i for i in range(value))
print(next(gen)) # 0
print(next(gen)) # 1
print(next(gen)) # StopIteration 에러 발생
```
그럼 왜 리스트 대신 제너레이터를 사용할까? 리스트를 사용하면 리스트의 크기만큼 메모리에 공간이 할당된다. 반면 제너레이터는 말그대로 next 함수로 호출될 때 값을 생성하고 해당 값만 메모리에 올린다! 즉, 메모리를 절약할 수 있다. 작은 데이터라면 상관없지만 큰 데이터에서는 제너레이터 사용이 필수이다.
#### References
- [🐍 제너레이터(Generator) - 코딩하는펭귄의 저장소](https://cooding-penguin.netlify.app/python/generator/)
- [How to Use Generators and yield in Python - Real Python](https://realpython.com/introduction-to-python-generators/)
---
## #29
#### How will you capitalize the first letter of string?
문자열 메서드 `capitalize`를 사용하면 된다.
```python
string = "boostcamp ai tech"
print(string.capitalize()) # Boostcamp ai tech
```
자세한 문자열 메서드는 [여기](https://www.w3schools.com/python/python_ref_string.asp)를 참고!
#### References
- [Python String Methods - w3schools](https://www.w3schools.com/python/python_ref_string.asp)
---
## #30
#### How will you convert a string to all lowercase?
문자열 메서드 `lower`을 사용하면 된다.
```python
string = "BOOSTCAMP AI TECH"
print(string.lower()) # boostcamp ai tech
```
#### References
- [Python String Methods - w3schools](https://www.w3schools.com/python/python_ref_string.asp)
---
## #31
#### How to comment multiple lines in python?
`#`을 여러 줄 사용하여 여러 줄의 주석을 달 수 있다.
```python
# this is my comment
# I am commenting multiple lines
# - boostcamp ai tech team 4
```
따옴표를 이용한 주석은 Docstring 형식으로 자세한 내용은 [#32](#32)를 참고!
#### References
- [Documenting Python Code: A Complete Guide - Real Python](https://realpython.com/documenting-python-code/)
---
## #32
#### What are docstrings in Python?
docstrings은 주석은 아니지만, 사용자에게 코드에 대한 설명을 적어놓은 문서(documentation)이다. docstrings는 `__doc__` 속성이나 `help()` 내장 함수로 접근할 수 있다. docstrings는 작은 따옴표(`'`) 혹은 큰 따옴표(`"`) 3개로 작성할 수 있다.
```python
def mult(a, b):
"""
Returns the product of a and b
- a(float): any real number
- b(float): any real number
"""
return a*b
```
```python
print(help(mult))
print(mult.__doc__)
```
> **💡 Comments(주석) vs Dosctrings**
> comments와 docstrings은 각각 `#`, `"""`을 쓴다는 점에서 다르지만 가장 큰 차이는 **읽는 대상**이다. comments는 개발을 위해 동료 혹은 나중에 코드를 읽을 나에게 남겨놓는 것이고 docstrings는 이 코드를 사용할 사용자들이 이해하기 쉽도록 남겨놓는 것이다.
#### References
- [Documenting Python Code: A Complete Guide - Real Python](https://realpython.com/documenting-python-code/)
---
## #33
#### What is the purpose of is, not and in operators?
`is`는 객체 비교 연산자(identity operator)로 두 변수가 참조하는 객체의 id가 같을 경우 **True**를 반환한다. 보통 두 변수가 참조하는 객체가 동일한 객체인지 확인할 때 사용한다.
```python
a = [1, 2, 3]
b = a
c = a.copy()
print(a is b) # True
print(a is c) # False
```
`not`은 단항 논리 연산자(logical operator)로 뒤에 오는 boolean 값을 뒤집는다. 뒤에 오는 값이 **True**이면 **False**를, **False**이면 **True**를 반환한다.
```python
print(not True) # False
print(not False) # True
```
`in`은 멤버 연산자(membership operator)로, 요소 a와 시퀀스 b가 있는 지를 확인하고 싶을 때 `a in b`로 표현하며 만약 a가 b 안에 있다면 **True**를, 없으면 **False**를 반환한다.
```python
b = "abc"
print("a" in b) # True
print("z" in b) # False
```
#### References
- [Python Operators - w3schools](https://www.w3schools.com/python/python_operators.asp)
---
## #34
#### What is the usage of help() and dir() function in Python?
`help()`는 docstrings를 작성하였다면 해당 docstrings를 출력한다. docstrings에는 클래스, 메서드의 사용법에 관한 내용이 담겨있으므로 해당 클래스와 메서드를 사용자에게 매우 유용하다. docstrings에 대한 내용은 [#31](#31) 참고!
`dir()`은 인자로 넣은 객체의 속성과 메서드를 문자열로 변환하고 그것을 요소로 갖는 정렬된 리스트를 반환한다. `dir`은 사용할 객체의 메서드와 속성에 대한 정보를 얻고 싶을 때 유용하다. 다만 인자가 없다면 현재 지역 스코프에서 정의된 함수와 변수들의 리스트를 반환한다.
```python
def func(x):
return x
a = 3
print(dir(a)) # 객체 a에 대한 속성, 메서드
print(dir(func)) # 함수 func에 대한 속성, 메서드
print(dir()) # 지역 스코프에 정의된 a와 func
```
#### References
- [내장 함수: help() - Python Documentation](https://docs.python.org/ko/3/library/functions.html#help)
- [내장 함수: dir() - Python Documentation](https://docs.python.org/ko/3/library/functions.html#dir)
- [10 Python built-in functions you should know](https://towardsdatascience.com/10-python-built-in-functions-you-should-know-fbd5c879e0ab)
---
## #35
#### Whenever Python exits, why isn’t all the memory de-allocated?
다른 객체나 전역 네임스페이스에서 참조되는 객체를 순환 참조하는 파이썬 모듈은 항상 해제되지는 않는다. 또한 C 라이브러리가 예약한 메모리의 해당 부분을 해제하는 것은 불가능하다. 그러므로 파이썬 종료 시, 모든 메모리가 해제되지는 않는다.
> **💡 순환 참조(Circular Reference)**
> 두 객체가 서로 참조하는 경우를 말한다.
> **💡 전역 네임스페이스(Global Namespace)**
> 네임스페이스(namespace)란 프로그래밍 언어에서 특정 객체를 이름에 따라 구분할 수 있는 범위를 의미한다. 전역 네임스페이스는 import한 모듈들의 이름을 포함하며, 스크립트가 끝날 때까지 지속된다.
#### References
- [Releasing memory in Python - Net-informations.com](http://net-informations.com/python/iq/memory.htm)
- [Whenever you exit Python, is all memory de-allocated? - BYTES](https://bytes.com/topic/python/answers/972248-whenever-you-exit-python-all-memory-de-allocated)
- [Circular References in Python - hearsaysocial](http://engineering.hearsaysocial.com/2013/06/16/circular-references-in-python/)
- [[Python] 네임스페이스 개념 정리 - Hyungcheol Noh's Blog](https://hcnoh.github.io/2019-01-30-python-namespace)
- [네임스페이스 - 제대로 파이썬](https://wikidocs.net/23109)
---
## #36
#### What is a dictionary in Python?
딕셔너리는 **key값과 그에 대응하는 value값을 얻을 수 있는 컬렉션**을 말한다. 딕셔너리는 데이터가 들어온 순서가 상관이 없고, 인덱싱이 되어 있어 key값으로 요소에 접근하여 데이터(= value) 수정이 가능하다. 하지만, key값은 고유 값이므로 key값 중복은 불가능하다. 주로 자체적으로 만든 key값으로 데이터에 접근하고 싶을 때 딕셔너리 컬렉션을 사용한다.
딕셔너리의 뜻은 사전이다. 영한 사전에서 각 영단어(ex. beautiful)에 대응하는 단어(ex. 아름다운)가 나오는 것처럼, 영단어가 key값이고 그에 대응하는 단어를 value값으로 볼 수 있다.
> **특징1** : 딕셔너리는 {, }를 사용하여 선언하며 { key1 : value1, key2 : value2, ... } 로 요소를 나타낸다.
- key값으로 변하지 않는 값을 사용하고, value값으로 변하는 값과 변하지 않는 값 둘 다 사용할 수 있다.
- key값으로 리스트를 사용하면, 값이 변할 가능성이 있기 때문에 인터프리터에서 type error를 발생시킨다.
```python
ex1 = {'name':'Groot', 'lover':'penguin', 'feature':'really cute'}
# 딕셔너리 생성자로 집합을 생성하는 경우
ex2 = dict(name='Groot', lover='penguin', feature='really cute')
# key값은 변하지 않는 값, value값은 변하지 않는 값과 변하는 값 둘 다 가능
ex3 = {[10, 3]:'birthday'} # type error!
```
> **특징2** : 딕셔너리는 딕셔너리 쌍(key : value)을 추가하거나 제거할 수 있다.
- 추가 : dict_ex[ 새로운 key값 ] = 그에 대응하는 value값으로 추가할 수 있다.
- 제거 : del 키워드를 이용해 특정 쌍을 제거할 수 있다.
- 딕셔너리 앞에 del 키워드를 쓰면 딕셔너리가 완전히 제거된다.
```python
ex = {'Kevin':180, 'Anna':165, 'Penelope':175}
# 새로운 딕셔너리 쌍 추가
ex['Groot'] = 100
print(ex) # {'Kevin': 180, 'Anna': 165, 'Penelope': 175, 'Groot': 100}
# del 키워드로 딕셔너리 쌍 제거
del ex['Penelope']
print(ex) # {'Kevin': 180, 'Anna': 165, 'Groot': 100}
# del 키워드로 딕셔너리 완전 제거
del ex
print(ex) # name error!
```
> **특징3** : 딕셔너리의 key값은 중복될 수 없다.
- key값은 고유값이므로 2개 이상의 key값이 존재할 수 없다.
- key값에 해당하는 value값을 어떤 걸 불러야할지 모르기 때문.
- key값이 중복될 경우 하나를 제외한 나머지 것들이 모두 무시된다.
- key값에 대입한 최근의 value값을 불러온다.
```python
ex = {'name': 'Groot', 'lover': 'Penguin', 'feature': 'cute', 'feature': 'handsome'}
print(ex) # {'name': 'Groot', 'lover': 'Penguin', 'feature': 'handsome'}
```
#### References
- [Python Dictionaries - w3schools](https://www.w3schools.com/python/python_dictionaries.asp)
---
## #37
#### How can the ternary operators be used in python?
ternary operators(삼항 연산자)는 조건문을 표시하는 데 사용되는 연산자이며 `[true_value] if [condition] else [false_value]`의 형태로 표현된다.
```python
a = 123
print("a is 123" if a==123 else "a is not 123") # a is 123
a = 456
print("a is 123" if a==123 else "a is not 123") # a is not 123
```
#### References
- [[Python] 삼항 연산자(Ternary Operator) - 똑똑이](https://m.blog.naver.com/wideeyed/221858874414)
---
## #38
#### What does this mean: `*args`, `**kwargs`? And why would we use it?
`*args`는 함수에 전달되는 argument의 수를 알 수 없거나, list나 tuple의 argument들을 함수에 전달하고자 할 때 사용한다.
파이썬에서는 어디서부터 어디까지 `*args`에 담아야 할지 알 수 없기 때문에, 일반 변수를 앞에 두고 그 뒤에 `*args`를 지정해 주어야 한다.
```python
def name(*args):
print(args)
name("샐리", "펭귄", "히스", "원딜")
# output: ('샐리', '펭귄', '히스', '원딜')
```
`**kwargs`는 함수에 전달되는 keyword argument의 수를 모르거나, dictionary의 keyword argument들을 함수에 전달하고자 할 때 사용한다.
`*args`와 `**kwargs`를 함께 사용하는 경우 `*args`를 `**kwargs`보다 앞에 두어야 한다.
```python
def name(**kwargs):
print(kwargs)
name(sally="샐리", penguin="펭귄", heath="히스", adc="원딜")
# output: {'sally': '샐리', 'penguin': '펭귄', 'heath': '히스', 'adc': '원딜'}
```
일반 변수, `*args`, `**kwargs`를 모두 사용하는 경우 다음과 같은 순서를 따른다.
```python
def function_name(일반변수, *args, **kwargs)
```
#### References
- [[Python] \*args와 \*\*kwargs - Jun94](https://velog.io/@hj8853/Python-args%EC%99%80-kwargs)
---
## #39
#### What does `len()` do?
`len()` 함수는 object의 길이(item의 수)를 return 한다.
argument로는 sequence(string, bytes, tuple, list, range, ...), collection(dictionary, set, frozenset, ...)을 받는다.
```python
stg = "ai-tech-interview"
len(stg) #17
ex_list = ["ai", "tech", "interview"]
len(ex_list) # 3
```
#### References
- [Built-in Functions - Python documentation](https://docs.python.org/3/library/functions.html#len)
---
## #40
#### Explain split(), sub(), subn() methods of “re” module in Python.
파이썬에서 정규표현식을 사용하기 위해 “re” 모듈을 사용한다. 문자열 수정을 위해 Python의 “re” 모듈은 3 가지 메서드를 제공한다.
- `re.split(pattern, string, maxplit=0)`: pattern을 구분자로 string을 분리하여 list로 반환한다.
```python
re.split('<[^<>]*>', '<html> Wow <head> header </head> <body> Hey </body> </html>')
# output: ['', ' Wow ', ' header ', ' ', ' Hey ', ' ', '']
```
- `re.sub(pattern, repl, string, count=0)`: string에서 pattern과 일치하는 부분에 대하여 repl로 교체하여 결과 문자열을 반환한다.
```python
re.sub('\d{4}', 'XXXX', '010-1234-5678')
# output: '010-XXXX-XXXX'
```
- `re.subn(pattern, repl, string, count=0)`: sub와 동일하나, 결과로 (결과문자열, 매칭횟수)를 튜플로 반환한다.
```python
re.subn('\d{4}', 'XXXX', '010-1234-5678')
# output: ('010-XXXX-XXXX', 2)
```
#### References
- [파이썬 – 정규식표현식(Regular Expression) 모듈 - devanix](https://devanix.tistory.com/296)
- [파이썬 정규표현식(re) 사용법 - 05. 주석, 치환, 분리 - YW & YY's Python, Machine & Deep Learning](<https://greeksharifa.github.io/%EC%A0%95%EA%B7%9C%ED%91%9C%ED%98%84%EC%8B%9D(re)/2018/08/04/regex-usage-05-intermediate/>)
---
## #41
#### What are negative indexes and why are they used?
> **인덱스**
- 시퀀스 객체에 `[]`(대괄호)를 붙여 사용
- 시퀀스 객체의 인덱스는 항상 0부터 시작
- 시퀀스 객체(list, tuple, range, 문자열)에 사용가능
- 시퀀스객체[인덱스]
> **음수 인덱스**
- 인덱스를 음수로 지정하면 뒤에서부터 요소에 접근하게 된다.
- -1은 뒤에서 첫 번째, -5는 뒤에서 다섯 번째 요소를 뜻한다.
- 시퀀스 객체(list, tuple, range, 문자열)에 사용가능
```python
example = ['Boostcamp', 'AI', 'Tech', 'penguin', 'sally', 'adc', 'heath']
print(example[5]) # adc
print(example[-2]) # adc
print(example[-4:]) # ['penguin', 'sally', 'adc', 'heath']
example = "BoostDevs"
print(example[:5]) # Boost
print(example[-4:-1]) # Dev
```
#### References
- [Python | 인덱스(index) - 황복실](https://velog.io/@sz3728/Python-index)
---
## #42
#### What are Python packages?
> **모듈**
모듈은 파이썬 코드를 논리적으로 묶어서 관리하고 사용할 수 있도록 하는 것으로, 보통 하나의 파이썬 `.py` 파일이 하나의 모듈이 된다. 모듈 안에는 함수, 클래스, 혹은 변수들이 정의될 수 있으며, 실행 코드를 포함할 수도 있다.
모듈에 관한 자세한 내용은 [#9. 모듈](#9) 참고!
> **패키지**
패키지는 특정 기능과 관련된 여러 모듈을 묶은 것으로 패키지는 모듈에 namespace를 제공한다. 패키지는 하나의 디렉토리에 놓여진 모듈들의 집합을 가리키는데, 그 디렉토리에는 일반적으로 `__init__.py` 라는 패키지 초기화 파일이 존재한다.
패키지는 모듈들의 컨테이너로서 패키지 안에는 또다른 서브 패키지를 포함할 수도 있다. 파일시스템으로 비유하면 패키지는 일반적으로 디렉토리에 해당하고, 모듈은 디렉토리 안의 파일에 해당한다.

패키지들의 모음인 라이브러리에 대한 내용은 [#52. 라이브러리](#52) 참고!
#### References
- [파이썬 패키지와 모듈 알아보기 - 승톨](https://velog.io/@seanlion/pythonmodule)
- [패키지 - 예제로 배우는 파이썬 프로그래밍](http://pythonstudy.xyz/python/article/18-%ED%8C%A8%ED%82%A4%EC%A7%80)
---
## #43
#### How can files be deleted in Python?
os 모듈을 import 한 후 `os.remove()` 함수를 사용하여 파일을 삭제할수있다.
```python
import os
os.remove("ai-tech-interview.txt")
```
자세한 내용은 [os.remove - Python documentation](https://docs.python.org/3/library/os.html#os.remove) 참고!
---
## #44
#### What are the built-in types of python?
Python의 Built-in type은 아래와 같다.
- Integer
- Floating-point
- Complex number
- String
- Boolean
- Built-in function
자세한 내용은 [Built-in Types - Python documentation](https://docs.python.org/3/library/stdtypes.html) 참고!
> <strong>💡 빌트인built-in이란?</strong>
> 어떤 기능이나 함수 등이 내장 또는 빌트인되어 있다는 뜻은 그것이 프로그램에서 바로 사용가능하도록 준비되어 있다는 뜻이다. 자세한 내용은 [basic-terminology-in-programming - shoark7](https://gist.github.com/shoark7/e8e103dd9a2ff11b94432c17c3826ab9#-%EB%82%B4%EC%9E%A5%EB%90%9Cbuilt-ins) 참고할 것.
---
## #45
#### What advantages do NumPy arrays offer over (nested) Python lists?
numpy array는 하나의 데이터 타입만 정의가 가능하다. Python list와 달리 다이나믹 타이핑을 지원하지 않으며, C의 Array를 사용하여 배열을 생성하기 때문에 속도가 빠르다.

Python list는 데이터 주소값을 저장하고 데이터를 가져올 때는 해당 주소에 가서 데이터를 가져온다. 반면 Numpy array는 C의 배열과 유사하여 연속된 주소를 가지고 있어 데이터를 가져올 때는 순서대로 가져오면 되기 때문에 메모리를 효율적으로 사용한다.
Numpy에 대한 내용은 [#66. Numpy](#66) 참고!
#### References
- [[python] numpy array 특징과 사용법 - 밀래의 코딩북](https://firework-ham.tistory.com/31)
---
## #46
#### How to add values to a python list?
`append()`, `extend()`, `insert()` 함수를 사용하여 list에 value를 추가할 수 있다.
> **append()**
`list.append(x)` 형태로 사용하며, $O(1)$의 시간복잡도를 갖는다. 괄호 안에 값을 입력하면 새로운 요소를 list 맨 끝에 추가한다. 요소를 추가할 때는 객체로 추가하게 되는데, 입력한 값이 리스트와 같은 반복 가능한 iterable 자료형이더라도 객체로 저장한다.
```python
nums = [1, 2, 3]
nums.append(4)
print(nums) # [1, 2, 3, 4]
nums.append([5, 6])
print(nums) # [1, 2, 3, 4, [5, 6]]
```
> **extend()**
`list.extend(iterable)` 형태로 사용하며, $O(N)$ 시간복잡도를 갖는다. 입력한 iterable 자료형의 항목 각각을 list의 끝에 하나씩 추가한다. iterable 자료형으로 추가되는 것이 아니라 iterable 자료형 안에 있는 항목이 하나씩 떼어져서 추가된다. append와 동일하게 요소를 list의 끝에 추가하지만 append와 다른 점은 괄호 안에는 iterable 자료형만 올 수 있다는 것이다. iterable 자료형이 아닌 경우 TypeError가 발생한다.
```python
nums = [1, 2, 3]
nums.extend([4])
print(nums) # [1, 2, 3, 4]
nums.extend([5, 6])
print(nums) # [1, 2, 3, 4, 5, 6]
```
> **insert()**
- 시간복잡도: ``
`list.insert(i, x)` 형태로 사용하며, $O(N)$ 시간복잡도를 갖는다. list의 원하는 위치 i 앞에 추가할 값 x를 삽입할 수 있다. i는 위치를 나타내는 인덱스를 숫자를 입력한다. 음수를 입력하면 배열의 끝을 기준으로 처리된다. 추가할 값 x는 객체로 추가되며 iterable 자료형이더라도 객체로 저장된다.
```python
nums = [1, 2, 3]
nums.insert(0, 10)
print(nums) # [10, 1, 2, 3]
nums.insert(-1, 99)
print(nums) # [10, 1, 2, 99, 3]
nums.insert(len(nums), [20, 30])
print(nums) # [10, 1, 2, 99, 3, [20, 30]]
```
> **`+` 연산자**
`list_1 + list_2` 형태로 사용하며, $O(1)$ 시간복잡도를 갖는다.
```python
nums = [1, 2, 4, 6, 1, 5]
print(nums + [10, 9, 8, 7]) # [1, 2, 4, 6, 1, 5, 10, 9, 8, 7]
```
#### References
- [파이썬 append( ), extend( ), insert( ) 함수 차이 / 요소추가함수 비교 (Python) - 영지공지](https://ooyoung.tistory.com/117)
- [파이썬 자료형 별 주요 연산자의 시간 복잡도 (Big-O) - 초보몽키의 개발공부로그](https://wayhome25.github.io/python/2017/06/14/time-complexity/)
---
## #47
#### How to remove values to a python list?
`remove()`, `pop()` 함수를 사용하여 list에 value를 삭제할 수 있다.
> **remove()**
`remove()`는 지우고자 하는 인덱스가 아닌, 값을 입력하는 방식이다. 만약 지우고자 하는 값이 리스트 내에 2개 이상이 있다면 순서상 가장 앞에 있는 값을 지우게 된다. 값을 삭제할 때 삭제된 값을 반환하지 않는다. `remove()`는 시간복잡도 $O(N)$를 갖는다.
```python
example = [1, 2, 3, 4, 5, 1]
example.remove(1)
print(example) # [2, 3, 4, 5, 1]
```
> **pop()**
`pop()`은 리스트에서 지우고자 하는 값의 인덱스를 받아서 지우는 방식이다. 값을 삭제할 때 삭제된 값을 반환한다. 인덱스를 지정하지 않으면 리스트의 마지막 요소가 삭제되며 반환된다. `pop()`은 시간복잡도 $O(N)$를 갖는다.
```python
example = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
print(example.pop()) # 10
print(example) # [1, 2, 3, 4, 5, 6, 7, 8, 9]
example = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
print(example.pop(3)) # 4
print(example) # [1, 2, 3, 5, 6, 7, 8, 9, 10]
```
> **del**
`del list[i]` 형태로 사용하며, 시간복잡도 $O(N)$을 갖는다. 값을 삭제할 때 삭제된 값을 반환하지 않는다.
```python
example = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
del example[7]
print(example) # [1, 2, 3, 4, 5, 6, 7, 9, 10]
example = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
del example[7:]
print(example) # [1, 2, 3, 4, 5, 6, 7]
```
#### References
- [파이썬 자료형 별 주요 연산자의 시간 복잡도 (Big-O) - 초보몽키의 개발공부로그](https://wayhome25.github.io/python/2017/06/14/time-complexity/)
---
## #48
#### Does Python have OOP concepts?
Python은 객체 지향 프로그래밍 언어이다. Python의 주요 OOP 개념에는 Class, Object, Method, Inheritance(상속), Polymorphism(다형성), Data Abstraction(데이터 추상화), Encapsulation(캡슐화)을 포함한다.
더 자세한 내용은 [#55. Inheritance](#55), [#59. Polymorphism](#59), [#60. Encapsulation](#60), [#61. Data Abstraction](#61) 참고!
#### References
- [Object Oriented Programming Python: All you need to know - Harshit kant](https://www.edureka.co/blog/object-oriented-programming-python/)
---
## #49
#### What is the difference between deep and shallow copy?
Shallow copy는 **새로운 객체(변수)를 만든 후에 원본에 접근할 수 있는 참조(reference)를 입력**한다. 이런 경우 서로 다른 변수명이지만 본질적으로 서로 같은 대상을 의미하므로 하나의 변수 역시 수정이 된다.
가변형(mutable) 자료형에 대해서 적용이 가능하다. 가변형(mutable) 자료형은 같은 주소에서 값(value)이 변경 가능하기 때문에 얕은 복사가 가능하다. 반면 불변형(immutable) 자료형은 본질적으로 변경이 불가능하므로 재배정을 통해 변수를 바꾼다. 따라서 재배정이 이루어지므로 객체가 서로 달라진다.
```python
a = [1, 2, 3, 4, 5]
b = a # shallow copy
a[1] = 10
print(a, b) # [1, 10, 3, 4, 5] [1, 10, 3, 4, 5]
```
Deep copy는 **새로운 객체(변수)를 만든 뒤에 원본의 복사본을 변수에 입력**한다. 서로 값만 같을 뿐 본질적으로 서로 다르기 때문에 한 변수가 수정될 시 다른 변수가 수정되지 않는다.
```python
a = [1, 2, 3, 4, 5]
b = a[:] # deep copy
a[1] = 10
print(a, b) # [1, 10, 3, 4, 5] [1, 2, 3, 4, 5]
```
```python
import copy
a = [1, 2, 3, 4, 5]
b = copy.deepcopy(a) # deep copy
a[1] = 10
print(a, b) # [1, 10, 3, 4, 5] [1, 2, 3, 4, 5]
```
#### References
- [[Python]Shallow copy & Deep copy - 박현희](https://velog.io/@hyoniii_log/PythonShallow-copy-Deep-copy/)
---
## #50
#### How is Multithreading achieved in Python?
파이썬에서 멀티 쓰레드를 구현하는 방법은 `threding 모듈(High level)`을 사용하거나 `thread 모듈(Low level)`을 사용하는 방법이 있다. 현재 thread 모듈은 deprecated 되어 threading 모듈을 사용하는 것을 권장한다.
멀티스레딩을 사용하면 당연히 속도가 빨라질 것이라 생각할 수 있지만, 파이썬의 GIL(Global Interpreter Lock) 정책으로 인해, 멀티스레딩을 사용한다 하더라도, 속도는 싱글스레드와 별반 다르지 않다.
하나의 자원에 여러 프로세스가 아무런 규칙없이 접근하면, 자원 동기화 문제가 발생할 수 있다. 이를 방지하기 위해서 자원에 lock을 두는데, Python은 모든 자원의 lock을 global하게 관리하고 있다. 한번에 하나의 스레드만 자원에 접근할 수 있다는 것이다. 이로인해, 자원을 공유하는 여러 스레드를 동시에 실행시킨다고 해도, 결국 GIL 때문에 한번에 하나의 스레드만 실행되는 것이다.
> **💡 멀티스레딩이 유용한 경우**
> GIL은 cpu 동작에 대해서만 적용된다. 쓰레드가 cpu 동작을 마치고 I/O 작업을 실행하는 동안에는 다른 쓰레드가 cpu 동작을 동시에 실행할 수 있다. 따라서 cpu 동작이 많지 않고 I/O동작이 더 많은 프로그램에서는 멀티 쓰레드만으로 성능적으로 큰 효과를 얻을 수 있다.
#### References
- [[Python] 파이썬 멀티 쓰레드(thread)와 멀티 프로세스(process) by Nathan Kwon](https://monkey3199.github.io/develop/python/2018/12/04/python-pararrel.html)
- [[운영체제] Concurrency : locks- blackinkgj](https://blackinkgj.github.io/Locks/)
- [What is GIL in Python language?](#67)
---
## #51
#### What is the process of compilation and linking in python?
파이썬 파일(`.py`)를 실행하면, 소스 코드는 바이트 코드(byte code)로 변환되며, `.pyc`, `.pyo` 파일 형식으로 저장된다. 이 때 소스 코드를 바이트 코드로 변환하는 과정을 **컴파일(compilation) 단계**라고 한다.
파이썬 가상머신(Python Virtual Machine)이 바이트 코드를 기계어(machine code)로 변환하여 어떤 운영체제든 실행할 수 있도록 한다. 이 때 우리의 코드와 인터프리터가 필요한 라이브러리를 연결시키는 과정이 있는데, 이를 **링크(linking) 단계**라고 한다.
참고로 dis 모듈을 사용하여 소스 코드가 어떤 바이트 코드로 변환되는지 확인할 수 있다.
```python
import dis
def mult(a, b):
return a*b
dis.dis(mult)
# output:
# 4 0 LOAD_FAST 0 (a)
# 2 LOAD_FAST 1 (b)
# 4 BINARY_MULTIPLY
# 6 RETURN_VALUE
```
#### References
- [Compiling and Linking in Python - Net-informations.com](http://net-informations.com/python/iq/linking.htm)
- [What is the process of compilation and linking in python? - tutorialspoint](https://www.tutorialspoint.com/what-is-the-process-of-compilation-and-linking-in-python)
- [Python Compilation/Interpretation Process - stackoverflow](https://stackoverflow.com/questions/3299648/python-compilation-interpretation-process)
- [How does Python work? - towards data science](https://towardsdatascience.com/how-does-python-work-6f21fd197888)
- [Is Python interpreted or compiled? Yes. - Ned Batchelder](https://nedbatchelder.com/blog/201803/is_python_interpreted_or_compiled_yes.html)
- [Can Python be compiled? is it compiled or interpreted? - astateofdata](https://www.astateofdata.com/python-programming/can-python-be-compiled/)
---
## #52
#### What are Python libraries? Name a few of them.
파이썬 라이브러리는 패키지의 모음이다.

주로 사용되는 파이썬 라이브러리로는 [`Numpy`](https://numpy.org/), [`Pandas`](https://pandas.pydata.org/), [`Matplotlib`](https://matplotlib.org/), [`Scikit-learn`](https://scikit-learn.org/stable/) 등이 있다.
패키지에 대한 더 자세한 내용은 [#42. 패키지](#42) 참고!
---
## #53
#### What is split used for?
`split()`은 특정 문자를 기준으로 문자열을 분리할 때 사용한다.
```python
str.split(sep=None, maxsplit=-1)
```
sep을 구분자로 사용하여 문자열에 있는 단어 list를 반환한다.
sep이 지정되면 구분자를 기준으로 문자열을 분리하고, sep이 지정되지 않았거나 None인 경우에는 whitespace를 기준으로 문자열을 분리한다.
maxsplit이 지정되면 그 수만큼의 분할이 수행되고, maxsplit이 지정되지 않았거나 -1인 경우에는 가능한 모든 분할이 수행된다.
```python
a = "ai tech interview"
print(a.split()) # ['ai', 'tech', 'interview']
a = "ai tech interview"
print(a.split()) # ['ai', 'tech', 'interview']
a = "ai-tech-interview"
print(a.split("-")) # ['ai', 'tech', 'interview']
a = "ai-tech-interview"
print(a.split("-", 1)) # ['ai', 'tech-interview']
```
#### References
- [str.split - Python documentation](https://docs.python.org/3/library/stdtypes.html#str.split)
---
## #54
#### How to import modules in python?
```python
import [패키지/모듈]
from [패키지] import [모듈/변수/함수/클래스]
from [모듈] import [변수/함수/클래스]
```
`import` 키워드를 사용하여 모듈을 가져올 수 있다. 세 가지 방법으로 모듈을 가져올 수 있다.
```python
import numpy # importing using the original module name
import numpy as np # importing using an alias name
from numpy import * # imports everything present in the numpy module
```
```python
from numpy import argmax as arm # 이런거도 된다
nums = [1, 2, 3, 4, 5]
print(arm(nums)) # 4
```
#### References
- [45.4 패키지에서 from import 응용하기 - 파이썬 코딩 도장](https://dojang.io/mod/page/view.php?id=2450)
---
## #55
#### Explain Inheritance in Python with an example.
상속을 통해 상위 (부모) 클래스의 멤버 함수, 멤버 변수들을 모두 하위 (자식) 클래스가 가질 수 있다. 상위 클래스를 상속함으로써 코드 재사용성이 더 좋아지고, 관리가 용이해진다.
파이썬은 부모 클래스 A 를 자식 클래스 B 가 상속하는 **Single Inheritance**,
부모 클래스 A 를 자식 클래스 B 가 다시 B 를 자식 클래스 C 가 상속하는 **Multi-level Inheritance**,
부모 클래스 A 가 여러 자식 클래스에 상속되는 **Hierarchical Inheritance**,
하나의 자식 클래스가 여러 부모 클래스를 상속하는 **Multiple Inheritance** 가 있다.
---
## #56
#### How are classes created in Python?
**class** 키워드를 사용하여 클래스를 만들 수 있다. 이 때, 클래스명 옆 괄호에 상속받을 부모 클래스를 설정할 수도 있다.
기본적으로 `__init__` 이라는 매직 메소드를 통해 멤버 변수들을 세팅할 수 있다. 자세히는 클래스가 객체로 선언될 때, 멤버 변수의 값을 초기화하는 역할을 담당한다.
클래스 내에서는 멤버 함수를 만들 수 있고, 클래스 객체에서 멤버 함수를 사용할 수 있다.
```python
class MyClass():
def __init__(self, feature):
self.feature = feature
...
def my_method(self):
...
```
---
## #57
#### What is monkey patching in Python?
주로 테스트를 위해 많이 사용되는 방법으로, 어떤 클래스나 모듈의 일부 (함수나 변수 등) 를 로컬에서 런타임으로만 instance 를 통해 수정하는 방법을 말한다.
예시로 heath.py 파일의 A 클래스에 a 라는 함수가 있는데, 다른 파일에서 A 를 import 하여 a 함수 대신 new_a 를 할당하여 사용하는 방법이 있다.
```python
from heath import A
A.a = new_a
my_A = A() # A 클래스 객체 할당
my_A.a # new_a 가 동작
```
#### References
- [Python - Monkey Patch - IT 초보](https://newbiestory.tistory.com/60)
---
## #58
#### Does python support multiple inheritance?
파이썬은 자바와 다르게 multiple inheritance 을 지원한다. multiple inheritance 의 개념은 [#55](#55) 에서 참고할 수 있다.
예시는 아래와 같다.
```python
class P_A():
...
class P_B():
...
class C(P_A, P_B): #P_A 와 P_B 클래스를 동시에 상속
...
```
---
## #59
#### What is Polymorphism in Python?
다형성은 객체지향의 주요 개념으로 여러가지 형태를 가질 수 있는 능력을 말한다. 다형성은 코드의 유지보수에 도움을 준다.
파이썬은 다형성을 지원하는데, + 연산이나 len 연산에 대해 생각해볼 수 있다. 이들은 여러 타입의 변수에 대해서도 동일한 기능을 제공하는데 overriding 과 overloading 을 통해 각기 다른 타입의 변수에도 반응하도록 다형성을 주었기 때문에 가능하다.
#### References
- [다형성(polymorphism)- 잔재미 코딩](https://www.fun-coding.org/PL&OOP1-8.html)
- [[python] 다형성(polymorphism) - Son's Data story](https://datastory1.blogspot.com/2020/03/python-polymorphism.html)
---
## #60
#### Define encapsulation in Python?
캡슐화는 주요 변수나 함수를 외부로부터 보호하는 방법을 말한다. 캡슐화를 통해 코드의 안전성을 높일 수 있다.
파이썬에서는 클래스를 생각해볼 수 있다. 클래스의 멤버 변수나 멤버 함수에 접근하기 위해서는 클래스에 대한 객체를 만들어야 한다. 객체를 통해 멤버에 접근하기 때문에 직접 변수를 손대는 것보다 데이터를 더 안전하게 지킬 수 있다.
---
## #61
#### How do you do data abstraction in Python?
데이터 추상화는 객체지향의 주요 개념으로 사용자에게 데이터의 주요 정보만 제공하여 구체적인 구현은 몰라도 사용할 수 있게 만드는 방법이다.
파이썬에서는 abstract class 를 통해 데이터 추상화를 할 수 있다. abstract class 를 사용하기 위해서는 `abc` 모듈을 import 하고 `metaclass=ABCClass` 와 `@abstractmethod` 를 사용해야 한다.
```python
from abc import *
class 추상클래스명(metaclass=ABCMeta):
@abstractmethod
def 추상메소드(self):
pass
```
---
## #62
#### Does python make use of access specifiers?
파이썬은 다른 언어와 달리 private, protected 등의 접근 제한자를 직접 명시하지 않고 변수명을 통해 접근 제어를 한다.
접두사 _ 가 한 개 있는 경우에는 protected, 접두사 _ 가 두 개 있는 경우에는 private, 접두사 _ 가 없거나 접미사 _ 가 두 개 이상 있는 경우에는 public 이다.
#### References
- [[python] 접근 제어자 - 불곰](https://brownbears.tistory.com/112)
- [public, private, protect의 차이점 - Eureka Developer](https://eurekadeveloper.tistory.com/entry/public-private-protect%EC%9D%98-%EC%B0%A8%EC%9D%B4%EC%A0%90)
---
## #63
#### How to create an empty class in Python?
파이썬에서 클래스 내부에 아무 내용 없이 선언만 하기 위해서는 `pass` 나 `...` 을 사용할 수 있다. 추가적으로 empty class 를 선언한 후, 외부에서 객체를 통해 클래스의 변수나 함수를 만들 수도 있다.
```python
class empty():
... # or pass
e = empty()
e.a = 10
print(e.a) # 10
```
---
## #64
#### What does an object() do?
파이썬은 모든 것이 객체이다. 따라서 기본적으로 object 클래스를 상속받고 있다. `object()` 함수를 사용하면 새로운 기본 object 객체를 반환받을 수 있다.
---
## #65
#### What is map function in Python?
map 함수는 iterable 한 객체의 모든 원소에 동일한 함수를 적용하는 기능을 한다.
첫 인자로 적용할 함수를, 두번째 인자로 iterable 한 객체를 넣으면, iterable 한 map 객체 형태로 각 원소에 대해 함수가 적용된 묶음들이 담겨 나온다.
```python
int_arr = list(map(int, input().split()))
```
---
## #66
#### Is python numpy better than lists?
파이썬의 리스트는 각 원소들의 값을 직접 사용하지 않고 원소들의 주소를 참조하는 방식을 사용하기 때문에 원소들의 타입이 정해지지 않아 편리하지만 메모리를 많이 사용하고 느리다는 단점이 있다.
반면, 넘파이는 C 기반으로 구현되어 원소들의 타입을 미리 설정하여 메모리를 적게 사용하고 빠르다. 또한 행렬과 선형대수에 편리한 함수들을 제공한다는 장점도 있다.
---
## #67
#### What is GIL in Python language?
멀티쓰레딩을 할 때, 공유 자원에 대해 여러 쓰레드가 동시에 접근한다면 갱신된 내용이 유실되는 등의 문제가 발생할 수 있다. 이를 막기 위해 파이썬은 GIL (Global Interpreter Lock) 을 통해 python interpreter 에 한 쓰레드만 접근하여 모든 자원을 사용할 수 있게 한다.
정확히는 멀티 쓰레드가 bytecode(=instruction) 한 라인씩을 들고 있기 때문에, 한 쓰레드의 bytecode 한 줄에 대해서만 GIL 은 허용한다.
#### References
- [[python] GIL, Global interpreter Lock은 무엇일까? - 수학과의 좌충우돌 프로그래밍](https://ssungkang.tistory.com/entry/python-GIL-Global-interpreter-Lock%EC%9D%80-%EB%AC%B4%EC%97%87%EC%9D%BC%EA%B9%8C)
- [왜 Python에는 GIL이 있는가 - 개발새발블로그](https://dgkim5360.tistory.com/entry/understanding-the-global-interpreter-lock-of-cpython)
---
## #68
#### What is the CPython?
파이썬은 일반적으로 C 로 구현된 인터프리터 언어이다. 일반적인 C 언어와 구분하기 위해 파이썬 구현체 C 를 CPython 이라고 부른다.
CPython 은 인터프리터이면서 컴파일러로 Python 코드를 C 가 아닌 bytecode 로 컴파일해주고, 이를 interpreter(virtual machine) 가 실행하게 만든다.
이러한 CPython 의 interpreter 적인 특징이 파이썬을 차별되게 만들었다.
#### References
- [
Python에 대하여, Python은 어떻게 동작하는가? Python의 장단점 - cjh5414](https://cjh5414.github.io/about-python-and-how-python-works/)
---
## #69
#### What are Decorators in Python?
함수를 인자로 받고 내부 함수에서 인자로 받은 함수를 사용하는 클래스나 함수가 있을 때, 인자로 사용할 함수를 간편하게 지정해주는 역할을 하는 것이 Decorator 이다.
Decorator 의 사용 문법은 인자가 될 함수 위에 `@외부함수이름` 을 붙여주면 된다.
아래 예시를 보면, Decorator 를 통해 big_number 와 big_number2 라는 서로 다른 함수를 make_time_checker 가 인자로 받아 내부 함수에서 사용하고 있다.
```python
import time
def make_time_checker(func):
def new_func(*args, **kwargs):
start_time = time.perf_counter()
result = func(*args, **kwargs)
end_time = time.perf_counter()
print('실행시간:', end_time - start_time)
return result
return new_func
@make_time_checker
def big_number(n):
return n ** n ** n
@make_time_checker
def big_number2(n):
return (n+1) ** (n+1) ** (n+1)
```
#### References
- [5) 데코레이터 - 제대로 파이썬](https://wikidocs.net/23106)
---
## #70
#### What is object interning?
파이썬에서는 모든 것이 객체이므로 변수들은 값을 바로 가지지 않고 값을 가진 주소를 참조하게 된다.
object interning 은 자주 사용될, 즉 재활용될 object 에 대해 매번 새로운 주소를 할당하는 것은 비효율적이므로, 하나의 주소에 값을 주고 그 주소를 재활용하는 작업을 말한다.
기본적으로 파이썬에서는 `-5~256, [a-Az-Z0-9_]` 에 대해 고정된 주소를 할당하여 interning 을 하고 있다.
#### References
- [파이썬의 효과적인 메모리 재활용 방법 Interning - Nephtyw'S Programming Stash](https://nephtyws.github.io/python/interning/)
---
## #71
#### What is @classmethod, @staticmethod, @property?
> **@classmethod**
클래스 내부의 함수 중에 @classmethod 로 선언된 함수에 대해서는 클래스의 객체를 만들지 않고도 바로 접근이 가능하다. 하지만 함수의 첫 인자로 클래스를 받아서, 상속되었을 때 자식 클래스의 데이터를 따르는 특징이 있다.
> **@staticmethod**
@staticmethod 는 @classmethod 와 마찬가지로 클래스의 객체를 만들지 않고도 바로 접근할 수 있다. 하지만 클래스를 인자로 받지 않기 때문에, 상속되었을 때에도 자식 클래스의 데이터를 따르지 않고 처음에 클래스에서 선언한 데이터대로 함수가 사용된다.
```python
class Language:
default_language = "English"
def __init__(self):
self.show = '나의 언어는' + self.default_language
@classmethod
def class_my_language(cls):
return cls()
@staticmethod
def static_my_language():
return Language()
def print_language(self):
print(self.show)
class KoreanLanguage(Language):
default_language = "한국어"
>>> from language import *
>>> a = KoreanLanguage.static_my_language()
>>> b = KoreanLanguage.class_my_language()
>>> a.print_language()
나의 언어는English
>>> b.print_language()
나의 언어는한국어
```
> **@property**
객체지향 언어에서는 캡슐화를 위해 변수를 직접 지정하지 않고 객체의 함수를 통해 지정하고 받아오는 setter, getter 함수를 사용한다. 파이썬에서는 이를 편하게 사용할 수 있도록 @property 를 제공한다.
getter 가 될 함수에 @property 를, setter 가 될 함수에 @변수.setter 를 붙이면 된다.
```python
class Test:
def __init__(self):
self.__color = "red"
@property
def color(self):
return self.__color
@color.setter
def color(self,clr):
self.__color = clr
if __name__ == '__main__':
t = Test()
t.color = "blue"
print(t.color)
```
#### References
- [44. class 정리, 정적메소드 @classmethod와 @staticmethod의 정리 - 파이썬 기본을 갈고 닦자!](https://wikidocs.net/16074)
- [파이썬에서 @property 에 대해 알아보자. - HAMA 블로그](https://hamait.tistory.com/827)
---
================================================
FILE: answers/5-network.md
================================================
> **📌 질문 중 일부는 <strong>[WeareSoft님의 tech-interview](https://github.com/WeareSoft/tech-interview)</strong>를 참고하였습니다.**
## Table of Contents
- [TCP/IP의 각 계층을 설명해주세요.](#1)
- [OSI 7계층와 TCP/IP 계층의 차이를 설명해주세요.](#2)
- [Frame, Packet, Segment, Datagram을 비교해주세요.](#3)
- [TCP와 UDP의 차이를 설명해주세요.](#4)
- [TCP와 UDP의 헤더를 비교해주세요.](#5)
- [TCP의 3-way-handshake와 4-way-handshake를 비교 설명해주세요.](#6)
- [TCP의 연결 설정 과정(3단계)과 연결 종료 과정(4단계)이 단계가 차이나는 이유가 무엇인가요?](#7)
- [만약 Server에서 FIN 플래그를 전송하기 전에 전송한 패킷이 Routing 지연이나 패킷 유실로 인한 재전송 등으로 인해 FIN 패킷보다 늦게 도착하는 상황이 발생하면 어떻게 될까요?](#8)
- [초기 Sequence Number인 ISN을 0부터 시작하지 않고 난수를 생성해서 설정하는 이유가 무엇인가요?](#9)
- [HTTP와 HTTPS에 대해서 설명하고 차이점에 대해 설명해주세요.](#10)
- [HTTP 요청/응답 헤더의 구조를 설명해주세요.](#11)
- [HTTP와 HTTPS 동작 과정을 비교해주세요.](#12)
- [CORS가 무엇인가요?](#13)
- [HTTP GET과 POST 메서드를 비교/설명해주세요.](#14)
- [쿠키(Cookie)와 세션(Session)을 설명해주세요.](#15)
- [DNS가 무엇인가요?](#16)
- [REST와 RESTful의 개념을 설명하고 차이를 말해주세요.](#17)
- [소켓(Socket)이 무엇인가요? 자신 있는 언어로 간단히 소켓 생성 예시를 보여주세요.](#18)
- [Socket.io와 WebSocket의 차이를 설명해주세요.](#19)
- [IPv4와 IPv6 차이를 설명해주세요.](#20)
- [MAC Address가 무엇인가요?](#21)
- [라우터와 스위치, 허브의 차이를 설명해주세요.](#22)
- [SMTP가 무엇인가요?](#23)
- [노트북으로 `www.google.com`에 접속을 했습니다. 요청을 보내고 받기까지의 과정을 자세히 설명해주세요.](#24)
- [여러 네트워크 topology에 대해 간단히 소개해주세요.](#25)
- [subnet mask에 대해서 설명해주세요.](#26)
- [data encapsulation이 무엇인가요?](#27)
- [DHCP를 설명해주세요.](#28)
- [routing protocol을 몇 가지 설명해주세요. (ex. link state, distance vector)](#29)
- [이더넷(ethernet)이 무엇인가요?](#30)
- [client와 server의 차이점을 설명해주세요.](#31)
- [delay, timing(jitter), throughput 차이를 설명해주세요.](#32)
---
## #1
#### TCP/IP의 각 계층을 설명해주세요.
TCP/IP는 인터넷에서 표준으로 사용되고 있는 네트워크 프로토콜(규칙)을 의미한다. TCP/IP는 IP(Internet Protocol)을 중심으로 한 여러 프로토콜의 집합체로, TCP/IP 5계층 혹은 TCP/IP 4계층(링크계층과 물리계층을 하나의 계층으로 보는 경우)으로 불린다.
TCP/IP는 크게 5개의 계층으로 구성된다.
> **애플리케이션 계층**(Application Layer, L5)
네트워크 애플리케이션과 애플리케이션 계층 프로토콜이 있는 곳이다. HTTP, SMTP, FTP와 같은 많은 프로토콜을 포함한다. 도메인 주소를 32비트 네트워크 주소로 변환하는 기능을 위한 DNS(Domain Name Server)를 지원한다. 애플리케이션 계층 패킷을 **메시지**(message)라고 한다.
> **트랜스포트 계층**(Transport Layer, L4)
네트워크 계층에서 보내온 데이터 정렬, 오류 정정 등을 수행하고 신뢰할 수 있는 통신을 확보한다. TCP/UDP 같은 프로토콜이 이 계층에 위치한다. TCP, UDP에 대한 내용은 [[#4] TCP와 UDP의 차이를 설명해주세요.](#4) 을 참고한다. 트랜스포트 계층 패킷을 **세그먼트**(segment)라고 한다.
> **네트워크 계층**(Network Layer/IP Layer, L3)
다른 네트워크에 있는 목적지에 데이터를 전송하는 역할을 수행한다. 즉, 네트워크 간의 통신을 가능하게 해주는 역할을 수행한다. 이를 위해, 라우터(router) 장비와 IP 프로토콜(오직 하나만 존재), 라우팅 프로토콜이 사용된다. 라우터는 다른 네트워크와 통신하기 위해 경로를 설정하고 논리주소를 결정하는 역할을 수행한다.(경로설정) 네트워크 계층의 패킷을 **데이터그램**(datagram)이라 한다.
> **링크 계층**(Data Link Layer, L2)
네트워크 기기 간 데이터 전송 및 물리 주소를 결정하는 역할을 수행한다. 주로 건물이나 특정 지역을 범위로 하는 네트워크인 랜(LAN)에서 데이터를 정상적으로 주고받기 위해 필요한 계층이다. 데이터 링크 계층에서는 일반적으로 이더넷(Ethernet) 프로토콜이 사용되며, 스위치(switch) 같은 장치가 사용된다. 링크 계층 패킷을 **프레임**(frame)이라 한다.
> **물리 계층**(Physical Layer, L1)
물리적인 연결과 전기 신호 변환/제어를 담당하여, 이진 데이터를 전기 신호로 변환한다. 또한 컴퓨터와 네트워크 장비를 물리적으로 연결하여, 하나의 노드에서 다른 노드로 **비트를** 이동시키는 역할을 수행한다. 물리 계층의 프로토콜들은 링크(실제 전송매체 ex.광케이블)에 의존한다.

#### References
- [CH.01 컴퓨터 네트워크와 인터넷 - LandvibeDev/cs-special-forces-headquarters](https://github.com/LandvibeDev/cs-special-forces-headquarters/blob/main/network/CH.01%EC%BB%B4%ED%93%A8%ED%84%B0%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC%EC%99%80%EC%9D%B8%ED%84%B0%EB%84%B7/CH.01%20%EC%BB%B4%ED%93%A8%ED%84%B0%20%EB%84%A4%ED%8A%B8%EC%9B%8C%ED%81%AC%EC%99%80%20%EC%9D%B8%ED%84%B0%EB%84%B7.md)
- [[네트워크] TCP/IP 5계층에서 일어나는 일 (1) - 코알라일락's BLOG](https://zion830.tistory.com/104)
---
## #2
#### OSI 7계층와 TCP/IP 계층의 차이를 설명해주세요.

(`네트워크 인터페이스 계층`: TCP/IP 5계층에서 물리계층과 링크계층을 하나로 묶은 것)
OSI 7계층은 TCP/IP 계층의 애플리케이션 계층을 더 세분화한 것이다. TCP/IP 계층과 다른, 응용계층, 표현계층과 세션계층에 대해서 설명하고 나머지는 [[#1] CP/IP의 각 계층을 설명해주세요.](#1)을 참고한다.
> **응용 계층**(Application Layer)
사용자 또는 애플리케이션이 네트워크에 접근할 수 있도록 해주는 계층이다. 사용자를 위한 인터페이스를 지원하며, 사용자에게 보이는 유일한 계층이다. 메일 전송, 인터넷 접속 등의 작업을 수행할 수 있다.
> **표현 계층**(Presentation Layer)
응용계층으로부터 전달받거나 전송하는 데이터의 인코딩 및 디코딩이 이루어지는 계층이다. 응용 계층에서 데이터를 이해할 수 있도록, 응용프로그램에 맞춰 변환하게 된다. 예를들어, JPEG, TIFF, GIF, MPEG 등의 다양한 포맷을 구분하게 된다.
> **세션 계층**(Session Layer)
응용프로세스가 통신을 관리하기 위한 방법을 정의한다. 네트워크상 양쪽의 연결을 관리/지속시키는 역할과 세션을 만들거나 없애는 역할을 담당하는 계층이다. 통신하는 사용자들을 동기화하고 오류복구를 진행한다. 통신연결은 포트를 기반으로 구성하여 연결되며, OS가 세션계층에 속한다.
#### References
- [네크워크의 기본 OSI7 계층 - reakwon 티스토리](https://reakwon.tistory.com/59?category=300675)
- [IT관련 용어 - [OSI 7계층] 이란? - pst8627 블로그](https://blog.naver.com/PostView.nhn?blogId=pst8627&logNo=221670903384)
---
## #3
#### Frame, Packet, Segment, Datagram을 비교해주세요. (TCP/IP 5계층 기준)
- **Packet**: 컴퓨터 간에 데이터를 주고받을 때, 네트워크를 통해 전송되는 **데이터 조각**을 패킷이라고 부른다. 송신 측(애플리케이션)은 많은 양의 데이터를 한번에 보내는 것이 아니라, 일정 단위로 잘라서 보낸다. 각 계층에서 필요한 정보는 캡슐화/역캡슐화되어 전달되고, 수신 측은 받은 패킷을 다시 조립해서 사용한다.
- **Segment**: Transport 계층(L4)에서 신뢰할 수 있는 통신을 구현하기 위한 헤더를 데이터(L5 계층 데이터)에 붙이는데, 이렇게 만들어진 패킷을 세그먼트라고 부른다.
- **Datagram**: Network 계층(L3)에서 다른 네트워크와 통신하기 위한 헤더를 세그먼트(L4 계층 데이터)에 붙인것을 데이터그램, 데이터 세그먼트라고 부른다.
- **Frame**: 데이터 링크 계층(L2)에서 물리적인 통신 채널을 열기 위해 패킷에 헤더와 트레일러를 붙인다. 트레일러는 데이터를 전달할 때 데이터 끝 부분에 붙이는 정보로, 주로 에러 검출에 사용된다.

> **왜 패킷을 잘라서 보낼까?**
많은 데이터를 한번에 보내게 되면, 데이터 손실의 가능성이 있으며, 대역폭(신호를 전송할 수 있는 주파수 범위)을 너무 많이 차지하게 되므로, 패킷의 흐름을 원활히 조절하기 위함이다.
> **소켓(Socket), 포트(Port), 패킷(Packet)**
**Port**는 프로세스를 식별하기 위해, 호스트 내부적으로 프로세스가 할당받는 고유한 값이다. 같은 호스트 내에서 서로 다른 프로세스가 같은 포트 넘버를 가질 수 있음, 대신 같은 소켓을 사용하지는 못한다. `accept()`를 통해 만들어지는 소켓에는 새로운 포트 번호가 할당되는 것이 아니라, 서버가 가지는 포트(웹서버 기준, 80)와 동일한 포트 번호를 가진다. 만약 지정된 포트 번호를 다른 소켓이 사용하고 있다면, `bind()` API는 에러를 리턴한다. 포트는 논리적인 접속장소이다.
**Socket**은 프로세스로부터 네트워크로 데이터를 전달하는 출입구(인터페이스) 역할을 한다. `프로세스에서 소켓을 연다`고 표현하며, 수신 측 호스트의 트랜스포트 계층은 실제로 데이터(세그먼트)를 직접 프로세스로 전달하지 않고, 중간 매개자인 소켓에게 전달한다. 호스트에서는 하나 이상의 소켓이 존재할 수 있으므로 소켓은 고유의 식별자를 가지고 있어야한다. 같은 프로세스가 같은 포트를 가지고도 여러 개의 소켓을 열 수 있기 때문에, 소켓과 포트는 다른 개념이다.
요약하자면, **소켓**은 프로세스가 네트워크를 통해서 데이터를 주고받으려면 반드시 열어야 하는 창구 같은 것이고, **포트**는 프로세스 식별을 위해 하나의 호스트에서 프로세스에 할당하는 고유값이고, **패킷**은 네트워크 상의 데이터 조각을 말하는 것이다.
> **캡슐화/역캡슐화**
- **캡슐화**(Encapsulation): (데이터 송신 시)하위 계층으로 패킷을 보낼때, 하위계층에서 필요로하는 추가정보(메타데이터)를 헤더/트레일러에 추가하여 보내게된다.
- **역캡슐화**(Decapsulation): 데이터 수신 시, 상위 계층으로 패킷을 전달하고, 전달된 패킷의 헤더를 차례대로 제거하면서 데이터를 얻게 된다.
#### References
- [패킷이란 무엇일까? 패킷의 정의와 구조 - Jay's Blog](https://enlqn1010.tistory.com/9)
- [[네트워크] TCP/IP 5계층에서 일어나는 일 (1) - 코알라일락's BLOG](https://zion830.tistory.com/104)
---
## #4
#### TCP와 UDP의 차이를 설명해주세요.
TCP와 UDP는 모두 트랜스포트 계층(4계층)의 프로토콜이다. TCP와 UDP가 **공통적**으로 가지고 있는 기능은 아래와 같다.
1. **트랜스포트 다중화/역다중화 기능**(Transport Multiplexing/Demultiplexing): `호스트 대 호스트 전달`을 `프로세스 대 프로세스 전달`로 확장
2. **무결성 검사(오류검출)**: 헤더에 오류 검출 필드를 포함
이제 TCP와 UDP 각각에 대해 알아보자.
**UDP**는 위의 가장 기본적인 두가지 기능만을 제공한다. UDP는 **비신뢰적인 서비스**로서, 프로세스에 의해서 전송된 데이터가 손상되지 않은채로 목적지에 도착하는 것을 보장하지 않는다. 또한 **비연결형 서비스**이며, 오류검출은 선택사항이다.
UDP는 비연결형 서비스이므로 연결설정이 불필요하고 연결상태가 없다. 따라서 연결을 설정하기위한 어떠한 지연이 없고, 유지해야하는 정보가 없기 때문에 더 많은 클라이언트를 수용할 수 있다. 또한 UDP의 패킷 오버헤드(8 byte per segment)가 TCP(20 byte per segment)에 비해 더 작다는 장점이 있다. 그러나 혼잡제어를 사용하지 않아, 네트워크가 폭주상태에 빠지는 것을 막을 수 없다는 단점과 신뢰적이지 않으므로, 몇몇의 정보를 잃어버릴 수 있다는 단점이 존재한다.
**TCP**는 가장 기본적인 두가지 기능도 제공하면서, 신뢰적인 데이터 전달(Reliable Data Transfer) 기능, 연결지향형 서비스, 혼잡제어(Congestion control) 등의 기능을 제공한다.
**신뢰적인 데이터 전달**은 흐름제어, 순서번호, 확인응답, 타이머 등의 기술을 사용하여 프로세스에게 데이터가 순서대로 정확히 전달되도록 하는 역할을 한다. 종단 시스템 간에 IP의 비신뢰적인 서비스를 프로세스 사이의 신뢰적인 데이터 전송 서비스로 만들수 있으며, TCP에서의 오류검출은 필수사항이다. **혼잡제어**는 보내는 쪽(송신측)의 트래픽을 조절하여 스위치/링크의 혼잡을 방지하는 역할을 한다. 이는 특정 애플리케이션을 위해 제공하는 특정 서비스가 아니라, 전체를 위한 서비스로서, 혼잡한 네트워크 링크에서 각 TCP 연결이 링크의 대역폭을 공평하게 공유하여 통과하도록 해준다.
따라서, UDP는 속도증가와 지연 감소를 위해서 많이 사용되고, TCP는 신뢰성이 중요한 경우에 사용된다. 예를들어, UDP는 동영상 전송과 같이, 몇 프레임 정도 손실되어도 괜찮은 데이터 전송에 사용되고, TCP는 몇몇의 정보도 손실되어서는 안되는 애플리케이션에 이용된다.
#### References
- [CH.03 트랜스포트 계층 - cs-special-forces-headquarters](https://github.com/LandvibeDev/cs-special-forces-headquarters/blob/main/network/CH.03%ED%8A%B8%EB%9E%9C%EC%8A%A4%ED%8F%AC%ED%8A%B8%EA%B3%84%EC%B8%B5/CH.03%20%ED%8A%B8%EB%9E%9C%EC%8A%A4%ED%8F%AC%ED%8A%B8%20%EA%B3%84%EC%B8%B5.md)
---
## #5
#### TCP와 UDP의 헤더를 비교해주세요.
**UDP segment**의 간략한 구조는 아래와 같다.

애플리케이션 데이터는 UDP 데이터그램의 데이터 필드에 위치한다. UDP 헤더는 2바이트(16비트)씩 구성된 4개의 필드를 가진다. UDP 헤더는 `출발지 포트번호`, `목적지 포트번호`, `체크섬`, `길이`로 이루어져있다.
- **포트번호**는 (목적지) 호스트가 (역다중화 기능을 수행하는) 정확한 프로세스에게 애플리케이션 데이터를 넘기게 하기 위해 사용된다.
- **체크섬**(checksum)은 세그먼트에 오류가 발생했는지를 검사하기 위해 사용되며, 체크섬은 UDP 세그먼트 이외에 IP 헤더의 일부 필드도 계산한다.(가상헤더) UDP 헤더와 데이터를 모두 포함하여 체크하게 된다.
- **길이**는 헤더를 포함하는 UDP 세그먼트의 길이(바이트 단위)를 나타낸다. UDP헤더와 데이터를 합친 길이를 나타낸다.
---
**TCP segment**의 간략한 구조는 아래와 같다.

TCP 소켓은 4개의 다른 요소들의 집합에 의해 식별된다.(`출발지 IP`, `출발지 포트번호`, `목적지 IP`, `목적지 포트번호`) 따라서 IP를 제외한 `출발지/도착지 포트번호`(각 16 bit)와 `sequence number`(32 bit), `ack number`(32 bit)를 합쳐, 기본적으로 20 byte의 헤더를 가지게 되며, 옵션을 포함하면 최대 60 byte의 헤더를 가질 수 있다. 다른 출발지 주소를 가지는 세그먼트는, 다른 소켓을 통해서 프로세스에 전달된다. UDP와 다르게, TCP 세그먼트는 출발지 주소가 다르면, 다른 소켓으로 전달된다.
- **포트번호**는 IP 정보와 결합하여 출발지, 도착지를 구분하기 위해 사용된다.
- **Sequence Number**는 SYN 패킷을 보낼때, 동기화를 위해 사용되는 번호이다. 초기 Sequence Number를 ISN이라 부르며, 여기에는 랜덤한 수가 담긴다.
- **Ack Number**는 ACK 패킷을 보낼 때 동기화를 위해 사용되는 번호이다.
#### References
- [CH.03 트랜스포트 계층 - cs-special-forces-headquarters](https://github.com/LandvibeDev/cs-special-forces-headquarters/blob/main/network/CH.03%ED%8A%B8%EB%9E%9C%EC%8A%A4%ED%8F%AC%ED%8A%B8%EA%B3%84%EC%B8%B5/CH.03%20%ED%8A%B8%EB%9E%9C%EC%8A%A4%ED%8F%AC%ED%8A%B8%20%EA%B3%84%EC%B8%B5.md)
---
## #6
#### TCP의 3-way-handshake와 4-way-handshake를 비교 설명해주세요.
**핸드셰이크**(Handshake)란, 호스트 간 데이터를 전송하기 전에 먼저 정확한 전송을 보장하기 위해 상대방 컴퓨터와 사전에 세션을 수립하는 과정을 의미한다.

**3-way handshake**는 TCP의 연결을 초기화 할 때 사용한다. 양쪽 모두 데이터를 전송할 준비가 되었다는 것을 보장하고, 실제로 데이터 전달이 시작하기전에 한쪽이 다른 쪽이 준비되었다는 것을 알수 있도록 한다. 양쪽 모두 상대편에 대한 초기 순차일련변호를 얻을 수 있도록 한다. 절차는 다음과 같다.
1. 접속 요청 프로세스가 연결 요청 메시지 전송한다.(SYN)
2. 접속 요청을 받은 프로세스가 요청을 수락한다는 확인 메시지를 보낸다. (ACK) 동시에 접속 요청을 받은 프로세스도 접속 요청을 한 프로세스에 연결 요청을 보낸다.(SYN) → (SYN + ACK)
3. 마지막으로 접속 요청 프로세스가 수락 확인을 보내 연결을 맺는다.(ACK)
단순히 응답을 주고받는데 2-way Handshake면 충분해보이지 않는가? 왜 3-way 일까? TCP/IP 통신은 양방향성 connection이다. 위의 그림의 1번 과정에서 클라이언트가 연결 요청을 SYN으로 보내면, 서버는 클라이언트가 요청한 SYN에 대한 대답(ACK)과 함께, 자신도 연결하겠다는 요청의 의미로 SYN을 보내고, 클라이언트로부터 요청에 대한 대답(과정 3)을 받아야한다. 이 과정은 2-way handshaked에서는 성립될 수 없다.

**4-way handshake**는 세션을 종료하기 위해 수행되는 절차이다. 구체적인 과정은 다음과 같다.
1. 클라이언트가 연결을 종료하겠다는 FIN 플래그를 전송한다.
2. 서버는 일단 확인메시지를 보내고 자신의 통신이 끝날때까지 기다리는데, 이 상태가 `TIME_WAIT` 상태이다.
3. 서버가 통신이 끝났으면 연결이 종료되었다고 클라이언트에게 FIN 플래그를 전송한다.
4. 클라이언트는 확인했다는 메시지를 보낸다.
> **💡 `CLOSE_WAIT` 와 `TIME_WAIT` 상태란 무엇일까?**
> `TIME_WAIT` 상태로 대기하는 이유는, 세션 종료후, 혹시나 네트워크에 아직 라이브 패킷이 존재할수도 있기때문이다.
> **💡 용어**
>
> - **SYN**(Synchronization): 연결요청, 세션을 설정하는데 사용되며 초기에 시퀀스 번호를 보낸다.
> - **ACK**(Acknowledgement): 보낸 시퀀스 번호에 TCP 계층에서의 길이 또는 양을 더한 것과 같은 값을 ACK에 포함하여 전송한다.
> - **FIN**(Finish) : 세션을 종료시키는데 사용되며 더 이상 보낸 데이터가 없음을 표시한다.
#### References
- [[네트워크] 3-way / 4-way Handshake 란? - 방구의 개발냄새](https://bangu4.tistory.com/74)
- [TCP의 3 way Handshake과 4 way Handshake - 자비스가 필요해](https://needjarvis.tistory.com/157)
- [3-way handshake 4-way handshake는 왜 필요할까? - 안 평범한 개발자의 하루](https://unordinarydays.tistory.com/172)
---
## #7
#### TCP의 연결 설정 과정(3단계)과 연결 종료 과정(4단계)이 단계가 차이나는 이유가 무엇인가요?
연결 설정 과정과 다르게, 연결 종료 과정에서 고려해야하는 경우가 존재하는데, 이는 전송중인 데이터에 대한 경우이다. 클라이언트는 아직 서버로부터 못 받은 데이터가 있을 것을 대비하여 일정시간동안 세션을 남긴다(`TIME_WAIT`). 모든 데이터를 다 보내서 더 이상 보낼 데이터가 없다는 의미의 `FIN`을 받으면, 바로 연결을 종료한다.
#### References
- [[네트워크] TCP의 연결과 종료 : 3-way-handshake & 4-way-handshake - cherishee](https://hee96-story.tistory.com/101)
---
## #8
#### 만약 Server에서 FIN 플래그를 전송하기 전에 전송한 패킷이 Routing 지연이나 패킷 유실로 인한 재전송 등으로 인해 FIN 패킷보다 늦게 도착하는 상황이 발생하면 어떻게 될까요?
클라이언트에서 세션을 종료시킨 후 뒤늦게 도착하는 패킷이 있다면 이 패킷은 Drop되고 **데이터는 유실**될 것이다.
A 클라이언트는 이러한 현상에 대비하여 Client는 Server로부터 `FIN`을 수신하더라도 일정시간동안 세션을 남겨놓고 잉여 패킷을 기다리는 과정을 거치게 되는데 이 과정을 `TIME_WAIT` 라고 한다. 일정시간이 지나면, 세션을 만료하고 연결을 종료시키며, `CLOSE` 상태로 변화한다.
#### References
- [[네트워크] 3-way / 4-way Handshake 란? - 방구의 개발냄새](https://bangu4.tistory.com/74)
---
## #9
#### 초기 Sequence Number인 ISN을 0부터 시작하지 않고 난수를 생성해서 설정하는 이유가 무엇인가요?
Connection을 맺을 때 사용하는 포트는 유한 범위 내에서 사용하고 시간이 지남에 따라 재사용된다.
따라서 두 통신 호스트가 과거에 사용된 포트 번호 쌍을 사용하는 가능성이 존재한다.
서버 측에서는 패킷의 SYN을 보고 패킷을 구분하게 되는데 난수가 아닌 순차적인 number가 전송된다면 이전의 connection으로부터 오는 패킷으로 인식할 수 있다.
이러한 문제가 발생할 가능성을 줄이기 위해서 난수로 ISN을 설정하는 것이다.
#### References
- [[Network] (TCP) 3-way-handshake & 4-way-handshake - 어제보다 한 걸음 더](https://k39335.tistory.com/21)
---
## #10
#### HTTP와 HTTPS에 대해서 설명하고 차이점에 대해 설명해주세요.
HTTP란 **서버/클라이언트 모델을 따라 데이터를 주고받기 위한 프로토콜**이다. 즉, HTTP는 인터넷에서 하이퍼텍스트를 교환하기 위한 통신 규약으로, 80번 포트를 사용하고 있다. 따라서 HTTP 서버가 80번 포트에서 요청을 기다리고 있으며, 클라이언트는 80번 포트로 요청을 보내게 된다.
HTTP는 1989년 팀 버너스 리(Tim Berners Lee)에 의해 처음 설계되었으며, WWW(World-Wide-Web) 기반에서 세계적인 정보를 공유하는데 큰 역할을 하였다.
HTTPS는 **HTTP에 데이터 암호화가 추가된 프로토콜**이다. HTTPS는 HTTP와 다르게 443번 포트를 사용하며, 네트워크 상에서 중간에 제3자가 정보를 볼 수 없도록 공개키 암호화를 지원하고 있다.
HTTP는 암호화가 추가되지 않았기 때문에 보안에 취약한 반면, HTTPS는 안전하게 데이터를 주고받을 수 있다. 하지만 HTTPS를 이용하면 암호화/복호화의 과정이 필요하기 때문에 HTTP보다 속도가 느리다. 또한 HTTPS는 인증서를 발급하고 유지하기 위한 추가 비용이 발생하다.
개인 정보와 같은 민감한 데이터를 주고받아야 한다면 HTTPS를 이용해야 하지만, 단순한 정보 조회 등 만을 처리하고 있다면 HTTP를 이용하면 된다.
#### References
- [[Web] HTTP와 HTTPS 및 차이점 - MangKyu's Diary](https://mangkyu.tistory.com/98)
---
## #11
#### HTTP 요청/응답 헤더의 구조를 설명해주세요.
(TODO: 답변 작성하기)
#### References
- [HTTP 구조 및 핵심 요소 - teddybearjung](https://velog.io/@teddybearjung/HTTP-%EA%B5%AC%EC%A1%B0-%EB%B0%8F-%ED%95%B5%EC%8B%AC-%EC%9A%94%EC%86%8C)
- [[네트워크] http 란 - 인생의 로그캣](https://noahlogs.tistory.com/34?category=827412)
- [HTTP 메시지 - MDN Web Docs](https://developer.mozilla.org/ko/docs/Web/HTTP/Messages)
---
## #12
#### HTTP와 HTTPS 동작 과정을 비교해주세요.
(TODO: 답변 추가하기)
#### References
- [HTTP & DNS & TCP 정의 및 동작원리 - lkh's](https://lkhlkh23.tistory.com/76)
- [[Web 기초] HTTP 통신 과정 - MYSTERICO BLOG](https://mysterico.tistory.com/29)
- [[Web 기초] HTTPS의 동작 원리 (feat. 와이어샤크) - MYSTERICO BLOG](https://mysterico.tistory.com/30)
---
## #13
#### CORS가 무엇인가요?
교차 출처 리소스 공유(Cross-Origin Resource Sharing, CORS)는 **추가 HTTP 헤더를 사용하여, 한 출처에서 실행 중인 웹 애플리케이션이 다른 출처의 선택한 자원에 접근할 수 있는 권한을 부여하도록 브라우저에 알려주는 체제**이다.
CORS 체제는 브라우저와 서버 간의 안전한 교차 출처 요청 및 데이터 전송을 지원한다. 최신 브라우저는 XMLHttpRequest 또는 Fetch와 같은 API에서 CORS를 사용하여 교차 출처 HTTP 요청의 위험을 완화한다.
> **CORS의 동작 원리**
1. 기본적으로 웹은 다른 출처의 리소스를 요청할 때는 HTTP 프로토콜을 사용하여 요청을 하는데, 이때 브라우저는 요청 헤더 (request header)에 `Origin` 필드에 요청을 보내는 출처를 담아 전송한다.
2. 서버는 요청에 대한 응답을 하는데, 응답 헤더(response header)에 `Access-Control-Allow-Origin`이라는 값에 '이 리소스를 접근하는 것이 허용된 출처'를 내려준다.
3. 이후 응답을 받은 브라우저는 자신이 보냈던 요청의 Origin과 서버가 보내준 응답의 `Access-Control-Allow-Origin`을 비교해 본 후 이 응답이 유효한 응답인지 아닌지를 결정한다.

#### References
- [CORS란 무엇인가 ? - pilyeooong.log](https://velog.io/@pilyeooong/CORS%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80)
- [교차 출처 리소스 공유 - 위키백과](https://ko.wikipedia.org/wiki/%EA%B5%90%EC%B0%A8_%EC%B6%9C%EC%B2%98_%EB%A6%AC%EC%86%8C%EC%8A%A4_%EA%B3%B5%EC%9C%A0)
---
## #14
#### HTTP GET과 POST 메서드를 비교/설명해주세요.
> **GET**
GET은 **클라이언트에서 서버로 어떠한 리소스로부터 정보를 요청하기 위해 사용되는 메서드**이다. GET을 통한 요청은 URL 주소 끝에 파라미터로 포함되어 전송되며, 이 부분을 쿼리 스트링(query string)이라고 부른다.
방식은 URL 끝에 `?`를 붙이고 그다음 `변수명1=값1&변수명2=값2...` 형식으로 이어 붙이면 된다. 예를 들면 `www.example.com/show?name1=value1&name2=value2`이다. 서버에서는 `name1`과 `name2`라는 파라미터 명으로 각각 `value1`과 `value2`의 파라미터 값을 전달받을 수 있다.
> **POST**
POST는 **클라이언트에서 서버로 리소스를 생성하거나 업데이트하기 위해 데이터를 보낼 때 사용되는 메서드**이다. POST는 전송할 데이터를 HTTP 메시지 body 부분에 담아서 서버로 보낸다.(body의 타입은 Content-Type 헤더에 따라 결정된다.)
GET에서 URL의 파라미터로 보냈던 `name1=value1&name2=value2`가 body에 담겨 보내진다 생각하면 된다. POST로 데이터를 전송할 때 길이 제한이 따로 없어 용량이 큰 데이터를 보낼 때 사용하거나 GET처럼 데이터가 외부적으로 드러나는 건 아니라서 보안이 필요한 부분에 많이 사용된다. POST를 통한 데이터 전송은 보통 HTML form을 통해 서버로 전송된다.
> **GET과 POST의 차이점**
- 사용목적: GET은 서버의 리소스에서 데이터를 요청할 때, POST는 서버의 리소스를 새로 생성하거나 업데이트할 때 사용한다.
- 요청에 body 유무: GET은 URL 파라미터에 요청하는 데이터를 담아 보내기 때문에 HTTP 메시지에 body가 없다. POST는 body에 데이터를 담아 보내기 때문에 당연히 HTTP 메시지에 body가 존재한다.
- 멱등성(idempotent): GET 요청은 멱등이며, POST는 멱등이 아니다.
> **💡멱등이란?**
> 멱등의 사전적 정의는 연산을 여러 번 적용하더라도 결과가 달라지지 않는 성질을 의미한다. GET은 리소스를 조회한다는 점에서 여러 번 요청하더라도 응답이 똑같을 것이다. 반대로 POST는 리소스를 새로 생성하거나 업데이트할 때 사용되기 때문에 멱등이 아니라고 볼 수 있다.(POST 요청이 발생하면 서버가 변경될 수 있다.)
#### References
- [[네트워크] get 과 post 의 차이 - 인생의 로그캣](https://noahlogs.tistory.com/35)
---
## #15
#### 쿠키(Cookie)와 세션(Session)을 설명해주세요.
> <strong>쿠키(Cookie)</strong>
쿠키는 **클라이언트(브라우저) 로컬에 저장되는 키와 값이 들어있는 작은 데이터 파일**이다. 사용자 인증이 유효한 시간을 명시할 수 있으며, 유효 시간이 정해지면 브라우저가 종료되어도 인증이 유지된다는 특징이 있다.
쿠키는 클라이언트의 상태 정보를 로컬에 저장했다가 참조하며, Response Header에 Set-Cookie 속성을 사용하면 클라이언트에 쿠키를 만들 수 있다.
쿠키는 사용자가 따로 요청하지 않아도 브라우저가 Request 시에 Request Header를 넣어서 자동으로 서버에 전송한다.
쿠키는 다음과 같이 동작한다.
1. 클라이언트가 페이지를 요청
2. 서버에서 쿠키를 생성
3. HTTP 헤더에 쿠키를 포함 시켜 응답
4. 브라우저가 종료되어도 쿠키 만료 기간이 있다면 클라이언트에서 보관
5. 같은 요청을 할 경우 HTTP 헤더에 쿠키를 함께 보냄
6. 서버에서 쿠키를 읽어 이전 상태 정보를 변경할 필요가 있을 때 쿠키를 업데이트하여 변경된 쿠키를 HTTP 헤더에 포함시켜 응답
> <strong>세션(Session)</strong>
세션은 쿠키를 기반하고 있지만, 사용자 정보 파일을 브라우저에 저장하는 쿠키와 달리 세션은 **서버 측에서 관리**한다. 서버에서는 클라이언트를 구분하기 위해 세션 ID를 부여하며 웹 브라우저가 서버에 접속해서 브라우저를 종료할 때까지 인증 상태를 유지한다.
접속 시간에 제한을 두어 일정 시간 응답이 없다면 정보가 유지되지 않게 설정이 가능하다.
사용자에 대한 정보를 서버에 두기 때문에 쿠키보다 보안에 좋지만, 사용자가 많아질수록 서버 메모리를 많이 차지하게 된다. 즉 동접자 수가 많은 웹 사이트인 경우 서버에 과부하를 주게 되므로 성능 저하의 요인이 된다.
클라이언트가 Request를 보내면, 해당 서버의 엔진이 클라이언트에게 유일한 ID를 부여하는 데 이것이 세션 ID다.
세션의 동작 방식은 다음과 같다.
1. 클라이언트가 서버에 접속 시 세션 ID를 발급
2. 클라이언트는 세션 ID에 대해 쿠키를 사용해서 저장하고 가지고 있음
3. 클라이언트는 서버에 요청할 때, 이 쿠키의 세션 ID를 서버에 전달해서 사용
4. 서버는 세션 ID를 전달받아서 별다른 작업 없이 세션 ID로 세션에 있는 클라언트 정보를 가져옴
5. 클라이언트 정보를 가지고 서버 요청을 처리하여 클라이언트에게 응답
> **쿠키와 세션의 차이점**
- **사용자의 정보가 저장되는 위치**: 쿠키는 서버의 자원을 전혀 사용하지 않으며, 세션은 서버의 자원을 사용한다.
- **보안**: 쿠키는 클라이언트 로컬에 저장되기 때문에 변질되거나 request에서 스니핑 당할 우려가 있어서 보안에 취약하다. 반면 세션은 쿠키를 이용해서 세션 ID만 저장하고 그것으로 구분해서 서버에서 처리하기 때문에 비교적 보안성이 좋다.
- **라이프 사이클**: 쿠키는 만료시간이 있지만 파일로 저장되기 때문에 브라우저를 종료해도 계속해서 정보가 남아 있을 수 있다. 또한 만료 기간을 넉넉하게 잡아두면 쿠키 삭제를 할 때까지 유지될 수도 있다. 반면에 세션도 만료시간을 정할 수 있지만 브라우저가 종료되면 만료시간에 상관없이 삭제된다.
- **속도**: 쿠키에 정보가 있기 때문에 서버에 요청 시 속도가 빠르다. 반면 세션은 정보가 서버에 있기 때문에 처리가 요구되어 비교적 느린 속도를 낸다.
세션은 서버의 자원을 사용하기 때문에 무분별하게 만들다 보면 서버의 메모리가 감당할 수 없어질 수가 있고 속도가 느려질 수 있기 때문에 쿠키를 함께 사용한다.
#### References
- [쿠키와 세션 개념 - 라이언 서버](https://interconnection.tistory.com/74)
---
## #16
#### DNS가 무엇인가요?
모든 네트워크 통신에는 고유의 주소, 즉 IP 주소가 필요하다. 이때 통신을 주고받는 주체가 되는 네트워크에 연결되어 있는 모든 장치들을 host라고 한다. IP는 사람이 이해하고 기억하기 어렵기 때문에 이를 위해서 각 ip에 부여한 이름이 <strong>도메인(Domain)</strong>이다. 예를 들어 210.89.164.90의 도메인은 naver.com이다.
DNS(Domain Name Server 또는 Domain Name Service 모두를 의미)는 숫자로 이루어진 IP 주소와 일정한 형식을 가진 도메인을 서로 매핑 시키고 정보를 가지고 있다. 예를 들어 네이버에 접속하기 위해 주소창에 도메인(naver.com)을 입력하면, 컴퓨터는 해당 도메인이 연결된 DNS로 가서 서버 IP를 요청한다.
요청받은 네임 서버는 해당 도메인과 연결되어 있는 서버 IP(210.89.164.90)를 찾은 후, 컴퓨터에게 알려준다.
이처럼 도메인에 연결된 서버의 주소를 찾아주는 역할이 **DNS**이다.
> **브라우저가 도메인에 해당하는 IP를 찾는 순서**
1. local cache 안에 검색한 해당 도메인의 IP가 있는지 확인한다. 이미 해당 도메인을 방문한 적이 있다면 컴퓨터가 해당 도메인의 IP를 기억하고 있으므로 그것을 사용한다.
2. 만약 캐시에 없다면 컴퓨터 내부에 파일 형태로 존재하는 hosts 파일을 검색해서 찾는다. 해당 hosts 파일에 특정 도메인과 IP를 매핑 시켜놓으면 해당 도메인은 지정한 IP로 이동한다.
3. 만약 위의 경우에서 도메인에 대한 IP를 찾지 못하면 최종적으로 DNS를 검색한다.

#### References
- [[Network] 네트워크 기초 개념 - 차근차근 개발로그](https://hyuntaekhong.github.io/blog/Network/#3-dnsdomain-name-service)
- [Domain, DNS란 무엇인가 - 매일의 공부 기록](https://study-recording.tistory.com/8)
---
## #17
#### REST와 RESTful의 개념을 설명하고 차이를 말해주세요.
`REST`란 **Re**presentational **S**tate **T**ransfer의 약자로, <u>URI로 자원(Resource)을 명시하고 HTTP 메서드를 통해 해당 자원에 대한 CRUD(Create, Read, Update, Delete) 연산을 적용하는 것</u>을 의미한다.
여기서의 자원은 데이터베이스의 정보를 말한다. 하지만 클라이언트가 직접 데이터베이스에 접속해 변경하는 것은 매우 위험한 방식 이다. 그래서 이를 막기 위해 REST API를 사용하는 것이다. **클라이언트**가 서버에 데이터를 조회·생성·삭제·업데이트를 하겠다고 <u>HTTP 메서드로 요청</u>을 하면 **서버**는 로직에 따라 데이터베이스에 접근하여 <u>요청을 처리</u>한다.
`RESTful`은 REST 아키텍처로 구현된 웹 서비스를 나타내기 위한 용어로, "REST API를 제공하는 웹 서비스는 RESTful하다"처럼 사용된다.
> **HTTP 메서드 종류**
요청의 종류에 다라 다른 HTTP 메서드를 사용하는데 주로 사용하는 대표적인 메서드는 다음과 같다.
| 메서드 | 역할 |
| :----: | :------------------------------------------------------ |
| GET | 데이터를 조회한다. |
| POST | 데이터를 등록한다. 인증 작업을 거칠 때 사용하기도 한다. |
| DELETE | 데이터를 삭제한다. |
| PUT | 데이터를 새 정보로 통째로 업데이트할 때 사용한다. |
| PATCH | 데이터의 특정 필드를 수정할 때 사용한다. |
> **URI란?**
URI는 Uniform Resource Identifier의 약자로, 자원을 식별자로 취급하여 나타내는 주소를 말한다. URI의 종류로 URL과 URN이 있다. URI는 일반적으로 다음과 같은 형식을 갖고 있다.

#### References
- [[Network] REST란? REST API란? RESTful이란? - HeeJeong Kwon](https://gmlwjd9405.github.io/2018/09/21/rest-and-restful.html)
- [REST API 제대로 알고 사용하기 - NHN Cloud Meetup!](https://meetup.toast.com/posts/92)
- [URL과 URI의 의미와 차이점 (Difference between URL & URI) - Lael's World](https://blog.lael.be/post/61)
- [통합 자원 식별자 - 위키피디아](https://ko.wikipedia.org/wiki/%ED%86%B5%ED%95%A9_%EC%9E%90%EC%9B%90_%EC%8B%9D%EB%B3%84%EC%9E%90)
- [21장. 백엔드 프로그래밍: Node.js의 Koa 프레임워크 - 리액트를 다루는 기술](http://www.yes24.com/Product/Goods/79260300)
---
## #18
#### 소켓(Socket)이 무엇인가요? 자신 있는 언어로 간단히 소켓 생성 예시를 보여주세요.
`소켓(Socket)`이란 <u>Application 프로세스와 end-to-end 통신을 제공하는 Transport 프로토콜 사이의 인터페이스</u>을 말한다. 즉, Application에서 Transport 프로토콜을 쓰기 위한 API를 말한다.
소켓은 크게 UDP와 TCP 두 종류로 분류할 수 있다. 자세한 내용은 [#4. TCP와 UDP의 차이를 설명해주세요.](#4)을 참고!
파이썬으로 TCP에서의 소켓과 UDP에서의 소켓 생성 코드를 구현하면 다음과 같다. 소켓을 생성한다고 바로 통신을 할 수 없으며 실제 통신을 하기 위해는 바인딩, 연결 등 추가 작업이 필요하다.
> **TCP**
- TCP Client
```python
from socket import *
server_name = "example.com"
server_port = 1234
client_socket = socket(AF_INET, SOCKET_STREAM) # 소켓 생성
client_socket.connect((server_name, server_port)) # 서버에 연결 요청
```
- TCP Server
```python
from socket import *
server_port = 1234
server_socket = socket(AF_INET, SOCKET_STREAM) # 소켓 생성
server_socket.bind(('', server_port)) # 소켓에 주소 바인딩
server_socket.listen(1) # 클라이언트 연결 대기
(client_socket, client_address) = server_socket.accept() # 클라이언트 연결 수락
```
> **UDP**
- UDP Client
```python
from socket import *
server_name = "example.com"
server_port = 1234
cl
gitextract_wex188is/
├── .github/
│ ├── PULL_REQUEST_TEMPLATE.md
│ ├── scripts/
│ │ └── convert_for_gitbook.py
│ └── workflows/
│ └── sync-gitbook.yml
├── .gitignore
├── .mergify.yml
├── LICENSE
├── README.md
├── SUMMARY.md
└── answers/
├── 1-statistics-math.md
├── 2-machine-learning.md
├── 3-deep-learning.md
├── 4-python.md
├── 5-network.md
├── 6-operating-system.md
├── 7-data-structure.md
├── 8-algorithm.md
└── statistics-math-distribution.md
SYMBOL INDEX (5 symbols across 1 files) FILE: .github/scripts/convert_for_gitbook.py function convert_inline_math (line 14) | def convert_inline_math(content): function convert_callouts (line 32) | def convert_callouts(content): function convert_toc_anchors (line 63) | def convert_toc_anchors(content): function convert_file (line 71) | def convert_file(filepath): function main (line 85) | def main():
Condensed preview — 17 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (299K chars).
[
{
"path": ".github/PULL_REQUEST_TEMPLATE.md",
"chars": 1020,
"preview": "| **⚠ PR 템플릿은 수정하지 말아주세요!** <br/> **🔥 [PR 작성 규칙](https://github.com/boostcamp-ai-tech-4/ai-tech-interview/discussions/18"
},
{
"path": ".github/scripts/convert_for_gitbook.py",
"chars": 2550,
"preview": "#!/usr/bin/env python3\n\"\"\"Convert GitHub markdown syntax to GitBook-compatible syntax.\n\nTransformations:\n1. Inline math:"
},
{
"path": ".github/workflows/sync-gitbook.yml",
"chars": 836,
"preview": "name: Sync to GitBook\n\non:\n push:\n branches:\n - main\n\njobs:\n sync:\n runs-on: ubuntu-latest\n permissions:"
},
{
"path": ".gitignore",
"chars": 1352,
"preview": "# Created by https://www.toptal.com/developers/gitignore/api/windows,macos,linux\n# Edit at https://www.toptal.com/develo"
},
{
"path": ".mergify.yml",
"chars": 1026,
"preview": "pull_request_rules:\r\n - name: Assign yourself and request reviews automatically\r\n conditions:\r\n - -merged\r\n "
},
{
"path": "LICENSE",
"chars": 1067,
"preview": "MIT License\n\nCopyright (c) 2021 boost-devs\n\nPermission is hereby granted, free of charge, to any person obtaining a copy"
},
{
"path": "README.md",
"chars": 12314,
"preview": "\n\n<div align=\"center\"> \n <a href=\"https://hits.sh/github.com/boost-devs/ai-tech-interview/\"><img alt=\""
},
{
"path": "SUMMARY.md",
"chars": 414,
"preview": "# Table of contents\n\n- [Notice](README.md)\n\n## 🧑💻 INTERVIEW\n\n- [Statistics/Math](answers/1-statistics-math.md)\n- [Machin"
},
{
"path": "answers/1-statistics-math.md",
"chars": 23460,
"preview": "> **📌 질문은 <strong>[zzsza님의 Datascience-Interview-Questions](https://github.com/zzsza/Datascience-Interview-Questions)</s"
},
{
"path": "answers/2-machine-learning.md",
"chars": 40728,
"preview": "> **📌 질문은 <strong>[zzsza님의 Datascience-Interview-Questions](https://github.com/zzsza/Datascience-Interview-Questions)</s"
},
{
"path": "answers/3-deep-learning.md",
"chars": 40104,
"preview": "> **📌 질문은 <strong>[zzsza님의 Datascience-Interview-Questions](https://github.com/zzsza/Datascience-Interview-Questions)</s"
},
{
"path": "answers/4-python.md",
"chars": 51600,
"preview": "> **질문은 <strong>[Top 100 Python Interview Questions You Must Prepare In 2021 - edureka!](https://www.edureka.co/blog/int"
},
{
"path": "answers/5-network.md",
"chars": 34868,
"preview": "> **📌 질문 중 일부는 <strong>[WeareSoft님의 tech-interview](https://github.com/WeareSoft/tech-interview)</strong>를 참고하였습니다.**\n\n#"
},
{
"path": "answers/6-operating-system.md",
"chars": 26628,
"preview": "> **📌 질문은 <strong>[WeareSoft님의 tech-interview](https://github.com/WeareSoft/tech-interview)</strong>를 참고하였습니다.**\n\n## Tab"
},
{
"path": "answers/7-data-structure.md",
"chars": 17505,
"preview": "> **📌 질문은 <strong>[WeareSoft님의 tech-interview](https://github.com/WeareSoft/tech-interview)</strong>를 참고하였으며, 질문에 대한 답변은"
},
{
"path": "answers/8-algorithm.md",
"chars": 25752,
"preview": "> **📌 질문은 <strong>[WeareSoft님의 tech-interview](https://github.com/WeareSoft/tech-interview)</strong>를 참고하였습니다.**\n\n## Tab"
},
{
"path": "answers/statistics-math-distribution.md",
"chars": 7492,
"preview": "## 📝 Table of Contents\n\n- [베르누이 분포](#1)\n- [이항 분포](#2)\n- [카테고리 분포](#3)\n- [다항 분포](#4)\n- [가우시안 정규 분포](#5)\n- [t 분포](#6)\n- [카"
}
]
About this extraction
This page contains the full source code of the boost-devs/ai-tech-interview GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 17 files (281.9 KB), approximately 128.3k tokens, and a symbol index with 5 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.