<jupyter_start><jupyter_text>"인구 데이터 기반 소득 예측 경진대회"> "인구 데이터 기반 소득 예측 경진대회"- toc:true- branch: master- badges: true- comments: true- author: jaeeon- categories: [jupyter, python]  인구 데이터 기반 소득 예측 경진대회- 대회 링크 : https://dacon.io/competitions/official/235892/overview/description- 목적 : 인구 데이터 바탕으로 소득이 5만달러 이하인지 초과인지 분류하기- 데이터:   1. train.csv : 학습 데이터  2. test.csv : 테스트 데이터  3. sample_submission.csv : 제출 양식  train data<jupyter_code>from google.colab import drive
drive.mount('/content/drive')<jupyter_output><empty_output><jupyter_text>데이터 확인하기<jupyter_code>import pandas as pd
train = pd.read_csv('/content/drive/MyDrive/Colab/data/train.csv')
train<jupyter_output><empty_output><jupyter_text>1. train.csv : 학습 데이터- id : 샘플 아이디- age : 나이- workclass : 일 유형- fnlwgt : CPS(Current Population Survey) 가중치- education : 교육수준- education.num : 교육수준 번호- marital.status : 결혼 상태- occupation : 직업- relationship : 가족관계- race : 인종- sex : 성별- capital.gain : 자본 이익- capital.loss : 자본 손실- hours.per.week : 주당 근무시간- native.country : 본 국적- target : 소득					   0 = <=50K (5만 달러 이하)					   1 = >50K (5만 달러 초과)    결측치 확인하기<jupyter_code>def check_missing_col(dataframe):
    missing_col = []
    for col in dataframe.columns:
        missing_values = sum(dataframe[col].isna())
        is_missing = True if missing_values >= 1 else False
        if is_missing:
            print(f'결측치가 있는 컬럼은: {col} 입니다')
            print(f'해당 컬럼에 총 {missing_values} 개의 결측치가 존재합니다.')
            missing_col.append([col, dataframe[col].dtype])
    if missing_col == []:
        print('결측치가 존재하지 않습니다')
    return missing_col

missing_col = check_missing_col(train)
print(train['workclass'].unique())
print(train['occupation'].unique())
print(train['native.country'].unique())
# 결측치를 처리하는 함수를 작성합니다.
def handle_na(data, missing_col):
    temp = data.copy()
    for col, dtype in missing_col:
        if dtype == 'O':
            # 범주형 feature가 결측치인 경우 해당 행들을 삭제해 주었습니다.
            temp = temp.dropna(subset=[col])
    return temp

train = handle_na(train, missing_col)

# 결측치 처리가 잘 되었는지 확인해 줍니다.
missing_col = check_missing_col(train) 
train.info()<jupyter_output><class 'pandas.core.frame.DataFrame'>
Int64Index: 15081 entries, 0 to 15080
Data columns (total 16 columns):
 #   Column          Non-Null Count  Dtype 
---  ------          --------------  ----- 
 0   id              15081 non-null  int64 
 1   age             15081 non-null  int64 
 2   workclass       15081 non-null  object
 3   fnlwgt          15081 non-null  int64 
 4   education       15081 non-null  object
 5   education.num   15081 non-null  int64 
 6   marital.status  15081 non-null  object
 7   occupation      15081 non-null  object
 8   relationship    15081 non-null  object
 9   race            15081 non-null  object
 10  sex             15081 non-null  object
 11  capital.gain    15081 non-null  int64 
 12  capital.loss    15081 non-null  int64 
 13  hours.per.week  15081 non-null  int64 
 14  native.country  15081 non-null  object
 15  target          15081 non-null  int64 
dtypes: int64(8), object(8)
memory usage: 2.0+ MB<jupyter_text>데이터 전처리 범주형 변수들을 라벨 인코딩<jupyter_code>#라벨인코딩을 하기 위함 dictionary map 생성 함수
def make_label_map(dataframe):
    label_maps = {}
    for col in dataframe.columns:
        if dataframe[col].dtype=='object':
            label_map = {'unknown':0}
            for i, key in enumerate(dataframe[col].unique()):
                label_map[key] = i  #새로 등장하는 유니크 값들에 대해 1부터 1씩 증가시켜 키값을 부여해줍니다.
            label_maps[col] = label_map
    return label_maps

