1. 회귀 분석

- 독립변수 x에 대응하는 종속변수 y와 가장 유사한 값을 갖는 함수 f(x)를 찾는 과정

→ f(x)를 통해 미래 사건 예측

    ^y = f(x) ≈ y

 

- 회귀 분석을 통해 구한 함수 f(x)가 선형 함수일 때 f(x) = 회귀 직선

- 선형 회귀 분석

  - 특성과 타겟 사이의 관계를 잘 나타내는 선형 회귀 모형을 찾고, 이들의 상관관계는 가중치/계수(m), 편향(b)에 저장됨

  => ^y = w * x + b

 

2. 비용 함수 = 손실 함수

- 선형 모델의 예측과 훈련 데이터 사이의 거리를 재는 함수

- 비용 함수의 결과값이 작을수록 선형 모델의 예측이 정확함

 

- 선형 회귀는 선형 모델이라는 가설을 세우는 방식이므로, 실제 데이터(훈련 데이터)와 선형 모델의 예측 사이에 차이 존재

- 실제 데이터와 선형 모델의 예측 사이의 차이를 평가하는 함수 → 비용 함수를 사용하여 정확도 계산

- MSE 가장 많이 사용 [실제값과 예측값의 차이인 오차들의 제곱의 평균]

 

3. 선형 회귀 구현

1) 선형 회귀 모델 구현

# 훈련 세트, 테스트 세트 생성
from sklearn.model_selection import train_test_split

train_input, test_input, train_target, test_target = train_test_split(perch_length, perch_weight, random_stae = 42)
train_input = train_input.reshape(-1, 1)
test_input = test_input.reshape(-1, 1)

# 50cm 농어 평균 무게 예측
from sklearn.linear_model import LinearRegression

lr = LinearRegression()
lr.fit(train_input, train_target)
print(lr.predict([50]))

# 1241.83860323

 

2) 회귀 확인

# 회귀 직선 ^y = W * x + b 구하기
print(lr.coef_, lr.intercept_)

# [39.01714496], -709.0186449535477
# => y = lr.coef_ * x + lr.intercept_

plt.plot([15, 50], [15*lr.coef_+lr.intercept_, 50*lr.coef_+lr.intercept_])

 

3) 훈련 세트 산점도 그리기

plt.plot([15, 50], [15*lr.coef_ + lr.intercept_, 50*lr.coef_ + lr.intercept_])

plt.scatter(train_input, train_target)

plt.scatter(50, 1241, 8, marker = '^')
plt.xlabel('length')
plt.ylabel('weight')
plt.show()

- 회귀 직선이 어느 정도는 데이터를 잘 나타내고 있음

- 그러나, 훈련 세트와 테스트 세트 모두 결정 계수가 너무 낮음 → 과소 적합

 + 산점도에서 매우 작은 길이를 가진 농어의 경우 회귀 직선이 데이터를 설명하지 못함

 

4. 선형 회귀 모델의 최적화 → 경사 하강법

- 머신러닝, 딥러닝 알고리즘을 학습시킬 때 사용하는 방법

- 비용 함수의 기울기를 계속 낮은 쪽으로 이동시켜 극값(최적값)에 이를 때까지 반복하는 것

 

- 경사 하강법을 이용하여 비용 함수에서 기울기가 '0'일 때의 비용(오차)값을 구할 수 있음

- 비용 함수의 최소값을 구하면 이때 회귀 함수를 최적화 할 수 있게 됨 

 

- 비용 함수에서 기울기가 '0'일 때 (비용 함수가 최솟값일 때) 모델의 기울기와 y절편을 구하여 회귀 함수 최적화

 

5. 경사 하강법 - learning rate(학습률)

- 선형 회귀에서 가중치(w)와 편향(b)을 경사 하강법에서 반복 학습시킬 때, 한 번 반복 학습시킬 때마다 포인트를 얼만큼씩 이동시킬 것인지 정하는 상수

- 학습률이 너무 작은 경우: local minimum에 빠질 수 있음

- 학습률이 너무 큰 경우: 수렴이 일어나지 않음

 

=> 적당한 learning rate를 찾는 것이 중요!

