【intel校企合作课程】基于机器学习的淡水质量预测

1.项目简介

1.1问题描述

        淡水是我们最重要和最稀缺的自然资源之一,仅占地球总水量的 3%。它几乎触及我们日常生活的方方面面,从饮用、游泳和沐浴到生产食物、电力和我们每天使用的产品。获得安全卫生的供水不仅对人类生活至关重要,而且对正在遭受干旱、污染和气温升高影响的周边生态系统的生存也至关重要。

1.2预期解决方案:

        通过参考英特尔的类似实现方案,预测淡水是否可以安全饮用和被依赖淡水的生态系统所使用,从而可以帮助全球水安全和环境可持续性发展。这里分类准确度和推理时间将作为评分的主要依据。

1.3数据集

训练集:https://filerepo.idzcn.com/hack2023/datasetab75fb3.zip

测试集:https://pan.baidu.com/s/1Eu_7hL_Kda8MvVqv46sOEA 
提取码:asd3 

2.数据探索

2.1查看数据集

查看数据集前五行

data = pandas.read_csv('../data/dataset.csv')
display(data.head())

查看各类特征是离散值还是连续值。

cat_cols = []  # 存储离散特征
float_cols = []  # 存储连续特征

for col in data.columns:
    if data[col].dtype == 'object':
        cat_cols.append(col)
    else:
        float_cols.append(col)

print('离散特征:', cat_cols)
print('连续特征:', float_cols)

将离散数据转化为连续数据

factor = pd.factorize(data['Color'])
print(factor)
data.Color = factor[0]
factor = pd.factorize(data['Source'])
print(factor)
data.Source = factor[0]
factor = pd.factorize(data['Month'])
print(factor)
data.Month = factor[0]
data.describe()

2.2数据可视化

查看数据类别

通过饼状图直观反映数量对比。

# 统计 Target 列中 0 和 1 的数量
target_counts = data['Target'].value_counts()

# 绘制饼形图
plt.figure(figsize=(8, 6))
plt.pie(target_counts, labels=target_counts.index, autopct='%1.1f%%', startangle=140)
plt.title('Distribution of Target')
plt.axis('equal')  # 使饼图为正圆形
plt.show()

热力图

显示属性之间的两两相关性

# 计算属性之间的相关系数矩阵
correlation_matrix = data.corr()
# 绘制热力图
plt.figure(figsize=(12, 10))
sns.heatmap(correlation_matrix, annot=True, cmap="coolwarm", fmt=".2f", linewidths=0.5)
plt.title("Correlation Heatmap of Attributes")
plt.show()

 绘制出属性与目标变量之间的相关系数柱形图。

import matplotlib.pyplot as plt

# 计算属性与目标变量之间的相关系数
correlation_with_target = data.corr()['Target'].sort_values(ascending=False)

# 绘制柱形图
plt.figure(figsize=(10, 6))
correlation_with_target.plot(kind='bar', color='skyblue')
plt.title('Correlation with Target Variable')
plt.xlabel('Features')
plt.ylabel('Correlation')
plt.xticks(rotation=45, ha='right')
plt.tight_layout()
plt.show()

3.数据处理

删除不相关列

data = data.drop(
    columns=['Index', 'Day', 'Time of Day', 'Month', 'Water Temperature', 'Source', 'Conductivity', 'Air Temperature'])

3.1获取各列的缺失值数量

# 获取各列的缺失值数量
missing_values = data.isnull().sum()
print(missing_values)

3.2处理缺失值和重复值

        数据完整性:通过填充缺失值,保证了数据的完整性,避免了由于缺失值导致的数据不完整的情况。

        特征选择:根据特征的方差和与目标变量的相关性进行特征选择,删除了方差较小且与目标变量相关性较低的特征,有助于减少特征空间的维度,提高模型的训练效率和泛化能力。

        提高模型性能:通过删除无关特征和噪声,可以提高模型的性能和预测准确性,使模型更加精确地捕捉数据的规律。

# 填充缺失值为均值
mean_value = data.mean()
data.fillna(mean_value, inplace=True)

# 删除方差较小的特征和与目标变量相关性较低的特征
var = data.var()
numeric = data.columns
for i in range(len(var) - 1):
    if var[i] <= 0.1:  # 方差小于或等于10%
        data = data.drop(numeric[i], axis=1)

variables = data.columns
for i in range(len(variables)):
    x = data[variables[i]]
    y = data[variables[-1]]
    if pearsonr(x, y)[1] > 0.05:  # 相关性 p 值大于0.05
        data = data.drop(variables[i], axis=1)

# 输出处理后的数据
print(data.head())

