728x90
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris # sklearn에서 제공하는 붓꽃 데이터
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
from sklearn.linear_model import LinearRegression
1. 문제정의
- 500명의 키와 몸무게, 비만도 라벨을 통해서 비만을 판단하는 모델을 만들어보자2. 데이터 수집
2. 데이터 수집
data = pd.read_csv('bmi_500.csv',
index_col = "Label" #Label컬럼을 인덱스로 설정)
3.데이터 전처리
info()로 데이터의 대략적인 요약을 확인하고 describe()로 기술통계를 확인하여 이상치 유무를 확인한다.
data.info()
#기술통계 확인
data.describe()
# 여기서는 이상치가 없는것을 확인 할 수 있다.
# 이상치 범위
# IQR = 3사분위 - 1사분위
# 1사분위 - 1.5*IQR보다 작고
# 3사분위 + 1.5*IQR보다 크면
# 이상치 이다.
# data.index는 모든 인덱스를 보여줌
# unique()는 중복되는 값을 뺴고 유일한 값만 보여줌
# 따라서 data.index.unique()는 인덱스의 종류를 볼 수 있다.
data.index.unique()
4. 탐색적 데이터 분석(EDA)
- 각 비만도를 등급별로 시각화해보자
# 시각화
dataObesity = data.loc['Obesity']
dataNormal = data.loc['Normal']
dataWeak = data.loc['Weak']
dataOverweight = data.loc['Overweight']
dataExtremeObesity = data.loc['Extreme Obesity']
dataExtremelyWeak = data.loc['Extremely Weak']
plt.scatter(dataObesity['Weight'], # x축 데이터
dataObesity['Height'], # y축 데이터
c = "red",
label = "Obesity")
plt.scatter(dataNormal['Weight'], # x축 데이터
dataNormal['Height'], # y축 데이터
c = "blue",
label = "Normal")
plt.scatter(dataWeak['Weight'], # x축 데이터
dataWeak['Height'], # y축 데이터
c = "green",
label = "Weak")
plt.scatter(dataOverweight['Weight'], # x축 데이터
dataOverweight['Height'], # y축 데이터
c = "yellow",
label = "Overweight")
plt.scatter(dataExtremeObesity['Weight'], # x축 데이터
dataExtremeObesity['Height'], # y축 데이터
c = "Magenta",
label = "Extreme Obesity")
plt.scatter(dataExtremelyWeak['Weight'], # x축 데이터
dataExtremelyWeak['Height'], # y축 데이터
c = "cyan",
label = "Extremely Weak")
plt.legend(loc = 'upper right') # 우측 상단에 label 띄우기
plt.legend(loc = (1.0, 0)) # 위치를 직접지정
plt.show()
위에서 scatter로 각 비만도 별로 색깔을 나눠서 그래프를 그렸는데
반복되는 코드가 너무 많은 것을 확인 할 수 있다.
함수를 만들어서 이를 간단히 바꿔보자.
def drawScatter(row, color):
plt.scatter(data.loc[row]['Weight'], # x축 데이터
data.loc[row]['Height'], # y축 데이터
c = color, label = row)
plt.figure(figsize=(8,8)) # 그래프 크기
labelName = data.index.unique()
# color = ['red', 'coral', 'yellow', 'yellowgreen', 'green', 'c']
color = ['green', 'yellow', 'yellowgreen', 'c', 'coral', 'red']
for row,color in zip(labelName, color):
drawScatter(row, color)
plt.legend(loc = (1.0, 0)) # label의 위치를 직접지정
plt.xlabel('Weight')
plt.ylabel('height')
plt.show()
5. 모델선택 및 하이퍼 파라미터 튜닝
# 문제/ 정답 데이터 나누기
data = pd.read_csv('bmi_500.csv')
print(data.head())
# Height, Weight -> 문제
# Label -> 정답
X = data.loc[:, ["Height", "Weight"]]
y = data.loc[: ,"Label"]
print(X.shape)
print(y.shape)
# 훈련 / 평가 데이터 나누기
X_train, X_test, y_train, y_test = train_test_split(X,y,random_state=3,
test_size = 0.3)
# KNN모델 사용
knn = KNeighborsClassifier()
6. 훈련
# 훈련
knn.fit(X_train, y_train)
7. 평가
# 평가
print(f"train score: {knn.score(X_train, y_train)}" +
f"\ntest scor: {knn.score(X_test, y_test)}")
예측하기
# 예측하기
# 문제 데이터인 X에 값을 2개 넣었으니 예측을 할때도 X를 2개씩 넣어야 한다.
knn.predict( [[174,67],[180,80]] )
이웃의 개수에 따른 훈련 점수와 평가점수를 구해보자.
trainList = []
testList = []
for k in range(1,101):
# 모델 선택 및 하이퍼 파라미터 튜닝
model = KNeighborsClassifier(n_neighbors = k)
# 모델학습
model.fit(X_train, y_train)
# 모델 평가
trainList.append(model.score(X_train, y_train))
print(f"train 이웃{k}개 : {trainList[k-1]}")
testList.append(model.score(X_test, y_test))
print(f"test 이웃{k}개 : {testList[k-1]}")
위에서 만든 점수를 이용해서 시각화를 해보자.
# 시각화
plt.figure(figsize=(25,5)) # 출력할 그래프 크기
plt.plot(range(1, 101), # X데이터 = 1~100
trainList, # y데이터
c="red")
plt.plot(range(1, 101), # X데이터 = 1~100
testList, # y데이터
c="blue")
plt.xticks(range(1,101))
plt.grid() #기준선
plt.show()
위에 그래프는 유클리드 거리 방식을 이용하여 구한 그래프이다.
이번에는 여러가지 방식을 이용하여 그래프를 구해보자.
trainList = []
testList = []
trainList2 = []
testList2 = []
trainList3 = []
testList3 = []
trainList4 = []
testList4 = []
for k in range(1,101):
model = KNeighborsClassifier(n_neighbors = k)
model.fit(X_train, y_train)
trainList.append(model.score(X_train, y_train))
testList.append(model.score(X_test, y_test))
for k in range(1,101):
# p=1 : 맨하튼 거리 방식
model = KNeighborsClassifier(n_neighbors = k, p=1)
model.fit(X_train, y_train)
trainList2.append(model.score(X_train, y_train))
testList2.append(model.score(X_test, y_test))
for k in range(1,101):
# 'distance': 거리의 역으로 가중치 포인트
model = KNeighborsClassifier(n_neighbors = k, weights="distance")
model.fit(X_train, y_train)
trainList3.append(model.score(X_train, y_train))
testList3.append(model.score(X_test, y_test))
for k in range(1,101):
# 'brute'는 무차별 대입 검색을 사용
model = KNeighborsClassifier(n_neighbors = k, algorithm='brute')
model.fit(X_train, y_train)
trainList4.append(model.score(X_train, y_train))
testList4.append(model.score(X_test, y_test))
# 한글 폰트 사용
from matplotlib import rc
rc('font',family='Malgun Gothic')
# 시각화
plt.figure(figsize=(30,10)) # 출력할 그래프 크기
plt.plot(range(1, 101), trainList, c="red", label = "train")
plt.plot(range(1, 101), testList, c="blue", label = "test")
plt.plot(range(1, 101), trainList2, c="red", linestyle=':', label = "train맨하튼")
plt.plot(range(1, 101), testList2, c="blue", linestyle=':', label = "test맨하튼")
plt.plot(range(1, 101), trainList3, c="red", linestyle='--', label = "trainDistance")
plt.plot(range(1, 101), testList3, c="blue", linestyle='--', label = "testDistance")
plt.plot(range(1, 101), trainList4, c="coral", linestyle='solid', label = "trainBrute")
plt.plot(range(1, 101), testList4, c="yellowgreen", linestyle='solid', label = "testBrute")
plt.legend(loc = (1.0, 0))
plt.xticks(range(1,101))
plt.grid() #기준선
plt.show()
아까 위에서 비만도를 등급별로 구별한 그래프위에 선형회귀선을 구해보자.
def drawScatter(row, color):
plt.scatter(data.loc[row]['Weight'], data.loc[row]['Height'],
c = color, label = row)
def drawPlot(row):
# plt.plot(data.loc[row]['Weight'], data.loc[row]['Height'],"o")
plt.plot(data.loc[row]['Weight'],model.predict(data.loc[row]["Weight"].values.reshape(-1,1)))
def modelFit(row):
model.fit(data.loc[row]["Weight"].values.reshape(-1,1), data.loc[row]["Height"])
# 선형회귀 그래프 그리기
# Weight x축, Height y축
data = pd.read_csv('bmi_500.csv',index_col = "Label")
plt.figure(figsize=(8,8))
labelName = data.index.unique()
color = ['green', 'yellow', 'yellowgreen', 'c', 'coral', 'red']
for row,color in zip(labelName, color):
drawScatter(row, color)
# 선형회귀선
model = LinearRegression()
for row in labelName:
modelFit(row)
drawPlot(row)
plt.legend(loc = (1.0, 0)) # label의 위치를 직접지정
plt.xlabel('Weight')
plt.ylabel('height')
plt.show()
728x90
'파이썬 > 머신러닝' 카테고리의 다른 글
[머신러닝]분류용 선형 모델(Linear Model - Classification) [스마트인재개발원] (0) | 2021.06.22 |
---|---|
[머신러닝] Decision Tree(결정트리) [스마트인재개발원] (0) | 2021.06.17 |
[머신러닝] 서울시 CCTV현황으로 선형회귀 구하기 (0) | 2021.06.04 |
[머신러닝] 과대적합과 과소적합 & KNN(K- 최근접 이웃 알고리즘) (0) | 2021.06.04 |
[머신러닝] 머신러닝의 개념과 과정 (0) | 2021.06.03 |