预测淡水质量

目录

预测淡水质量

问题描述:

预期解决方案:

需求:

项目简介

数据探索

导包

设置中文显示

设置intel加速组件 

查看数据集 

将object进行因子化

查看数据统计性描述 

相关性分析

处理缺失值、重复值、偏差值 

处理数据不平衡 

 XGBoost算法

数据建模

模型参数定义

定义XGBoost分类器

模型训练

模型推理

结果可视化

总结 

预测淡水质量

问题描述:

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

预期解决方案:

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

需求:

需要使用英特尔® ONEAPI AI分析工具包 。

项目简介

通过提供的淡水质量数据集,对数据首先进行数据探索、数据预处理、利用机器学习建立模型,并进行欺诈数据的检测。
1、数据探索:查看数据集规模、数据类型、缺失值情况以及统计性描述。
2、数据预处理:处理缺失值、平衡数据样本
3、利用机器学习建立模型:支持向量机分类、集成学习

数据探索

导包

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

设置中文显示

设置了NLSLANG环境变量为简体中文,并使用UTF-8编码,方便输出结果。并设置显示最多100列的DataFrame,超过100列则省略

最后设置modin引擎为Dask,Dask 是一个用于分析计算的灵活的并行计算库,实现大型多维数据集分析的更快执行以及加速和扩展数据科学制作流程或工作流程的强大工具。

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

os.environ['MODIN_ENGINE'] = 'dask'

设置intel加速组件 

配置一个高性能的数据处理和分析环境,结合了 daal4pymodin 和 sklearnex 三个库来加速数据处理和机器学习算法的运算。

调用 patch_sklearn() 后,scikit-learn 的算法在执行时可能会利用 modin 的并行计算能力,从而加速模型训练和预测。

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

df.info() 

查看数据集 

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

from sklearnex import patch_sklearn

patch_sklearn()

展示结果如下: 

 

可以看到此 CSV 文件中含有 5956842 条数据,有24 列,浮点型(float64)占 19 列,整型(int64)字段占 2 列,对象型(object)占 3 列,总共占用内存空间大约 1.1GB。

将object进行因子化

将Color, Source,Month等英文字段进行因子化,处理为数字型变量

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]

 因子化结果:

查看数据统计性描述 

desc=df.describe()
skewness=df.skew()
kurtosis=df.kurtosis()
skewness_df = pd.DataFrame([skewness], index=['Skewness'], columns=df.columns)
desc=pd.concat([desc, skewness_df], axis=0)
kurtosis_df = pd.DataFrame([kurtosis], index=['Kurtosis'], columns=df.columns)
desc=pd.concat([desc, kurtosis_df], axis=0)
display(desc.style.format('{:,.3f}').background_gradient(subset=(desc.index[1:],desc.columns[:]),cmap='OrRd'))

 显示如下:

可以看到,部分字段偏差值较高,比如Iron,Lead等,需要进一步做处理。

相关性分析

展示DataFrame df 中各个特征与目标列 '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': '40, 10'
}
plt.rcParams.update(params)
plt.xticks(bar.index, bar.index, rotation=-60, fontsize=10)
plt.show()

 

从上图可以看出,'Index', 'Day', 'Time of Day', 'Month', 'Water Temperature', 'Source', 'Conductivity', 'Air Temperature'这些列相关度很低,需要删除不相关的列 

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

处理缺失值、重复值、偏差值 

查看各值情况

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))

数据集重复值、缺失值比较多,需要进一步处理。

对所有特征值为空的样本以0填充,删除重复值。

df = df.fillna(0)
df = df.drop_duplicates()

 偏差值处理,删除偏差值比较大的列。

检查每个特征的缺失值比例是否超过20%,如果超过,则将该特征从数据框中删除。检查每个数值型特征的方差是否小于等于0.1,如果小于等于0.1,则将该特征从数据框中删除。

from scipy.stats import pearsonr

variables = df.columns
df = df

var = df.var()
numeric = df.columns
df = df.fillna(0)
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], 1)

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

查看处理之后结果: 

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))

 

处理数据不平衡 

print(df.Target.value_counts())
target = df.Target.value_counts()
target.rename(index={1: 'state 1', 0: 'state o'}, inplace=True)
plt.pie(target, [0, 0.05], target.index, autopct='%1.1f%%')
plt.show()

 

使用下采样对数据进行平衡处理,使用train_test_split()函数将X和y分割成训练集和测试集,其中测试集占总数据的20%。同时,使用StandardScaler()函数对训练集和测试集进行标准化处理,使得每个特征的均值为0,标准差为1,以提高模型的性能。 

from imblearn.under_sampling import RandomUnderSampler
import datetime

X = df.iloc[:, 0:len(df.columns.tolist()) - 1].values
y = df.iloc[:, len(df.columns.tolist()) - 1].values

# # 下采样
under_sampler = RandomUnderSampler(random_state=21)
X, y = under_sampler.fit_resample(X, y)

X = df.drop('Target', 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

 XGBoost算法

数据建模

模型参数定义

from sklearn.metrics import make_scorer, precision_score, recall_score, accuracy_score,f1_score, roc_auc_score
param_grid = {
    'max_depth': [10, 15, 20],
    "gamma": [0, 1, 2], # -> 0
    "subsample": [0.9, 1], # -> 1
    "colsample_bytree": [0.3, 0.5, 1], # -> 1
    'min_child_weight': [4, 6, 8], # -> 6
    "n_estimators": [10, 50, 80, 100], # -> 80
    "alpha": [3, 4, 5] # -> 4
}

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),
}

