728x90

대표적인 분류 문제로 피마 인디언 당뇨병 여부를 예측(분류)를 해보자

 

링크는 www.kaggle.com/uciml/pima-indians-diabetes-database

 

 

잠깐 소개 문구를 읽어보면

 

당뇨병,  소화, 신장 질환 등을 연구하는 국립 연구소에서 얻은 데이터고

 

이 데이터셋으로 우리가 할일은 환자가 당뇨병을 가지고 있는지 예측하면 된다.

 

 

내용물은 여러개의 독립변수와 한개의 목표 변수(Outcome)

 

독립 변수는 환자의 임신 횟수, BMI, 인슐린, 나이 등이 있다고 한다.

 

 

 

우리가 할일은 뭐더라

 

일단 이 문제가 당뇨병 여부인지를 판단하는 것이므로 

 

분류 문제임을 알았다.

 

 

 

 

머신러닝 알고리즘을 활용하는 과정은

 

0. 데이터 훑어보기

1. 탐색적 데이터 분석

2. 전처리

3. 모델 학습

4. 성능 평가

 

정도로 분류할수 있을거 같구.

 

 

 

 

 

지금까지 학습한 내용들을 전부 활용해서 해보면

 

탐색적 데이터 분석에서는

 

시본으로 페어플롯이나 다양한 플롯들을 그리면서 분석할 예정

 

 

전처리 단계에서는 

 

결측치 처리, 라벨 인코딩, 열 드롭 등 할거고

 

 

모델 학습 단계에서는

 

분류기 모델들 설정,

 

gridsearchcv로 하이퍼 파라미터별 최적 추정기를 구하고자 한다.

 

 

 

성능 평가 단계에서는 조금전에 확인한

 

성능 평가지표들을 구하여 비교해보자

 

 

 

 

0. 빠르게 훑어보기

- 평소 하던데로 기본 라이브러리 임포트와 데이터 프레임 조회

- 기초 통계량, 데이터 형태 등을 확인해봄.

* 위 설명대로 당뇨병 여부인 목표변수 Outcome과 이를 설명하기 위한 Pregenancies, BMI, Insulin 등이 있다.

import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns

df = pd.read_csv("res/pima/diabetes.csv")
df.info()

 

 

 

 

 

 

 

1. 탐색적 데이터 분석

- 데이터를 전처리 하기에 앞서 데이터간 의미를 한번 살펴보고자 한다.

- 우선 데이터나 변수도 많지 않고, 편하게 seaborn의 pairplot을 사용해보자.

* 사진이 잘 안보이므로 따로 다운로드 받아서 확대해서 보면 수월하다.

- 회귀 문제가 아니다 보니 출력 변수와 타 변수간의 상관관계를 알아보기가 힘들다.

sns.pairplot(df)

- 회귀 문제가 아니다 보니 출력 변수와 타 변수간의 상관관계를 알아는데는 pairplot은 좋지 않아보인다.

 

 

- 한번 임신 횟수에 대한 박스 플롯을 보자

 -> 평균 임신 횟수가 약 3회 정도가 되나 13회를 넘어가는 아웃라이어들이 존재한다.

 -> 한개의 박스 플롯으로 의미있는 정보를 보기 힘드니 여러개를 띄워보자

sns.boxplot(y="Pregnancies", data=df)

- 당뇨병 여부에 따른 임신 횟수를 살펴봣더니, 임신 횟수가 적을 수록 당뇨병 발병이 적은걸 알수 있다.

sns.boxplot(x="Outcome", y="Pregnancies", data=df)

- 나머지 변수들도 비슷한 결과를 보이고 있다.

- 나이대별 발병 여부는 어떨까?

 -> 젊은 층보다 중고령층인 경우 발병확률이 높음을 알 수 있다.

plt.figure(figsize=(12,6))
sns.barplot(x="Age", y="Outcome", data=df)

- 임신 횟수별  발병율을 바 플롯으로 본 결과. 횟수가 많을수록 유병율이 높은걸 확인할수 있다.

plt.figure(figsize=(12,6))
sns.barplot(x="Pregnancies", y="Outcome", data=df)

대강 탐색적 데이터 분석은 여기까지 하고

 

 

2. 전처리

이제 전처리 과정을 생각해보려고 한다.

 

전처리 과정에서 할일은 이렇게 정리할수 있을것같다.

 

1. 결측치 처리

2. 데이터 분할

3. 인코딩

4. 스케일링/정규화

5. 아웃라이어 처리

 

 

 

2. 1 우선 결측치 부터 처리하자

- 전처리 단계서 사용할 라이브러리 임포트

- 결측치를 확인해보니 존재하지 않는다.

from sklearn.preprocessing import LabelEncoder
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split

df.isnull().sum()

 

 

 

2.2 아웃라이어 처리

- 데이터프레임의 기초 통계량들을 보자

- 값 > 평균 + 3 * 표준편차들은 아웃라이어로 보고 좀 생각해보자

 

- 전체 768 행 데이터 중에서 아웃라이어들 갯수를 다 합쳐도 40개쯤 되는거 같다. 

 -> 이 아웃라이어가 존재하는 행들은 다 제거해주자.

cols = df.columns
print(df.shape)
for col in cols:
    mean = df[col].mean()
    std = df[col].std()
    threshold = mean + 3 * std
    n_outlier = np.sum(df[col] > threshold)
    print(col + ". num of outlier : "+str(n_outlier))

 

- 위 조건을 넘는 값을 아웃라이어로 판단하고, 제거하였다.

 -> 제거한 결과 768개 에서 727개로 줄어듦. 이제 스케일링 처리를 수행하자.

cols = df.columns
print("before drop outlier : {}".format(df.shape))
for col in cols:
    mean = df[col].mean()
    std = df[col].std()
    threshold = mean + 3 * std
    n_outlier = np.sum(df[col] > threshold)
    #print(df[df[col] > threshold])
    df.drop(df[df[col] > threshold].index[:], inplace=True)

df.dropna()
print("after drop outlier : {}".format(df.shape))

 

 

 

2.3 피처 스케일링

- 가우시안 커널을 사용하는 머신러닝 기법들은 특징들이 가우시안 분포를 따르는 경우 잘 동작된다고 한다.

- 모든 피쳐 데이터들을 표준화 시켜주기 위해 Standard Scaler를 사용해보자

 -> 모든 데이터들이 표준 정규분포를 따르는 값들로 변환이 되었다.

