
에이타니
● RMSE
scikit - learn의 mean_squared_error 함수를 통해 계산된 MSE 값에 제곱근(Square Root)를 취한다.
→ numpy 라이브러리의 np.sqrt() 함수를 사용
● F1 - Score
- 산술평균은 하나의 값이 매우 낮더라도 다른 하나가 높으면 평균값이 어느정도 높게 유지될 수 있다.
- but. 조화평균을 사용하는 F1-score는 precision과 Recall 두 지표가 모두 높을 때만 높은 값을 가지며, 어느 한쪽이 심하게 낮으면 결과도 크게 낮아지기 때문에 지표 간의 불균형을 방지하고 보다 균형 잡힌 모델 성능을 평가할 수 있다.
● 클래스 불균형
- 정확도(Accuracy)는 신뢰할 수 없는 지표이다.
- 소수 클래스의 학습 부족을 야기한다.
- 실무에서 정상/이상, 질병 유/무 등의 데이터는 자연스럽게 불균형한다.
- 모델이 다수 클래스에 과적합되는 경향이 있다.
- class_weight = 'balanced' : scikit-learn에서 클래스 불균형을 자동으로 처리하는 옵션, 각 클래스에서 역비례 가중치를 부여
● 오버 샘플링 - SMOTE
- Synthetic Minority Over-sampling Technique는 소수 클래스의 샘플과 그 이웃 샘플들 사이를 선형 보간하여 새로운 합성 샘플을 생성하는 기법이다.
- 소수 클래스의 샘플을 증가시키는 기법
● 언더 샘플링
- 다수 클래스를 제거하는 기법
- 랜덤 언더샘플링은 다수 클래스의 중요한 정보를 담고 있는 샘플을 제거할 수 있어 정보 손실 위험이 있다.