- 시작을 0.01로 시작해서 overshooting이 일어나면 값을 줄이고, 학습 속도가 매우 느리다면 값을 올리는 방향으로 진행

 

import numpy as np
import matplotlib.pyplot as plt

X = np.random.rand(100)
Y = 0.2 * X + 0.5       # 실제값 함수 가정

plt.figure()
plt.scatter(X, Y)
plt.show()

 

# 실제값, 예측값 산점도 그리는 함수
def plot_prediction(pred, y):
    plt.figure()
    plt.scatter(X, Y)
    plt.scatter(X, pred)
    plt.show()

# 경사 하강법 구현
W = np.random.uniform(-1, 1)
b = np.random.uniform(-1, 1)

learning_rate = 0.7    # 임의

for epoch in range(100):
    Y_pred = W * X + b    # 예측값
    
    error = np.abs(Y_pred - Y).mean()
    if error < 0.001:
        break
    
    # gradient descent 계산 (반복할 때마다 변경되는 W, b값)
    w_grad = learning_rate * ((Y_pred-Y) * X).mean()
    b_grad = learning_rate * ((Y_pred-Y)).mean()
    
    # W, b 값 갱신
    W = W - w_grad
    b = b - b_grad
    
    # 실제값과 예측값이 얼마나 근사해지는지 epoch % 5 ==0 될 때마다 그래프 그림
    if epoch % 5 == 0:
        Y_pred = W * X + b
        plot_prediction(Y_pred, Y)

[파랑: 실제값, 주황: 예측값]

- 반복문이 실행되면서 오차가 점차 작아짐을 알 수 있음

- 최종적으로 오차가 줄어들며 실제값을 정확히 추정할 수 있음!

 

6. 다항 회귀

- 다항식을 사용한 선형 회귀

- y = a * x² + b * x + c 에서 x²을 z로 치환하면 y = a * z + b * x + c라는 선형식으로 쓸 수 있음

 

=> 다항식을 이용해서도 선형 회귀를 할 수 있음 → 최적의 곡선 찾기

- 비선형성을 띄는 데이터도 선형 모델을 활용하여 학습시킬 수 있다는 것

 

- 다항 회귀 기법: log, exp, 제곱 등을 적용해 선형식으로 변형한 뒤 학습시키는 것

위의 선형회귀 모델의 문제점 해결

# 50cm 농어 평균 무게 예측

# 훈련 세트, 테스트 세트의 길이를 제곱한 값의 열 추가 - 새로운 훈련, 테스트 세트 생성
train_poly = np.column_stack((train_input**2, train_input))
test_poly = np.column_statck((test_input**2, test_input))

# 새로운 훈련 세트, 테스트 세트로 선형 회귀 모델 훈련
lr = LinearRegression()
lr.fit(train_poly, train_target)

# 무게 예측
print(lr.predict([50**2, 50]))

# [1573.98423528]

 

7. 다항 회귀 구현

1) 회귀 다항식 y = a * x² + b * x + c 구하기

print(lr.coef_, lr.intercept_)

# [1.01433211 -21.55792498] 116.05021078278259

=> 회귀 다항식) 무게 = 1.01 * 길이² - 21.6 * 길이 + 116.05

 

2) 훈련 세트의 산점도, 회귀 다항식 그리기

# 훈련 세트 산점도
plt.scatter(train_input, train_target)

point = np.arange(15, 50)

# 15~49까지 회귀 다항식 그래프 그리기
plt.plot(point, 1.01*point**2 -21.6*point + 116.05)

# 농어 데이터 표시하기
plt.scatter(50, 1574, marker = '^')

plt.xlabel('length')
plt.ylabel('weight')
plt.show()

# 결정 계수
print(lr.score(train_poly, train_target))
print(lr.score(test_poly, test_target))

# 0.9706807451768623
# 0.9775935108325121

- 결정 계수 점수가 1에 근접하므로, 해당 모델은 위의 선형 모델보다 정확성이 높음

'ML & DL' 카테고리의 다른 글

[BITAmin] K-최근접 이웃 알고리즘  (2) 2023.01.23
[BITAmin] 데이터 전처리  (0) 2023.01.23

1. K-NN