X = df.loc[:, df.columns != "Outcome"]
y = df.loc[:, df.columns == "Outcome"]
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

print(X_scaled[:,:6])

 

 

 

 

 

 

3. 모델링 

 

 

결측치는 없고,

아웃라이어 제거했고,

스케일링도했고,

라벨링 할 값도 존재하지 않는다.

 

이제 전처리 과정은 끝났으니 모델 구성, 학습을 해보자

 

 

내가 사용할 분류기는

 

1. Logistic Regression

 

2. SVM

 

3. Decision Tree

 

4. Random Forest

 

이 내가지를 사용하고자 한다.

 

 

여기서 grid seacrh cv를 사용하고자 하는데 사용할 파라미터들을 정리해야한다.

 

다큐먼트를 참고하여 설정할 파라미터들

 

1. Logistic Regression

 -> penalty : "l1", "l2", "elasticnet", "none"   default "l2"

 

2. SVM.svc

 -> kernel{‘linear’, ‘poly’, ‘rbf’, ‘sigmoid’}, default=’rbf’

 

3. Decision Tree

4. Random Forest

 트리는 max_depth와 min_samples_split을 사용하자.

 

 

 

 

하이퍼 파라미터에 따른 각 분류기들별 최적 성능과 최적의 파라미터를 구한 결과

 

대부분 비슷비슷하나

 

로지스틱 회귀에서 0.7917로 가장 좋은 성능이 나왔다.

 

 

 

 

from sklearn.linear_model import LogisticRegression
from sklearn.svm import SVC
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import GridSearchCV


def fit_clasifiers(gs_clfs, X, y):
    for clf in gs_clfs:
        print(X.shape)
        clf.fit(X, y)
    
def show_gridsearch_result(gs_clfs):
    estimators = []
    scores = []
    params = []
    for clf in gs_clfs:
        estimators.append(str(clf.estimator))
        scores.append(clf.best_score_)
        params.append(clf.best_params_)


    for i, val in enumerate(estimators):
        print(val)
        print(scores[i])
        print(params[i])
        
X_train, X_test, y_train, y_test = train_test_split(X_scaled, y, test_size=0.2)

lr = LogisticRegression()
svc = SVC(probability=True)
dt = DecisionTreeClassifier()
rf = RandomForestClassifier()

param_lr = {"penalty":["l1", "l2", "elasticnet", "none"]}
param_svc = {"kernel":["linear", "poly", "rbf", "sigmoid"]}
param_tree = {
    "max_depth" : [3, 4, 5, 6],
    "min_samples_split" : [2, 3]
}

gs_lr = GridSearchCV(lr, param_grid=param_lr, cv=5, refit=True)
gs_svc = GridSearchCV(svc, param_grid=param_svc, cv=5, refit=True)
gs_dt = GridSearchCV(dt, param_grid=param_tree, cv=5, refit=True)
gs_rf = GridSearchCV(rf, param_grid=param_tree, cv=5, refit=True)

gs_clfs = [gs_lr, gs_svc, gs_dt, gs_rf]
fit_clasifiers(gs_clfs, X_train, y_train)
show_gridsearch_result(gs_clfs)


 

 

 

 

 

5. 평가지표들 살펴보기

- l2 패널티를 준 로지스틱 회귀 모델에서

- 혼동 행렬, 정확도, 재현률, 정밀도, roc curve와 roc_auc score 등을 살펴보자

- 정확도는 77.39, 정밀도는 0.8이나 재현율이 0.56으로 크게 떨어지고 있다.

- 임계치 0.3 부근에서 교차하므로 이지점을 기준으로 분류가 필요해보인다.

 

from sklearn.metrics import accuracy_score, confusion_matrix, roc_auc_score
from sklearn.metrics import recall_score, precision_score,roc_curve
from sklearn.metrics import precision_recall_curve

def show_metrics(y_test, y_pred):
    confusion = confusion_matrix(y_test, y_pred)
    accuracy = accuracy_score(y_test, y_pred)
    precision = precision_score(y_test, y_pred)
    recall = recall_score(y_test, y_pred)
    print(confusion)
    print("Acc : {}".format(accuracy))
    print("precision : {}".format(precision))
    print("recall : {}".format(recall))

def show_precision_recall_curve(y_test,prob_positive_pred):
    precisions, recalls, thresholds = precision_recall_curve(y_test, prob_positive_pred)
    print("th val : {}".format(thresholds[:4]))
    print("precision val : {}".format(precisions[:4]))
    print("recalls val : {}".format(recalls[:4]))

    df = {
        "thresholds":thresholds, 
          "precisions":precisions[:-1], 
          "recalls":recalls[:-1]
    }
    df = pd.DataFrame.from_dict(df)

    sns.lineplot(x="thresholds", y="precisions", data=df)
    sns.lineplot(x="thresholds", y="recalls", data=df)

    


y_pred = gs_lr.predict(X_test)
pred_prob = gs_lr.predict_proba(X_test)
show_metrics(y_test, y_pred)
y_pred = np.concatenate([pred_prob, y_pred.reshape(-1, 1)], axis=1)
prob_positive_pred = y_pred[:, 1]

show_precision_recall_curve(y_test,prob_positive_pred)

 

- roc cuv

 -> roc_auc 값은 0.8188

 

 

def show_roc_curve(y_test,prob_positive_pred):
    fpr, tpr, thresholds = roc_curve(y_test,prob_positive_pred)

    print("fpr val : {}".format(fpr[:4]))
    print("tpr val : {}".format(tpr[:4]))
    print("thresholds val : {}".format(thresholds[:4]))

    df = {"threshold":thresholds, "fpr":fpr, "tpr":tpr}
    df = pd.DataFrame.from_dict(df)
    sns.lineplot(x="fpr", y="tpr", data=df)

    roc_score = roc_auc_score(y_test, prob_positive_pred)
    print(roc_score)

show_roc_curve(y_test,prob_positive_pred)

 

 

 

 

 

 

 

 

6. 수정

 

이 문제를 풀면서 이상하게

 

정확도가 떨어지는지 보니

 

아웃라이어 처리때 상한 아웃라이어만 처리하고

 

하한 아웃라이어들은 처리하지 않았더라

 

 

하한 아웃라이어의 값들을 살펴보았다.

 

 

6.1 하한 아웃라이어

 