코드카타
92번 프로세스
운영체제의 역할 중 하나는 컴퓨터 시스템의 자원을 효율적으로 관리하는 것입니다.
이 문제에서는 운영체제가 다음 규칙에 따라 프로세스를 관리할 경우 특정 프로세스가 몇 번째로 실행되는지 알아내면 됩니다.
1. 실행 대기 큐(Queue)에서 대기중인 프로세스 하나를 꺼냅니다.
2. 큐에 대기중인 프로세스 중 우선순위가 더 높은 프로세스가 있다면 방금 꺼낸 프로세스를 다시 큐에 넣습니다.
3. 만약 그런 프로세스가 없다면 방금 꺼낸 프로세스를 실행합니다.
3.1 한 번 실행한 프로세스는 다시 큐에 넣지 않고 그대로 종료됩니다.
예를 들어 프로세스 4개 [A, B, C, D]가 순서대로 실행 대기 큐에 들어있고, 우선순위가 [2, 1, 3, 2]라면 [C, D, A, B] 순으로 실행하게 됩니다.
현재 실행 대기 큐(Queue)에 있는 프로세스의 중요도가 순서대로 담긴 배열 priorities와, 몇 번째로 실행되는지 알고싶은 프로세스의 위치를 알려주는 location이 매개변수로 주어질 때, 해당 프로세스가 몇 번째로 실행되는지 return 하도록 solution 함수를 작성해주세요.
제한사항
●priorities의 길이는 1 이상 100 이하입니다.
○ priorities의 원소는 1 이상 9 이하의 정수입니다.
○ priorities의 원소는 우선순위를 나타내며 숫자가 클 수록 우선순위가 높습니다.
● location은 0 이상 (대기 큐에 있는 프로세스 수 - 1) 이하의 값을 가집니다.
○ priorities의 가장 앞에 있으면 0, 두 번째에 있으면 1 … 과 같이 표현합니다.
- 우선순위가 높은 프로세스가 있으면 현재 프로세스를 큐 뒤로 이동
- 실행된 프로세스는 제거
- 순서
1. 큐에 (우선순위, 인덱스)를 저장
2. pop한 프로세스보다 높은 우선순위가 있는지 확인
3. 있으면 다시 append
4. 없으면 실행 횟수 증가
5. 원하는 위치의 프로세스가 실행되면 종료
from collections import deque
def solution(priorities, location):
queue = deque()
# (우선순위, 위치) 형태로 큐 생성
for i, p in enumerate(priorities):
queue.append((p, i))
answer = 0
while queue:
current = queue.popleft()
# 큐 안에 더 높은 우선순위가 있는지 확인
if any(current[0] < q[0] for q in queue):
queue.append(current)
else:
# 실행
answer += 1
# 찾는 프로세스라면 반환
if current[1] == location:
return answer
93번 피로도
XX게임에는 피로도 시스템(0 이상의 정수로 표현합니다)이 있으며, 일정 피로도를 사용해서 던전을 탐험할 수 있습니다.
이때, 각 던전마다 탐험을 시작하기 위해 필요한 "최소 필요 피로도"와 던전 탐험을 마쳤을 때 소모되는 "소모 피로도"가 있습니다.
"최소 필요 피로도"는 해당 던전을 탐험하기 위해 가지고 있어야 하는 최소한의 피로도를 나타내며, "소모 피로도"는 던전을 탐험한 후 소모되는 피로도를 나타냅니다.
예를 들어 "최소 필요 피로도"가 80, "소모 피로도"가 20인 던전을 탐험하기 위해서는 유저의 현재 남은 피로도는 80 이상 이어야 하며, 던전을 탐험한 후에는 피로도 20이 소모됩니다.
이 게임에는 하루에 한 번씩 탐험할 수 있는 던전이 여러개 있는데, 한 유저가 오늘 이 던전들을 최대한 많이 탐험하려 합니다.
유저의 현재 피로도 k와 각 던전별 "최소 필요 피로도", "소모 피로도"가 담긴 2차원 배열 dungeons 가 매개변수로 주어질 때, 유저가 탐험할수 있는 최대 던전 수를 return 하도록 solution 함수를 완성해주세요.
제한사항
● k는 1 이상 5,000 이하인 자연수입니다.
● dungeons의 세로(행) 길이(즉, 던전의 개수)는 1 이상 8 이하입니다.
○ dungeons의 가로(열) 길이는 2 입니다.
○ dungeons의 각 행은 각 던전의 ["최소 필요 피로도", "소모 피로도"] 입니다.
○ "최소 필요 피로도"는 항상 "소모 피로도"보다 크거나 같습니다.
○ "최소 필요 피로도"와 "소모 피로도"는 1 이상 1,000 이하인 자연수입니다.
○ 서로 다른 던전의 ["최소 필요 피로도", "소모 피로도"]가 서로 같을 수 있습니다.
● 문제 접근 과정
처음에는 던전을 어떤 순서로 방문해야 최대 개수를 탐험할 수 있는지가 핵심이라고 생각했다.
각 던전은 입장 조건(최소 필요 피로도)이 있고, 탐험 후 피로도가 감소하기 때문에 단순히 피로도가 높은 던전부터 가는 방식으로는 최적의 결과를 보장할 수 없다.
던전 개수가 최대 8개로 작기 때문에 모든 방문 순서를 확인하는 완전탐색이 가능하다고 판단했다.
따라서 현재 피로도를 기준으로 탐험 가능한 던전을 하나 선택하고, 탐험한 던전은 다시 방문하지 않도록 체크하면서 다음 던전을 탐색하는 DFS 방식으로 접근했다.
DFS를 진행하면서 현재까지 탐험한 던전 개수를 저장하고, 탐색할 때마다 최댓값을 갱신했다.
탐색이 끝나면 방문 처리를 다시 해제하는 백트래킹을 사용해 다른 탐험 순서도 모두 확인했다.
● 정리
* 던전 수가 작기 때문에 완전탐색 가능
* 던전 순서에 따라 결과가 달라지므로 모든 경우 탐색 필요
* DFS + 방문 체크 + 백트래킹으로 최대 탐험 횟수 탐색
* 시간복잡도는 최대 O(N!)이며 N이 8이라 충분히 가능
def solution(k, dungeons):
# 던전 방문 여부를 저장하는 리스트
# 예) visited[0] = True -> 0번 던전은 탐험 완료
visited = [False] * len(dungeons)
# 최대 탐험 가능한 던전 개수 저장
answer = 0
# 현재 피로도와 탐험한 던전 개수를 가지고 탐색
def dfs(fatigue, count):
nonlocal answer
# 현재까지 탐험한 던전 개수 중 최댓값 갱신
answer = max(answer, count)
# 모든 던전을 확인
for i in range(len(dungeons)):
need = dungeons[i][0] # 던전 입장에 필요한 최소 피로도
consume = dungeons[i][1] # 탐험 후 소모되는 피로도
# 아직 방문하지 않았고, 현재 피로도로 입장 가능하다면
if not visited[i] and fatigue >= need:
# 해당 던전 방문 처리
visited[i] = True
# 던전을 탐험하고 감소한 피로도로 다음 탐색 진행
dfs(fatigue - consume, count + 1)
# 다른 탐험 순서를 확인하기 위해 방문 상태 되돌리기 (백트래킹)
visited[i] = False
# 초기 피로도와 탐험 횟수 0부터 시작
dfs(k, 0)
return answer
94번 타겟 넘버
n개의 음이 아닌 정수들이 있습니다.
이 정수들을 순서를 바꾸지 않고 적절히 더하거나 빼서 타겟 넘버를 만들려고 합니다.
예를 들어 [1, 1, 1, 1, 1]로 숫자 3을 만들려면 다음 다섯 방법을 쓸 수 있습니다.
-1+1+1+1+1 = 3
+1-1+1+1+1 = 3
+1+1-1+1+1 = 3
+1+1+1-1+1 = 3
+1+1+1+1-1 = 3
사용할 수 있는 숫자가 담긴 배열 numbers, 타겟 넘버 target이 매개변수로 주어질 때 숫자를 적절히 더하고 빼서 타겟 넘버를 만드는 방법의 수를 return 하도록 solution 함수를 작성해주세요.
제한사항
● 주어지는 숫자의 개수는 2개 이상 20개 이하입니다.
● 각 숫자는 1 이상 50 이하인 자연수입니다.
● 타겟 넘버는 1 이상 1000 이하인 자연수입니다.
각 숫자마다 + 또는 -를 선택할 수 있기 때문에 모든 경우를 확인해야 한다고 생각했다.
숫자의 개수가 최대 20개라서 2^20 정도의 경우만 탐색하면 되므로 DFS를 사용해 모든 경우를 탐색했다.
DFS에서는 현재까지 계산한 값과 몇 번째 숫자인지를 전달하고,
마지막 숫자까지 탐색했을 때 합이 target과 같으면 정답 개수를 증가시키는 방식으로 해결했다.
def solution(numbers, target):
answer = 0
def dfs(index, total):
nonlocal answer
# 모든 숫자를 사용한 경우
# 현재 합이 target이면 경우의 수 증가
if index == len(numbers):
if total == target:
answer += 1
return
# 현재 숫자를 더하는 경우
dfs(index + 1, total + numbers[index])
# 현재 숫자를 빼는 경우
dfs(index + 1, total - numbers[index])
# 0번째 숫자부터 탐색 시작
dfs(0, 0)
return answer

머신러닝 심화 강의