- mean_absolute_error (평균 절대 오차, MAE) - mean_squared_error (평균 제곱 오차, MSE) - root_mean_squared_error (RMSE) - mean_absolute_percentage_error (MAPE) - r2_score (설명력, 얼마나 잘 맞았는지)
📌 결과가 숫자(value) 로 나오는 문제 (예: 70점, 23.5도)
모델
데이터로부터 패턴을 찾아 수학식으로 정리해 놓은것
모델링 : 오차가 적은 모델을 만드는 과정
모델의 목적 - 표본(샘플)을 가지고 모집단(전체)을 예측하기 위해서
독립변수, 종속변수
핵심 개념
구분 뜻 쉽게 말하면
**독립변수
(Independent Variable)**
결과에 영향을 주는 원인
“시험 공부 시간”, “운동량”, “광고비”
종속변수 (Dependent Variable)
독립변수에 의해 결정되는 결과
“시험 점수”, “체중 변화”, “매출액”
독립변수 → 원인 / 입력값 (X) Feature
종속변수 → 결과 / 출력값 (Y) Target
📊 머신러닝 관점
역할 의미
독립변수
모델이 이용하는 입력 데이터
종속변수
예측하려는 목표값
오차
평균 = 가장 단순한 모델. 평균도 모델이다
모델 예측값과 관측값(실제값)의 차이
우리의 목표는 오차값을 평균보다 줄여서 평균보다 나은 모델을 만드는 것 수치 데이터에 대해서는 평균, 분류 데이터에 대해서는 최빈값 보다 나아야 성능이 좋다
가변수화(또는 더미 변수화, One-hot encoding)
문자나 범주형 데이터를 숫자(0과 1)로 바꾸는 과정
왜냐하면 대부분의 머신러닝 모델은 숫자 데이터만 계산할 수 있기 때문
두가지 목적
(1) 문자 데이터를 숫자로 바꾸는 효과
Gender (원본 데이터) Male Female 원핫인코딩
Male
1
0
남자면 1
Female
0
1
여자면 1
Male
1
0
남자면 1
Female
0
1
여자면 1
가변수화 과정은 하나만 1을 갖기 때문에 One-Hot-Encoding이라고 부른다
(2) 숫자의 크기가 비교되지 않게 숫자형 범주값을 별도의 독립된 변수로 떼는 것
서로 크기 비교가 안 되는 범주(카테고리)를 모델이 ‘순서가 있는 숫자’로 오해하지 않도록 각각 따로 분리한다는 뜻
색깔 숫자로 바꾼 값
빨강
1
파랑
2
초록
3
이렇게 바꾸면 모델이 이렇게 생각할 수 있음
“초록(3)은 빨강(1)보다 3배 크네!”
하지만 색깔은 크고 작음이 없는 ‘범주형 데이터’
그래서 이렇게 숫자로 넣으면 잘못된 의미를 만들어버림
그래서 하는 게 바로 “가변수화(= 원핫인코딩)”
각 범주를 서로 독립된 변수(열) 로 만들어 주는 거
색깔 빨강 파랑 초록
빨강
1
0
0
파랑
0
1
0
초록
0
0
1
이제 숫자의 크고 작음은 사라지고, “어떤 색인지”만 표시됨
→ (2)는 안해도 되지만 (1)은 안하면 에러남
Gender (원본 데이터) Male Female
Male
1
0
Female
0
1
Male
1
0
Female
0
1
이 표에서 Male이 없어도 Female변수만 있어도 Male값을 예측할 수 있음
Gender (원본 데이터) Male Female
Male
0
Female
1
Male
0
Female
1
여자가 아닌건 남자라는거고 남자가 아닌건 여자라는거임 변수들이 같은말을 하는데 굳이 여러개 둘 필요가 없음
여러개 있으면 모델이 혼란스러워해
그래서
drop=True를 지정해 가변수화 결과로 만들어진 열 중 하나를 제거
데이터 준비
(1) 결측치 처리
# 결측치 확인
data.isnull().sum()
확인하고
# 전날 값으로 결측치 채우기
예제 데이터가 시계열 데이터였고 결측치가 solar.R이라 전날꺼로 채우면 될 것 같아서
이걸로 했음
data.ffill(inplace=True)
# 확인
data.isnull().sum()
(2) 변수 제거 : 분석에 의미 없다고 판단되는 변수 제거
# 변수 제거
drop_cols = ['Month', 'Day']
data.drop(columns=drop_cols, inplace=True)
#data.drop(columns=drop_cols, inplace=True) 이렇게 써도 됨
# 확인
data.head()
데이터 분리
데이터 셋을 학습용, 검증용, 평가용 데이터로 분리함
근데 수업에서는 편의상 학습용, 평가용 데이터로 나눌거임(머신러닝에서만)
(3) x, y 분리
우선 target 변수를 명확히 지정
target을 제외한 나머지 변수들 데이터는 x로 선언
target 변수 데이터는 y로 선언
이 결과로 만들어진 x는 데이터프레임, y는 시리즈
이후 모든 작업은 x, y를 대상으로 진행
# target 확인
타겟은 내가 판단해서 정하는 것
target = 'Ozone'
# 데이터 분리
x = data.drop(target, axis=1) inplace=True를 주면 x값은 none이 됨 그래서 주면 안돼
원본 데이터는 그대로 둬야하니까
y = data.loc[:, target]
(4) 학습용, 평가용 데이터 분리
학습용, 평가용 데이터를 적절한 비율로 분리
반복 실행 시 동일한 결과를 얻기 위해 random_state 옵션을 지정
# 모듈 불러오기
from sklearn.model_selection import train_test_split
# 7:3으로 분리
x_train, x_test, y_train, y_test = train_test_split(x,y
,test_size=0.3,random_state = 1) random_state를 주지 않으면 진짜 막 섞임
Scikit-Learn
지도/비지도 학습 알고리즘을 제공하는 대표적인 파이썬 라이브러리
여러 알고리즘을 같은 구조의 코드로 사용할 수 있어 배우기 쉬움
과대적합 vs 과소적합
구분 뜻 비유
과적합 (Overfitting)
훈련 데이터에는 너무 잘 맞지만, 새로운 데이터에는 잘 못 맞추는 상태
시험 예상문제만 외워서 실제 시험을 망치는 학생
과소적합 (Underfitting)
훈련 데이터조차 제대로 학습하지 못한 상태
공부를 거의 안 해서 기본 문제도 틀리는 학생
예를 들어
조카에게 야구공을 주고 공에 대해 학습을 해라
조카가 야구공을 보고 공은 둥글구나, 가죽으로 씌워져있네, 공은 실밥이 있구나, 돌덩이처럼 딱딱하네, 내 주먹만하네, …
근데 축구공, 농구공, 럭비공, 배구공 등은 공이라고 골라내지 못하고 야구공만 공이라고 인지함
→ 과적합
세 가지 상태로 비교
상태 설명 훈련 데이터 성능 테스트 데이터 성능
과소적합
너무 단순함 (덜 배움)
낮음
낮음
적합
적당히 잘 배움 (일반화 잘됨)
높음
높음
과적합
너무 외움 (훈련에만 맞춤)
매우 높음
낮음
모델이 적절히 학습하게 만드는 과정 = 튜닝
모델링
회귀인지 분류인지에 따라 사용할 알고리즘과 평가 방법이 달라짐
우선 다음 알고리즘과 평가 방법을 사용하겠음 맛보기 코드로
알고리즘: LinearRegression
평가방법: mean_absolute_error
(1) 모델링
# 1단계: 불러오기
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_absolute_error
# 2단계: 선언하기
model = LinearRegression() 선형 회귀모델 쓸거다
# 3단계: 학습하기
model.fit(x_train, y_train) 학습 데이터로 학습하자
학습이 끝나면 성능이 어떻든 모델이 만들어짐
# 4단계: 예측하기
y_pred = model.predict(x_test) x 테스트로 예측해봐
아직 y 테스트는 모델에게 주지 않았기 때문
# 5단계: 평가하기
mean_absolute_error(y_test, y_pred)
(2) 예측값 실제값 비교
# 예측값, 실젯값 확인
print(y_pred[:10]) 이 자체가 배열이니까 벨류즈 안쓰고
print(y_test.values[:10]) y 테스트 결과는 시리즈니까 .values 결과 = 배열
# 예측값, 실젯값 시각화 비교
plt.plot(y_pred)
plt.plot(y_test.values) y_test는 시리즈니까 배열로 가져오기 위해 y_test.values
plt.legend(['predicted', 'Actual']) 범례
plt.show()
1. Pandas가 제공하는 plot() 메소드에 kind='kde' 를 지정해
Density Plot을 쉽게 그릴 수 있음
diabetes['BMI'].plot(kind='kde')
plt.show()
2. Seaborn의 kdeplot() 함수를 사용해 Density Plot을 그림
sns.kdeplot(x='BMI', data=diabetes)
plt.show()
📌 확률 밀도 함수
셀 수 있는 값의 분포, 즉 이산 확률 분포는 표로 표현 할 수 있음
(예를 들면 주사위를 던져 1 ~ 6이 나올 수 있는 확률)
반면에 셀 수 없는 값의 분포, 즉 연속 확률 분포는 대상 값이 너무 많아 표로 표현할 수 없다
그래서 연속 확률 분포는 함수(=그래프), 즉 그래프로 표현
(예 예를 들어 키가 140~180 사이인 학생들의 키 분포)
Box Plot (교안 / 질문이 중요하다고 했던 박스플롯 박사)
Box Plot은 이해하기가 다소 어렵지만, 데이터 분포를 확인하는 유익한 시각화 도구
Matplotlib의 boxplot() 함수를 사용해 Box Plot을 그린다
plt.boxplot(x='BMI', data=diabetes[diabetes['BMI'].notna()]) 결측치는 제외하고
plt.show()
주의: 결측치가 있으면 그래프가 그려지지 않는다
Seaborn의 boxplot() 함수를 사용해 Box Plot 그리기
sns.boxplot(x='BMI', data=diabetes[diabetes['BMI'].notna()])
sns.boxplot(x='BMI', data=diabetes)**Seaborn**은 결측치가 있어도 그려짐
plt.show()
쓰고 싶은거 쓰면 됨
★★ 박스플롯의 의미
IQR : 25%와 75% 사이의 차이
만약 75% 가 20이고 25% 가 5라면 IQR은 15
**Q3에서 IQR*1.5만큼 쭈욱 가보면 어느 경계가 나오지만 이 경계는 박스플롯에 나타나지 않음
**Q1에서 IQR*1.5만큼 쭈욱 가봐도 어느 경계가 나오지만 이 경계는 박스플롯에 나타나지 않음
이 선들을 넘어 서는 값들은 이상치
이상치 제외 최댓값과 최솟값과 **갔을때 경계 사이에는 값이 없음
시계열 데이터 시각화
Matplotlib의 plot() 함수를 사용해 Line Plot
air['Date'] = pd.to_datetime(air['Date'])
plt.plot('Date', 'Ozone', data=air, label='Ozone')
plt.plot('Date', 'Temp', data=air, label='Temp')
plt.xlabel('Date')
plt.legend()
plt.show()
Seaborn의 lineplot() 함수를 사용해 Line Plot
sns.lineplot(x='Date', y='Ozone', data=air, label='Ozone')
sns.lineplot(x='Date', y='Temp', data=air, label='Temp')
plt.legend()
plt.show()