- 하한 아웃라이어들은 대부분 0으로 나오길래, 실제 값이 0인 데이터들의 갯수를 확인하였다.

- 임신 여부는 0일수도 있으니 넘어가더라도 SkinThickness와 insulin의 0이 너무 많다고 나오고 있다.

   =>다른 열의 0행들은 제거하면 되지만, 많은 부분을 차지하는 행은 평균 값을 삽입해주자.

def show_lower_outlier(df, stdev=3, show_total=False):

    # lower bound outliers
    cols = df.columns
    print(df.shape)
    for col in cols:
        #std
        mean = df[col].mean()
        std = df[col].std()
        threshold = mean - stdev * std
        n_outlier = np.sum(df[col] < threshold)
        print(col + ". mean : "+str(round(mean,3))+", num of outlier : "+str(n_outlier))
        if (show_total == True) & (n_outlier != 0):
            print(df.loc[(df[col] < threshold),col][:5])
        
        print("   -> cnt of zero : " + str(np.sum(df[col] == 0))+"\n")

show_lower_outlier(df,show_total=True)

 

- 인슐린, 피부두께, 혈압에 평균을 대입

df.loc[ df.loc[:, "Insulin"] == 0 , "Insulin"] = df["Insulin"].mean()
df.loc[ df.loc[:, "SkinThickness"] == 0 , "SkinThickness"] = df["SkinThickness"].mean()
df.loc[ df.loc[:, "BloodPressure"] == 0 , "BloodPressure"] = df["SkinThickness"].mean()

show_lower_outlier(df,show_total=True)

 

 

- outcome을 제외한 타 컬럼들의 0값은 Nan으로 변환후 제거

 -> 768행에서 752행으로 줄었다.

 * 그냥 outcome을 진작에 떄놓고 할걸 ..  떗따 붙엿다 힘들다. 

print("before drop: "+ str(df.shape))

dfi = df.loc[:, (df.columns != "Outcome") & (df.columns != "Pregnancies")]
dfi[dfi[:] == 0] = np.NaN
dfi = dfi.dropna()
df.iloc[:,:-1] = dfi

show_lower_outlier(df,show_total=True)

 

 

 

 

 

 

너무 이문제에서 삽질 많이 했는데

 

 

매번 바뀌긴 하지만 결과를 정리하면

 

 

다음 전처리만 한 경우

- 상한 : 평균 + 3 * std 제거

=> acc : 0.753. , ROC AUC = 0.8119

전처리 추가시

- 하한 : 평균 - 3 * std제거,   일부 변수 0값 평균 대입, 0제거

=> ACC = 0.82119, ROC AUC = 0.8947

 

 

여러번 실행하면서 결과가 달라지다보니

 

하한 전처리를 추가했다고 항상 성능이 개선되지는 않았다.

 

 

300x250
728x90

머신러닝 성능 평가 지표

- confusion matrix 오차 행렬

- accuracy 정확도

- recall 재현률

- precision 정밀도

- f1 score

- roc auc

 

 

오차 행렬 confusion matrix

  True False
Positive TP FP
Negative TN TF

- TP : 예측기 긍정, 실제 긍정

- FP : 예측기 긍정, 실제 부정

- TN : 예측기 부정, 실제 부정

- FN : 예측기 부정, 실제 긍정

 => 예측기것을 먼저 보고, T이면 예측기와 실제가 동일/F이면 실제값이 예측기와 다름

 

정확도 accuracy

- (TP + TN)/전체

- 예측기가 실제 긍정 부정을 찾을 비율

 

재현율 recall

- 예측기가 없마나 실제 긍정에서 참긍정을 잘 재현하는가?

- 참긍정/(참긍정 + 거짓부정 ) => TP/(TP + FN)

- 민감도 sensitify, TPR tru Postiive Rate라고도 함.

- 실제 참을 부정으로 판단 시 중요 지표. -> 양성 환자를 음성으로 판단시 위험

 

 

정밀도

- 참긍정/(참긍정 + 거짓긍정) => TP/(TP + FP)

- 예측기가 참을 얼마나 정밀하게 구하는가

- 부정 데이터를 긍정으로 잘못 예측 시 큰 영향을 받는 경우 중요 지표 -> 스팸 메일을 긍정으로 판단시 지장

 

 

 

 

 

 

Confusion_matrix, accuracy, recall, precision 보기

- sklearn.metrics 모듈에서 confusion_matrix, accuracy_score, recall_score, precision_score 제공

- 아래와 같이 전처리 한 경우에 대한 성능 평가 지표들

from sklearn.metrics import precision_recall_curve
from sklearn.metrics import accuracy_score, precision_score, recall_score, confusion_matrix
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelEncoder

def get_categroy(age):
    cat = ""
    if age <= -1: cat = "Unknown"
    elif age <= 5: cat = "Baby"
    elif age <= 12: cat = "Child"
    elif age <= 18: cat = "Teenager"
    elif age <= 25: cat = "Student"
    elif age <= 35: cat = "Young Adult"
    elif age <= 60: cat = "Adult"
    else : cat = "Elderly"
    return cat

def feature_tf(df):
    enc_feature = ["Sex", "AgeGroup"]
    drop_feature = ["Name", "Embarked", "Ticket", "Cabin", "Age"]
    df["AgeGroup"] = df["Age"].apply(lambda x : get_categroy(x))
    df.drop(columns = drop_feature, inplace=True)
    for feature in enc_feature:
        enc = LabelEncoder()
        df[feature] = enc.fit_transform(df[feature])
    return df

def show_metrics(y_test, y_pred):
    confusion = confusion_matrix(y_test, y_pred)
    accuracy = accuracy_score(y_test, y_pred) 
    precision = precision_score(y_test, y_pred)
    recall = recall_score(y_test, y_pred)
    print(confusion)
    print("Acc : {}".format(accuracy))
    print("precision : {}".format(precision))
    print("recall : {}".format(recall))

df = pd.read_csv("res/titanic/train.csv")
X = df.iloc[:, df.columns != "Survived"]
y = df.iloc[:, df.columns == "Survived"]
feature_tf(X)

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)


lr = LogisticRegression()
lr.fit(X_train, y_train)
y_pred = lr.predict(X_test)
show_metrics(y_test, y_pred)

 

 

 

예측 레이블 확률 구하기 Estimator.predict_proba(X)

