【Intel校企合作课程】淡水质量预测

1.作业简介

1.1问题描述

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

1.2预期解决方案

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

1.3数据集

https://filerepo.idzcn.com/hack2023/datasetab75fb3.zip

1.4项目加速相关技术

  1. modin:Modin 使用Ray、Dask或Unidist提供一种轻松的方式来加速pandas 、脚本和库。与其他分布式 DataFrame 库不同,Modin 提供与现有 pandas 代码的无缝集成和兼容性。即使使用 DataFrame 构造函数也是相同的。

  2. sklearnex:借助面向 Scikit-learn* 的英特尔® 扩展,加速 Scikit-learn ,并且仍然完全符合所有 Scikit-Learn API 和算法。英特尔® Extension for Scikit-learn是一款免费软件 AI 加速器,可为各种应用程序带来超过 10-100 倍的加速。

    面向 Scikit-learn* 的英特尔® 扩展为您提供了一种加速现有 scikit-learn 代码的方法。加速是通过打补丁实现的:用扩展提供的优化版本替换现有的 scikit-learn 算法。

  3. daal4py组件:可将训练好的xgboost转换为 daal4py 模型,以便进一步改进预测时间性能, 利用底层的英特尔® 高级矢量扩展指令集(英特尔® AVX-512)硬件,最大限度地提高英特尔® 至强® 处理器上的梯度提升性能。

2.数据探索

2.1导入相关库

import os
import xgboost
from xgboost import XGBClassifier
import time
import warnings

import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
import plotly.io as pio
import plotly.graph_objects as go
from sklearn.utils import resample

from sklearn.model_selection import train_test_split, StratifiedKFold, GridSearchCV, RandomizedSearchCV
from sklearn.preprocessing import RobustScaler
from sklearn.metrics import roc_auc_score, roc_curve, auc, accuracy_score, f1_score
from sklearn.preprocessing import StandardScaler
import sklearn
from sklearn.metrics import precision_recall_curve, average_precision_score
import daal4py as d4p

import modin.pandas as pd
from modin.config import Engine
Engine.put("dask")

from sklearnex import patch_sklearn

patch_sklearn()

运行上面的代码之后会输出下方内容,表示sklearn的扩展已经启用。

在这里插入图片描述

os.environ['NLSLANG']='SIMPLIFIED CHINESE_CHINA.UTF8'
pd.set_option( 'display.max_columns', 100)

2.2读入数据并分析

使用pandas读入csv数据文件,并输出数据的大小,部分信息,和数据的结构。

df = pd.read_csv('./dataset.csv')
print("Data shape: {}\n".format(df.shape))
display(df.head())

df.info()

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.3数据特征分析

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

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

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

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

在这里插入图片描述

将离散值转换成连续性数据。

display(df.head())
factor = pd.factorize(df['Color'])
print(factor)
df.Color = factor[0]
factor = pd.factorize(df['Source'])
print(factor)
df.Source = factor[0]
factor = pd.factorize(df['Month'])
print(factor)
df.Month = factor[0]

df.describe()

在这里插入图片描述

2.4数据相关性分析

对处理后的数据进行对Target的相关性分析。

bar = df.corr()['Target'].abs().sort_values(ascending=False)[1:]

plt.bar(bar.index, bar, width=0.5)
# 设置figsize的大小
pos_list = np.arange(len(df.columns))
params = {
    'figure.figsize': '20, 18'
}
plt.rcParams.update(params)
plt.xticks(bar.index, bar.index, rotation=-60, fontsize=10)
plt.show()

在这里插入图片描述

针对相关性较差的和无关的数据,我们将其舍去。

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

2.5缺失值,重复值,偏差值处理

查看处理过后的数据的缺失和重复情况。

display(df.isna().sum())
missing = df.isna().sum().sum()
duplicates = df.duplicated().sum()
print("\nThere are {:,.0f} missing values in the data.".format(missing))
print("There are {:,.0f} duplicate records in the data.".format(duplicates))

在这里插入图片描述

由于缺失值较多,我们将其删除会使有效数据大量流失,所以这里对缺失值采取线性插值的方法进行补全,而对少量的重复值直接舍去。

