机器学习完成银行客户认购产品预测

 

目录

一、查看数据

二、数据预处理

三、绘制热力图查看特征相关性

四、各列中的值替换为对应的整数

五、统计目标变量的数量

六、构建模型


一、查看数据

 数据来源:【教学赛】金融数据分析赛题1:银行客户认购产品预测_学习赛_天池大赛-阿里云天池的赛制 (aliyun.com)

1. 

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

train=pd.read_csv("train.csv")
train

test=pd.read_csv("test.csv")
test

运行结果: 

2. 

# 训练集、测试集合并
df =pd.concat([train, test], axis=0)

#筛选出所有数据类型为'O'(即object,通常表示字符串)的列
cat_columns = df.select_dtypes(include='O').columns
df[cat_columns]

运行结果: 

 

 

二、数据预处理

1. 

import pandas as pd

# 读取CSV文件
data = pd.read_csv('train.csv')

# 查看缺失值数量
missing_values = data.isnull().sum()

print("缺失值统计:")
print(missing_values)

 运行结果:

 

2. 

import pandas as pd
from sklearn.preprocessing import MinMaxScaler

# 加载数据集
data = pd.read_csv("train.csv")  

# 选择需要进行缩放的特征列
features = ["age", "duration", "campaign", "pdays","previous","emp_var_rate","cons_price_index","cons_conf_index","lending_rate3m","nr_employed"]

# 创建MinMaxScaler对象,将数据进行归一化处理
scaler = MinMaxScaler()

# 对特征进行缩放
scaled_data = scaler.fit_transform(data[features])

# 创建缩放后的DataFrame
scaled_df = pd.DataFrame(data=scaled_data, columns=features)

# 输出缩放结果
print(scaled_df.head())

运行结果:

 

 

 

三、绘制热力图查看特征相关性

1.

import matplotlib.pyplot as plt
# 计算特征相关性矩阵
correlation_matrix = df.corr()

# 绘制热力图
plt.imshow(correlation_matrix, cmap='coolwarm', interpolation='nearest')
plt.colorbar()
plt.title('Feature Correlation Heatmap')
plt.xticks(range(correlation_matrix.shape[1]), correlation_matrix.columns, rotation=90)
plt.yticks(range(correlation_matrix.shape[1]), correlation_matrix.columns)
plt.show()

 运行结果:

 

四、各列中的值替换为对应的整数

 

        目的可能是为了将不规范的字符串形式转换为规范的形式(整数形式),以便于后续的分析或计算。通过.value_counts(),我们可以了解哪个数据最多或最少,或者数据的分布情况。这对于数据分析和可视化可能非常有用。

import pandas as pd

df['job'] = df['job'].map({category: i for i, category in enumerate(df['job'].unique())})
#df['job'].value_counts()


df['marital'] = df['marital'].replace({'unknown': 0, 'single': 1,'married':2,'divorced':3})
#df['marital'].value_counts()

education_mapping = {'unknown': 0, 'illiterate': 1, 'basic.4y': 2, 'basic.6y':3,'basic.9y': 4, 'high.school': 5, 'university.degree': 6, 'professional.course': 7}
df['education'] = df['education'].replace(education_mapping)
#df['education'].value_counts()

df['housing'] = df['housing'].replace({'unknown': 0, 'no': 1, 'yes': 2})
#df['housing'].value_counts()

df['loan'] = df['loan'].replace({'unknown': 0, 'no': 1, 'yes': 2})
#df['loan'].value_counts()

df['contact'] = df['contact'].replace({'cellular': 0, 'telephone': 1})
#df['contact'].value_counts()

df['day_of_week'] = df['day_of_week'].replace({'mon': 0, 'tue': 1, 'wed': 2, 'thu':3,'fri': 4})
#df['day_of_week'].value_counts()

df['poutcome'] = df['poutcome'].replace({'nonexistent': 0, 'failure': 1, 'success': 2})
#df['poutcome'].value_counts()

df['default'] = df['default'].replace({'unknown': 0, 'no': 1, 'yes': 2})
#df['default'].value_counts()

df['month'] = df['month'].replace({'mar': 3, 'apr': 4, 'may': 5, 'jun': 6, 'jul': 7, 'aug': 8, 'sep': 9, 'oct': 10, 'nov': 11, 'dec': 12})
#df['month'].value_counts()

 