- 학습 완료된 추정기에 테스트 데이터를 주면, 해당 데이터에 대한 예측 확률 제공

- np.concatenate로 probability와 y_pred 값을 이은 결과는 아래와 같음

y_pred = lr.predict(X_test)
prob = lr.predict_proba(X_test)
res = np.concatenate([prob, y_pred.reshape(-1, 1)], axis=1)
res

 

 

분류기 임계치에 따른 정밀도, 재현율 변화 Classifier.precision_recall_curve(y_true, prob_positive_pred)

- 실제 값과 긍정 예측 확률이 주어질때 임계치별 정밀도와 재현율의 변화를 보여줌

- 반환 값 : 정밀도, 재현율, 임계치

 

prob_positive_pred = lr.predict_proba(X_test)[:, 1]

precisions, recalls, thresholds = precision_recall_curve(y_test, prob_positive_pred)

print("th val : {}".format(thresholds[:4]))
print("precision val : {}".format(precisions[:4]))
print("recalls val : {}".format(recalls[:4]))

 

 

시각화하기

- 세 변수들 -> dict -> df -> seaborn으로 시각화

- 임계치 0.4부근에서 정밀도와 재현률의 교차점이 존재

df = {"thresholds":thresholds, "precisions":precisions[:-1], "recalls":recalls[:-1]}
df = pd.DataFrame.from_dict(df)
sns.lineplot(x="thresholds", y="precisions", data=df)
sns.lineplot(x="thresholds", y="recalls", data=df)

 

 

 

 

F1 Score

- 정밀도와 재현율을 결합하여 만들어진 지표.

- 둘중 하나에 치우쳐지지 않아야 높은 값을 가짐.

 

ROC Curve (Receiver Operation Characteristic Curve)

- 통신 장비 성능 평가를 위해 고안됨,

-  X 축 : FPR(False Positive Rate), Y : TPR(True Positive Rate)

- TPR = TP/(TP + FN) 재현율, 민감도로 참 긍정/전체 참

- FPR : FP/(FP + TN) 거짓 긍정/전체 거짓

 

 

ROC Curve 모듈과 시각화

- from sklearn.metrics import roc_curve

- roc_curve(y_true, prob_pred_positive) -> FPR, TPR, thresholds

- 곡선은 1에 가까울수록 좋음. 

from sklearn.metrics import roc_curve

fpr, tpr, thresholds = roc_curve(y_test,prob_positive_pred)

print("fpr val : {}".format(fpr[:4]))
print("tpr val : {}".format(tpr[:4]))
print("thresholds val : {}".format(thresholds[:4]))

df = {"threshold":thresholds, "fpr":fpr, "tpr":tpr}
df = pd.DataFrame.from_dict(df)
sns.lineplot(x="fpr", y="tpr", data=df)

 

 

ROC AUC Score

- ROC 곡선의 AUC(Area under Curve).

- 곡선 아래의 넓이로 1에 가까울 수록 좋음. 

from sklearn.metrics import roc_auc_score
roc_score = roc_auc_score(y_test, prob_positive_pred)
print(roc_score)

 

 

300x250
728x90

난 개인적으로 시각 관련 알고리즘에 관심이 있는 편인데

 

opencv에서 제공하는 기본 함수 밖에 사용할 줄 모르니

 

어떻게 실제 연구에서 쓰는 알고리즘들을 구현하고, 연구할수있을까 막막할때가 많았다.

 

 

 

논문 잘 정리된 내용들이 많은데

 

부족한 영어실력으로 굳이 모든 내용을 번역해서 공부하는건 정말 아닌것같고,

 

 

 

 

pca나 sift 같은 알고리즘들을 구현한 내용들을

 

github에서 보긴했지만 엄두가 안나더라.

 

 

 

 

그래도 이전에 슈도코드를 보면서 직접 따라 구현해본다거나

 

이런 내용들을 몇번 검색해 봤었는데 원하는 답을 찾지는 못했었다.

 

 

 

이번에는 쿼라에 누가 이런 질문을 올린걸 찾았다.

 

ref : www.quora.com/How-do-I-learn-how-to-implement-algorithms-and-data-structures-in-C++

 

 

코딩 닌자에서 강의 들으면서 구현해보는게 좋다고 한다.

 

읽다보니 광고였네 ..

 

 

 

 

아무튼 c++로 데이터구조와 알고리즘 구현 연습이 필요한데 막상 시작하기가 참 힘들다.

 

 

 

이거랑 상관없이

 

 

jason brownlee라는 분이 좋은 머신러닝 알고리즘을 만드는 방법을 정리해서 올려주셧더라

 

 

 

ref : machinelearningmastery.com/how-to-implement-a-machine-learning-algorithm/

 

 

그러다가 찾은 책

 

Mastering Machine Learning Algorithms: Expert techniques for implementing popular machine learning algorithms, fine-tuning your models, and understanding how they work, 2nd Edition Paperback – January 31, 2020

 

복잡한 머신러닝 모델들을 만들고 싶은 사람들을 대상으로 하고, 평판은 되게 좋다.

 

www.amazon.com/Mastering-Machine-Learning-Algorithms-understanding/dp/1838820299/ref=sr_1_1?dchild=1&keywords=Master+Machine+Learning+Algorithms&qid=1606119400&sr=8-1

 

 

 

아무튼 데이터구조와 알고리즘 연습하긴 해야할듯하다 ㅠㅠ.

 

 

 

 

300x250

'그외 > 로그' 카테고리의 다른 글

캐글 대회 참여와 시험 준비  (0) 2020.12.03
컴퓨터 비전 알고리즘 구현 - 1. 시작  (0) 2020.11.26
과제 마무리  (0) 2020.11.19
시험 과제를 하면서  (0) 2020.11.17
인공지능에 대해 공부하면서  (0) 2020.11.11
728x90

빅데이터의 오류

- 결측치 : 누락된 변수 값

- 잡음 : 센서 노이즈로 인해 기존 값에서 벗어난 정도.

- 아웃라이어 : 기존의 데이터와 큰 차이를 보이는 데이터

 

 

 

빅데이터 분석 도구

- hadoop : 빅데이터 처리를 위한 자바 기반 오픈소스 프레임워크

- R : 통계 기법, 시각화 함수 제공. 하둡과 연동하여 빅데이터 처리

- presto : 페이스북에서 개발. 하둡 sql 처리 엔진

