머신러닝
머신러닝 - 캐글 집값 예측분석
인생진리
2023. 2. 15. 01:01
import pandas as pd
train =pd.read_csv("./data/personal_income_train.csv", index_col='no')
test =pd.read_csv("./data/personal_income_test.csv",index_col='no')

- age : 나이
- workclass : 개인의 고용상태
- fnlwgt : 인구조사국이 부여하는 개인의 가중치(전체 집단에서 개별 구성요소가 차지하는 비중이나 중요도를 수치로 나타낸 값을 말한다)
- education : 최종학력
- education-num : 교육수준 숫자로 범주화(높을수록 교육수준이 높음)
- marital-status : 결혼여부
- occupation : 개인의 직업
- relationship : 가정 내 각 개인의 관계
- race : 인종
- sex : 성별
- capital-gain : 개인의 자본 이익($)
- capital-loss : 개인의 자본 손실($)
- hours-per-week : 주당 근무 시간
- native-country : 출신 국가
- income : 수입 ★(5000이상 : 1, 미만: 0)
train.head(20)
import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns
from glob import glob
import pandas as pd
import sys
train.shape
train['workclass'].value_counts()
# ? 1663
train['occupation'].value_counts()
# ? 1668
train['native-country'].value_counts()
# ? 495
#### 결측치
- workclass : 1663
- occupation : 1668
- native-country : 495
- workclass(일 유형)가 ?면 occupation(직업)도 ?임 -> 값이 거의 비슷하기 때문
### 데이터 차원 확인하기
train = pd.DataFrame(train)
print('train : ',df_train.shape)
train = pd.DataFrame(train)
print('train : ',df_train.shape)
test = pd.DataFrame(test)
print('test : ',df_test.shape)
train.info()
train.info()
#### 귀찮으니 ? 값을 전부 nan(null)로 교체
def remove_blank(row):
return row.strip()
train['workclass_1']=train['workclass'].apply(remove_blank)
train['occupation_1']=train['occupation'].apply(remove_blank)
train['native-country_1']=train['native-country'].apply(remove_blank)
test['workclass_1']=test['workclass'].apply(remove_blank)
test['occupation_1']=test['occupation'].apply(remove_blank)
test['native-country_1']=test['native-country'].apply(remove_blank)
#.loc[df_train[조건문,"넣을곳"]=널값을넣을거임
train.loc[train['workclass_1']=='?',"workclass"]=np.nan
train.loc[train['occupation_1']=='?',"occupation"]=np.nan
train.loc[train['native-country_1']=='?',"native-country"]=np.nan
test.loc[test['workclass_1']=='?',"workclass"]=np.nan
test.loc[test['occupation_1']=='?',"occupation"]=np.nan
test.loc[test['native-country_1']=='?',"native-country"]=np.nan
# null이 잘 들어갔는지 확인해보자
train.isnull().sum()
# 필요 없는 열이 3개 추가되었으므로 삭제
train = train.drop(['workclass_1'], axis=1)
train = train.drop(['occupation_1'], axis=1)
train = train.drop(['native-country_1'], axis=1)
test = test.drop(['workclass_1'], axis=1)
test = test.drop(['occupation_1'], axis=1)
test = test.drop(['native-country_1'], axis=1)
train.isnull().sum()
#탐색적 데이터 분석 - 데이터 확인
# 분산 - mean과 std - 평균(mean)보다 더 큰 표준펴차(std)를 가진 것이 분산이 큰 것
# 이상치 - 최소값 min 25% 최대값max 75% 에서 확인
# 평향 - mean과 50% 차이가 큰 경우 편향된 것
# Fare - mean 32.204, 50% 14.454 편향됨을 알 수 있음
#std - 표준편차
train.describe()
test.describe()
train['workclass'].unique()
# 널값에 집어넣으 데이터 분석
train['workclass'].value_counts()
train['occupation'].value_counts()
train['native-country'].value_counts()
#널값들
train['workclass'].isnull().sum()
train['occupation'].isnull().sum()
train['native-country'].isnull().sum()
# 가장 많은것을 집어넣음
train['workclass'] = train['workclass'].fillna('Private')
train['occupation'] = train['occupation'].fillna('Prof-specialty')
train['native-country'] = train['native-country'].fillna('United-States')
test['workclass'] = test['workclass'].fillna('Private')
test['occupation'] = test['occupation'].fillna('Prof-specialty')
test['native-country'] = test['native-country'].fillna('United-States')
train['workclass'].unique()
test['workclass'].unique()
test.info()
train.info()
# cabin 시각화
# seaborn 라이브러리 활용
import seaborn as sns
sns.countplot(data = train, x='education-num', hue='sex')
import matplotlib.pyplot as plt
train['education']
plt.figure(figsize=(20,5)) #가로,세로
sns.countplot(data = df_train,
x = 'workclass',
hue = 'income')
plt.figure(figsize=(20,5))
sns.countplot(data = train,
x = 'hours-per-week',
hue = 'income')
plt.figure(figsize=(20,5))
sns.countplot(data = train,
x = 'relationship',
hue = 'income')
sns.countplot(data= train,
x='sex',
hue = 'income')
train.columns
train['Title'] = train['education-num']
test['Title'] = test['education-num']
train.drop(['education-num2'], axis=1,inplace=True)
test.drop(['education-num2'], axis=1,inplace=True)
test.drop(['Title'], axis=1,inplace=True)
train.head()
test.head()
train.info()
### 모델링
- 인코딩(문자형태의 데이터를 숫자형태의 데이터로 변환)
1. label encoding
2. one-hot encoding
- 범주형 변수를 표현하는데 가장 널리 쓰이는 방법
- 분류하고자 하는 범주(종류)만큼의 자릿수(컬럼)를 만들고 1과 0만을
이용하여 표현 하는 방식
- 모델선택 및 하이퍼 파라미터 조정
- 모델 학습
- 모델 평가
# int 타입 이외 집어넣기
categorical_features = []
for i in train.columns:
if train[i].dtype =='object':
categorical_features.append(i)
categorical_features = []
for i in test.columns:
if test[i].dtype =='object':
categorical_features.append(i)
for feature_name in categorical_features:
one_hot = pd.get_dummies(train[feature_name], prefix=feature_name) # 원핫 인코딩
train.drop(feature_name, axis=1, inplace=True) # 기존 글자형태 컬럼 삭제
train = pd.concat([train, one_hot], axis=1) # 기존 데이터에 원-핫 데이터 붙이기
for feature_name in categorical_features:
one_hot = pd.get_dummies(test[feature_name], prefix=feature_name) # 원핫 인코딩
test.drop(feature_name, axis=1, inplace=True) # 기존 글자형태 컬럼 삭제
test = pd.concat([test, one_hot], axis=1) # 기존 데이터에 원-핫 데이터 붙이기
# train, test의 차집합 연산!
set(train.columns)-set(test.columns)
test['native-country_ Holand-Netherlands'] = 0
set(train.columns)-set(test.columns)
X_train = train.drop('income',axis =1)
y_train = train['income']
X_test= test[X_train.columns]
X_test
score_lst = []
for i in range(1,30,2): # 이웃이 작으면 복잡-> 과대적합 확률 up, 많으면 단순 -> 과소적합 확률 up
knn_model = KNeighborsClassifier(n_neighbors=i) # 이웃에 따른 모델 생성
knn_result = cross_val_score(knn_model,X_train, y_train, cv = 5) # 교차검증 성능
score_lst.append(knn_result.mean()) # 평균치 리스트에 담기
x = range(1,30,2)
y = score_lst
plt.plot(x,y)
#모델 선택
from sklearn.neighbors import KNeighborsClassifier
from sklearn.tree import DecisionTreeClassifier
knn_model = KNeighborsClassifier(n_neighbors=20) # 이웃에 따른 모델 생성
knn_model.fit(X_train,y_train)
pre = knn_model.predict(X_test)
pre
# kaggle에 y_test 가있어 업로드해야함
result = pd.read_csv('data/sample_submission.csv')
result['income'] = pre
result.to_csv('hyochang_income_01.csv',index =False)
from xgboost.sklearn import XGBClassifier
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
simple_xgb = XGBClassifier()
simple_xgb.fit(X_train,y_train)
pre = simple_xgb.predict(X_test)
pre
result = pd.read_csv('data/sample_submission.csv')
result['income'] = pre
result.to_csv('hyochang_income_02.csv',index =False)
from lightgbm import LGBMClassifier
from lightgbm import early_stopping
from lightgbm import log_evaluation
simple_lgb = LGBMClassifier()
simple_lgb.fit(X_train,y_train)
pre = simple_lgb.predict(X_test)
result = pd.read_csv('data/sample_submission.csv')
result['income'] = pre
result.to_csv('hyochang_income_03.csv',index =False)
from sklearn.linear_model import Ridge, Lasso
train_error = []
test_error = []
alpha_list = ["0.001","0.01","0.1","1","10","100","1000"]
for i in alpha_list:
ridge_model=Ridge(alpha =float(i)).fit(X_train,y_train)
pre_train = ridge_model.predict(X_train)
pre_test = ridge_model.predict(X_test)
e1= mean_squared_error(pre_train,y_train)
e2 = mean_squared_error(pre_test,y_test)
train_error.append(e1)
test_error.append(e2)
print("alpha : ",i)
print("Ridge 훈련오차 : ",e1)
print("Ridge 평가오차 : ",e2)
ridge = Ridge(alpha= 0.1)
lasso= Lasso(alpha=0.1)
ridge.fit(X_train,y_train)
lasso.fit(X_train,y_train)
pre_ridge_train = ridge.predict(X_train)
pre_ridge_test = ridge.predict(X_test)
result = pd.read_csv('data/sample_submission.csv')
result['income'] = pre_ridge_test
result.to_csv('hyochang_income_05.csv',index =False)
- 데이터 로드: train 데이터와 test 데이터를 불러옵니다.
- 결측치: workclass, occupation, native-country 열에서 "?" 값을 nan (null) 값으로 교체합니다.
- 데이터 전처리: 결측치를 가장 많은 값으로 채웁니다.
- 시각화: education-num, workclass, hours-per-week, relationship, sex에 대한 countplot을 그립니다.
- 인코딩: 글자형태의 데이터를 숫자형태의 데이터로 변환합니다. 여기서는 one-hot encoding을 사용합니다.
- 모델링: 모델을 선택하고 하이퍼 파라미터를 조정하여 학습하고 평가합니다.
personal_income_train.csv와 personal_income_test.csv 두 개의 데이터셋을 로드하고
전처리하는 것이 목적입니다.
데이터는 개인의 수많은 측정치와 관련된 경력 특징,
그리고 연간 소득에 대한 정보를 포함하고 있습니다.
코드의 목적은 데이터를 모델링에 준비하는 것입니다.