數據預處理
通過網盤分享的文件:銀行流失預測數據和代碼
鏈接: https://pan.baidu.com/s/1loiB8rMvZArfjJccu4KW6w?pwd=pfcs 提取碼: pfcs
非數值特征處理
- 目的:將非數值特征轉換為數值型,以便模型能夠處理。
- 方法:
- 地理位置:可以使用獨熱編碼(One-Hot Encoding)或標簽編碼(Label Encoding)將不同國家/地區轉換為數值。
- 性別:可以使用標簽編碼,將“男”和“女”分別編碼為0和1。
- 結果文件:保存為
Churn-Modelling-newT.csv
數據離散化處理
- 目的:將連續變量轉換為離散變量,簡化模型復雜度,提高模型的可解釋性。
- 方法:
- 統計分析:對連續數據進行描述性統計分析,了解數據的分布情況。
- 離散化方法:
- 等寬離散化:將數據分為等寬的區間。
- 等頻離散化:將數據分為等頻的區間。
- 基于聚類的離散化:使用聚類算法確定離散化的區間。
- 結果文件:保存為
Churn-Modelling-new-tree.csv
數據篩選
- 目的:去除與模型訓練無關的特征列,保留有意義的數據,解決數據不均衡問題。
- 方法:
- 特征篩選:舍去如行號、用戶編號、用戶姓名等無關特征。
- 數據平衡:
- 過采樣:增加少數類別的樣本數量。
- 欠采樣:減少多數類別的樣本數量。
- 結果文件:保存為
final.csv
數據分割
- 目的:將數據集分為訓練集和測試集,用于模型訓練和評估。
- 方法:按照4:1的比例分割數據集。
- 結果文件:
- 訓練集:
Churn-Modelling-train.csv
- 測試集:
Churn-Modelling-test.csv
- 訓練集:
數據集預覽
數據特征列描述
RowNumber:行號
CustomerID:用戶編號
Surname:用戶姓名
CreditScore:信用分數
Geography:用戶所在國家/地區
Gender:用戶性別
Age:年齡
Tenure:當了本銀行多少年用戶
Balance:存貸款情況
NumOfProducts:使用產品數量
HasCrCard:是否有本銀行信用卡
IsActiveMember:是否活躍用戶
EstimatedSalary:估計收入
Exited:是否已流失,作為標簽數據
代碼部分
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelEncoder, KBinsDiscretizer
# 過采樣與欠采樣解決數據不均衡問題
from imblearn.over_sampling import RandomOverSampler
from imblearn.under_sampling import RandomUnderSampler# 讀取數據
df = pd.read_csv('Churn-Modelling.csv')# a) 非數值特征處理
# 地理位置 - 獨熱編碼
geography_dummies = pd.get_dummies(df['Geography'], prefix='Geography')
df = pd.concat([df, geography_dummies], axis=1)
df.drop('Geography', axis=1, inplace=True)# 性別 - 標簽編碼
label_encoder = LabelEncoder()
df['Gender'] = label_encoder.fit_transform(df['Gender'])# 保存處理后的文件
df.to_csv('Churn-Modelling-newT.csv', index=False)# b) 數據離散化處理
# 信用分數、年齡、存貸款情況、估計收入 - 等寬離散化
discretizer = KBinsDiscretizer(n_bins=5, encode='ordinal', strategy='uniform')
columns_to_discretize = ['CreditScore', 'Age', 'Balance', 'EstimatedSalary']
df[columns_to_discretize] = discretizer.fit_transform(df[columns_to_discretize])# 保存處理后的文件
df.to_csv('Churn-Modelling-new-tree.csv', index=False)# c) 數據篩選
# 去除無關特征列
df.drop(['RowNumber', 'Customerid', 'Surname'], axis=1, inplace=True)X = df.drop('Exited', axis=1)
y = df['Exited']# 過采樣
over_sampler = RandomOverSampler(sampling_strategy=0.5)
X_over, y_over = over_sampler.fit_resample(X, y)# 欠采樣
under_sampler = RandomUnderSampler(sampling_strategy=0.8)
X_resampled, y_resampled = under_sampler.fit_resample(X_over, y_over)# 保存篩選后的文件
final_df = pd.concat([X_resampled, y_resampled], axis=1)
final_df.to_csv('final.csv', index=False)# d) 數據分割
X_train, X_test, y_train, y_test = train_test_split(X_resampled, y_resampled, test_size=0.2, random_state=42)train_df = pd.concat([X_train, y_train], axis=1)
test_df = pd.concat([X_test, y_test], axis=1)train_df.to_csv('Churn-Modelling-train.csv', index=False)
test_df.to_csv('Churn-Modelling-test.csv', index=False)
小注
要查看LabelEncoder
是如何將類別值映射到整數的,你可以使用LabelEncoder
對象的classes_
屬性。這個屬性是一個數組,包含了原始類別值的排序列表,其索引位置對應于轉換后的整數值。
以下是如何查看性別類別值映射的方法:
label_encoder = LabelEncoder()
df['Gender'] = label_encoder.fit_transform(df['Gender'])# 查看類別值的映射
print(label_encoder.classes_)
假設df['Gender']
列包含兩個唯一值'Male'
和'Female'
,LabelEncoder
會根據它們在數據中出現的順序進行排序(通常是字典序),然后進行編碼。例如,如果輸出是:
['Female' 'Male']
這意味著'Female'
被編碼為0,'Male'
被編碼為1。如果順序相反,那么'Male'
將被編碼為0,'Female'
被編碼為1。
如果你想要明確地指定編碼方式,可以使用map
函數手動設置映射:
# 假設我們想要將'Male'編碼為0,'Female'編碼為1
gender_mapping = {'Male': 0, 'Female': 1}
df['Gender'] = df['Gender'].map(gender_mapping)
這樣就可以確保'Male'
總是被編碼為0,'Female'
總是被編碼為1。