기타/통계, 머신러닝

250708_머신러닝(앙상블), 파이썬(람다함수, 고차함수, try-except)

baektree 2025. 7. 8. 23:50

요약/나만의 인사이트

  • 파이썬
    • 튜플 언팩킹
      • 튜플을 언팩킹해서 변수에 담아 반환할 수 있다.
      names = ['김철수', '나응식', '배영만']
      scores = [86, 46, 90]
      
      for name, score in zip(names, scores):
      	print(f"{name}의 점수는 {score}점")
      
      #김철수의 점수는 86점
      #나응식의 점수는 46점
      #배영만의 점수는 90점
      # ('김철수', 86), ('나응식', 46), ('배영만', 90)의 튜플을 언팩킹해서 튜플 속 요소를 name과 score에 담아냄
      
    • 람다함수
      • lambda매겨변수 : 표현식
      • 함수를 간결하게 표현 한 것
      • 함수를 선업없이, 이름없이 사용할 수 있다.
      • map이나 filter와 같은 고차함수와 같이 쓰인다.
      #함수
      def plus(x,y):
      	print(x + y)
      
      #람다함수
      plus = lambda x, y : x + y
      print(plus(3, 5))
      
      #람다함수 다르게 
      print((lambda x, y: x + y)(3, 5))
      
    • filter, map
      • filter (함수, 이러터블한 데이터) : 반복가능한 객체에 특정 조건을 만족하는 요소들만 필터링해
      numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
      
      # numbers의 요소를 반복할건데 x가 짝수인 경우만 필터링해서 반환해
      even_numbers = filter(lambda x : x % 2 == 0, numbers)
      print(list(even_numbers))
      
      • map(함수, 이터러블한 데이터): 반복가능한 객체에 특정 함수를 동작시켜서 요소들을 반환해
      numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
      
      # numbers의 요소를 반복할건데 x에 인자(요소)를 받아 제곱해서 반환해
      squared_numbers = map(lambda x : x**2, numbers)
      print(list(squared_numbers))
      
    • try, except
      • try 중요한코드 except 오류 시 처리될 내용
      • 코드에 오류가 있어도 작동한다. 이후 오류를 안전하게 처리할 수 있다.
      students = ["영희", "철수", "민수"]
      averages = [81, 70, 90]
      
      student_score = list(zip(students, averages))
       # [('영희', 81), ('철수', 70), ('민수', 90)]
       
      try:
      	num = int(input("숫자를 입력하세요.: "))
      	name, score = student_score[num] #튜플에서만 언팩킹가능
      	print(f"{name}의 점수는 {score}입니다.")
      except IndexError:
      	print("해당 번호의 학생은 없습니다.")
      except ValueError:
      	print("정수를 입력해주세요.")
      
  • numpy 인덱싱과 슬라이싱
    • 넘파이에서 만든 arr이 2차원 배열일 때 행, 열 방향으로 슬라이싱과 인덱싱
      • 1:3 범위 슬라이싱 (끝 숫자 직전까지 포함)
      • 1 특정한 인덱스 하나 선택
    • 다양한 예시
      • arr[:, 1:3] 모든행, 1번~ 2번 열까지 선택
      • arr[:, 1] 모든행, 1번 열
      • arr[:, :] 모든행, 모든열
      • arr[:, 0:2] 모든행, 0번 열부터 1번째 열까지 선택
      • arr[:3, 1] 0~2번 행까지, 1번열만
      • arr[1, 0:2] 1번 행, 0번 ~1번열까지
      • 1차원 배열과 2차원 배열2차원 - np.array([
      • [10, 20, 30, 40], - 리스트가 여러개 [50, 60, 70, 80], ])
      • 1차원 - np.array([10, 20, 30, 40]) - 리스트가 하나