df = df.fillna(df.interpolate(method='linear'))
df = df.drop_duplicates()

处理后再次查看缺失和重复情况。

在这里插入图片描述

对于偏差值,我们通过检查皮尔逊相关系数与缺失值的比例和数值型特征的方差值来筛选符合要求的特征。

from scipy.stats import pearsonr

variables = df.columns
df = df

var = df.var()
numeric = df.columns
df = df.fillna(df.interpolate())
for i in range(0, len(var) - 1):
    if var[i] <= 0.1:  # 方差大于10%
        print(variables[i])
        df = df.drop(numeric[i],axis=1)
variables = df.columns

for i in range(0, len(variables)):
    x = df[variables[i]]
    y = df[variables[-1]]
    if pearsonr(x, y)[1] > 0.05:
        print(variables[i])
        df = df.drop(variables[i],axis=1)

variables = df.columns
print(variables)
print(len(variables))

在这里,我们将Lead特征舍去,最后剩下15个有效特征。

在这里插入图片描述

2.6数据分布变换

我们查看剩下的数据分布情况。

df.hist(bins=50,figsize=(16,12))

在这里插入图片描述

发现有些数据的分布不规则,此处对其进行非线性变换,使其转换成便于模型拟合的类正态分布。

# 针对不规则分布的变量进行非线性变换,一般进行log
log_col = ['Iron', 'Zinc', 'Turbidity', 'Copper', 'Manganese']
show_col = []
for col in log_col:
    df[col + '_log'] = np.log(df[col])
    show_col.append(col + '_log')
    
df[show_col].hist(bins=50,figsize=(16,12))

在这里插入图片描述

3.模型训练

3.1数据划分

对最后处理好的数据进行划分,分为训练集和测试集,并对数据进行标准化处理。

X = df.drop( ['Target','Iron', 'Zinc', 'Turbidity', 'Copper', 'Manganese'], axis=1)
y = df['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

3.2创建XGBoost分类器

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)

3.3参数设置

对随机网格搜索的参数进行配置。

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]
}

3.4模型训练

对模型进行训练。

refit_score = "f1_score"

start_time = time.time()
print(start_time)
rd_search = RandomizedSearchCV(xgb, param_grid, n_iter=10, cv=3, refit=refit_score, scoring=sklearn.metrics.make_scorer(f1_score), 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(time.time() - start_time)

训练完成后,输出训练过程和最优参数如下。

在这里插入图片描述

使用训练好后的模型对测试集进行推理测试。

test_data = pd.read_csv('test_data.csv')

test_data = test_data.drop(
    columns=['Index', 'Day', 'Time of Day', 'Month', 'Water Temperature', 'Source', 'Conductivity', 'Air Temperature'])
pd.factorize(test_data['Color'])
test_data.Color = factor[0]
test_data = test_data.fillna(test_data.interpolate(method='linear'))
test_data = test_data.drop_duplicates()

log_col = ['Iron', 'Zinc', 'Turbidity', 'Copper', 'Manganese']
show_col = []
for col in log_col:
    test_data[col + '_log'] = np.log(test_data[col])
    show_col.append(col + '_log')
test_data = test_data.drop( ['Iron', 'Zinc', 'Turbidity', 'Copper', 'Manganese'], axis=1)

y_true = test_data['Target']
X_test = test_data.drop(
    columns=['Lead', 'Target'])

scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)

from datetime import datetime
start = datetime.now()
y_pred = xgb.predict(X_test)
time = datetime.now() - start
f1 = f1_score(y_true, y_pred)

print('\nF1 score: {}'.format(f1))
print('Inference time: {} seconds'.format(time))

在这里插入图片描述

4.总结

在本次项目中,我学习使用了Intel下的oneAPI组件来对淡水的质量进行预测,在项目的实际开发中,Intel AI Analytics Toolkit对问题的解决有很大的提升,面对如此大量的数据也能很快的训练出模型,并且模型的效果也很令人满意。相信在未来,Intel的oneAPi组件会给我们带来更多的惊喜。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值