数据来源:Titanic - Machine Learning from Disaster | Kaggle
import pandas as pd
import pandas as pd #用于数据处理和分析,可处理表格数据。
import numpy as np #用于数值计算,提供了高效的数组操作。
import matplotlib.pyplot as plt #用于绘制各种类型的图表
import seaborn as sns #基于matplotlib的高级绘图库,能绘制更美观的统计图形。
from sklearn.preprocessing import StandardScaler, MinMaxScaler #用于数据预处理,进行归一化
# 设置中文字体(解决中文显示问题)
plt.rcParams['font.sans-serif'] = ['SimHei'] # Windows系统常用黑体字体
plt.rcParams['axes.unicode_minus'] = False # 正常显示负号
data1 = pd.read_csv('train.csv') # 读取训练集
data2 = pd.read_csv('test.csv')# 读取测试集
# 先筛选字符串变量
discrete_features = data1.select_dtypes(include=['object']).columns.tolist()
对于Name特征,直接去除,不做处理
对于Sex特征,进行独热编码
对于Ticket特征,统计其出现次数,并进行分箱,然后进行独热编码
对于Cabin特征,提取其前缀,对前缀的种类进行独热编码
对于Embarked特征,直接进行独热编码
# 去除 Name 特征
data1.drop('Name', axis=1, inplace=True)
data2.drop('Name', axis=1, inplace=True)
# Sex 独热编码,记得需要将bool类型转换为数值
def one_hot_encode_and_convert(df, original_df):#对独热编码函数进行封装,方便后续调用
# 对 Sex 列进行独热编码
encoded_df = pd.get_dummies(df, columns=['Sex'])
# 找出独热编码后新增的特征名
new_columns = [col for col in encoded_df.columns if col not in original_df.columns]
# 将新增的布尔类型列转换为整数类型
for col in new_columns:
df[col] = encoded_df[col].astype(int)
# 删除原始的 Sex 列
if 'Sex' in df.columns:
df.drop('Sex', axis=1, inplace=True)
return df
# 提前读取数据
train_data = pd.read_csv("train.csv")
test_data = pd.read_csv("test.csv")
# 对 data1 和 data2 进行处理
data1 = one_hot_encode_and_convert(data1, train_data)
data2 = one_hot_encode_and_convert(data2, test_data)
#对Ticket特征进行处理,将Ticket的频次进行分箱,然后对分箱结果进行独热编码
def process_ticket_feature(df):
"""
对数据框中的 Ticket 特征进行处理,包括计算频次、分箱、独热编码,并删除中间列。
参数:
df (pandas.DataFrame): 输入的数据框,包含 'Ticket' 列。
返回:
pandas.DataFrame: 处理后的数据框。
"""
# 计算每个 Ticket 的频次
ticket_counts = df['Ticket'].value_counts()
# 将频次映射到数据集中
df['Ticket_Frequency'] = df['Ticket'].map(ticket_counts)
# 对频次进行分箱
bins = [0, 1, 5, np.inf]
labels = ['Low', 'Medium', 'High']
df['Ticket_Frequency_Bin'] = pd.cut(df['Ticket_Frequency'], bins=bins, labels=labels)
# 对分箱结果进行独热编码
ticket_bin_encoded = pd.get_dummies(df['Ticket_Frequency_Bin'], prefix='Ticket_Bin')
# 将独热编码后的特征转换为整数类型
ticket_bin_encoded = ticket_bin_encoded.astype(int)
# 合并编码后的特征并删除中间列
df = pd.concat([df, ticket_bin_encoded], axis=1)
df = df.drop(['Ticket', 'Ticket_Frequency', 'Ticket_Frequency_Bin'], axis=1)
return df
data1 = process_ticket_feature(data1)
data2 = process_ticket_feature(data2)
#对Cabin特征,提取其前缀,对前缀的种类进行独热编码
def process_cabin_feature(df):
"""
对数据框中的 Cabin 特征进行处理,提取其前缀并进行独热编码。
参数:
df (pandas.DataFrame): 输入的数据框,包含 'Cabin' 列。
返回:
pandas.DataFrame: 处理后的数据框。
"""
# 提取 Cabin 特征的前缀
def extract_prefix(cabin):
if pd.notna(cabin):
return cabin[0]
else:
return 'NaN'
df['Cabin_Prefix'] = df['Cabin'].apply(extract_prefix)
# 对前缀进行独热编码
cabin_prefix_encoded = pd.get_dummies(df['Cabin_Prefix'], prefix='Cabin')
# 将独热编码后的特征转换为整数类型
cabin_prefix_encoded = cabin_prefix_encoded.astype(int)
# 合并编码后的特征并删除中间列
df = pd.concat([df, cabin_prefix_encoded], axis=1)
df = df.drop(['Cabin', 'Cabin_Prefix'], axis=1)
return df
data1 = process_cabin_feature(data1)
data2 = process_cabin_feature(data2)
#Embarked特征独热编码
def one_hot_encode_embarked(df):
"""
对数据框中的 Embarked 特征进行独热编码,并将编码结果转换为整数类型。
参数:
df (pandas.DataFrame): 输入的数据框,包含 'Embarked' 列。
返回:
pandas.DataFrame: 处理后的数据框。
"""
# 对 Embarked 特征进行独热编码
embarked_encoded = pd.get_dummies(df['Embarked'], prefix='Embarked')
# 将独热编码结果转换为整数类型
embarked_encoded = embarked_encoded.astype(int)
# 合并编码后的特征到原始数据框
df = pd.concat([df, embarked_encoded], axis=1)
# 删除原始的 Embarked 列
df = df.drop('Embarked', axis=1)
return df
data1 = one_hot_encode_embarked(data1)
data2 = one_hot_encode_embarked(data2)
#缺失值用众数补充
def fill_missing_with_mode(df):
"""
使用每列的众数填充数据框中的缺失值。
参数:
df (pandas.DataFrame): 输入的数据框。
返回:
pandas.DataFrame: 填充缺失值后的数据框。
"""
for column in df.columns:
# 计算每列的众数,取第一个值(因为众数可能有多个)
mode_value = df[column].mode()[0]
# 用众数填充该列的缺失值
df[column].fillna(mode_value, inplace=True)
return df
data1 = fill_missing_with_mode(data1)
data2 = fill_missing_with_mode(data2)
# 划分数据集
from sklearn.model_selection import train_test_split
X = data1.drop(['Survived'], axis=1) # 特征,axis=1表示按列删除
y = data1['Survived'] # 标签
# 按照8:2划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) # 80%训练集,20%测试集
from skopt import BayesSearchCV
from skopt.space import Integer, Categorical
import xgboost as xgb #XGBoost分类器
import lightgbm as lgb #LightGBM分类器
from sklearn.ensemble import RandomForestClassifier #随机森林分类器
from sklearn.metrics import classification_report, confusion_matrix
import time
import warnings #用于忽略警告信息
warnings.filterwarnings("ignore") # 忽略所有警告信息
# --- 1. 贝叶斯优化随机森林 ---
print("\n--- 1. 贝叶斯优化随机森林 (训练集 -> 测试集) ---")
# 定义要搜索的参数空间
search_space = {
'n_estimators': (50, 500),
'max_depth': (3, 20),
'min_samples_split': (2, 20),
'min_samples_leaf': (1, 10),
'max_features': (0.1, 1.0),
}
# 创建贝叶斯优化搜索对象
bayes_search = BayesSearchCV(
estimator=RandomForestClassifier(),
search_spaces=search_space,
n_iter=32, # 迭代次数,可根据需要调整
cv=5, # 5折交叉验证,这个参数是必须的,不能设置为1,否则就是在训练集上做预测了
n_jobs=-1,
scoring='accuracy'
)
start_time = time.time()
# 在训练集上进行贝叶斯优化搜索
bayes_search.fit(X_train, y_train)
end_time = time.time()
print(f"贝叶斯优化耗时: {end_time - start_time:.4f} 秒")
print("最佳参数: ", bayes_search.best_params_)
# 使用最佳参数的模型进行预测
best_model = bayes_search.best_estimator_
best_pred = best_model.predict(X_test)
print("\n贝叶斯优化后的随机森林 在测试集上的分类报告:")
print(classification_report(y_test, best_pred))
print("贝叶斯优化后的随机森林 在测试集上的混淆矩阵:")
print(confusion_matrix(y_test, best_pred))
# --- 2. 贝叶斯优化XGBoost ---
print("\n--- 2. 贝叶斯优化XGBoost (训练集 -> 测试集) ---")
# 定义要搜索的参数空间
search_space = {
'n_estimators': (50, 500),
'learning_rate': (0.01, 0.3),
'max_depth': (3, 10),
'min_child_weight': (1, 10),
'subsample': (0.5, 1.0),
'colsample_bytree': (0.5, 1.0)
}
# 创建贝叶斯优化搜索对象
bayes_search = BayesSearchCV(
estimator=xgb.XGBClassifier(),
search_spaces=search_space,
n_iter=32, # 迭代次数,可根据需要调整
cv=5, # 5折交叉验证,这个参数是必须的,不能设置为1,否则就是在训练集上做预测了
n_jobs=-1,
scoring='accuracy'
)
start_time = time.time()
# 在训练集上进行贝叶斯优化搜索
bayes_search.fit(X_train, y_train)
end_time = time.time()
print(f"贝叶斯优化耗时: {end_time - start_time:.4f} 秒")
print("最佳参数: ", bayes_search.best_params_)
# 使用最佳参数的模型进行预测
best_model = bayes_search.best_estimator_
best_pred = best_model.predict(X_test)
print("\n贝叶斯优化后的XGBoost 在测试集上的分类报告:")
print(classification_report(y_test, best_pred))
print("贝叶斯优化后的XGBoost 在测试集上的混淆矩阵:")
print(confusion_matrix(y_test, best_pred))
from sklearn.metrics import accuracy_score
# --- 3. 贝叶斯优化LightGBM ---
print("\n--- 3. 贝叶斯优化LightGBM (训练集 -> 测试集) ---")
# 过滤 LightGBM 相关警告
warnings.filterwarnings("ignore", category=UserWarning, module="lightgbm")
# 定义要搜索的参数空间
search_space = {
'n_estimators': (50, 500),
'learning_rate': (0.01, 0.3),
'max_depth': (3, 10),
'num_leaves': (20, 200),
'min_child_samples': (5, 50),
'subsample': (0.5, 1.0),
'colsample_bytree': (0.5, 1.0)
}
# 创建贝叶斯优化搜索对象
bayes_search = BayesSearchCV(
estimator=lgb.LGBMClassifier(),
search_spaces=search_space,
n_iter=32, # 迭代次数,可根据需要调整
cv=5, # 5折交叉验证,这个参数是必须的,不能设置为1,否则就是在训练集上做预测了
n_jobs=-1,
scoring='accuracy'
)
start_time = time.time()
# 在训练集上进行贝叶斯优化搜索
bayes_search.fit(X_train, y_train)
end_time = time.time()
print(f"贝叶斯优化耗时: {end_time - start_time:.4f} 秒")
print("最佳参数: ", bayes_search.best_params_)
# 使用最佳参数的模型进行预测
best_model = bayes_search.best_estimator_
best_pred = best_model.predict(X_test)
print("\n贝叶斯优化后的LightGBM 在测试集上的分类报告:")
print(classification_report(y_test, best_pred))
print("贝叶斯优化后的LightGBM 在测试集上的混淆矩阵:")
print(confusion_matrix(y_test, best_pred))
# 计算并输出测试集上的准确率
test_accuracy = accuracy_score(y_test, best_pred)
print(f"贝叶斯优化后的LightGBM 在测试集上的准确率: {test_accuracy:.4f}")
选了3个模型进行训练,以精准度作为评判标准,最终是XGBoost的模型最好,所以用XGBoost进行预测。
# 提取特征,假设训练时使用的特征列都在 data2 中
# 你可能需要根据实际情况调整特征列名
if 'Cabin_T' not in data2.columns:
data2['Cabin_T'] = 0
# 确保特征顺序和训练时一致
train_features = ['PassengerId', 'Pclass', 'Age', 'SibSp', 'Parch', 'Fare', 'Sex_female', 'Sex_male', 'Ticket_Bin_Low', 'Ticket_Bin_Medium', 'Ticket_Bin_High', 'Cabin_A', 'Cabin_B', 'Cabin_C', 'Cabin_D', 'Cabin_E', 'Cabin_F', 'Cabin_G', 'Cabin_NaN', 'Cabin_T', 'Embarked_C', 'Embarked_Q', 'Embarked_S']
X_pred = data2[train_features]
# 使用之前调好的 XGBoost 最佳模型进行预测
best_model = bayes_search.best_estimator_ # 这里使用贝叶斯优化得到的最佳模型
predictions = best_model.predict(X_pred)
# 将预测结果添加到一个新的 DataFrame 中
if 'PassengerId' in data2.columns:
result_df = pd.DataFrame({
'PassengerId': data2['PassengerId'],
'Survived': predictions
})
else:
result_df = pd.DataFrame({
'Survived': predictions
})
# 将结果保存到 CSV 文件中
output_file_path = 'gender_submission.csv'
result_df.to_csv(output_file_path, index=False)
print(f"预测结果已保存到 {output_file_path}")
最终将结果上传到平台,分数0.75837
@浙大疏锦行