赛题简介
本次教学赛是陈博士发起的数据分析系列赛事第1场 —— 银行客户认购产品预测
赛题以银行产品认购预测为背景,想让你来预测下客户是否会购买银行的产品。在和客户沟通的过程中,我们记录了和客户联系的次数,上一次联系的时长,上一次联系的时间间隔,同时在银行系统中我们保存了客户的基本信息,包括:年龄、职业、婚姻、之前是否有违约、是否有房贷等信息,此外我们还统计了当前市场的情况:就业、消费信息、银行同业拆解率等。
用户购买预测是数字化营销领域中的重要应用场景,通过这道赛题,鼓励学习者利用营销活动信息,为企业提供销售策略,也为消费者提供更适合的商品推荐。
金融数据分析比赛的目的是为了更好地带动数据科学初学者一起玩起来,因此我们鼓励所有选手,基于赛题发表notebook分享,内容包含但不限于对赛题的理解、数据分析及可视化、算法模型的分析以及数据分析思路等内容
赛题背景
赛题以银行产品认购预测为背景,想让你来预测下客户是否会购买银行的产品。在和客户沟通的过程中,我们记录了和客户联系的次数,上一次联系的时长,上一次联系的时间间隔,同时在银行系统中我们保存了客户的基本信息,包括:年龄、职业、婚姻、之前是否有违约、是否有房贷等信息,此外我们还统计了当前市场的情况:就业、消费信息、银行同业拆解率等。
赛题数据:
举办方提供submission.csv、 test.csv 、train.csv三个文件 需要可前往天池自行查看
一.代码解读
1.用pandas库进行数据处理
import pandas as pd
import numpy as np
df=pd.read_csv("train.csv")
test=pd.read_csv("test.csv")
df['subscribe'].value_counts()
#####
2.用matplotlib和seaborn库进行数据可视化
这段代码的目的是绘制一个条形图,展示订阅状态为'yes'的用户的'duration'列数据在不同区间内的分布情况,并在每个条形上方显示该区间内数据占总数据的百分比
import matplotlib.pyplot as plt
import seaborn as sns
bins = [0, 143, 353, 1873, 5149]
df1 = df[df['subscribe'] == 'yes']
binning = pd.cut(df1['duration'], bins, right=False)
time = pd.value_counts(binning)
# 可视化
time = time.sort_index()
fig = plt.figure(figsize=(6, 2), dpi=120)
sns.barplot(x=time.index, y=time, color='royalblue') # 更新此行代码,指定x和y参数
x = np.arange(len(time))
y = time.values
for x_loc, jobs in zip(x, y):
plt.text(x_loc, jobs + 2, '{:.1f}%'.format(jobs / sum(time) * 100), ha='center', va='bottom', fontsize=8)
plt.xticks(fontsize=8)
plt.yticks([])
plt.ylabel('')
plt.title('duration_yes', size=8)
sns.despine(left=True)
plt.show()
得到的图像如下:
3.接下来分析训练集和测试集中数值变量和分类变量的分布情况
# 分离数值变量与分类变量
Nu_feature = list(df.select_dtypes(exclude=['object']).columns)
Ca_feature = list(df.select_dtypes(include=['object']).columns)
#查看训练集与测试集数值变量分布
import matplotlib.pyplot as plt
import seaborn as sns
import warnings
warnings.filterwarnings("ignore")
plt.figure(figsize=(20,15))
i=1
for col in Nu_feature:
ax=plt.subplot(4,4,i)
ax=sns.kdeplot(df[col],color='red')
ax=sns.kdeplot(test[col],color='cyan')
ax.set_xlabel(col)
ax.set_ylabel('Frequency')
ax=ax.legend(['train','test'])
i+=1
plt.show()
# 查看分类变量分布
Ca_feature.remove('subscribe')
col1=Ca_feature
plt.figure(figsize=(20,10))
j=1
for col in col1:
ax=plt.subplot(4,5,j)
ax=plt.scatter(x=range(len(df)),y=df[col],color='red')
plt.title(col)
j+=1
k=11
for col in col1:
ax=plt.subplot(4,5,k)
ax=plt.scatter(x=range(len(test)),y=test[col],color='cyan')
plt.title(col)
k+=1
plt.subplots_adjust(wspace=0.4,hspace=0.3)
plt.show()
这段代码的目的是分析训练集和测试集中数值变量和分类变量的分布情况,并将其可视化。数值变量的核密度估计图可以显示变量的分布情况,而分类变量的散点图可以显示变量的频率分布情况。通过将训练集和测试集的图形进行对比,可以评估训练集和测试集是否存在统计上的差异,运行结果如下:
3.对分类变量进行编码,并计算数据集中变量之间的相关性矩阵
相关性矩阵是一个方阵,其对角线上的元素为1,表示变量与自身的相关性为1。非对角线上的元素表示变量之间的相关性,范围在-1到1之间。相关性比较高的特征在模型的特征输出部分也占据比较重要的位置,这意味着这些特征对模型的预测性能可能有较大的影响。如果两个特征之间的相关性比较高,可以考虑将其中一个特征去除,以减少数据集中的多重共线性。
from sklearn.preprocessing import LabelEncoder
lb = LabelEncoder()
cols = Ca_feature
for m in cols:
df[m] = lb.fit_transform(df[m])
test[m] = lb.fit_transform(test[m])
df['subscribe']=df['subscribe'].replace(['no','yes'],[0,1])
correlation_matrix=df.corr()
plt.figure(figsize=(12,10))
sns.heatmap(correlation_matrix,vmax=0.9,linewidths=0.05,cmap="RdGy")
# 几个相关性比较高的特征在模型的特征输出部分也占据比较重要的位置
运行结果如下
4.对数据集中的分类变量进行编码,以便在后续的机器学习模型中使用
OrdinalEncoder是一种常用的分类变量编码方法,它将分类变量中的每个类别映射为一个整数值。例如,如果有一个分类变量'job',其中包含三个类别'admin.'、'blue-collar'和'entrepreneur',则OrdinalEncoder会将它们分别映射为0、1和2。这样,分类变量就可以在机器学习模型中使用了
from sklearn import preprocessing
# 数据预处理
x = df1[['job','marital','education','default','housing','loan','contact','month','day_of_week','poutcome','subscribe']].values
encoder=preprocessing.OrdinalEncoder()
encoder.fit(x)
x=encoder.transform(x)
df1[['job','marital','education','default','housing','loan','contact','month','day_of_week','poutcome','subscribe']]=x
df1.head()
运行结果如下:
5.对数据集中的连续变量进行归一化处理,将数据集中的连续变量的取值范围缩放到[0,1]区间
归一化处理是一种常用的数据预处理方法,它可以使数据集中的连续变量具有相同的数值范围,从而使得不同特征的量纲不会影响模型的训练和预测。在进行机器学习模型训练和预测时,可以使用归一化后的数据集。
import numpy as np
# 归一化 X 数据
def normalize_data(data):
# 计算数据的最小值和最大值
data_min = np.min(data, axis=0)
data_max = np.max(data, axis=0)
# 归一化数据到 [0, 1] 区间
normalized_data = (data - data_min) / (data_max - data_min)
return normalized_data, data_min, data_max
normalized_X, X_min, X_max = normalize_data(df1)
df1=normalized_X
df1.to_csv('train11.csv',index=False)
df1
运行结果:
6.这段代码使用了LightGBM库中的LGBMClassifier来训练一个二分类模型,并使用交叉验证来评估模型的性能。
这段代码的主要目的是使用LGBMClassifier模型进行二分类问题的训练和预测,并使用交叉验证来评估模型的性能。最后,将预测结果保存到GBM预测.csv文件中
from lightgbm.sklearn import LGBMClassifier
from sklearn.model_selection import train_test_split, KFold
from sklearn.metrics import roc_auc_score, accuracy_score
import pandas as pd
import numpy as np
# 数据准备
X = df.drop(columns=['id', 'subscribe'])
Y = df['subscribe']
test = test.drop(columns='id')
# 划分训练集和测试集
x_train, x_test, y_train, y_test = train_test_split(X, Y, test_size=0.3, random_state=1)
# 建立模型
gbm = LGBMClassifier(n_estimators=666, learning_rate=0.01, boosting_type='gbdt',
objective='binary', max_depth=-1,
random_state=2022, metric='auc')
# 交叉验证
result1 = []
mean_score1 = 0
n_folds = 5
kf = KFold(n_splits=n_folds, shuffle=True, random_state=2022)
for train_index, test_index in kf.split(X):
x_train_fold, x_val_fold = X.iloc[train_index], X.iloc[test_index]
y_train_fold, y_val_fold = Y.iloc[train_index], Y.iloc[test_index]
gbm_fold = LGBMClassifier(n_estimators=666, learning_rate=0.01, boosting_type='gbdt',
objective='binary', max_depth=-1,
random_state=2022, metric='auc')
gbm_fold.fit(x_train_fold, y_train_fold)
y_pred1 = gbm_fold.predict_proba(x_val_fold)[:, 1]
print('验证集AUC: {}'.format(roc_auc_score(y_val_fold, y_pred1)))
mean_score1 += roc_auc_score(y_val_fold, y_pred1) / n_folds
y_pred_final1 = gbm_fold.predict_proba(test)[:, 1]
result1.append(y_pred_final1)
# 模型评估
print('mean 验证集auc: {}'.format(mean_score1))
cat_pre1 = np.sum(result1, axis=0) / n_folds
ret1 = pd.DataFrame(cat_pre1, columns=['subscribe'])
ret1['subscribe'] = np.where(ret1['subscribe'] > 0.5, 'yes', 'no').astype('str')
ret1.to_csv('GBM预测.csv', index=False)
运行结果如下:
验证集AUC: 0.8988875080674169
mean 验证集auc: 0.8903770694648746
这个过程可以帮助我们理解哪些特征对模型的预测结果影响最大,从而有助于模型的解释和特征重要性的分析。通过观察条形图,我们可以看到每个特征的正向或负向影响,以及其对模型预测的相对贡献。
import shap
import lightgbm as lgb
from sklearn.datasets import load_breast_cancer
# 加载示例数据集
data = load_breast_cancer()
X = data.data
y = data.target
# 拟合LightGBM模型
gbm = lgb.LGBMClassifier()
gbm.fit(X, y)
# 使用SHAP解释模型
explainer = shap.TreeExplainer(gbm)
shap_values = explainer.shap_values(X)
shap.summary_plot(shap_values, X, plot_type="bar", max_display=20)
运行结果:
二.总结
大赛的特点和亮点包括:
-
奖金池丰厚:2024年的比赛设置了22万元人民币的奖金池,吸引开发者参与。
-
关注热门赛道:比赛探索了可观测、AI网关、通义灵码三大热门赛道,这些赛道代表了当前技术发展的前沿方向。
-
提升运维效率:通过比赛,参赛者可以探索如何提升运维观测效率,这对于保障业务平稳运行和安全生产至关重要。
-
降低AI调用成本:比赛鼓励开发者探索降低AI调用成本的方法,这对于推动AI技术的普及和应用具有重要意义。
-
促进开源社区发展:大赛鼓励开源技术的使用和贡献,有助于促进开源社区的发展。
-
国际影响力:大赛面向全球开发者,具有国际影响力,有助于推动全球技术交流和合作。
-
历史悠久的比赛:自2015年开始,阿里云天池大赛已经举办了多年,积累了丰富的经验和资源。
-
多元化的参赛者:大赛吸引了来自不同领域和背景的开发者参与,包括学生、专业人士和爱好者等。
-
实践导向:大赛注重实践能力的培养,参赛者需要通过解决实际问题来展示自己的技术能力。
-
技术交流平台:大赛为开发者提供了一个交流和学习的平台,有助于促进技术的创新和发展。
总之,阿里云天池大赛是一个具有重要影响力的技术竞赛活动,它不仅为开发者提供了展示自己才华的机会,也为推动新技术的发展和创新人才的培养做出了积极贡献
本文链接:写文章-CSDN创作中心