- 주변의 가장 가까운 K개의 데이터를 보고 새로운 데이터를 판단하는 알고리즘

- N개의 특성을 가진 데이터는 n차원의 공간에 점으로 표현됨

- 유사한 특성의 데이터는 거리가 가깝고, 다양한 거리 함수를 통해 데이터 간 거리를 구할 수 있음

 

- KNN 분류

  - 종속변수 Y : 범주형 데이터 -> 어떤 범주에 속하는지, K개 중 과반수 의결에 의해 분류

 

- KNN 회귀

  - 종속변수 Y : 연속형 데이터 -> K개의 최근접 이웃이 가진 평균

 

2. 최적의 K 값 찾는 방법

- 최적의 K값은 데이터에 의존적이며, 현실적으로 만족할만한 수준의 값을 찾음

  - Trial & Error → Python 반복문 사용

- 매우 작은 K는 overfitting 초래: 데이터의 지역적 특성을 지나치게 반영함

- 매우 큰 K는 underfitting 초래: 모델이 과하게 정규화됨

 

1) 방법

- K 후보군 결정 : 1부터 학습데이터 개수 -1까지, 데이터 개수가 많다면 1부터 √n까지

- Train & Test 도는 Validation 데이터에 대해 knn 에러율 구함

- 에러율이 가장 낮은 K 선택

 

2) 종속변수가 범주형일 경우

- Tie 문제를 막기 위해 K는 홀수 권장

- 짝수일 경우 2:2, 3:3 등으로 동일하게 나뉠 수 있기 때문 

 

3) 종속변수가 연속형일 경우

- Inverse distance weighted average 고려 가능

- 거리가 가까운 관측치들에게 가중치를 부과해 가중평균으로 구하는 것

 

from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_breast_cancer
import matplotlib.pyplot as plt

cancer = load_breast_cancer()
x_train, x_test, y_train, y_test = train_test_split(cancer.data, cancer.target, 
                                   test_size = 0.3, stratify = cancer.target, random_state = 100)
                                   
training_accuracy = []
test_accuracy = []
neighbors_settings = range(1, 101)

for n_neighbors in neighbors_settings:
    clf = KNeighborsClassifier(n_neighbors = n_neighbors)
    clf.fit(x_train, y_train)
    training_accuracy.append(clf.score(x_train, y_train))
    test_accuracy.append(clf.score(x_test, y_test))
    
plt.plot(neighbors_settings, training_accuracy, label = 'train_accuracy')
plt.plot(neighbors_settings, test_accuracy, label = 'test_accuracy')
plt.ylabel('accuracy')
plt.xlabel('n_neighbors')
plt.legend()
plt.show()

 

3. K-NN 회귀

- K개의 최근접 다변량 이웃 샘플로부터 연속 변수를 예측하기 위해 사용

- 이웃 샘플의 타겟값을 평균하여 예측하고자 하는 데이터의 예측값으로 사용

- 다양한 회귀 모델의 평가지표를 통해 모델 성능 측정

  - 결정계수(R²), MSE, RMSE, MAE, MAPE, MPE

- 훈련 세트, 테스트 세트에 대한 평가 점수를 통해 과대/과소 적합 / 적정 판단

 

1) 장점

- 학습 데이터의 노이즈에 크게 영향 받지 않음

- 학습 데이터의 수가 충분하다면 상당히 좋은 성능을 보임

- 훈련 단계가 빠름

- 데이터의 분산까지 고려하면 상당히 robust 해짐

 

2) 단점

- 모델을 따로 생성하지 않아 특징과 클래스 간의 관계를 이해하는 부분에 제약이 있음

- 최적 이웃 수와 사용할 거리 척도를 데이터 각각의 특성에 맞게 연구자가 임의로 설정해야 함

- 새 관측치와 각 학습 데이터 간의 거리를 전부 측정해야하므로 '분류, 예측' 단계가 느림

 

3) 사용시 유의점

- combining rule : KNN은 주변 이웃의 분포에 따라 예측 결과가 달라짐

  - 다수결

  - 가중합 : 거리(유사도)가 가까울수록 더 큰 가중치 부여

 

