사이킷런 설치 : anaconda → pip install sklearn
import numpy as np
from sklearn import linear_model #sklearn 안에 있는 linear_model 사용
# Tranining Data Ser
# Supervised Learning(지도 학습)
#sklearn linear_model에서는 기본적으로 2차원(matrix)으로 써야 해요
x_data = np.array([1,2,3,4,5]).reshape(-1,1) # 5행 1열 matrix
t_data = np.array([3,5,7,9,11]).reshape(-1,1)
# linear regression object 생성
#linear_model 이가지고 있는 linear_model 함수
model = linear_model.LinearRegression() #완성된 형태가 아닌 linear regression 모델이 생성
#만들어진 model을 학습시켜요
model.fit(x_data, t_data) #fit은 데이터를 넣어서 모델에 맞춘다는 의미
#학습된 weight와 bias를 확인해 보아요! (y = wx + b)
print('weight : {}, bias : {}'.format(model.coef_,model.intercept_)) #coef_ 기울기,intercept_ 절편
# predicion(예측)
model.predict([[20]]) # 입력값을 2차원으로 썼기 때문에 형식을 맞춰줘야 해요.
Weight : [[2.]], bias : [1.]
[[41.]]
새로운 데이터 파일을 준비했어요! (ozone 데이터)
#ozone.csv 파일을 준비했어요!
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
## 수치 미분 함수가 있어야 해요
# 미분을 수행할 함수
def numerical_derivative(f, x):
# f : loss함수가 들어가요
# x : w(가중치) , b(바이어스)가 들어가요!
delta_x = 1e-4
derivative_x = np.zeros_like(x) # [0.0 0.0]
it = np.nditer(x, flags=['multi_index'])
while not it.finished:
idx = it.multi_index
tmp = x[idx]
# 중앙 차분으로 수치 미분하는 식 : (f(x + delta_x) - f(x-delta_x)) / 2 * delta_x
x[idx] = tmp + delta_x
fx_plus_deltax = f(x)
x[idx] = tmp - delta_x
fx_minus_deltax = f(x)
derivative_x[idx] = (fx_plus_deltax - fx_minus_deltax) / (2 * delta_x)
x[idx] = tmp
it.iternext()
return derivative_x
# Raw Data Loading
df = pd.read_csv('./data/ozone/ozone.csv', sep=',')
display(df.head())
# 태양의 세기, 온도, 바람에 따른 오존량을 측정한 데이터.
# Ozone 이 Label, 태양 바람, 온도에 따른 오존량
# 여기서 Simple Linear Regression 예제를 위해 x데이터(독립변수)를 온도만 사용할 거예요!
training_data_set = df[['Temp','Ozone']]
display(training_data_set) # 153 rows × 2 columns, 결치값 존재
# 지금은 결치값을 삭제할 거예요!
training_data_set = training_data_set.dropna(how='any')
display(training_data_set) # 116 rows × 2 columns
# 삭제된 행의 수가 많아 삭제는 그다지 좋은 방법이 아닌 거 같아요! 하지만 우리 예제는 삭제로 진행합니다!
#이상치를 처리해야 해요!
plt.scatter(training_data_set['Temp'],training_data_set['Ozone'])
plt.show()
# 이상치에 따라 결과가 달라져서 이상치를 버려야 할지 포함해야 할지 선택해야 해요.(어려워요)
# 이상치가 있는것을 눈으로 확인했어요 → 지금은 일단 넘어가요
#Training Data Set
x_data = training_data_set['Temp'].values.reshape(-1,1) #Series 뽑아서 numpy로 변환후 2차원 metrix
t_data = training_data_set['Ozone'].values.reshape(-1,1)
# y = Wx + b => Y = XW + b, (Weight & bias 정의)
W = np.random.rand(1,1) # 2차원 matrix 랜덤값 세팅
b = np.random.rand(1)
# 만들어진 모델을 이용한 예측값을 알려주는 함수
def predict(x):
return np.dot(x,W) + b # Y = XW + b
def loss_func(input_value): # [W의 값, b의 값], 수치 미분 함수에 인자로 들어가서 사용돼야 해요.
input_w = input_value[0].reshape(-1,1) # W 값 꺼내서 2차원으로 변환
input_b = input_value[1]
# 평균제곱오차를 이용한 loss값 계산
y = np.dot(x_data,input_w) + input_b #현재 w와 현재b를 가지고 예측(예측 값)
return np.mean(np.power((t_data-y),2)) #실제값과 예측값의 차이의 제곱
# learning rate를 설정
learning_rate = 1e-4
# 충분한 횟수로 반복적인 학습을 진행
for step in range(300000):
# 어떤 함수를 어떤 지점에서 미분해~
# W와 b값을 하나로 만들어서 넘겨줘요 → loss가 사용
input_param = np.concatenate((W.ravel(), b.ravel()), axis=0) # [W의 값, b의 값]
# 현재 w를 기준으로 편미분
derivative_result = learning_rate * numerical_derivative(loss_func, input_param)
W = W - derivative_result[0].reshape(-1,1)
b = b - derivative_result[1]
if step % 30000 == 0:
print('W : {}, b : {}, loss : {}'.format(W,b, loss_func(input_param)))
# 학습을 시킬때 loss가 작아야 좋아요.
W : [[1.57356721]], b : [-79.42607687], loss : 618.858362562077
# 온도가 화씨 62일때 예측 오존량은 얼마?
print(predict([[62]])) # [[16.86508577]] 이게 맞는 값인가???
[[16.85469692]]
#산점도 추출
plt.scatter(x_data, t_data)
plt.plot(x_data, x_data*W + b, color='r')
plt.show()
# 같은 내용을 이번에는 sklearn으로 model을 만들고 예측하는 그래프를 그려 보아요!
from sklearn import linear_model
model = linear_model.LinearRegression() # model 생성
# 만들어진 모델을 이용해서 학습해요!
model.fit(x_data, t_data)
# W와 b를 구해보아요!
print('W : {}, b : {}'.format(model.coef_, model.intercept_))
#W : [[2.4287033]], b : [-146.99549097]
# python구현 시 : W : [[1.57728942]], b : [-79.72019127]
# sklearn 구현 시 : W : [[2.4287033]], b : [-146.99549097]
# prediction(예측값)
print(model.predict([[62]]))
#[[3.58411393]]
# python 구현 시 : [[16.86508577]]
# sklearn 구현 시 : [[3.58411393]]
# plt.scatter(x_data, t_data)
# plt.plot(x_data, x_data*W + b, color='r')
# plt.plot(x_data, x_data*model.coef_ + model.intercept_, color='g')
# plt.show()
# sklearn 구현시 : [[3.58411393]]
python과 skleatn을 이용해 온도에 따른 ozone 량 예측을 해 보았어요! → 2가지가 차이가 있어요!
Machine Learning에서 학습이 잘 되기 위해서 위해서는 데이터 전처리(data preprocessing)가 필수예요!!
Data Preprocessing
1. 결측치 ?? → 여기서는 딱히 문제없을 거 같아요!
2. 이상치(outliner) : 데이터의 일반적인 값 보다 편차가 상대적으로 큰 data
→ 전체 data 패턴에서 동떨어져 있는 관측치, 이런 이상치는 '평균'에 많이 미치기 때문에 반드시 처리해 주어야 해요!
이상치를 검출하는 방법이 있어요 variance, likelihood ,NN,density
일반적인 프로그램적으로 2가지 방법을 써요.
1. 이상치를 검출하기 위해 4 분위를 이용한 tukey fences
2. 정규분포와 표준편차를 이용한 z - score
matplotlib 같은 visualization(시각화) module은 Boxplot 기능을 제공
Tukey Fence
이상치 처리에 대해서 알아보아요 ( Tukey Fence, z - score)
# Tukey Fence
import numpy as np
import matplotlib.pyplot as plt
data = np.array([1,2,3,4,5,6,7,8,9,10,11,12,13,14,22.1])
fig = plt.figure() # 새로운 figure는 생성.figure는 도화지라고 생각하면 편해요.
fig_1 = fig.add_subplot(1,2,1) # 1행 2열의 subplot에서 1번위치, 왼쪽
fig_2 = fig.add_subplot(1,2,2) # 1행 2열의 subplot에서 2번위치, 오른쪽
fig_1.set_title('Original Data Boxplot') #제목추가
fig_1.boxplot(data)
fig.tight_layout() # 전체 도화지에 대해서 tight_layout을 호출하면 간격을 조정해줘요!
plt.show()
max = 14 . min=1 , 이상치 = 22.1
# 앗 boxplot을 확인했더니 이상치가 있어요!
# numpy로 사분위수를 구해보아요! percentile ()함수를 이용하면 돼요!
import numpy as np
import matplotlib.pyplot as plt
data = np.array([1,2,3,4,5,6,7,8,9,10,11,12,13,14,22.1])
fig = plt.figure() # 새로운 figure는 생성.figure는 도화지라고 생각하면 편해요.
fig_1 = fig.add_subplot(1,2,1) # 1행 2열의 subplot에서 1번위치, 왼쪽
fig_2 = fig.add_subplot(1,2,2) # 1행 2열의 subplot에서 2번위치, 오른쪽
fig_1.set_title('Original Data Boxplot') #제목추가
fig_1.boxplot(data)
print(np.percentile(data,25)) #4.5 , 25는 1,4분위를 뜻해요
print(np.percentile(data,50)) #8.0 , 50은 중위값
print(np.median(data)) # 중위값은 median으로도 표현돼요
print(np.percentile(data,75)) #11.5 , 75는 3.4분위
iqr_value = np.percentile(data,75) - np.percentile(data,25)
print('IQR_value : {}'.format(iqr_value)) # 7.0
upper_bound = iqr_value * 1.5 + np.percentile(data,75)
print('upper_bound : {}'.format(upper_bound)) # 22.0
lower_bound = np.percentile(data,25) - iqr_value * 1.5
print('lower_bound : {}'.format(lower_bound)) # -6.0
# 우리 데이터에 대해 이상치를 출력하세요!(boolean indexing)
print(data[(data > upper_bound) | (data < lower_bound)]) # [22.1]
result_data = data[(data <= upper_bound) & (data >= lower_bound)]
print('정제된 데이터 : {}'.format(result_data))
#정제된 데이터 : [ 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14.]
fig_2.set_title('Remove Outlier Data Boxplot')
fig_2.boxplot(result_data)
fig.tight_layout() # 전체 도화지에 대해서 tight_layout을 호출하면 간격을 조정해줘요!
plt.show()
이상치처리를위한 또 다른 방법 (Z - score) → 정규분포와 표준편차를 이용!
from scipy import stats #stats에는 z score 계산해주는 함수를 가지고 있어요!
data = np.array([1,2,3,4,5,6,7,8,9,10,11,12,13,14,22.1])
# zscore_threshould = 2.0 # 상위 99.7 , 2.0은 많이 사용돼요!
zscore_threshould = 1.8 # 1.8 로 해볼게요 (1.8이하, +1.8이상 걸러냄)
stats.zscore(data)
array([-1.40160702, -1.21405925, -1.02651147, -0.8389637 , -0.65141593,
-0.46386816, -0.27632038, -0.08877261, 0.09877516, 0.28632293,
0.4738707 , 0.66141848, 0.84896625, 1.03651402, 2.55565098])
np.abs(stats.zscore(data)) # 절대값으로 변환해줘요!
array([1.40160702, 1.21405925, 1.02651147, 0.8389637 , 0.65141593,
0.46386816, 0.27632038, 0.08877261, 0.09877516, 0.28632293,
0.4738707 , 0.66141848, 0.84896625, 1.03651402, 2.55565098])
# data[np.abs(stats.zscore(data)) > zscore_threshould] # array([22.1])
#outlier를 출력
outlier = data[np.abs(stats.zscore(data)) > zscore_threshould]
np.isin(data,outlier)
array([False, False, False, False, False, False, False, False, False,
False, False, False, False, False, True])
np.isin(data,outlier, invert=True) # invert를 써서 역으로 잡아봐요.
array([ True, True, True, True, True, True, True, True, True,
True, True, True, True, True, False])
# 이상치를 제거한 결과
data[np.isin(data,outlier, invert=True)] # 정제된 데이터
array([ 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13.,
14.])
'머신러닝 딥러닝' 카테고리의 다른 글
0831 MultipleLlinear Regression (0) | 2021.08.31 |
---|---|
0831 정규화(Normalization) (0) | 2021.08.31 |
0827Machine Learning에서Linear Regression (0) | 2021.08.27 |
0826 회귀(regression ) (0) | 2021.08.26 |
0826 편미분(partial derivative), 연쇄법칙(Chain Rule) (0) | 2021.08.26 |
댓글