# 각 범주형 변수에 인코딩 값을 부여하는 함수
def label_encoder(dataframe, label_map):
    for col in dataframe.columns:
        if dataframe[col].dtype=='object':
            dataframe[col] = dataframe[col].map(label_map[col])
            #dataframe[col] = dataframe[col].fillna(label_map[col]['unknown']) #혹시 모를 결측값은 unknown의 값(0)으로 채워줍니다.
    return dataframe

train = label_encoder(train, make_label_map(train))
train<jupyter_output><empty_output><jupyter_text>모델 선언과 학습- 변수 및 모델 정의<jupyter_code># 분석에 필요 없는 id 와 예측하고자 하는 값 타겟을 제거해줍니다.
X = train.drop(['id','target'], axis=1)
y = train['target']
from sklearn.linear_model import LogisticRegression

# 모델 선언
model = LogisticRegression(solver='liblinear')

# 모델 학습
model.fit(X, y)
# 먼저 점수를 메기는 방법인 평가 지표(Metric)를 정의합니다.
import numpy as np

def ACCURACY(true, pred):   
    score = np.mean(true==pred)
    return score
# 모델의 예측과 실제 정답값을 비교합니다.
prediction = model.predict(X)

score = ACCURACY(y, prediction)

print(f"모델의 정확도는 {score*100:.2f}% 입니다")<jupyter_output>모델의 정확도는 79.09% 입니다<jupyter_text>train.csv 학습/검증셋 분리하기<jupyter_code>from sklearn.model_selection import train_test_split

data = train.drop('id', axis = 1).copy() #필요없는 id열 삭제
train_data, val_data = train_test_split(data, test_size=0.5)
train_data.reset_index(inplace=True) #전처리 과정에서 데이터가 뒤섞이지 않도록 인덱스를 초기화
val_data.reset_index(inplace=True)
print( 'train 데이터 셋 모양 :', train_data.shape)
print( 'val 데이터 셋 모양 :', val_data.shape)
train_data.head()
X_train = train_data.drop(['index', 'target'], axis=1) #training 데이터에서 독립변수 추출
y_train = train_data.target #training 데이터에서 라벨 추출
X_train.shape
### 모델 학습
from sklearn.ensemble import RandomForestClassifier

model = RandomForestClassifier() # 모델을 객체에 할당
model.fit(X_train, y_train) # 모델 학습

#pred = model.predict(test)<jupyter_output><empty_output><jupyter_text>검증셋으로 모델 성능 검증<jupyter_code>X_val = val_data.drop(['index', 'target'], axis=1)  #validation 데이터에서 전처리된 문서 추출
y_val = val_data.target #validation 데이터에서 라벨 추출
y_pred = model.predict(X_val)
print(y_pred)
from sklearn import metrics

print('RandomForestClassifier 의 예측 정확도는', round(metrics.accuracy_score(y_val, y_pred),3)) # 정확도 확인<jupyter_output>RandomForestClassifier 의 예측 정확도는 0.845<jupyter_text>랜덤 포레스트 하이퍼 파라미터 튜닝<jupyter_code>### max_depth
from sklearn.ensemble import RandomForestClassifier

model_md1 = RandomForestClassifier(max_depth = 1) # 모델을 객체에 할당
model_md10 = RandomForestClassifier(max_depth = 10)

model_md1.fit(X_train, y_train) # 모델 학습
model_md10.fit(X_train, y_train) 

pred_md1 = model_md1.predict(X_val)
pred_md10 = model_md10.predict(X_val)

print('RF max_depth = 1 의 예측 정확도는', round(metrics.accuracy_score(y_val, pred_md1),3)) # 정확도 확인
print('RF max_depth = 10 의 예측 정확도는', round(metrics.accuracy_score(y_val, pred_md10),3)) # 정확도 확인
### n_estimators
from sklearn.ensemble import RandomForestClassifier

model_ne1 = RandomForestClassifier(n_estimators = 1) # 모델을 객체에 할당
model_ne200 = RandomForestClassifier(n_estimators = 200)

model_ne1.fit(X_train, y_train) # 모델 학습
model_ne200.fit(X_train, y_train) 

pred_ne1 = model_ne1.predict(X_val)
pred_ne200 = model_ne200.predict(X_val)