- 정규화

  - 데이터 간 분포가 크게 다를 경우 각 변수의 차이를 해석하기 어려움

  - 알고리즘의 적절한 적용을 위해 정규화 과정 필요

 

4. 거리 함수

1) 유클리드 거리(Euclidean Distance) = L2 Distance

- 연속 변수에서 가장 일반적으로 사용하는 거리 척도

- 관측치 사이의 최단거리

 

- 유클리드 함수를 채택할 경우 K를 정하기 위해 반드시 '정규화'가 선행되어야 함

 

2) 맨해튼 거리(Manhattan Distance) = L1 Distance

- 각 좌표축 방향으로만 이동할 경우에 계산되는 거리

 

3) 해밍 거리(Hamming Distance)

- 두 개의 이진 데이터 문자열을 비교하기 위한 지표

- 두 문자열의 각 위치의 문자 비교 → 동일하지 않은 문자 수 = '해밍 거리'

- 길이가 같은 두 개의 이진 문자열 비교 시 해밍 거리는 두 비트가 다른 비트 위치의 개수

- 해밍 거리 d가 d >= 2a + 1이면 a개의 오류를 정정할 수 있음

 

- Feature를 벡터화할 때

- Clustering에서 독립변수가 범주형일 경우

- 네트워크를 통해 전송될 때 오류 감지 / 수정에 사용

- 자연어 처리에서 데이터 간 형태적 유사성(단어 간 거리)을 계산해 유사도 평가할 때

 

5. 회귀 모델 평가 지표

1) 결정계수 (R² Score)

- 모델이 데이터를 얼마나 잘 예측하는지에 대한 지표

- 실제 값의 분산 대비 예측 값의 분산 비율

- 평균으로 예측했을 때의 오차(총오차)보다 모델을 사용했을 대 얼마나 더 좋은 성능을 내는지 비율로 나타낸 값

- R : 표본 상관계수

- SST : 총 제곱합          SST = Σ(yᵢ - y̅)²

- SSE : 설명된 제곱합    SSE = Σ(^yᵢ - y̅)² 

- SSR : 잔차 제곱합       SSR = Σ(^uᵢ)²              # ^uᵢ 잔차 = 표본집단 회귀식에서 예측된 값 - 실제 관측값

 

-  = 0 : x, y는 선형 관계 없음

-  = 1 : x, y는 완벽한 선형 관계

- R²가 1에 가까울수록 회귀 모형이 적합함

# sklearn
r2_score(y_true, y_pred, sample_weight = None, multioutput = 'uniform_average')

'''
y_true : 올바른 목표값
y_pred : 예상 목표값
sample_weight : 가중치
'uniform_average' : 모든 출력의 오차를 평균 무게로 평균화
'''

 

2) 오차 제곱 평균 MSE (Mean Squared Error)

- 예측 값과 실제 값의 차이의 제곱에 대해 평균을 낸 값

- 이상치에 민감

- MSE 값이 작을수록 좋지만, 과대적합이 될 수 있음

- MSE의 범위는 0~무한대

- MSE가 100일 때 이 모형이 좋은지 기준이 없어 판단이 어려움 → MAPE의 퍼센트 값을 이용해 성능 평가하기도 함

from sklearn.metrics import mean_squared_error

mse = mean_squared_error(y_true, y_pred)
print("mse = {:.3f}".format(mse_))

# mse = 11.264

 

3) 평균 제곱근 오차 RMSE (Root Mean Squared Error)

- MSE에 루트를 씌운 값

- MSE의 장단점을 거의 그대로 따라감

- 제곱 오차에 대한 왜곡 줄여줌 + robust함에서 강점을 보임

- 오류 지표를 루트를 통해 실제값과 유사한 단위로 변환하기 때문에 해석이 쉬움

- 실생활에서 쓰는 계산법을 벗어났기 때문에 'RMSE로 구한 에러값만큼 모델이 틀리다'고 말할 수는 없음

- 그럼에도 큰 오류값 차이에 대해 큰 패널티를 주는 이점

rmse = np.sqrt(mse)

 

4) 평균 절대 오차 MAE (Mean Absolute Error)

- 절대값을 취하기 때문에 가장 직관적으로 알 수 있는 지표

