☑️ 서론 및 목차

오늘부터는 TIL 가독성을 높이기 위해

 

학습을 시작하며 드는 생각

 

공부를하며 모르는 부분들과 실습을 진행하며 만난 오류들을 정리

 

공부를 마무리하며 회고

 

순서로 진행할 것입니다.

 

필기와 코드 설명은 쥬피터 노트북 코드상자에 정리할 것으로 GITHUB링크를 참고해야합니다.

 

TIL/AI/AI_5_1-5.ipynb at main · Onesword-Jang/TIL

 

TIL/AI/AI_5_1-5.ipynb at main · Onesword-Jang/TIL

오늘 배운 것은?! Contribute to Onesword-Jang/TIL development by creating an account on GitHub.

github.com

 

 


☑️ 학습 시작

오늘의 공부는  AI모델활용 강의  5-5까지 듣고 머신러닝의 비지도 학습을 복습할 것입니다.

 

강의만 듣고있으면 12시간 중 절반의 시간을 멍 때리기 때문에 강의양을 조절했습니다.

 

지금 까지 강의를 들으며 느낀 생각은

 

AI모델을 활용하면 정말 다양하고 내가 원하는게 무엇이든지 만들어 낼 수 있을거라는 생각이 들었습니다.

 

그 만큼 조심해야하는 부분이 많고 세세하게 설정해야하는 부분이 많아 보여 어렵게 느껴지지만 

 

나중에 숙달이 되었을 땐 꼭 궁금하거나 만들고 싶다고 생각이 드는 모델을 만들어 보고싶습니다.


☑️ 학습 중 만난 문제

AI모델활용 5 - 1

1. FastAPI 서버 실행 부분에서 ipynb파일을 바로 실행 시킬 수 없음 (FastAPI를 정의한 app을 찾을 수 없다고 Error가 나옴)

FastAPI를 사용할 땐 py파일을 만들어 사용하거나 vscode에서 만들면 쉽다.

쥬피터 노트북에서 사용하는 3가지 방법이있다.

 

1) 매직 명령어 사용

%%writefile AI_5.py
from fastapi import FastAPI
app = FastAPI()

@app.get("/")
def read_root():
    return {"Hello": "World"}

2) subprocess 사용

import subprocess
subprocess.run(["uvicorn", "AI_5:app", "--reload"])
  • 이 방법은 Uvicorn 프로세스에 점유되어 다른 셀을 사용할 수 없는 한계가 있다.

3) 별도 터미널에서 실행

  • 일반 터미널이나 Anaconda Prompt에서 FastAPI를 실행하는 것이 가장 간편한 방법
  • Jupyter Notebook은 FastAPI 서버와 독립적으로 사용할 수 있어, 서버 실행에 영향을 받지 않는다.

4) 쥬피터 노프북 셀에서 사용 방법은 3번 째 코드

2.  port의 종류

- 8000 : 테스트 용

 

- Well-Known Ports(0-1023): 이 범위의 포트는 표준화된 프로토콜에 의해 사용

  • 80 : HTTP
  • 443 : HTTPS
  • 25 : SMTP
  • 21 : FTP

- Registered Ports (1024-49151): 이 범위는 특정 애플리케이션에 의해 등록되어 사용

  • 3306 : MySQL
  • 5432 : PostgreSQL

- Dynamic/Private Ports (49152-65535): 이 범위의 포트는 동적으로 할당되는 포트로, 일반적으로 클라이언트 애플리케이션이 서버에 연결할 때 임시로 사용

 

AI모델 활용 5 - 4

1. numpy와 ultralytics의 컴파일러 문제와 빌드도구(meson)의 경로 관련 오류

이 문제는 주로 Visual Studio C++ 빌드도구가 누락되어 발생한다.

해결방법

https://visualstudio.microsoft.com/ko/visual-cpp-build-tools/

  1. Visual Studio C++ 빌드 도구 설치(설치 중 "Windows용 C++ CMake tools" 같이 다운하면 좋음)
  2. 사전 빌드된 numpy설치 (1.24.3)
  3. 설치 재시도(사전 빌드 numpy설치 후)