- bigquery : 구글 개발 빅데이터 처리 엔진.

- 맵리듀스 : 빅데이터 병렬처리 함수

- summingbird :  스톰과 하둡의 결합. 스트리밍 맵리듀스 시스템

 

 

 

빅데이터 솔루션

- 아파치 재단 : 오픈소스 프로젝트 수행

- cloudera : 하둡 배포판 제공

- 애저 : 빅데이터, 모바일, 저장소 등 통합 클라우드 플랫폼

- AWS : 애저와 동일

 

 

 

결측치 처리

- 삭제 : 결측치가 적은경우

- 대체 : 결측치가 많은 경우 다른 값으로 대치하는것이 좋음.

 

결측치 대체법

- 평균 삽입 : 해당 변수의 평균값을 결칙치에 삽입

- 보간법 : 시계열 데이터의 경우 보간하여 삽입

- 추정법 : 누락 값을 추정하여 삽입.

 

 

300x250
728x90

빅데이터 수집 과정

1. 데이터 유형 파악하기 : 종류, 크기, 수집 주기에 따라 구분 -> RDB data, JSON, img, log

2. 수집 방법 : 유형에 따라 최적

     -> 정형 데이터는 Sqoop, Vendor Driver, API

     ->  로그/센서는 Scribe, Flume

     ->  텍스트/이미지/영상 등 FTP/크롤러 등

3. 수집 솔루션 : 구성요소, 데이터 처리방식, 기본 아키텍처 확인

4. HW 구축 : 서버, 저장소, 네트워크 등 구축, 스펙 검토

5. 실행 환경 호가인 : 수집 프로그램의 동작 환경 확인.

 

 

 

빅데이터 수집 유형

1. 정형 데이터

- 테이블 형테의 데이터 -> RDB 데이터, Excel

 

2. 반정형 데이터 

- 웹 문서 같은 데이터로 내부에 메타 데이터를 가짐.

- HTML, XML, JSON 등

 

3. 비정형 데이터

- 텍스트, 이미지 같은 데이터

- 그대로 분석하기 힘들어 전처리 과정을 거침

 

 

 

 

 

데이터 유형에 따른 수집 

1. 정형 데이터

- Apache Scoop, API 등과 같은 수집/소켓프로그램으로 모음

 

2. 반정형 데이터

- Flume, Scribe, 블루투스, Log collector, 스트리밍

 

3. 비정형 데이터

- 웹/소셜 -> 크롤러

- 텍스트,이미지 등 -> FTP/API

 

 

 

 

데이터 형태 별 대표적인 수집 기술

- Apache Sqoop(정형 데이터용) : Hadoop과 연계한 대량 데이터 전송 및 분석, 병렬 데이터 전송

- Apach Flume(반정형 데이터용) :  로그 수집기, 분산 서비스, 대량 이벤트 정보 전송

- Scrapy(비정형) : 웹 크롤링하여 수집 -> 마이닝 등에 활용

 

 

 

텍스트 수집 기법

- scarping : 웹 문서에 대한 정보를 수집

- crawling : url link로 반복 수집

- ftp : 파일 전송 프로토콜

- rss : 사이트 정보를 공유하기 위한 기술로 xml 기반 콘텐츠 배급 프로토콜. 

- 개방 api : 외부에서 접근 가능

 

 

 

변수의 분류

- 계량적 변수와 비계량적 변수

- 계량적 변수 : 수치로 측정되는 데이터에 대한 변수. 연속/이산 변수로 또 나뉨 -> 매출액

- 비계량적 변수 : 수치로 측정과는 관련없는 데이터에 대한 변수 -> 성별, 의견

 

 

데이터 척도

- 명목 척도 normial scale : 소속 분류. -> 성별, 나라, 구분

- 서열 척도 ordinal scale : 순위 구분 -> 등수, 평점

- 구간 척도 interval scale : 서열과 차이 구분 -> 온도

- 비율 척도 ration scale : 척도간 비율 -> 나이, 길이

 

 

 

빅데이터 분석 기술의 활용 사례

- 머신 러닝 : 영화 구매 패턴으로 다른 영화 추천

- 감정 분석 : 고객 반응 분석

- 소설 네트워크 분석 : 평판이 어떤지 관찰

- 연관 분석 : 관련 상품 구입 여부 분석

- 분류 : 새 고객이 어느 집단에 속하는가

- 회귀 : 고객 연령대에 따라 구입 상품에 어떻게 되는 확인

 

 

 

저장 시스템

1. RDBMS 관계형 데이터베이스 시스템

- 정형 데이터 저장

- 반정형 데이터로부터 추출

- 개념/논리/물리 db 설계

- Mysql, oracle 등

 

2. nosql dbms

- json 형태의 데이터 관리. 제약이 덜함

- mongodb와 cassandra 등

* 카산드라 : 오픈소스 dbms, 분산 시스템 이용.

 

 

300x250
728x90

타이타닉 생존자 예측에 있어서 할 일은 대강 다음으로 정리할수 있을것 같다.

- 전처리 

- 모델 선정

- 교차검증, 하이퍼 파라미터 조정

- 시각화

 

 

 

1. 라이브러리 임포트

- 대강 생각나는 라이브러리들

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.preprocessing import StandardScaler
from sklearn.preprocessing import LabelEncoder
from sklearn.model_selection import GridSearchCV
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier

 

2. 데이터 읽고 훑어보기

 

train_df = pd.read_csv("res/titanic/train.csv")
test_df = pd.read_csv("res/titanic/test.csv")

train_df.head()

 

- info로 보니 891 x 12 형태

- 기초 통계량

- 결측치 조회 및 삭제

* Cabin의 경우 결측치가 687개라 그냥 결측치를 삭제하는경우 891개 중 687개가 삭제되어버렸다.

 => Cabin과 Age의 결측치는 삭제하지 말고, fillna()로 채워주자

print(train_df.isnull().sum())
train_df = train_df.dropna()
print()
print(train_df.isnull().sum())
print(train_df.info())

- 결측치 채우고, 나머지 삭제

 -> "age"는 나이 평균, "cabin"은 N으로 대체

train_df = pd.read_csv("res/titanic/train.csv")

train_df["Age"].fillna(train_df["Age"].mean(), inplace=True)
train_df["Cabin"].fillna("N", inplace=True)
train_df = train_df.dropna()
print()
print(train_df.isnull().sum())
print(train_df.info())

 

 