- MSE보다 특이치에 robust (제곱하지 않아 이상치에 덜 민감)

- 절대값을 취하기 때문에 모델이 underperformance인지 overperformance인지 알 수 없음

from sklearn.metrics import mean_absolute_error

mean_absolute_error(y_true, y_pred)

 

5) 평균 절대비 오차 MSPE (Mean Absolute Percentage Error)

- MAE와 마찬가지로 MSE보다 이상치에 robust

- MAPE는 퍼센트값을 가지며 0에 가까울수록 회귀 모형의 성능이 좋다고 볼 수 있음

- 0~100% 의 값을 가지므로 성능 비교 해석 가능

- 추가적으로 모델에 대한 편향 존재 → MPE를 통해 대응 & 0 근처의 값에 대해서는 사용하기 어려움

mean_absolute_percentage_error(y_true, y_pred)

 

6) MPE (Mean Percentage Error)

- MAPE에서 절대값을 제외한 지표

- 과대평가인지 과소평가인지 알 수 있어 유용함

- MAE, MSE는 절대 오차 측정 / MAPE, MPE는 상대 오차 측정

- sklearn에서 구현된 것이 보이지 않음

def MPE(y_true, y_pred):
    return np.mean((y_true - y_pred) / y_true) * 100

MPE(y_true, y_pred)

 

6. KNN 회귀 구현

class sklearn.neighbors.KNeighborsRegressor(n_neighbhors=5, *, weights='uniform', algorithm='auto', 
                                            leaf_size=30, p=2, metric='minkowski', metric_params=None, n_jobs=None):
                                            
'''
n_neighbors: 이웃의 수 K (defualt = 5)
weights: 예측에 사용되는 가중 방법 결정 (default = 'uniform') or callable
  "uniform" : 각각의 이웃이 모두 동일한 가중치
  "distance" : 거리가 가까울수록 높은 가중치
  callable : 사용자가 직접 정의한 함수 사용
algorithm('auto', 'ball_tree', 'kd_tree', 'brute') : 가장 가까운 이웃을 계산할 때 사용할 알고리즘
  "auto" : 입력된 훈련 데이터에 기반해 가장 적절한 알고리즘 사용
  "ball_tree" : Ball-Tree 구조
  "kd_tree" : KD-Tree 구조
  "brute" : Brute-Force 탐색 사용
leaf_size : Ball-Tree나 KD-Tree의 leaf size 결정 (default = 30)
  - 트리를 저장하기 위한 메모리, 트리의 구성과 쿼리 처리 속도에 영향
p : 민코프스키 미터법의 차수 결정 (1이면 맨해튼 거리, 2이면 유클리드 거리)
'''

 

from sklearn.neighbors import KNeighborRegressor

knr = KNeighborsRegressor()

knr.fit(train_input, train_target)
knr.score(test_input, test_target)          # 테스트 모델에 대한 평가
# 0.9928094061
test_prediction = knr.predict(test_input)   # 테스트 세트에 대한 예측
knr.score(train_input, train_target)        # 훈련 모델에 대한 평가
# 0.9698823289                                이 경우는 과소적합 (훈련 < 테스트 점수)

knr.n_neighbors = 3                         # 모델을 훈련세트에 잘 맞게 하기 위해 k 줄임 (5→3)
knr.fit(train_input, train_target)          # 재훈련
knr.score(train_input, train_target)
# 0.9804899950
knr.score(test_input, test_target)
# 0.9746459963                              # 훈련 > 테스트 점수이고, 차이가 크지 않으므로 적합!

knr.KNeighborRegressor()
x = np.arange(5, 45).reshape(-1, 1)
knr.n_neighbors = 3

knr = KNeighborsRegressor()
x =np.arange(5, 45).reshape(-1, 1)           # 5에서 45까지 x 좌표 생성 
for n in [1, 5, 10]:
    knr.n_neighbors = n
    knr.fit(train_input, train_target)       # 모델 훈련
    prediction = knr.predict(x)              # 지정한 범위 x에 대한 예측
    plt.scatter(train_input, train_target)
    plt.plot(x, prediction)
    plt.title('n_neighbors = {}'.format(n))
    plt.xlabel('length')
    plt.ylabel('weight')
    plt.show()

 