☑️ 머신 러닝 비지도 학습

🔎 K-means-clustering

1. matplotlib의 패키지 의존성 문제로 설치 불가

  • 딥러닝, AI모델활용 강의에 사용하던 가상환경을 사용해서 모듈들의 버젼 때문으로 인지
  • 머신러닝 거성환경을 사용하고 update를 한 뒤 해결!

2. 클러스터링 모델 적용 후 생성된 군집 번호 열추가 안함

  • 할당 단계를 거치고 결과를 반환해줄 열을 추가 하지않아 오류가 난 것으로 인지
  • Cluster열을 추가하는 코드 추가
    # KMeans 모델 생성 및 군집 추가
    kmeans = KMeans(n_clusters=5, random_state=42)  # 군집 개수(n_clusters)는 조정 가능
    data['Cluster'] = kmeans.fit_predict(data_scaled)  # 클러스터 결과 추가

🔎 계층적 군집화

1. 불러오는 모듈 정의

from sklearn.cluster import AgglomerativeClustering
  • AgglomerativeClustering은 sklearn의 군집화 알고리즘 중 하나로, 상향식 계층적 군집화 방식
    import scipy.cluster.hierarchy as sch
  • scipy.cluster.hierarchy는 SciPy에서 계층적 군집화를 위한 다양한 함수와 도구를 제공하는 모듈
  • 덴드로그램(Dendrogram)을 시각화하는 dendrogram 함수와, 상향식 군집화를 수행하는 linkage 함수를 제공

2. 덴드로그램이란?

  • 데이터 포인트 간의 유사도와 계층적 클러스터링 결과를 시각화하는 트리 형태의 다이어그램
  • 데이터가 군집화되는 과정을 단계별로 표시
  • 특정 위치에서 가지가 나뉘는 위치를 기준으로 최적의 클러스터 수를 직관적으로 파악 가능

3. k개를 찾는 방법

  • 엘보우 방법
  • 실루엣 분석(-1~1): 1에 가까울수록 잘 분리된 군집
  • 지식 및 경험
  • 일반적으론 2~10개 정도 사용해서 최적을 찾음(많을수록 오버피팅이 될 수 있음)

4. plt.scatter 간소화

colors = ['red', 'blue', 'green', 'cyan', 'magenta']
for i, color in enumerate(colors):
    plt.scatter(X_scaled[y_hc == i, 0], X_scaled[y_hc == i, 1], s=100, c=color, label=f'Cluster {i+1}')
  • enumerate는 파이썬 내장 함수로, 리스트와 같은 순회 가능한(iterable) 객체를 반복하면서 각 요소의 인덱스와 값을 동시에 가져올 수 있게 해준다.

 


☑️ 회고

AI모델활용 강의를 들으며

 

아직 저는 API 키를 발급 받지 않은 상태에서 진행했기에

 

직접적으로 결과를 볼 수 없었는데

 

강사님께서 직접 음성 생성 AI을 활용하는 모습을 보여주셔서 굉장히 흥미로웠습니다.

 

머신러닝 비지도 학습을 진행하며

 

이전에 학습할 때 보다 학습하기 수월했으며 재미있었다.

 

하지만 아직도 모르는 부분 까먹은 부분이 많아 보인다.

 

마지막으로

 

강의를 듣다가 주말에 포트폴리오를 만드는 시간을 가지려했었단걸 떠올렸습니다.

 

오늘이 저의 생일이라 약속이 많아 진행하지 못했는데 이번 주에 도전하는 시간을 매일 1~2시간 정도 가져야겟습니다.

 

 

머신러닝의 구성요소

  • 데이터 셋: 데이터 모음
  • 입력 데이터 특징(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

 

🔎이상치 처리

데이터 셋에서 비정상적인 값 처리

  • 확인IQR

#특정 열의 이상치 확인

#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^2를 계산. R2R^2 값은 모델의 설명력을 나타내며, 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로 만드는 이유: 데이터의 변동성을 통일하여 스케일 차이로 인해 발생하는 문제를 완화.

+ Recent posts