print('RF n_estimators = 1 의 예측 정확도는', round(metrics.accuracy_score(y_val, pred_ne1),3)) # 정확도 확인
print('RF n_estimators = 200 의 예측 정확도는', round(metrics.accuracy_score(y_val, pred_ne200),3)) # 정확도 확인
### max_features
from sklearn.ensemble import RandomForestClassifier

model_mf1 = RandomForestClassifier(max_features = 1) # 모델을 객체에 할당
model_mf3 = RandomForestClassifier(max_features = 3)

model_mf1.fit(X_train, y_train) # 모델 학습
model_mf3.fit(X_train, y_train) 

pred_mf1 = model_mf1.predict(X_val)
pred_mf3 = model_mf3.predict(X_val)

print('RF n_estimators = 1 의 예측 정확도는', round(metrics.accuracy_score(y_val, pred_mf1),3)) # 정확도 확인
print('RF n_estimators = 3 의 예측 정확도는', round(metrics.accuracy_score(y_val, pred_mf3),3)) # 정확도 확인
model_2 = RandomForestClassifier(max_depth = 10, n_estimators = 200, max_features = 3) # 최종 모델
model_2.fit(X_train, y_train) 
y_pred_2 = model_2.predict(X_val)
print(y_pred_2)
print('Tuned RandomForestClassifier 의 예측 정확도는', round(metrics.accuracy_score(y_val, y_pred_2),3)) # 정확도 확인<jupyter_output>[0 0 0 ... 1 1 0]
Tuned RandomForestClassifier 의 예측 정확도는 0.85<jupyter_text>XGBoost<jupyter_code>import xgboost as xgb

# 모델 선언
model = xgb.XGBClassifier() 

# 모델 훈련
model.fit(X_train,y_train) 

# 모델 예측
y_pred_3 = model.predict(X_val) 

print(y_pred_3)
print('XGBoost의 예측 정확도는', round(metrics.accuracy_score(y_val, y_pred_3),3)) # 정확도 확인
xgb.plot_importance(model)<jupyter_output><empty_output><jupyter_text>: xgb.plot_importance() 메쏘드에 XGBoost 모형객체를 넣어 변수중요도를 파악할 수 있다.중요도가 높은 변수는 age : 나이와 capital.gain : 자본 이익인 것을 알 수 있다.<jupyter_code>import matplotlib.pyplot as plt

xgb.plot_tree(model, num_trees=0, rankdir='LR')

fig = plt.gcf()
fig.set_size_inches(150, 100)

plt.show()<jupyter_output><empty_output><jupyter_text>xgb.plot_importance(model)을 바탕으로 중요하지 않은 변수인     workclass : 일 유형, sex : 성별, education : 교육수준, race : 인종, native.country : 본 국적를 제외시키고 XGBoost을 사용하여 분석해볼 것입니다.<jupyter_code>train_data.head()
X_train_xg = train_data.drop(['index', 'target','workclass', 'sex', 'education', 'race', 'native.country','relationship'], axis=1) #training 데이터에서 독립변수 추출
y_train_xg = train_data.target #training 데이터에서 라벨 추출
val_data.head()
X_val_xg = val_data.drop(['index', 'target','workclass', 'sex', 'education', 'race', 'native.country','relationship'], axis=1)  #validation 데이터에서 전처리된 문서 추출
y_val_xg = val_data.target #validation 데이터에서 라벨 추출
import xgboost as xgb

# 모델 선언
model = xgb.XGBClassifier() 

# 모델 훈련
model.fit(X_train_xg,y_train_xg) 

# 모델 예측
y_pred_4 = model.predict(X_val_xg) 

print(y_pred_4)
print('XGBoost의 예측 정확도는', round(metrics.accuracy_score(y_val_xg, y_pred_4),3)) # 정확도 확인<jupyter_output>[0 0 0 ... 1 1 0]
XGBoost의 예측 정확도는 0.854<jupyter_text>위에서 했던 xgboost 보다 예측 정확도가 0.001가 낮아졌습니다.  그러면, target과 다른 변수들의 상관관계를 살펴본 후,변수를 제거하여 다시 xgboost로 모델을 훈련해 보겠습니다.<jupyter_code>corr_matrix = train_data.corr()