五、统计目标变量的数量

import matplotlib.pyplot as plt

# 统计目标变量的数量
subscribe_counts = train['subscribe'].value_counts()

# 绘制饼图
plt.pie(subscribe_counts, labels=subscribe_counts.index, autopct='%.1f%%')
plt.title('Target Variable Distribution')
plt.show()
df[cat_columns]
df['subscribe'] = df['subscribe'].replace({'no': 0, 'yes': 1})
df['subscribe'].value_counts()

运行结果:

解释代码:

        从train DataFrame中提取了'subscribe'列,并使用value_counts()方法统计了每个唯一值(假设是'yes'和'no')出现的次数。结果保存在subscribe_counts Series中。

        将df DataFrame中'subscribe'列的值从字符串'no'和'yes'替换为整数0和1。

        使用value_counts()方法统计了替换后'subscribe'列中每个唯一值(现在是0和1)的出现次数。 

 

六、构建模型

1.

import matplotlib.pyplot as plt
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from sklearn.ensemble import RandomForestClassifier
from sklearn.preprocessing import LabelEncoder
from sklearn.metrics import confusion_matrix

cat_cols = ['job', 'marital', 'default', 'housing', 'month', 'poutcome']

for col in cat_cols:
    le = LabelEncoder()
    train[col] = le.fit_transform(train[col])
print(train[col])

# 对数值型特征进行标准化处理
num_cols = ['age', 'duration', 'campaign', 'pdays', 'previous', 'emp_var_rate', 'cons_price_index', 
            'cons_conf_index', 'lending_rate3m', 'nr_employed']
scaler = StandardScaler()
train[num_cols] = scaler.fit_transform(train[num_cols])

# 特征构造
train['last_contact_days'] = train.apply(lambda x: (x['campaign']-1) * 7 + x['pdays'], axis=1)

 运行结果:

解释代码:

  1. 类别特征的标签编码

    • 首先,定义了一个列表 cat_cols,其中包含了需要进行标签编码的类别特征列的名称。
    • 使用 for 循环遍历 cat_cols 中的每个特征列。
    • 在循环内,为当前列 col 创建了一个新的 LabelEncoder 对象 le
    • 使用 le.fit_transform() 方法将当前列 col 中的所有类别值转换为整数(通常是0到n-1的整数,其中n是类别数量)。
    • 将转换后的整数值重新赋值给原始数据集 train 中的相应列。
    • 注意:在循环结束后,print(train[col]) 这行代码只打印了最后一个类别特征列转换后的值,因为它是在循环外部执行的,并且 col 的值在循环结束后是 cat_cols 中的最后一个元素。
  2. 数值特征的标准化

    • 定义了一个列表 num_cols,其中包含了需要进行标准化的数值特征列的名称。
    • 创建了一个 StandardScaler 对象 scaler
    • 使用 scaler.fit_transform() 方法将 num_cols 中列出的所有数值特征列进行标准化处理。标准化通常是将数据转换为均值为0,标准差为1的分布。
    • 将标准化后的数据重新赋值给原始数据集 train 中的相应列。
  3. 特征构造

    • 创建了一个新的特征 last_contact_days
    • 使用 apply() 方法和 lambda 函数来定义新特征的构造逻辑。具体来说,新特征的值是基于 campaign 和 pdays 这两列的计算得出的。x['campaign']-1 表示营销活动的次数减1(可能是为了处理某些特殊情况或逻辑),然后乘以7(可能是基于一周7天的假设),再加上 pdays(表示上一次联系后的天数)。
    • 将新构造的特征添加到原始数据集 train 中。

2.

#  划分数据集
train = df[df['subscribe'].notnull()] # train为数据中subscribe不缺失的部分
test = df[df['subscribe'].isnull()] # test为数据中subscribe缺失的部分
X = train.drop('subscribe', axis=1)
y = train['subscribe']
X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2, random_state=42)

#  创建LightGBM数据集
import lightgbm as lgb
train_dataset = lgb.Dataset(X_train, label=y_train)
val_dataset = lgb.Dataset(X_val, label=y_val)