4.训练模型

        XGBoost(eXtreme Gradient Boosting)是一种非常流行的机器学习算法,特别适用于回归和分类问题。它是一种基于决策树的集成学习算法,以其出色的性能和可扩展性而闻名。以下是XGBoost的一些关键特点:

        梯度提升框架(Gradient Boosting Framework):XGBoost是一种梯度提升框架,通过迭代地训练决策树来逐步改进模型的性能。

        正则化:XGBoost在目标函数中引入了正则化项,以防止过拟合,包括L1和L2正则化。

        高性能:XGBoost实现了并行处理和高效的缓存优化,以提高训练速度。它还支持分布式计算,可以在大规模数据集上进行训练。

        灵活性:XGBoost支持多种损失函数和分裂准则,使其适用于各种类型的问题。

        特征重要性:XGBoost可以计算特征的重要性得分,帮助识别最相关的特征。

        缺失值处理:XGBoost能够自动处理缺失值,不需要对数据进行预处理。

        可解释性:虽然XGBoost是一种复杂的模型,但它仍然提供了一些解释模型预测的功能,例如特征重要性排序和树结构可视化。

4.1划分数据

        将数据集换分为训练集和测试集,其中训练集占80%,测试集占20%。

from imblearn.under_sampling import RandomUnderSampler
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
import datetime
 
X = data.iloc[:, 0:len(data.columns.tolist()) - 1].values
y = data.iloc[:, len(data.columns.tolist()) - 1].values
 
# # 下采样
under_sampler = RandomUnderSampler(random_state=21)
X, y = under_sampler.fit_resample(X, y)
 
X = data.drop('Target', axis=1)
y = data['Target']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=21)
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
print("Train Shape: {}".format(X_train_scaled.shape))
print("Test Shape: {}".format(X_test_scaled.shape))
 
X_train, X_test = X_train_scaled, X_test_scaled

4.2构建模型设置参数

from sklearn.metrics import make_scorer, precision_score, recall_score, accuracy_score,f1_score, roc_auc_score  
from xgboost import XGBClassifier

param_grid = {
    'max_depth': [10, 15, 20],
    "gamma": [0, 1, 2], 
    "subsample": [0.9, 1], 
    "colsample_bytree": [0.3, 0.5, 1], 
    'min_child_weight': [4, 6, 8], 
    "n_estimators": [10,50, 80, 100], 
    "alpha": [3, 4, 5] 
}
 
scorers = {
    'precision_score': make_scorer(precision_score),
    'recall_score': make_scorer(recall_score),
    'accuracy_score': make_scorer(accuracy_score),
    'f1_score': make_scorer(f1_score),
    'roc_auc_score': make_scorer(roc_auc_score),
}
xgb = XGBClassifier(
    learning_rate=0.1,
    n_estimators=15,
    max_depth=12,
    min_child_weight=6,
    gamma=0,
    subsample=1,
    colsample_bytree=1,
    objective='binary:logistic', # 二元分类的逻辑回归,输出概率
    nthread=4,
    alpha=4,
    scale_pos_weight=1,
    seed=27)
 

4.3训练模型

refit_score = "f1_score"
 
start_time = datetime.datetime.now()
print(start_time)
rd_search = RandomizedSearchCV(xgb.XGBClassifier(), param_grid, n_iter=10, cv=3, refit=refit_score, scoring=scorers, verbose=10, return_train_score=True)
rd_search.fit(X_train, y_train)
print(rd_search.best_params_)
print(rd_search.best_score_)
print(rd_search.best_estimator_)
print(datetime.datetime.now() - start_time)

4.4模型预测

对验证集进行预测

import joblib
import time
from sklearn.metrics import f1_score

# 加载保存的模型
loaded_model = joblib.load('best_xgb_model.joblib')

# 开始计时
start_time = time.time()

# 使用加载的模型进行预测
predictions = loaded_model.predict(X_test_scaled)

# 结束计时
end_time = time.time()

# 计算预测时间
prediction_time = end_time - start_time
print("预测时间(秒):", prediction_time)

# 计算F1分数
f1 = f1_score(y_test, predictions)
print("F1分数:", f1)

预测时间为约0.079秒,F1分数为约0.895。

对测试集进行预测

test_data = pd.read_csv('../data/test_data.csv')
test_data = test_data.drop(
    columns=['Index' ,'Day','Lead', 'Time of Day', 'Month', 'Water Temperature', 'Source', 'Conductivity', 'Air Temperature'])
factor = pd.factorize(test_data['Color'])
print(factor)
test_data.Color = factor[0]

X = test_data.iloc[:, 0:len(test_data.columns.tolist()) - 1].values
y = test_data.iloc[:, len(test_data.columns.tolist()) - 1].values 
X = test_data.drop('Target', axis=1)
y = test_data['Target']
# 开始计时
start_time = time.time()

# 使用加载的模型进行预测
predictions = loaded_model.predict(X)

# 结束计时
end_time = time.time()
# 计算预测时间
prediction_time = (end_time - start_time)
print("预测时间(秒):", prediction_time)

# 计算F1分数
f1 = f1_score(y, predictions) 
print("F1分数:", f1)

预测时间为约0.084秒,F1分数为约0.90。

  • 24
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值