새롭게 알게 된 것

  • 앙상블 기법
    • 앙상블
      • 여러개의 모델 조합 더 좋은 예측 성능 효과를 구현하는 것
      • 개별 모델의 편향과 분산을 상호 보완 → 과적합 문제 해결
    • 종류
      • Bagging - 병렬적(독립적)으로 학습
      • Boosting - 순차적으로 학습
  • 배깅(Bagging)
    • 학습데이터를 무작위로 여러 부분으로 나누어 각각 독립적으로 모델을 학습
    • 예측 시에는 여러모델의 결과를 평균(회귀), 혹은 다수결(분류)로 결정
    • 랜덤 포레스트 : 결정 트리 여러개를 만들 때, 각 트리에 사용하는 피처와 데이터 샘플을 무작위로 선택
    • 많은 수의 모델을 학습해야 하므로 메모리 사용량이 많아질 수 있음.
  • 부스팅(Boosting)
    • 순차적으로 모델을 학습하면서 이전 모델이 만든 예측 오류를 보정하도록 설계
    • 각 단계에서 오류를 보정하기 때문에, 복잡한 데이터 패턴을 잘 포착
    • 종류 : XGBOOST, LightGBM, CatBoost
      • XGBOOST 시나리오
        1. 기본 모델 훈련 - 예측 오류 확인
        2. 예측 오류가 컸던 샘플에 대해 높은 가중치 부여
        3. 다음 모델(결정 트리) 훈련 - 다시 오류 보정
        4. 이 과정을 여러번 반복하여 최종 예측 시에는 모두 합산
      • catboost
        • cat_features에 범주형 변수 넣어주면 인코딩 안해도 됨 그래도 학습, 예측 가능
        • vervose = 1 하나씩 학습할 때마다 보여줌
        • stratify=y를 통해 생존 여부의 클래스 분포가 분할 시 유지되도록 합니다.
  • 과적합
    • 학습한 데이터에 대해선 지나치게 최적화
    • 그러나 테스트(실제환경)에는 성능이 떨어지는 상황
    • 일반화가 잘 안된 상황
    • 앙상블 모델의 이점 = 과적합 문제 해결
      (why 다양한 모델을 사용해 결론을 내리니까)
    • 모델이 복잡하면 과적합이 발생할 수 있다. (why 트레인 데이터의 모든 데이터를 민감하게 반응 할 수 있기 때문)
    • 너무 많은 에폭(반복횟수)이 있으면 과적합의 우려가 있음.
    • 과적합의 해결
      • 앙상블(서로 다른 모델을 결합)
      • 규제(regularization) : 가중치가 극단적인 값을 가지지 않도록함.
      • 드롭아웃: 딥러닝에서 주로 사용, 학습시 일부 뉴런을 비활성화 해서 결과 조합
      • 데이터 증강 : 기술을 써서 데이터를 늘리는 것
      • 조기종료: 성능이 좋을 것 같은 순간까지만 학습
  • 과소적합
    • 학습이 잘 안된 것, 그래서 예측 성능도 좋지 않음
    • 따라서 학습을 제대로 시켜줘야 함, 모델의 구조를 변경할 수 있음. 모델을 더욱 복잡하게 함
  • 하이퍼파라미터 튜닝
    • 파라미터 : 모델이 학습해서 모델이 결정한 값
    • 하이퍼파라미터 : 모델이 학습을 하기 전 사람이 정해준 값
    • 하이퍼파라미터 튜닝을 위한 준비
      • 데이터셋 분할
        • train학습, test성능평가, vaildation하이퍼파라미터 성능평가 (vaildation은 하이퍼파리미터 튜닝 후 성능 평가시 활용)
      • 교차검증
        • train : test : vaildation = 8 : 2(1:1)
        • but vaildation 하나만으론 부족, 국소적인 평가만 이뤄짐. 다른 데이터도 vaildation으로 나눠(fold를 여러개 나눈다) 검증한다.
        • 데이터가 적을 때만 사용
  • 하이퍼파라미터 튜닝방법
    1. grid search : 미리 정의된 하이퍼파라미터 후보들의 모든 조합을 시도
    2. randomized search : 임의로 샘플링된 하이퍼파라미터의 조합을 일정 횟수만 시도
    3. 베이지안 최적화 : 가장 유망한 하이퍼파라미터의 범위를 중점적으로 탐색

특히 어려웠던 것

  • 파이썬 코드타카 시저암호 (아스키 코드: 문자를 숫자로 표준화 한것)
    • 문제
      • 어떤 문장의 각 알파벳을 일정한 거리만큼 밀어서 다른 알파벳으로 바꾸는 암호화 방식을 시저 암호라고 합니다. 예를 들어 "AB"는 1만큼 밀면 "BC"가 되고, 3만큼 밀면 "DE"가 됩니다. "z"는 1만큼 밀면 "a"가 됩니다**. 문자열 s와 거리 n을 입력받아 s를 n만큼 민 암호문을 만드는 함수**, solution을 완성해 보세요.
    • 개념
      • ord(’A’) : 문자 → 숫자
      • cha(65) : 숫자 → 문자
      • 알파벳 대문자는 65부터 ~
      • 알파벳 소문자는 97부터 ~
      • 알파벳은 전부 26개
    • 핵심
      • 문자를 숫자로 바꿔준다.
      • 문자의 숫자 위치를 찾는다.
      • 다시 문자로 변환한다.
      • 이때 알파벳 첫글자로 돌아오는지 확인하기 위해 26을 나눠 나머지를 확인한다.
      • 한바퀴 도는지 확인하기 위해선 대소문자 알파벳 첫시작을 0 ~ 25로 인덱싱을 해야한다.
    • 풀이
    • def solution(s, n):
      	result = ''
      	for char in s:
      		if char.isupper():
      				result += chr((ord(char) - ord('A') + n ) % 26 + ord('A'))
      		elif char.islower():
      				result += chr((ord(char) - ord('a') + n ) % 26 + ord('a'))
      		else:
      				result += char
      	return result
      
    • 해석
      • if char.isupper(): 대문자면 (’A’ ~ ‘Z’)
      • ord(char) - ord(’A’): ‘A’를 0으로 맞추기 위해 기준점 정한다. (0~25범위로)
      • +n n만큼 밀어줌
      • % 26: 알파벳 26글자니까 Z를 넘어서면 다시 A부터 시작하도록 (순환)
      • + ord('A'): 다시 아스키 코드로 복원
      • chr(...): 숫자를 문자로 변환
      • result += chr((ord(char) - ord('A') + n ) % 26 + ord('A')) 해당문자 유니코드에서 ‘A’유니코드를 뺀다. (알파벳 첫 시작이 0이게 맵핑, 이유는 26으로 나눠주기 위함.) 그러고 밀리는 만큼 더해준다. 한바퀴 돌 수 있으므로 26을 나눈 나머지를 더해주고 마지막으로 다시 유니코드 숫자로 변환해준다.
      • result += char 공백이 있을 경우 그대로 추가한다. 공백도 char로 받는다.