탐색적 데이터 분석

1. 단순 확인

- 일단 각 컬럼 별 분포를 해보자

- 우선 해당 데이터프레임의 컬럼 조회

- 아까 결측치를 채운 카빈부터 보자

 -> 호실이다보니 수가 적은 경우가 많아보인다.

- 남여 비율과 생존여부, 등급

2. 그룹별 조회

- 성별에 따른 생존 여부

train_df.groupby(["Sex", "Survived"])["Survived"].count()

- 선실등급별 생존여부

train_df.groupby(["Pclass", "Survived"])["Survived"].count()

- 나이별 생존여부.

   * 나이의 경우 나이대별로 보지않다보니 힘들다. 그룹화가 필요해보이고, 이번에 시각화해서 보자

train_df.groupby(["Age", "Survived"])["Survived"].count()

 

 

 

3. 시각화

- 성별에 따른 생존여부

sns.barplot(x="Sex", y="Survived",data=train_df)

- 성별과 선실 등급에 따른 생존여부

sns.barplot(x="Sex", y="Survived", hue="Pclass", data=train_df)

 

 

* DataFrame.apply() 함수를 이용한 나이대별 그룹화

 -> 25 ~ 35인 Young Adult가 가장 많은걸 확인할 수 있음. 

 (아마 아까 Age의 결측치를 평균으로 채운 영향으로보임)

def get_categroy(age):
    cat = ""
    if age <= -1: cat = "Unknown"
    elif age <= 5: cat = "Baby"
    elif age <= 12: cat = "Child"
    elif age <= 18: cat = "Teenager"
    elif age <= 25: cat = "Student"
    elif age <= 35: cat = "Young Adult"
    elif age <= 60: cat = "Adult"
    else : cat = "Elderly"
    return cat

train_df["AgeGroup"] = train_df["Age"].apply(lambda x : get_categroy(x))
train_df["AgeGroup"].value_counts()

- 나이대 그룹과 성별에 따른 생존 여부를 살펴보자

 -> 아기, 어린이와 여성의 경우 생존률이 높게 나옴

sns.barplot(x="AgeGroup", y="Survived", hue="Sex", data=train_df)

- 선실 등급과 나이 그룹에 대해서도 살펴보면 -> 1등실 사람일수록 생존률이 높음

- 다른 변수로 Parch(탑승 부모, 어린이인원), SibSp(탑승 형재, 배우자 인원)도 살펴보면 

 -> PClass, Age에 비하여 균등하게 나옴 => 좋은 변수는 아님

 

 

4. 인코딩 하기

- 아까 Sex, Cabin, Embarked 변수가 문자열로 되어있는걸 보았으니 인코딩이 필요

 

def encoding(df):
    features = ["Cabin", "Sex", "Embarked"]

    for feature in features:
        encoder = LabelEncoder()
        df[feature] = encoder.fit_transform(df[feature])
    
    return df

train_df = encoding(train_df)
train_df.head()

 

* 아까 잊었는데 값이 고유한 변수들은 삭제해주자

 -> Age, Ticket 는 삭제

train_df.drop(["Name", "Ticket"], axis=1, inplace=True)
train_df.head()

 

 

 

 

GridSearchCV를 이용한 최적의 분류기와 하이퍼 파라미터 찾기

- 데이터는 loc로 X, y  선택

- random forest와 결정 트리 사용

X = train_df.loc[:,train_df.columns != "Survived"]
y = train_df.loc[:,train_df.columns == "Survived"]

rf_clf = RandomForestClassifier()
dt_clf = DecisionTreeClassifier()

param = {
    "max_depth" : [3, 4, 5, 6],
    "min_samples_split" :[2, 3, 4, 5]
}

rf_gs = GridSearchCV(rf_clf, param_grid=param, cv=5, refit=True)
dt_gs = GridSearchCV(dt_clf, param_grid=param, cv=5, refit=True)

rf_gs.fit(X, y)
dt_gs.fit(X, y)

print("Random Forest")
print(rf_gs.best_score_)
print(rf_gs.best_params_)
print("\n\ndecision tree")
print(dt_gs.best_score_)
print(dt_gs.best_params_)

- 최적의 성능과 하이퍼 파라미터는 아래의 사진과 같음

 -> 랜덤 포레스트로 깊이 5, min_sample_split이 2일때 0.829로 좋았음.

 

 

 

 

 

 

300x250
728x90

데이터 전처리

- sklearn의 머신러닝 알고리즘을 사용하기전에 결손치나 문자열 값을 처리해주어야 함

-> 결손치 제거

-> 문자열을 카테고리(인코딩하여)나, 벡터화

* PK로 사용할수 있는 값(주민번호, 아이디)은 제거하는 것이 좋음

 

 

 

 

데이터 인코딩

- 라벨 인코딩, 원핫 인코딩 

- 라벨 인코딩 LabelEncoding : 카테고리형 문자열 변수에 클래스 할당

  * sklearn.preprocessing에서 제공 

from sklearn.preprocessing import LabelEncoder

items = ["한국", "미국", "미국", "중국", "러시아", "호주"]

encoder = LabelEncoder()
encoder.fit(items)

lables = encoder.transform(items)
print(lables)
print(encoder.classes_)

- 원핫인코딩 OneHotEncoding : 각 카테고리가 고유의 컬럼을 가지고, 해당하면 1아니면 0의값을 갖도록하는방식

from sklearn.preprocessing import OneHotEncoder
lables = lables.reshape(-1,1)
print(lables)

oh = OneHotEncoder()
oh.fit(lables)
oh_lables = oh.transform(lables)

print(oh_lables.toarray())

 

 

 

 

 

피처 스케일링 feature scaling

- 다른 범위의 값들을 갖는 변수를 일정 수준으로 변환하는 작업

 ->  ex. 표준화 standardization, 정규화 normalization

- 표준화 : 특정 피처값을 표준 정규 분포의 값으로 변환. (해당 값 - 해당 피처 평균)/해당 피처 표준편차

- 정규화 : 피처 값을 0 ~ 1사이 값으로 변환.

* sklearn의 정규화 : 벡터 정규화. 새 피처값 = 해당 피처값/해당 행의 유클리디안 거리

 

 

 

StandardScaler

- sklearn.preprocess 모듈

