머신러닝의 구성요소
- 데이터 셋: 데이터 모음
- 입력 데이터 특징(Feature): 데이터셋의 개별 속성
- 출력 데이터 레이블(lable): 예측하고자 하는 예측 변수
- 모델: 정다(레이블)을 예측할 수 있는 지식을 학습할 수 있는 프로그램
- 학습: 모델이 데이터를 통해 패턴을 인식하고, 이를 기반으로 예측을 수행 할 수 있도록 함수 내의 가중치를 조정하는 과정
- 훈련: 모델이 데이터를 통해 학습하는 과정
- 테스트: 학습된 모델의 성능을 평가하는 과정
🔎 학습방법
지도학습(레이블 O)
회귀: 연속적인 값 예측 (주택 가격, 주식 가격)
분류: 이산적인 값 예측(스팸 필터링, 이미지 분류)
비지도 학습(레이블 X)
군집화: 데이터를 유사 그룹으로 묶는 문제(고객 세분화, 이미지 세그멘테이션)
이미지 세그멘테이션: 이미지을 픽셀단위로 나누어 어떤 객체에 또는 어떤 영역에 속하는지 구분하는 기술
차원축소: 고차원 데이터를 저차원으로 변환(PCA, t-SNE)
앙상블 학습(여러개의 모델 결합)
배깅: 여러 모델을 독립적으로 학습시키고, 에측을 평균내거나 다수결 투표(랜덤 포레스트)
부스팅: 여러 모델을 순차적 학습시키고, 이전 모델의 오차를 보완
스태킹: 여러 모델을 학습시키고 예측결과를 새로운 데이터로 사용하여 메타 모델을 학습
☑️ 데이터 셋 다운 및 기본정보 확인
kaggle
예시 : 타이타닉 데이터셋 다운로드
- kaggle competitions download -c titanic
다운로드한 데이터 import
- import pandas as pd
- train_df = pd.read_csv('train.csv')
- test_df = pd.read_csv('test.csv')
데이터 확인
- 행열 확인 print(df.shape)
- 컬럼명 확인 print(df.columns)
- 타입확인 print(df.dtypes)
- 통계 확인 print(df.describe())
- 정보확인(NULL갑스 타입 등) print(df.info())
☑️ 데이터 전처리
🔎 결측치 처리
df_dropped_rows = df.dropna() # null 행 제거
df_dropped_cols = df.dropna(axis=1) #null 열 제거
df_filled = df.fillna(0) 0으로 대체
df_filled_mean = df.fillna(df.mean())평균값으로 대체
df_filled_median = df.fillna(df.median()) 중간값으로 대체
df_filled_mode = df.fillna(df.mode().iloc[0]) 각 열의 최빈값으로 대체
#sklearn의 linear에서 LinearRegression 회귀모델 임포트
from sklearn.linear_model import LinearRegression
#결측치 있는 열과 없는 열 구분
df_with_na = df[df['column_with_na'].isnill()]
df_without_na = df[df['column_with_na'].notnull()]
model = LinearRegression()
model.fit(df_without_na[['feature1', 'feature2']], df_without_na['column_with_na'])
predicted_values = model.predict(df_with_na[['feature1', feature2']])
df.loc[df['column_with_na'].isnull(), 'column_with_na'] = predicted_valuse
🔎이상치 처리
데이터 셋에서 비정상적인 값 처리
#특정 열의 이상치 확인
#25%보다 작거나 75%보다 크면 이상치로 처리
#quantile로 이상치의 기준점 설정
Q1 = df['C'].quantile(0.25)
Q3 = df['C'].quantile(0.75)
IQR = Q3 - Q1
#이상치 범위 설정
lower_bound = Q1 - 1.5 * IQR
upper_bound = Q3 + 1.5 * IQR
#여기서 |는 OR의 논리연산자
#C열의 값중 lower_bound보다 작거나 upper_bound보다 큰 수를 이상치로 간주해 outliers에 저장해서 확인
outliers = df[(df['C'] < lower_bound) | (df['C'] > upper_bound)]
print(outliers)
#C 열의 값이 lower_bound와 크거나 같은 값 그리고upper_bound보다 작거나 같은 값을 df_no_outliers에 저장
df_no_outliers = df[(df['C'] >= lower_bound) & (df['C'] <= upper_bound)]
print(df_no_outliers)
#C열의 평균값을 mean_value에 저장
#apply를 사용해서 C에 대해 특정 함수나 연산을 적용
#lambda로 함수식을 한줄로 정리 x에는 c열의 각 값이 들어간다.
#C 열의 각 값을 검사하여, 값이 lower_bound보다 작거나 upper_bound보다 크면 그 값을 해당 열의 평균값으로 대체, 아니면 값 유지
mean_value = df['C'].mean()
df['C'] = df['C'].apply(lambda x: mean_value if x < lower_bound or x > upper_bound else x)
🔎중복값 제거
#중복된 행 확인
print(df.duplicated().sum())
#제거
df_no_duplicates = df.drop_duplicates()
🔎데이터 타입 변환
df['column_name'] = df['column_name'].astype(int)
df['column_name'] = df['column_name'].astype(str)
df['column_name'] = df['column_name'].astype(float)
🔎인코딩
머신러닝은 수치형 데이터를 인자로 받기 때문에 범주형 데이터를 수치형으로 변환 하는거다.
원핫 인코딩
#get_dummies를 활용해 수치형 데이터로 바꾼다.
#get_dummies를 진행할 df데이터 프레임의 category_column카테고리 컬럼을 지정
df_encoded = pd. get_dummies(df, columns=['category_column'])
print(de_encoded.head())
🔎샘플링 랜덤으로 추출
#50% 샘플 추출
#비율 frac
df_sampled = df.sample(frac=0.5)
#100개 샘플 추출
#개수 n
df_sampled_n = df.sample(n=100)
🔎특징 선택 및 추출
#SelectKBest k개의 특징을 선택하는 방법을 제공하는 클래스
#f_classif 독립변수와 종속변수 사이의 상관성을 측정하여 높은 상관성을 가진 특성을 선택(분류문제에서 사용)
from sklearn.feature_selection import SelectKBest, f_classif
#selector객체 생성
#score_func = f_classif 특징에 F-값을 계산해 높은 값 가진 특징이 더 중요하다고 간주
#k는 가장 중요한 5개의 특징 선택 지정
selector = SelectKBest(score_func=f_classif, k=5)
#fit_transform입력 데이터(주어진 데이터)X, 타겟 레이블(정답 값)y 특징 선택 수행
#X_new에 선택된 5개의 특징으로 된 새로운 데이터셋 지정
X_new = selector.fit_transform(X, y)
#get_support(indices=True)는 선택된 특징들의 인덱스를 반환
selected_features = selector.get_support(indices=True)
print(selected_features)
# 두 열의 곱을 새로운 특징으로 추가
df['new_feature'] = df['feature1'] * df['feature2']
# 두 열의 합을 새로운 특징으로 추가
df['new_feature_sum'] = df['feature1'] + df['feature2']
☑️ 회귀모델 학습
Scikit_learn
기능
데이터 전처리
모델 학습
모델 평가
모델 예측
Scikilt-learn 설치
conda install scikit-learn
pip install scikit-learn
회귀 모델 예제
import pandas as pd
import numpy as np
# train_test_split 데이터를 훈련 세트와 테스트 세츠로 나누기 위한 함수
# LinearRegression연속적인 값 예측하는 회귀 문제 해결
# mean_squared_error, r2_score모델의 성능을 평가하기 위한 메트릭
from sklearn.model_selection import train_test_split
from sklearn.linear import LinearRegression
from sklearn.metrics import mean_squared_error, r2_score
#데이터 생성
#X는 독립변수(특징) 데이터 (6개의 샘플, 2개의 특징)
#y는 종속변수(타겟) 데이터(각 샘플의 정답값)
X = np.array([[1, 1], [2, 2], [3, 3], [4, 4], [5, 5],[6,6]])
y = np.array([1, 2, 3, 4, 5, 6])
#데이터 분할
# train_test_split(...)주어진 데이터를 훈련 데이터와 테스트 데이터로 나누는 함수
#test_size=0.2 전체 데이터의 20%를 데스트 데이터로 설정 나머지는 훈련 데이터 설정
#random_state=42 데이터 분할의 일관성을 위해 랜덤 시드를 설정
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
랜덤 시드는 어떻게 결정해야하는가?
임의로 정한다. 일반적으로 정수 값을 사용하며, 0 이상의 정수를 설정한다
42라는 정수를 사용했을 뿐, 특별한 의미는 없다.
#회귀 모델 생성 및 학습
model = LinearRegression() #선형 회귀 모델의 인스턴스 생성
model.fit(X_train, y_train) #생성한 모델에 훈련 데이터를 학습 시킨다. x_train과 y_train 데이터 기반으로 학습
인스턴스는 왜 생성하는가?
선형 회귀 알고리즘을 사용하여 데이터에 대해 학습(fit)하고 예측(predict), 모델 파라미터 확인(model.coed_로 회귀계수를 model.intercept_로 절편을 확인 가능)하기 위함
#예측
# model.predict(X_test) 학습된 모델을 사용하여 테스트데이터 X_test에 대한 예측값을 계산.예측 결과는 y_pred에 저장
y_pred = model.predict(X_test)
model.predict도 메서드 함수인가?
메서드이다. 메서드는 특정 클래스의 인스턴스에서 사용할 수 있는 함수
#모델 평가
# mean_squared_error(y_test, y_pred): 테스트 데이터에 대한 실제 값 y_test와 예측 값 y_pred 간의 평균 제곱 오차(MSE)를 계산
# MSE는 예측의 정확성을 나타내는 지표로, 값이 작을수록 모델의 성능이 좋다는 의미
mse = mean_squared_error(y_test, y_pred)
# r2_score(y_test, y_pred): 결정 계수 R2R^2R2를 계산. R2R^2R2 값은 모델의 설명력을 나타내며, 1에 가까울수록 모델이 실제 데이터를 잘 설명한다는 뜻. 0이면 모델이 종속 변수의 평균으로 예측하는 것과 같고, 음수일 경우 모델이 평균보다 더 나쁜 성능을 보이는 것.
r2 = r2_score(y_test, y_pred)
print(f'Mean Squared Error: {mse}')
print(f'R^2 Score: {r2}')
☑️ 로지스틱모델 학습
import numpy as np
import pandas as pd
# load_breast_cancer 유방암 데이터셋 로드
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
# StandardScaler데이터의 평균을 0, 분산을 1로 스케일링
from sklearn.preprocessing import StandardScaler
스케일링을 왜 진행하고 왜 평균을 0, 분산을 1로 만드는 건가
모델 성능과 학습 속도에 긍정적인 영향
스케일링을 통해 입력 특징이 동일한 스케일로 변환되면, 알고리즘이 더욱 빠르고 효율적으로 수렴하고 정규화 가능
평균을 0으로 만드는 이유: 스케일링을 통해 데이터의 중심을 원점으로 이동시킴으로써 모델이 각 변수에 대한 가중치를 더 공정하게 학습할 수 있도록 합니다.
분산을 1로 만드는 이유: 데이터의 변동성을 통일하여 스케일 차이로 인해 발생하는 문제를 완화.
# 데이터 로드
data = load_breast_cancer()
X = data.data
y = data.target
# 데이터 분할
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 데이터 스케일링
scaler = StandardScaler()
#훈련 세트, 테스트 세트를 스케일링하고 변환
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)
#모델 학습
# LogisticRegression 이진 분류 문제를 해결
from sklearn.linear_model import LogisticRegression
# accuracy_score 모델의 정화도 계산 함수
# classifcation_report 정밀도, 재현율, F1점수 등 모델의 성능을 요약한 보고서 생성 함수
# confusion_matrix 예측 결과와 실제 값을 비교하여 혼동 행렬 생성 함수(모델의 분류 성능 시각화)
from sklearn.metrics import accuracy_score, classifcation_report, confusion_matrix
model = LogisticRegression()
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
# accuracy_score(y_test, y_pred) 실제값 y_test와 예측 값 y_pred를 비교하여 정확도 계산
print(f"Accuracy: {accuracy_score(y_test, y_pred)}")
# classification_report(y_test, y_pred) 모델의 성능을 요약하여 출력(정밀도, 재현율,F1점수, 지원)
print(f"Classification Report:\n{classification_report(y_test, y_pred)}")
# confusion_matrix(y_test, y_pred) 혼동 행렬을 생성하여 모델의 성능을 시각적으로 나타낸다.
print(f"Confusion Matrix:\n{confusion_matrix(y_test, y_pred)}")
정밀도Precision
재현율 Recall
F1-score 정밀도와 재현율 간의 조화 평균
지원Support 각 클래스의 속한 실제 샘플 수
평균 Average 나온 숫자들이 비슷할 수록 좋다.
혼동행렬에서 행은 실제 클래스, 열을 예측 클래스
☑️ 생성형 AI를 활용한 학습 방법과 Prompt Engineering
프로그래밍 vs인공지능 모델
공통점: 개발자가 주어진 입력이 무엇을 출력할지 설계
차이점:
프로그래밍은 입출력의 관계에 대한 알고리즘을 직접구현
인공지능 모델을 입출력의 관계를 데이터를 통해 학습
생성형AI
이미지 생성AI DALL-E, Midjourney, Stable Diffusion Web UI
동영상 생성AI Gen-3,
텍스트 생성 AI: 챗지피티, Claide, Gemimi, Preflexty
음악 생성AI Suno, Udio
LLM대규모 언어 모델
텍스트 생성, 번역, 질문 답변, 요약 등
다양한 언어 관련 작업을 하나의 모델에서 수행
대표적
OpenAI(GPT)
Google(Gemini)
Meta(LLaMA3)
LLM의 원리
입력과 출력 사이의 조건부 확률 분포를 학습합니다.
새로운 입력이 주어졌을 때 학습된 조건부 확률 분포를 통해 모든 토큰별 확률을 예측하고, 그 중 가장 가능성이 높은 토큰을 선택하여 답변
몬티홀 문제(조건부 문제)
LLM의 한계
실제로 계산 하는게 아니라서 학습 데이터 분포를 벗어난 입력을 넣으면 신뢰할 수 없는 출력을 생성할 확률이 매우 큼
데이터 편향
데이터 오류
모호한 지시 처리: 다양한 해석을 할 수 있는 질문이나 지시 => 세부적인 정보와 구체적인 답변 예시 등을 통해 답변 할 수 있도록 유도
맥락 유지의 어려움: 핵심정보 요약해 맥락 유지
할루시네이션: 문맥에 맞는 듯 보이지만 실제로는 근거없는 내용을 생성하는 현상으로, 사용자에게 잘못된 정보를 제공할 수 있음
외부 지식 및 데이터 베이스의 내용을 프롬프트에 넣어 해당 내용에 근거해 답변을 생성하도록 함 (RAG, Retrieval-Augmented Generation)
정보의 한계: 최신 정보 및 새로운 전문적인 지식을 제공 못함
질문에 대한 내용을 인터넷에서 검색 후 LLM
프롬프트 엔지니어링 기초
명확한 지침 제공: 중요한 세부 사항이나 문맥 및 제약 조건 등을 명시
페르소나 부여: 시스템 메세지를 사용하여 모델에 페르소나 부여
프롬프트 명시적 구조화(형식적 구조 예시화)
줄임말 순화 프로그램 만들기
☑️ 회고
랜덤 시드는 어떻게 결정해야하는가?
임의로 정한다. 일반적으로 정수 값을 사용하며, 0 이상의 정수를 설정한다
42라는 정수를 사용했을 뿐, 특별한 의미는 없다.
인스턴스는 왜 생성하는가?
선형 회귀 알고리즘을 사용하여 데이터에 대해 학습(fit)하고 예측(predict), 모델 파라미터 확인(model.coed_로 회귀계수를 model.intercept_로 절편을 확인 가능)하기 위함
model.predict도 메서드 함수인가?
메서드이다. 메서드는 특정 클래스의 인스턴스에서 사용할 수 있는 함수
스케일링을 왜 진행하고 왜 평균을 0, 분산을 1로 만드는 건가
모델 성능과 학습 속도에 긍정적인 영향
스케일링을 통해 입력 특징이 동일한 스케일로 변환되면, 알고리즘이 더욱 빠르고 효율적으로 수렴하고 정규화 가능
평균을 0으로 만드는 이유: 스케일링을 통해 데이터의 중심을 원점으로 이동시킴으로써 모델이 각 변수에 대한 가중치를 더 공정하게 학습할 수 있도록 합니다.
분산을 1로 만드는 이유: 데이터의 변동성을 통일하여 스케일 차이로 인해 발생하는 문제를 완화.