corr_matrix["target"].sort_values(ascending=False)<jupyter_output><empty_output><jupyter_text>train data의 target과 다른 변수들의 상관관계를 살펴봤을 때, 1에 가까워 양의 관계를 가지고 있는 변수들은     education.num     0.334992    age               0.256567    hours.per.week    0.241954    capital.gain      0.226078이고,  -1에 가까워 응의 관계를 가지고 있는 변수들은     sex              -0.214647    relationship     -0.238034    marital.status   -0.265266입니다. 상관계수가 0에 가깝게 나오는 변수들을 target과의 선형관계가 없기때문에 제거하고 모델을 훈련해볼 것입니다.<jupyter_code>X_train_cor = train_data.drop(['index', 'target','workclass', 'capital.loss', 'education', 'race', 'native.country','fnlwgt','occupation'], axis=1) #training 데이터에서 독립변수 추출
y_train_cor = train_data.target #training 데이터에서 라벨 추출
X_val_cor = val_data.drop(['index', 'target','workclass', 'capital.loss', 'education', 'race', 'native.country','fnlwgt','occupation'], axis=1)  #validation 데이터에서 전처리된 문서 추출
y_val_cor = val_data.target #validation 데이터에서 라벨 추출
import xgboost as xgb

# 모델 선언
model = xgb.XGBClassifier() 

# 모델 훈련
model.fit(X_train_cor,y_train_cor) 

# 모델 예측
y_pred_5 = model.predict(X_val_cor) 

print(y_pred_5)
print('XGBoost의 예측 정확도는', round(metrics.accuracy_score(y_val_cor, y_pred_5),3)) # 정확도 확인<jupyter_output>[0 0 1 ... 1 1 0]
XGBoost의 예측 정확도는 0.846<jupyter_text>위에서 했던 xgboost 보다 예측 정확도가 0.008가 낮아졌습니다.xgboost로 모델을 훈련시키기에는 제일 첫번째에 했던 train_data를 사용해서 하는 것이 좋다고 판단했습니다.  LightGBM  test data - 변수 및 모델정리<jupyter_code># csv형식으로 된 데이터 파일을 읽어옵니다.
test = pd.read_csv('/content/drive/MyDrive/Colab/data/test.csv')
test.head()
test = label_encoder(test, make_label_map(test))
test = test.drop(['id'],axis=1)
test.head()
# 전처리가 완료된 테스트 데이터셋을 통해 본격적으로 학습한 모델로 추론을 시작합니다.
prediction = model.predict(test)
prediction<jupyter_output><empty_output><jupyter_text>- 랜덤 포레스트 하이퍼 파라미터 튜닝<jupyter_code>test = pd.read_csv('/content/drive/MyDrive/Colab/data/test.csv')
test = label_encoder(test, make_label_map(test))
test = test.drop('id', axis=1)
test.head()
X_train= data.drop(['target'], axis=1) #전체 training 데이터에서 독립변수 추출
y_train = data.target #전체 training 데이터에서 라벨 추출
### RandomForestClassifier
model = RandomForestClassifier(max_depth = 10, n_estimators = 200, max_features = 3) #앞서 튜닝한 하이퍼 파라미터 max_depth, n_estimators, max_features
model.fit(X_train, y_train) 
y_pred = model.predict(test)
### XGBoost Classifier
import xgboost as xgb

model = xgb.XGBClassifier() 
model.fit(X_train,y_train) 
y_pred = model.predict(test)<jupyter_output><empty_output><jupyter_text>Dacon 대회에 제출하기 (Submission)<jupyter_code># 제출용 Sample 파일을 불러옵니다
submission = pd.read_csv('/content/drive/MyDrive/Colab/data/sample_submission.csv')
submission.head()
submission['target'] = prediction

# 데이터가 잘 들어갔는지 확인합니다
submission
# csv 파일 만들기
submission.to_csv('submit.csv', index=False)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.11671152434548569, 'fraction_numerical': 0.03140037517331376, 'mean_word_length': 4.435283687943262, 'pattern_counts': {'":': 0, '<': 61, '<?xml version=': 0, '>': 63, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '16', 'dir': 'jupyter-structured-clean-dedup', 'id': '384250', 'license': 'Apache-2.0', 'n_tokens_mistral': 6279, 'n_tokens_neox': 6890, 'n_words': 1145, 'path': '_notebooks/2022-06-21-population-input.ipynb', 'repo_name': 'WooJaaEon/jaong', 'size': '12261'}