7. 과대 적합 / 과소 적합

1) 과대 적합 overfitting

- 모델이 훈련 세트에는 좋은 성능을 내지만, 테스트 세트에서는 낮은 성능을 내는 경우

- 훈련 세트와 테스트 세트에서 측정한 성능 간격이 큼 = 분산이 큼

- 주요 원인: 훈련 세트에 충분히 다양한 샘플이 포함되지 않음

- 해결 방법

  - 훈련 세트에 충분히 다양한 샘플 포함시키기

  - 모델이 훈련 세트에 집착하지 않도록 가중치 제한하기 (모델의 복잡도 낮춤)

  - 훈련 데이터의 잡음 줄이기 (outlier, error 제거)

 

2) 과소 적합 underfitting

- 훈련 세트와 테스트 세트의 성능에는 차이가 크지 않지만 모두 낮은 성능을 내는 경우

- 훈련 세트와 테스트 세트의 성능이 서로 가까워지면 성능 자체가 낮음

- 편향이 큼

- 해결 방법

  - 복잡도가 더 높은 모델 사용

  - 가중치 규제 완화

 

'ML & DL' 카테고리의 다른 글

[BITAmin] 선형 회귀  (0) 2023.01.23
[BITAmin] 데이터 전처리  (0) 2023.01.23

1. 데이터 전처리

- 특정 분석에 적합하게 데이터를 가공하는 작업

 

- 완결성: 필수로 기입되어 있어야 하는 데이터는 모두 입력되어야 한다.

- 유일성: 동일한 데이터가 불필요하게 중복되어 있으면 안된다.

- 통일성: 데이터가 모두 동일한 형식으로 입력되어야 한다.

 

2. 주의해야 하는 점

- 잡음 Noise: 측정 과정에서 무작위로 발생하여 측정값의 에러를 발생시키는 것. 이상치와 달리 예측하기 어려움

- 아티펙트 Digital Artifact: 어떤 기술적인 요인으로 인해 반복적으로 발생하는 왜곡이나 에러

- 정밀도 Precision: 동일한 대상을 반복적으로 측정했을 때, 각 결과의 친밀성을 나타내는 것. 측정 결과의 표준편차로 표현 가능

- 편향 bias: 측정 장비에 포함된 시스템적인 변동 (ex. 영점 조절이 되지 않은 체중계)

- 정확도 Accuracy: 평향에 영향 받음. 유효 숫자의 사용에 있어서 중요함

- 이상치 Outlier: 대부분의 데이터와 다른 특성을 보이너가, 특정 속성의 값이 다른 개체들과 달리 유별난 값을 가지는 데이터. 잡음과 다름

- 결측치 Missing Value: 값이 표기되지 않은 값

- 모순, 불일치 Inconsistent Value: 동일한 개체에 대한 측정 데이터가 다르게 나타나는 경우

- 중복 Duplicated data: 중복된 데이터 사이에 속성의 차이나, 값의 불일치가 발생하면 문제가 됨

 

3. 전처리 순서

1) 데이터 수집: 분석이나 학습에 필요한 데이터를 수집하는 작업

- 데이터 분석 및 모델 생성의 첫 과정

- 목적에 맞는 정보 수집을 위해 문제 정의 필요

 

2) 데이터 정제: 비어있는 데이터나 잡음, 모순된 데이터를 정합성이 맞도록 교정하는 작업

- 데이터를 활용할 수 있도록 만드는 과정

- 컴퓨터가 읽을 수 없는 요소의 제거 및 숫자나 날짜 등의 형식에 대해 일관성 유지

- 누락값, 불일치 값, 오류 값 수정

 

3) 데이터 통합: 여러 개의 데이터 베이스, 데이터 집합 또는 파일을 통합하는 작업

- 서로 다른 데이터 세트가 호환이 가능하도록 통합

- 같은 객체, 같은 단위나 좌표로 통합

 

4) 데이터 축소: 샘플링, 차원 축소, 특징 선택 및 추출을 통해 데이터 크기를 줄이는 작업

