카테고리 없음

06.26 머신러닝 심화

tundercloud 2026. 6. 26. 19:56

에이타니

 

● 클래스 불균형 문제 해결 - 가중치 조정 (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

머신러닝 심화 강의

 

머신러닝 심화 챕터3.ipynb
0.43MB
머신러닝 심화 챕터4.ipynb
0.24MB