- 가우시안 커널을 사용하는 알고리즘(SVM, 선형회귀, 로지스틱회귀)는 데이터가 가우시안 분포를 따른다고 가정

  -> 표준화가 중요

 

from sklearn.preprocessing import StandardScaler
from sklearn.svm import SVC

scaler = StandardScaler()
scaler.fit(X)
X_scaled = scaler.transform(X)
df_scaled = pd.DataFrame(data=X_scaled, columns=data.feature_names)


print("befor scaling")
print(X.mean())
print(X.var())

print("\nafter scaling")
print(df_scaled.mean())
print(df_scaled.var())

 

 

MinMaxSacler

- 0 ~ 1 사이 값으로 변환. (음수 포함시 -1 ~ 1)

from sklearn.preprocessing import MinMaxScaler

scaler = MinMaxScaler()
scaler.fit(X)
X_scaled = scaler.transform(X)

df_scaled = pd.DataFrame(data=X_scaled, columns=data.feature_names)
print(df_scaled.min())
print(df_scaled.max())

 

 

 

 

 

 

 

 

 

 

 

300x250
728x90

sklearn 모듈 개요

 

1. 데이터셋 datasets

 

2. 특징 처리

 2.1 preprocessing

  - 인코딩, 정규화, 스케일링 등

 2.2 feature_selection

  - 큰 영향을 미치는 피처 순서대로 선정

 2.3 feature_extraction

  - 피처 추출

 2.4 decomposition

  - 차원 축소 알고리즘 지원. LDA, PCA, SVD 등

3. 데이터 분할, 검증, 하이퍼 파라미터 튜닝 model_selection

 - 교차 검증, 최적 하이퍼파라미터 추출을 위한 그리드 서치 등 제공

4. 성능평가 척도 metrics

 - 정확도 accuracy, 재현율(모델 참/실제 참) recall, 정밀도(모델참/전체 참) precision, ROC-AUC, RMSE 등

 

5. 머신러닝 알고리즘

 5.1 ensemble : 랜덤 포레스트, 어댑티브부스트, 그라디언트 부스트

 5.2 linear_model : 선형 모델, 릿지, 라쏘, 로지스틱 회귀, SGD

 5.3 naive_bayes : 나이브 베이즈, 가우시안NB

 5.4 neighbors : K-NN

 5.5 svm : 서포트 벡터 머신 관련 알고리즘

 5.6 tree : 결정 트리

 5.7 cluster : k-means, dbscan 등

 

6. pipeline : 피처 처리, 학습, 예측 등을 함께 할수있는 묶음.

 

 

 

 

 

 

 

 

 

교차 검증

 

교차 검증하기

- 과적합 문제를 개선하기 위해 사용

 * 과적합 : 학습 데이터에 모델이 과도하게 맞춰져, 실제 예측시 성능이 떨어지는 현상.

- 학습 데이터를 학습, 검증 데이터로 분할하여 학습 (위의 train_test_split으로 분할하여 학습한 것과 같이)

 

 

k fold cross validation

- 데이터를 k개로 분할하여 (k-1)개로 학습, 1개로 테스트를 k번 수행하여 검증하는 방법

- model_selection의 KFold 사용

- KFold(n_split=)  -> KFold.split(X) 데이터를 n_split 만큼 분할하여 인덱스 반환

from sklearn.model_selection import KFold

kfold = KFold(n_splits=5)
num_iter = 0

cv_acc = []

for train_idx, test_idx in kfold.split(X):
    X_train, X_test = X.iloc[train_idx, :], X.iloc[test_idx, :]
    y_train, y_test = y.iloc[train_idx], y.iloc[test_idx]
    
    clf.fit(X_train, y_train)
    y_pred = clf.predict(X_test)
    num_iter = num_iter + 1
    acc = round(accuracy_score(y_test, y_pred), 10)
    
    print("{}번 검증 셋 정확도 : {} ".format(num_iter, acc))
    cv_acc.append(acc)

print("mean of accuracy : {} ".format(round(np.mean(cv_acc),7)))

 

 

stratified K fold

- 타겟 레이블의 비율이 불균형한 데이터를 위한 k fold

- 타겟 레이블의 분포도를 반영하여 인덱스 제공

- KFold와 다르게 StratifiedKFold.split(X, y)는 X와 y를 같이 제공해주어야 함.

from sklearn.model_selection import StratifiedKFold

skf = StratifiedKFold(n_splits=5)

for train_idx, test_idx in skf.split(X, y):
	...

 

 

cross_val_score

- 교차 검증과 성능 평가 척도를 한번에 하는 함수

- cross_val_score(estimator, X, y=None, scoring=None, cv=None, n_jobs=1, verbose=0, ....)

from sklearn.model_selection import cross_val_score
scores = cross_val_score(clf, X, y, scoring="accuracy", cv=5)
print(scores)
print(np.mean(scores))

 

 

 

 

 

하이퍼 파라미터 탐색

 

GridSearchCV

- GridSearchCV(estimator, param_grid, scoring, cv, refit)

 * param_grid : 하이퍼 파라미터 딕셔너리, refit : 디폴트 true, 최적 하이퍼파라미터로 재학습

 

from sklearn.model_selection import GridSearchCV


clf = DecisionTreeClassifier()
param = {
    "max_depth":[1, 2, 3, 4, 5],
    "min_samples_split":[2, 3, 4]
}

grid_clf = GridSearchCV(clf, param_grid=param, cv=5, refit=True)
grid_clf.fit(X_train, y_train)

scores_df = pd.DataFrame(grid_clf.cv_results_)
scores_df.head()

- GridSearchCV.cv_result_로 결과 반환. 데이터프레임으로 변환 후 출력 시

 -> max_depth가 5이고, min_samples_split이 1인 경우 최적 성능

- GridSearchCV의 변수로 best_params_, best_score_, best_estimator_ 등 제공

print(grid_clf.best_params_)
print(grid_clf.best_score_)

clf = grid_clf.best_estimator_
print(clf.score(X_test, y_test))

 

 

 

 

 

 

 

300x250
728x90

sklearn

- 파이썬에서 머신러닝을 사용하기 위한 api들을 제공함.

- 전처리, 데이터셋, 군집화, 분류, 회귀 등

 

 

붓꽃 문제 다루기

 

라이브러리 import

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris

 

 

아이리스 데이터 읽기 및 확인

- sklearn의 load함수로 호출한 데이터셋은 bunch타입