定义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)

模型训练

refit_score = "f1_score"

start_time = datetime.datetime.now()
print(start_time)
rd_search = RandomizedSearchCV(xgb, 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)

 

模型推理

一、使用划分的测试集

from datetime import datetime
inference_start_time = datetime.now()
 
# 模型推理代码
y_pred = rd_search.best_estimator_.predict(X_test)
 
# 计算模型推理时间
inference_time = datetime.now() - inference_start_time
print("模型推理时间:", inference_time)
f1 = f1_score(y_test, y_pred)
print("模型在测试集上的f1分数:", f1)

 

得到推理时间为0.298s,经过多次测试后,F1的分数为0.83左右

二、使用统一的测试集

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

factor = pd.factorize(test_df['Color'])
test_df.Color = factor[0]
factor = pd.factorize(test_df['Source'])
test_df.Source = factor[0]
factor = pd.factorize(test_df['Month'])
test_df.Month = factor[0]
 
test_df
 
test_df = test_df.drop(
    columns=['Index', 'Day', 'Time of Day', 'Month', 'Water Temperature', 'Source', 'Conductivity', 'Air Temperature'])

test_df = test_df.fillna(0)
test_df = df.drop_duplicates()
 
from imblearn.under_sampling import RandomUnderSampler
import datetime

X = df.iloc[:, 0:len(df.columns.tolist()) - 1].values
y = df.iloc[:, len(df.columns.tolist()) - 1].values

# # 下采样
under_sampler = RandomUnderSampler(random_state=21)
X, y = under_sampler.fit_resample(X, y)

X = df.drop('Target', 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)

X_train, X_test = X_train_scaled, X_test_scaled
 
import pandas as pd
from datetime import datetime
 
# 记录开始时间
inference_start_time = datetime.now()
 
# 模型推理代码
y_pred = rd_search.best_estimator_.predict(X_test)
 
# 计算模型推理时间
inference_time = datetime.now() - inference_start_time
print("模型推理时间:", inference_time)
 
# 计算模型在测试集上的f1分数并输出
f1 = f1_score(y_test, y_pred)
print("模型在测试集上的f1分数:", f1)

 

得到推理时间为0.217s,经过多次测试后,F1的分数为0.83左右

结果可视化

from scipy import interp

params = {'legend.fontsize': 'x-large',
          'figure.figsize': (12, 9),
         'axes.labelsize': 'x-large',
         'axes.titlesize':'x-large',
         'xtick.labelsize':'x-large',
         'ytick.labelsize':'x-large'}
plt.rcParams.update(params)



tprs = []
aucs = []
mean_fpr = np.linspace(0, 1, 100)

skf = StratifiedKFold(n_splits=5)
linetypes = ['--',':','-.','-','-','O']

i = 0
cv_data =skf.split(X_test, y_test)

for train, test in cv_data:
    probas_ = rd_search.predict_proba(X_test[test])
    # Compute ROC curve and area the curve
    fpr, tpr, thresholds = roc_curve(y_test[test], probas_[:, 1])
    tprs.append(interp(mean_fpr, fpr, tpr))
    tprs[-1][0] = 0.0
    roc_auc = auc(fpr, tpr)
    aucs.append(roc_auc)
    plt.plot(fpr, tpr, lw=1.5,linestyle = linetypes[i], alpha=0.8,
             label='ROC fold %d (AUC = %0.2f)' % (i, roc_auc))

    i += 1
plt.plot([0, 1], [0, 1], linestyle='--', lw=1, color='r',
         label='Chance', alpha=.6)

mean_tpr = np.mean(tprs, axis=0)
mean_tpr[-1] = 1.0
mean_auc = auc(mean_fpr, mean_tpr)
std_auc = np.std(aucs)
plt.plot(mean_fpr, mean_tpr, color='b',
         label=r'Mean ROC (AUC = %0.2f $\pm$ %0.2f)' % (mean_auc, std_auc),
         lw=2, alpha=.8)

std_tpr = np.std(tprs, axis=0)
tprs_upper = np.minimum(mean_tpr + std_tpr, 1)
tprs_lower = np.maximum(mean_tpr - std_tpr, 0)
plt.fill_between(mean_fpr, tprs_lower, tprs_upper, color='grey', alpha=.2,
                 label=r'$\pm$ 1 std. dev.')

plt.xlim([-0.02, 1.02])
plt.ylim([-0.02, 1.02])
plt.xlabel('FPR',fontsize=20)
plt.ylabel('TPR',fontsize=20)
# plt.title('ROC')
plt.legend(loc="lower right")
plt.show()

 

总结 

通过本次实验,我了解到了intel的oneAPI在机器学习与数据挖掘领域的应用,体验到了intel AI Analytics Toolkit工具实际对于问题解决的提升,可以说oneAPI完成了人工智能领域的一个巨大贡献,兼顾机器学习和深度学习,为开发者和应用者提供了极大的便利。

本模型使用XGBoost,并使用随机网格搜索进行优化,经过10次训练 , f1分数在0.83左右准确性较高,通过使用Intel 的组件中进行加速,经过多次推理测试,得到推理时间在0.24s左右.所需时间较短,准确性较高。

  • 21
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值