
에이타니
● 클래스 불균형 문제 해결 - 가중치 조정 (Class Weighting)
- 손실 함수에서 각 클래스의 샘플에 서로 다른 가중치를 부여하는 방식
- 소수의 클래스의 샘플에 더 큰 가중치를 부여하면, 해당 샘플의 오분류 시 더 큰 손실이 발생하여 모델이 소수 클래스를 더 중요하게 학습하게 됨.
- 데이터셋의 크기를 변경하지 않고 손실 함수만 조정하므로 학습 시간이 크게 증가하지 않는다.
- 가중치 조정도 소수 클래스에 과도한 가중치를 부여하면 과적합 위험이 있다.
- 주로 분류 문제에 사용되며, 회귀 문제에만 국한되지 않음.
● 머신러닝에서 모델의 일반화 성능 (Generalization)
- 모델이 학습 과정에서 보지 못한 새로운 데이터에 대해서도 좋은 성능을 발휘하는 능력을 의미함.
→ 모델이 데이터의 본질적인 패턴을 학습했음을 나타냄.
● 과적합
- 학습 데이터의 노이즈까지 학습하여 학습 데이터에서는 높은 성능, 테스트 데이터에서는 낮은 성능을 보여 성능 차이를 발생시킴.
- 학습 데이터가 부족하면 일반적인 패턴을 학습하지 못해 새로운 데이터에서 성능이 떨어진다.
- 성능 차이의 주요 원인 : 데이터 분포의 차이 (Distribution Shift)
● 모델의 일반화 성능 향상 방법
- L1, L2 정규화 등은 모델의 가중치를 제한하여 과적합을 방지하고 일반화 성능을 향상시킨다.
- 교차 검증은 제한된 데이터를 효과적으로 활용하여 모델의 일반화 성능을 객관적으로 평가할 수 있다.
- 더 많은 데이터는 모델이 다양한 패턴을 학습하게 하여 일반화 성능을 향상시키는 가장 효과적인 방법 중 하나