- 대용량 데이터에 대한 복잡한 데이터 분석은 실행하기 어렵거나 불가능한 경우가 많음

 

5) 데이터 변환: 데이터를 정규화, 이산화 또는 집계를 통해 변환하는 작업

 

4. 데이터 전처리 기법

- 집계 Aggregation

- 샘플링 Sampling

- 차원 축소 Dimensionality Reduction

- 특징 선택 Feature Subset Selection

- 특징 생성 Feature Creation

- 이산화와 이진화 Discretization and Binarization

- 속성 변화 Attribute Transformation

 

5. 전처리 전 데이터 확인

- shape: 데이터 크기 출력

- head(): 데이터 상위 5개 행 출력

- tail(): 데이터 하위 5개 행 출력

- info(): 데이터 전반적인 정보 제공 (행/열 크기, 컬럼명, 컬럼을 구성하는 값의 자료형 등)

- describe(): 데이터 컬럼별 요약 통계량 제공

 

6. 결측치 처리

- NA : 값이 표기되지 않은 값. 결측치

- 제거, 대치, 예측모델로 처리

 

1) 전체 결측치 확인

df.isnull()
pd.isnull(df)

# 결측치일 때 true 반환
# isnull -> notnull : 결측치일 때 false 반환

 

2) 인덱싱 후 결측치 개수 확인하기

df['col'].isnull()

 

3) 결측치 만들기

df.ix[[row1, row2], ['col']] = None

 

4) 전체 결측치 개수 확인

df.isnull().sum()
df.isnull().value_counts()
df.isnull().sum(1)

 

5-1) 결측치 제거

- dropna() : 판다스에서 누락 데이터를 제거하는 함수

- 목록삭제 : 결측치가 있는 행/열은 전부 삭제

df = df.dropna()           # default, 행 제거
df = df.dropna(axis = 1)   # 열 제거

 

- 단일값 삭제 : 행/열 자체가 결측치일 때, 혹은 조건부 삭제

df = df.dropna(how = 'all')   
df = df.dropna(thresh = 1)     

df = df.dropna(subset=['col1', 'col2', 'col3'], how = 'all')  # 모두 결측치일 때 해당 행 삭제
df = df.dropna(subset=['col1', 'col2', 'col3'], thresh = 2)   # 특정 열에 2개 초과의 결측치가 있을 때 해당 행 삭제

 

5-2) 대치

- 단순 대치: 중앙값, 최빈값, 0, 분위수, 주변값, 예측값 등으로 결측치 대치

- 다중 대치: 단순 대치법을 여러번! (대치 - 분석 - 결합)

 

- 판다스에서 결측치 대치하는 함수들

fillna()

# 전체 결측치를 특정 단일값으로 대치
df.fillna(0)  

# 특정 열에 결측치가 있을 경우 다른 값으로 대치
df['col'] = df['col'].fillna(0)
df['col'] = df['col'].fillna(df['col'].mean())

# 결측치 바로 이후 행 값으로 채우기
df.fillna(method='bfill')

# 결측치 바로 이전 행 값으로 채우기
df.fillna(method='pad')
replace()

# 결측치 값 0으로 채우기
df.replace(to_replace = np.nan, value = 0)
interpolate()

# 인덱스를 무시하고, 값을 선형적으로 같은 간격으로 처리
df.interpolate(method = 'linear', limit_direction = 'forward')

 

5-3) 예측 모델

- 결측값을 제외한 데이터로부터 모델을 훈련하고 추정값을 계산하고 결측치 대체

- K-NN, 가중 K-NN, 로지스틱 회귀, SVM, 랜덤 포레스트 방식 등

 

7. 중복 데이터 처리

- 중복은 언제든지 발생할 수 있지만, 중복 데이터 사이에 속성의 차이나 값의 불일치가 발생한 경우, 처리해야 함

- 두 개체를 합치거나 응용에 적합한 속성을 가진 데이터를 선택하는 등

# 중복 데이터 확인
df.duplicated(['col'])

# 중복 데이터 삭제
drop_duplicates()

# 해당 열의 첫 행을 기준으로 중복 여부 판단 후, 중복되는 나머지 행 삭제
drop_duplicated(['col'])

