目录
一、查看数据
数据来源:【教学赛】金融数据分析赛题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)
运行结果:
解释代码:
-
类别特征的标签编码:
- 首先,定义了一个列表
cat_cols
,其中包含了需要进行标签编码的类别特征列的名称。 - 使用
for
循环遍历cat_cols
中的每个特征列。 - 在循环内,为当前列
col
创建了一个新的LabelEncoder
对象le
。 - 使用
le.fit_transform()
方法将当前列col
中的所有类别值转换为整数(通常是0到n-1的整数,其中n是类别数量)。 - 将转换后的整数值重新赋值给原始数据集
train
中的相应列。 - 注意:在循环结束后,
print(train[col])
这行代码只打印了最后一个类别特征列转换后的值,因为它是在循环外部执行的,并且col
的值在循环结束后是cat_cols
中的最后一个元素。
- 首先,定义了一个列表
-
数值特征的标准化:
- 定义了一个列表
num_cols
,其中包含了需要进行标准化的数值特征列的名称。 - 创建了一个
StandardScaler
对象scaler
。 - 使用
scaler.fit_transform()
方法将num_cols
中列出的所有数值特征列进行标准化处理。标准化通常是将数据转换为均值为0,标准差为1的分布。 - 将标准化后的数据重新赋值给原始数据集
train
中的相应列。
- 定义了一个列表
-
特征构造:
- 创建了一个新的特征
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]
解释代码:
划分数据集
- 选择训练集和测试集:
train = df[df['subscribe'].notnull()]
:选择subscribe
列不缺失的行作为训练集。test = df[df['subscribe'].isnull()]
:选择subscribe
列缺失的行作为测试集(注意:这里的测试集并不是用来评估模型性能的验证集,而是最终用于预测未知数据的集合)。
- 特征和目标变量分离:
X = train.drop('subscribe', axis=1)
:从训练集中删除subscribe
列(目标变量),剩下的作为特征变量X
。y = train['subscribe']
:从训练集中提取subscribe
列作为目标变量y
。
- 进一步划分训练集为训练子集和验证子集:
- 使用
train_test_split
函数将X
和y
进一步划分为X_train
、X_val
、y_train
和y_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)