- 주제 : [분류] 은행 고객 이탈여부 분류
- 사용 데이터 : https://www.kaggle.com/datasets/shubhammeshram579/bank-customer-churn-prediction/data
- 프로젝트 목표 : 고객 데이터를 분석하여 이탈 유저를 예측하는 분류 모델을 개발하고, 이를 통해 고객 유형별 리텐션 향상 전략을 수립한다.
- 프로젝트 핵심내용 : 다양한 머신러닝 모델을 활용하여 성과 지표를 분석해 최적의 모델을 선정하고, 고객을 클러스터링한 후 이탈이 예측되는 그룹별 이탈 방지 전략을 제시한다.
PPT 필수 내용 : 1. 모델 별 성과 표 2. 고객 클러스터링 => 구체적인 전략 제시
- 데이터 준비
- 데이터 탐색: 각 변수별 분포, 클래스별 분포 차이, 결측치나 이상치 확인
- 결측값 처리: 평균, 중앙값 대체 혹은 결측치가 아닌 값들을 기반으로 회귀예측을 통한 보완(규모가 작으면 아예 제거도 가능)
- 이상치 처리: IQR, Z-score 등으로 탐색해 처리
# 1. 결측치 확인
df.isnull().sum()
'''
CustomerId 0
CreditScore 0
Geography 1
Gender 0
Age 1
Tenure 0
Balance 0
NumOfProducts 0
HasCrCard 1
IsActiveMember 1
EstimatedSalary 0
Exited 0
dtype: int64
'''
missing_data = df[df.isnull().any(axis=1)]
missing_data
# Geography : CustomerId 15592531
# age : CustomerId 15592389
# HasCrCard : CustomerId 15737888
# IsActiveMember : CustomerId 15792365
# 1-1. 중복값 확인
duplicates = df['CustomerId'].value_counts()[lambda x: x > 1]
duplicates
"""
15628319 2
15682355 2
"""
# 2. 범주형 컬럼 확인
df.describe(include="object")
"""
Surname Geography Gender
count 10002 10001 10002
unique 2932 3 2
top Smith France Male
freq 32 5014 5458
"""
IQR기법으로 연속형데이터를 가진 컬럼의 이상치 확인
-> 아래와 같은 코드로 Age, Balance, EstimatedSalary, CreditScore 컬럼의 이상치 확인.
# iqr 기법
# age컬럼 안에 결측치 존재하기 때문에 dropna()추가
age_q1 = np.percentile(df['Age'].dropna(), 25)
age_q3 = np.percentile(df['Age'].dropna(), 75)
age_iqr = age_q3 - age_q1
age_lower_bound = age_q1 - 1.5 * age_iqr
age_upper_bound = age_q3 + 1.5 * age_iqr
print(age_upper_bound)
print(age_lower_bound)
'''
62.0
14.0
'''
# 이상치 확인
age_score_outliers = df[(df['Age'] < age_lower_bound) | (df['Age'] > age_upper_bound)]
print('Age 이상치 개수:', len(age_score_outliers))
print('Lower Bound: ',age_lower_bound,'\nUpper Bound: ', age_upper_bound)
print(age_score_outliers)
'''
RowNumber CustomerId Surname CreditScore Geography Gender Age \
58 59 15623944 T'ien 511 Spain Female 66.0
85 86 15805254 Ndukaku 652 Spain Female 75.0
104 105 15804919 Dunbabin 670 Spain Female 65.0
158 159 15589975 Maclean 646 France Female 73.0
181 182 15789669 Hsia 510 France Male 65.0
... ... ... ... ... ... ... ...
9753 9754 15705174 Chiedozie 656 Germany Male 68.0
9765 9766 15777067 Thomas 445 France Male 64.0
9832 9833 15814690 Chukwujekwu 595 Germany Female 64.0
9894 9895 15704795 Vagin 521 France Female 77.0
9936 9937 15653037 Parks 609 France Male 77.0
Tenure Balance NumOfProducts HasCrCard IsActiveMember \
58 4 0.00 1 1.0 0.0
85 10 0.00 2 1.0 1.0
104 1 0.00 1 1.0 1.0
158 6 97259.25 1 0.0 1.0
181 2 0.00 2 1.0 1.0
... ... ... ... ... ...
9753 7 153545.11 1 1.0 1.0
9765 2 136770.67 1 0.0 1.0
9832 2 105736.32 1 1.0 1.0
9894 6 0.00 2 1.0 1.0
9936 1 0.00 1 0.0 1.0
EstimatedSalary Exited
58 1643.11 1
85 114675.75 0
104 177655.68 1
158 104719.66 0
181 48071.61 0
... ... ...
9753 186574.68 0
9765 43678.06 0
9832 89935.73 1
9894 49054.10 0
9936 18708.76 0
age_score_outliers.describe() 시행시 max값이 92.
특별히 제거해야할만한 이상치는 보이지 않는것 같다...
'''
결과 : 모든 컬럼값에서 특별히 제거해야할만한 값을 찾지 못했다.
-> 일단 customerID의 중복값 2행과 null값 4행을 제거한 데이터로 EDA진행.
- 이탈자 기준 확인하기
# 이탈 고객의 기준 찾기
# 1-1 은행에 잔액 없는 고객 : 500명
df2[(df2['Exited']==1) & (df2['Balance'] == 0)]
# 1-2 은행에 잔액이 남아있는 고객 : 1537명 -> 처리 중?
df2[(df2['Exited']==1) & (df2['Balance'] > 0)]
# 2-1 활동성이 없는 고객 : 1302명
df2[(df2['Exited']==1) & (df2['IsActiveMember'] == 0)]
# 2-2 활동중인 고객 : 735명 -> 처리 중?
df2[(df2['Exited']==1) & (df2['IsActiveMember'] == 1)]
# 3-1 신용카드가 없는 고객 : 613명
df2[(df2['Exited']==1) & (df2['HasCrCard'] == 0)]
# 3-2 신용카드가 있는 고객 : 1424명 -> 처리 중?
df2[(df2['Exited']==1) & (df2['HasCrCard'] == 1)]
# 4-1 가입된 상품이 없는 고객 : 0명
df2[(df2['Exited']==1) & (df2['NumOfProducts'] == 0)]
# 4-2 가입된 상품이 있는 고객 : 2037명 -> 처리 중?
df2[(df2['Exited']==1) & (df2['NumOfProducts'] > 0)]
파이썬 300제 31~40
문자열 대문자 / 소문자로 바꾸기 : .upper(), .lower(), .capitalize(), .title()
ticker = "btc_krw"
ticker.upper() #모든 문자를 대문자로
# 출력: BTC_KRW
ticker = "BTC_KRW"
ticker.lower() #모든 문자를 소문자로
# 출력: btc_krw
n = 'hello'
n.capitalize() #맨 앞글자만 대문자로
# 출력: Hello world
n = 'hello world'
n.title() #알파벳 외의 문자(숫자, 특수기호, 띄어쓰기 등)로 나누어져 있는 영단어의 첫 글자를 모두 대문자로
# 출력: Hello World
문자열 공백 제거 : .rstrip()
data = "039490 "
data.rstrip()
'내일배움캠프 > TIL' 카테고리의 다른 글
[TIL]250123_추천 받은 통계학 개념서, 파이썬_format(),strip() (0) | 2025.01.23 |
---|---|
[TIL]250122_머신러닝 개인과제3-4번,아티클스터디 (0) | 2025.01.22 |
[TIL]250121_파이썬 print의 옵션, 딕셔너리 형태의 key, value이용법 (0) | 2025.01.21 |
[TIL]250120_파이썬 베이직반 복습_수정중... (0) | 2025.01.20 |
[TIL]250117_QCC4회차, 개인과제 복습 (0) | 2025.01.17 |