#  定义LightGBM模型参数
params = {
    'objective': 'binary',
    'metric': 'binary_logloss',
    'boosting_type': 'gbdt',
    'num_leaves': 62,
    'learning_rate': 0.01,
    'feature_fraction': 0.8,  
    'bagging_fraction': 0.7,
    'bagging_freq': 6,
    'verbose': 0
}

#  训练LightGBM模型
num_boost_round = 950   #提升过程的迭代次数   
model = lgb.train(params, train_dataset, valid_sets=[train_dataset, val_dataset], num_boost_round=num_boost_round)

#  在验证集上进行预测
y_pred = model.predict(X_val)
y_pred_binary = [1 if p >= 0.5 else 0 for p in y_pred]

 解释代码:

划分数据集

  1. 选择训练集和测试集
    • train = df[df['subscribe'].notnull()]:选择subscribe列不缺失的行作为训练集。
    • test = df[df['subscribe'].isnull()]:选择subscribe列缺失的行作为测试集(注意:这里的测试集并不是用来评估模型性能的验证集,而是最终用于预测未知数据的集合)。
  2. 特征和目标变量分离
    • X = train.drop('subscribe', axis=1):从训练集中删除subscribe列(目标变量),剩下的作为特征变量X
    • y = train['subscribe']:从训练集中提取subscribe列作为目标变量y
  3. 进一步划分训练集为训练子集和验证子集
    • 使用train_test_split函数将Xy进一步划分为X_trainX_valy_trainy_val。这里,test_size=0.2表示验证子集占原始训练集的20%。

创建LightGBM数据集

  • import lightgbm as lgb:导入LightGBM库。
  • train_dataset = lgb.Dataset(X_train, label=y_train) 和 val_dataset = lgb.Dataset(X_val, label=y_val):分别为训练子集和验证子集创建LightGBM数据集对象。

定义LightGBM模型参数

  • 这里定义了一个包含多个参数的字典params,这些参数用于配置LightGBM模型的行为。
    • 'objective': 'binary':设置目标为二分类问题。
    • 'metric': 'binary_logloss':使用二元对数损失作为评估指标。
    • 'boosting_type': 'gbdt':使用基于梯度的提升树(Gradient Boosting Decision Tree)。
    • 其他的参数(如'num_leaves''learning_rate''feature_fraction''bagging_fraction''bagging_freq')都是用于控制模型训练和复杂度的。

训练LightGBM模型

  • num_boost_round = 950:设置提升过程的迭代次数为950次。
  • model = lgb.train(params, train_dataset, valid_sets=[train_dataset, val_dataset], num_boost_round=num_boost_round):使用定义的参数params、训练数据集train_dataset和验证数据集val_dataset来训练模型。

在验证集上进行预测

  • y_pred = model.predict(X_val):使用训练好的模型对验证集X_val进行预测,得到预测概率。
  • y_pred_binary = [1 if p >= 0.5 else 0 for p in y_pred]:将预测概率转化为二分类标签(如果预测概率大于或等于0.5,则认为是正类,否则是负类)。

3.

#  评估模型
from sklearn.metrics import accuracy_score,precision_score,recall_score,f1_score
accuracy = accuracy_score(y_val, y_pred_binary)
precision = precision_score(y_val, y_pred_binary)
recall = recall_score(y_val, y_pred_binary)
f1 = f1_score(y_val, y_pred_binary)

print("Accuracy:", accuracy)  #准确率
print("Precision:", precision) # 精确率
print("Recall:", recall)      #召回率
print("F1 Score:", f1)        #f1分数


#  在测试集上进行预测
X_test = test.drop('subscribe', axis=1)
y_test_pred = model.predict(X_test)
y_test_pred_binary = [1 if p >= 0.6 else 0 for p in y_test_pred]   


#  保存预测结果
submission = pd.DataFrame({'id': test['id'], 'subscribe': y_test_pred_binary})
submission.to_csv('submission.csv', index=False)

# 将预测结果转换为提交格式
result = pd.read_csv('./submission.csv')
result['subscribe'] =y_test_pred_binary
result['subscribe'] = result['subscribe'].map({1: 'yes', 0: 'no'})

# 保存预测结果
result.to_csv('./baseline_decision_tree.csv', index=False)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值