- sklearn.utils.Bunch의 DESCR에서 해당 데이터셋에대한 설명 

 

 

bunch 데이터를 데이터 프레임으로 변환 및 확인

- 머신러닝 알고리즘을 적용하기위해 데이터프레임 데이터로 변환

df = pd.DataFrame(columns=data.feature_names, data=data.data)
df["label"] = data.target
df.head()

 

 

데이터 분할하기

- 훈련용 데이터와 테스트용 데이터 분할

- sklean.model_selection의 train_test_split()함수 사용

- train_test_split(X, y, test_size=None)

  -> test_size에는 전체 데이터프레임의 비율 지정. 0.2의 경우 20%

 

from sklearn.model_selection import train_test_split

X = df.iloc[:,:-1]
y = df["label"]

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)

 

 

 

학습 모델

- Estimator 클래스

  -> Classifier, Regressor 등

- Estimator.fit(X, y)

  - X, y 데이터로 학습

- Estimator.predict(X)

 - 주어진 X 데이터로 예측

 

 

학습 모델 사용하기

- 본 붓꽃 문제는 특징들을 이용한 분류 문제. 의사결정트리 사용

- 의사결정 트리는 sklearn의 tree에 있음.

 

 

from sklearn.tree import DecisionTreeClassifier
clf = DecisionTreeClassifier()

clf.fit(X_train, y_train)
y_pred = clf.predict(X_test)

 

 

 

모델 성능 척도

- 정확도, 재현률, MSE 등 존재

- 다음 경우 estimator.score()와 정확도, MSE 사용

from sklearn.metrics import accuracy_score
from sklearn.metrics import mean_squared_error


print("decision tree score using train : {}".format(clf.score(X_train, y_train)))
print("decision tree score using test : {}".format(clf.score(X_test, y_test)))
print("accuracy : {}".format(accuracy_score(y_test, y_pred)))
print("MSE : {}".format(mean_squared_error(y_test, y_pred)))

 

 

 

 

 

300x250
728x90

넘파이 개요

- 파이썬 선형대수 library

- 루프 없이 빠르게 선형대수 처리 가능

- C++에서 Eigen, Armadillo 같은 lib

- 저수준 언어 기반 호환 API 제공. -> 성능에서 중요한 부분은 C/C++로 작성. 넘파이에서 호출가능

넘파이 배열

- 생성 : arrange, zeros, eyes

- 재배치 : reshape

- 인덱싱 처리 등 내용은 생략

Pandas

  • 금융 분석가 웨스 매키니가 만든 데이터 핸들링 라이브러리
  • DBMS, Excel의 테이블과 유사한 데이터들을 다룸
  • 대표적인 자료구조로 Series와 DataFrame
  • Series : 칼람이 하나인 데이터 구조
  • DataFrame ; 칼럼이 여러개인 데이터 구조

www.kaggle.com/c/titanic/data

titanic data 보기

 

DataFrame.head()

- 해당 DataFrame의 앞 5개 데이터 확인

 

 

 

DataFrame.info()

- 해당 데이터프레임의 컬럼의 데이터 갯수와 데이터 타입조회

 

 

DataFrame.describe()

- 해당 데이터프레임의 기초통계량 조회

 

 

Series.value_counts()

- 해당 컬럼의 그룹별 갯수를 카운트

- 다음 경우 3등석이 491, 2등석이 184, 1등석이 216개임을 확인

print(type(df["Pclass"]))
df["Pclass"].value_counts()

 

 

데이터 프레임 컬럼 추가

- 다음의 경우 age_0이라는 컬럼이 추가.

- 값은 0으로 지정

df["age_0"] = 0
df.head()

 

 

데이터 프레임 컬럼 값 변경

df["age_0"] = df["age_0"] + 20
df.head()

 

데이터 프레임 열 삭제

- DataFrame.drop(labels=None, axis=0, index=None, columns=None, inplace=False)

- labels : 삭제 컬럼명 지정

- axis : 0인경우 행, 1인경우 열 지정

- inplace : 해당 DataFrame에 적용 여부. 

- 나머지는 doc 참조

- 아래의 경우 age_0 열이 삭제된것을 확인

 

df.drop(labels="age_0", axis=1, inplace=True)
df.head()

 

 

 

 

데이터프레임 인덱싱 - 1. loc (명칭 기반인덱싱)

- DataFrame.loc[키값, 열이름]

df.loc[3, "Name"]

 

 

 

데이터프레임 인덱싱 - 2. iloc (숫자 기반인덱싱)

- DataFrame.iloc[키, 열]

 

데이터 프레임 인덱싱 조합

- Pclass >=2 인 경우. 4번째까지 출력

df[df["Pclass"] >= 2][:4]

- Pclass >=2 이고, Survived=1인 경우, 4개 출력

df[(df["Pclass"] >= 2) & (df["Survived"] == 1)][:4]

 

집계함수 aggregation

- min(), max(), sum(), count()등

print(df.mean())
print(df.count())
print(df["Age"].count())
print(df[["Age","Fare"]].count())

 

 

그룹함수 groupby

- DataFrame.groupby(그룹할컬럼명)

   -> DataFrameGroupBy 객체 반환

group = df.groupby("Sex")
print(type(group))

- 해당 객체는 집계함수 사용 가능

print(group.count())

group.describe()

 

 

- 여러 컬럼으로 그룹핑 가능

group = df.groupby(["Pclass", "Sex"])
group.describe()

 

결측치 확인 - DataFrame.isnull().sum()

- DataFrame.isnull() 은 모든 행열에서 결측치 여부에 따라 true, false를 반환

 - + sum()으로 각열에 대한 결측치들을 합하여 갯수를 알려줌

df.isnull().sum()

 

 

 

결측치 제거 - DataFrame.dropna(axis=None, how=None)

- Axis :  axis = 0인 경우 행, axis = 1인경우 열, axis=None이면 행렬 다 적용

- how : how = "any" 결측치가 하나라도 존재하면 제거, how = " all" 전체가 결측치인경우제거

df = df.dropna(axis=0)
df.isnull().sum()

 

 

 

람다식 적용하기

- DataFrame.apply(람다식) 으로 데이터프레임에 함수 적용 가능

df["NameLen"] = df["Name"].apply(lambda x : len(x))
df[["Name","NameLen"]].head()

300x250

+ Recent posts