df.drop_duplicates(keep = )
    subset = None           # default, 특정 열 지정 X, 모든 열에 대해 작업 수행
    keep = 'first'          # 가장 처음에 나온 데이터만 남김
    keep = 'last'           # 가장 마지막에 나온 데이터만 남김
    keep = False            # 중복된 어떤 데이터도 남기지 않음

 

8. 불균형 데이터 처리

- 분류를 목적으로 하는 데이터 셋에 클래스 라벨의 비율이 불균형한 경우

- 각 클래스에 속한 데이터 개수 차이가 큰 데이터

- 정상 범주의 관측치 수와 이상 범주의 관측치 수가 현저히 차이나는 데이터

- 이상 데이터를 정확히 찾아내지 못할 수 있음

 

8-1) Under Sampling

- 다수 범주의 데이터를 소수 범주의 데이터 수에 맞게 줄이는 샘플링 방식

- Random Undersampling, Tomek's Link, CNN

 

8-2) Over Sampling

- 소수 범주의 데이터를 다수 범주의 데이터 수에 맞게 늘리는 샘플링 방식

- Random Oversampling

- ADASYN, SMOTE

 

9. 이상치 탐지 기법

1) z-score

- z = (x - μ) / σ

- 변수가 정규분포 따른다고 가정, 각 특성값이 평균에서 표준편차의 몇 배만큼 떨어져 있는지 나타냄

- z-score가 임계치보다 크거나 작은 관측치를 이상치라고 규정

- 임계치 조정함으로써 기준 조정

def z_score_outlier(df, col, thres = 3):
    z_score = (df[col] - df[col].mean()) / df[col].std()
    return df[(z_score > thres) | (z_score < -thres)]

 

2) IQR

- IQR = Q3 - Q1

- Q3 + 1.5*IQR 이상이거나, Q1 - 1.5*IQR 이하인 경우 이상치라고 규정

- 1.5 대신 다른 값 이용해 기준 조정 가능

def IQR_outlier(df, col, scale = 1.5):
    Q1 = df[col].quantile(0.25)
    Q3 = df[col].quantile(0.75)
    IQR = Q3 - Q1
    lower_limit = Q1 - scale * IQR
    upper_limit = Q3 + scale * IQR
    
    return df[(df[col] > upper_limit) | df[col] < lower_limit)]

 

3) DBSCAN

- 밀도 기반 군집화 알고리즘

- 하이퍼 파라미터: eps(반경, default=0.5), min_samples(core point가 되기 위한 최소한의 이웃 수, default=5)

# 이상치 탐지
from sklearn.cluster import DBSCAN

model = DBSCAN(eps = .3, min_samples = 10)
pred = model.fit_predict(abalone)

# 이상치 개수
(pred == -1).sum()

 

10. 레이블 인코딩

- 문자열 카테고리 피처를 코드형 숫자 값으로 변환하는 것

# pandas
df.factorize()

# scikit-learn
LabelEncoder()
encoder.fit_transform() # 학습, 변환 한번에

 

11. 원핫 인코딩

- 피처값의 유형에 따라 새로운 피처를 생성해 고유값에 해당하는 컬럼에만 1 표시, 나머지 컬럼에는 0을 표시하는 방식

- 숫자의 크기 차이를 만드는 레이블 인코딩의 단점 보완

 

12. Feature Scaling

- 서로 다른 변수 값의 범위를 일정한 수준으로 맞추는 작업

- 변수 값의 범위 또는 단위가 달라서 발생 가능한 문제 예방

- 머신러닝 모델이 특정 데이터의 bias 갖는 것 방지

 

1) 표준화 Standardization

- 서로 다른 범위의 변수들을 평균이 0이고 분산이 1인 가우시안 정규분포를 가진 값으로 변환

- ScandardScaler()

 

2) 정규화 Normalization

- 변수값들을 모두 0과 1 사이의 값으로 변환하는 방식

- MinMaxScaler()

'ML & DL' 카테고리의 다른 글

[BITAmin] 선형 회귀  (0) 2023.01.23
[BITAmin] K-최근접 이웃 알고리즘  (2) 2023.01.23

+ Recent posts