코드카타
95번 K진수에서 소수 개수 구하기
양의 정수 n이 주어집니다. 이 숫자를 k진수로 바꿨을 때, 변환된 수 안에 아래 조건에 맞는 소수(Prime number)가 몇 개인지 알아보려 합니다.
● 0P0 처럼 소수 양쪽에 0이 있는 경우
● P0 처럼 소수 오른쪽에만 0이 있고 왼쪽에는 아무것도 없는 경우
● 0P 처럼 소수 왼쪽에만 0이 있고 오른쪽에는 아무것도 없는 경우
● P 처럼 소수 양쪽에 아무것도 없는 경우
● 단, P 는 각 자릿수에 0을 포함하지 않는 소수입니다.
○ 예를 들어, 101은 P 가 될 수 없습니다.
예를 들어, 437674을 3진수로 바꾸면 211020101011입니다.
여기서 찾을 수 있는 조건에 맞는 소수는 왼쪽부터 순서대로 211, 2, 11이 있으며, 총 3개입니다. (211, 2, 11을 k진법으로 보았을 때가 아닌, 10진법으로 보았을 때 소수여야 한다는 점에 주의합니다.)
211은 P0 형태에서 찾을 수 있으며, 2는 0P0 에서, 11은 0P 에서 찾을 수 있습니다.
정수 n과 k가 매개변수로 주어집니다. n을 k진수로 바꿨을 때, 변환된 수 안에서 찾을 수 있는 위 조건에 맞는 소수의 개수를 return 하도록 solution 함수를 완성해 주세요.
제한사항
● 1 ≤ n ≤ 1,000,000
● 3 ≤ k ≤ 10
1. n을 k진수로 변환한다.
● 파이썬은 k진수 변환을 직접 지원하지 않으므로 나머지를 이용해 변환한다.
2. 변환된 문자열에서 0을 기준으로 숫자를 분리한다.
● 조건에서 P 양쪽에 0이 있을 수 있다고 했으므로,
● 0을 만나면 그 앞뒤의 숫자들은 모두 후보가 된다.
● 따라서 split('0')을 사용하면 쉽게 후보 숫자를 얻을 수 있다.
3. 각 후보 숫자를 10진수로 바꾸고 소수인지 확인한다.
● 빈 문자열은 제외한다.
● 1은 소수가 아니다.
● √n까지만 나눠보면 충분하다.
def solution(n, k):
# 1. n을 k진수로 변환
def convert(n, k):
result = ""
while n > 0:
result += str(n % k)
n //= k
return result[::-1]
# 2. 소수 판별 함수
def is_prime(num):
if num < 2:
return False
# 제곱근까지만 확인
for i in range(2, int(num ** 0.5) + 1):
if num % i == 0:
return False
return True
# k진수 변환
number = convert(n, k)
# 0 기준으로 분리
candidates = number.split('0')
answer = 0
# 후보 숫자 확인
for c in candidates:
if c != "":
if is_prime(int(c)):
answer += 1
return answer
96번 주차 요금 계산
주차장의 요금표와 차량이 들어오고(입차) 나간(출차) 기록이 주어졌을 때, 차량별로 주차 요금을 계산하려고 합니다.
아래는 하나의 예시를 나타냅니다.
● 요금표
| 기본 시간(분) | 기본 요금(원) | 단위 시간(분) | 단위 요금(원) |
| 180 | 5000 | 10 | 600 |
● 입/출차 기록
| 시각(시:분) | 차량 번호 | 내역 |
| 05:34 | 5961 | 입차 |
| 06:00 | 0000 | 입차 |
| 06:34 | 0000 | 출차 |
| 07:59 | 5961 | 출차 |
| 07:59 | 0148 | 입차 |
| 18:59 | 0000 | 입차 |
| 19:09 | 0148 | 출차 |
| 22:59 | 5961 | 입차 |
| 23:00 | 5916 | 출차 |
● 자동차별 주차 요금
| 차량 번호 | 누적 주차 시간 (분) | 주차 요금 (원) |
| 0000 | 34 + 300 = 334 | 5000 + ⌈(334 - 180) / 10⌉ x 600 = 14600 |
| 0148 | 670 | 5000 +⌈(670 - 180) / 10⌉x 600 = 34400 |
| 5961 | 145 + 1 = 146 | 5000 |
● 어떤 차량이 입차된 후에 출차된 내역이 없다면, 23:59에 출차된 것으로 간주합니다.
○ 0000번 차량은 18:59에 입차된 이후, 출차된 내역이 없습니다. 따라서, 23:59에 출차된 것으로 간주합니다.
● 00:00부터 23:59까지의 입/출차 내역을 바탕으로 차량별 누적 주차 시간을 계산하여 요금을 일괄로 정산합니다.
● 누적 주차 시간이 기본 시간이하라면, 기본 요금을 청구합니다.
● 누적 주차 시간이 기본 시간을 초과하면, 기본 요금에 더해서, 초과한 시간에 대해서 단위 시간 마다 단위 요금을 청구합니다.
○ 초과한 시간이 단위 시간으로 나누어 떨어지지 않으면, 올림합니다.
○ ⌈a⌉ : a보다 작지 않은 최소의 정수를 의미합니다. 즉, 올림을 의미합니다.
주차 요금을 나타내는 정수 배열 fees, 자동차의 입/출차 내역을 나타내는 문자열 배열 records가 매개변수로 주어집니다. 차량 번호가 작은 자동차부터 청구할 주차 요금을 차례대로 정수 배열에 담아서 return 하도록 solution 함수를 완성해주세요.
제한사항
● fees의 길이 = 4
○ fees[0] = 기본 시간(분)
○ 1 ≤ fees[0] ≤ 1,439
○ fees[1] = 기본 요금(원)
○ 0 ≤ fees[1] ≤ 100,000
○ fees[2] = 단위 시간(분)
○ 1 ≤ fees[2] ≤ 1,439
○ fees[3] = 단위 요금(원)
○ 1 ≤ fees[3] ≤ 10,000
● 1 ≤ records의 길이 ≤ 1,000
○ records의 각 원소는 "시각 차량번호 내역" 형식의 문자열입니다.
○ 시각, 차량번호, 내역은 하나의 공백으로 구분되어 있습니다.
○ 시각은 차량이 입차되거나 출차된 시각을 나타내며, HH:MM 형식의 길이 5인 문자열입니다.
□ HH:MM은 00:00부터 23:59까지 주어집니다.
□ 잘못된 시각("25:22", "09:65" 등)은 입력으로 주어지지 않습니다.
○ 차량번호는 자동차를 구분하기 위한, `0'~'9'로 구성된 길이 4인 문자열입니다.
○ 내역은 길이 2 또는 3인 문자열로, IN 또는 OUT입니다. IN은 입차를, OUT은 출차를 의미합니다.
○ records의 원소들은 시각을 기준으로 오름차순으로 정렬되어 주어집니다.
○ records는 하루 동안의 입/출차된 기록만 담고 있으며, 입차된 차량이 다음날 출차되는 경우는 입력으로 주어지지 않습니다.
○ 같은 시각에, 같은 차량번호의 내역이 2번 이상 나타내지 않습니다.
○ 마지막 시각(23:59)에 입차되는 경우는 입력으로 주어지지 않습니다.
○ 아래의 예를 포함하여, 잘못된 입력은 주어지지 않습니다.
□ 주차장에 없는 차량이 출차되는 경우
□ 주차장에 이미 있는 차량(차량번호가 같은 차량)이 다시 입차되는 경우
1. 기록 분리
● records를 하나씩 확인하면서 시간, 차량번호, 입출차 상태로 나눈다.
● 시간은 계산하기 편하게 분 단위로 변환한다.
2. 입차/출차 관리
● 차량이 IN 이면 현재 입차 시간을 저장한다.
● 차량이 OUT 이면 저장된 입차 시간과 현재 시간을 이용해 주차 시간을 계산하고 누적한다.
3. 출차하지 않은 차량 처리
● 마지막까지 IN 상태인 차량은 23:59에 출차했다고 가정한다.
● 23:59를 분으로 바꿔서 계산한다.
4. 요금 계산
● 기본 시간 이하 → 기본 요금
● 기본 시간 초과 → 기본 요금 + 초과 시간에 대한 요금
● 단위 시간으로 나누어 떨어지지 않으면 올림 처리
import math
def solution(fees, records):
# 기본 시간, 기본 요금, 단위 시간, 단위 요금
base_time, base_fee, unit_time, unit_fee = fees
# 차량별 누적 주차 시간
total_time = {}
# 현재 입차한 차량 저장
parking = {}
# 시간을 분으로 변환하는 함수
def convert_time(time):
h, m = map(int, time.split(":"))
return h * 60 + m
for record in records:
time, car, status = record.split()
time = convert_time(time)
if status == "IN":
# 입차 시간 저장
parking[car] = time
else:
# 출차 -> 주차 시간 계산
total = time - parking[car]
# 누적 시간 저장
total_time[car] = total_time.get(car, 0) + total
# 출차했으므로 제거
del parking[car]
# 출차 기록이 없는 차량 처리
for car, in_time in parking.items():
total = convert_time("23:59") - in_time
total_time[car] = total_time.get(car, 0) + total
answer = []
# 차량 번호 오름차순 정렬
for car in sorted(total_time.keys()):
time = total_time[car]
# 기본 시간 이하
if time <= base_time:
fee = base_fee
# 기본 시간 초과
else:
extra_time = time - base_time
# 올림 처리
count = math.ceil(extra_time / unit_time)
fee = base_fee + count * unit_fee
answer.append(fee)
return answer

머신러닝 심화 강의