判别饮用水可饮用的多机器学习模型

2024-04-21 03:52

本文主要是介绍判别饮用水可饮用的多机器学习模型,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

注意:本文引用自专业人工智能社区Venus AI

更多AI知识请参考原站 ([www.aideeplearning.cn])

项目背景

饮用水是人类生存的基本需求之一,也是维护健康和有效保护健康政策的重要组成部分。因此,确保饮用水质量对于国家、地区和地方层面的健康和发展至关重要。在某些地区,已经证明投资于供水和卫生设施可以产生净经济效益,因为减少了不良健康效应和医疗成本,这些成本超过了实施干预措施的成本。

项目目标

本项目的主要目标是建立一个机器学习模型,通过水质指标来预测饮用水是否安全可饮用。我们将利用水质数据集中的各种指标来训练模型,以便快速、准确地判断水是否适合人类消费。这将有助于政府、水供应公司和公众监控和确保饮用水的质量,从而维护健康和提高生活质量。

项目应用

这个项目的应用潜力非常广泛。一些潜在的应用包括:

  1. 饮用水供应公司:可以使用该模型来定期检查饮用水质量,确保其符合标准,并采取必要的措施来解决潜在问题。
  2. 政府监管机构:可以使用该模型来监测和调查水质问题,确保公众的健康和安全。
  3. 智能家居设备:家用净水器或自动饮水机可以使用该模型来检测进入系统的水是否安全。
  4. 公众健康宣传:政府和非营利组织可以使用这一模型来提高公众对饮用水质量的意识,鼓励人们保持警惕。

数据集描述

我们将使用名为”water_potability.csv”的数据集,其中包含了3276个不同水体的水质指标。以下是数据集中的主要特征:

  1. pH值:评估水的酸碱平衡的重要参数。WHO建议的pH值范围为6.5到8.5。
  2. 硬度:主要由钙和镁盐引起。硬度可影响水的肥皂性能。
  3. 溶解固体总量 (TDS):反映水中的矿物质溶解度。高TDS值表示水中的矿物质含量高。
  4. 氯胺:主要用于处理饮用水的消毒剂。
  5. 硫酸盐:天然存在于土壤、岩石和水中的物质。
  6. 电导率:反映水中溶解物质的离子浓度。
  7. 有机碳:反映水中的有机物含量。
  8. 三卤甲烷:可能存在于用氯处理的水中。
  9. 浊度:反映水中固体物质的数量。
  10. 饮用水可饮性:1表示可饮,0表示不可饮。

模型选择与依赖库

为了预测饮用水的可饮性,我们将使用以下机器学习模型进行训练和比较:

  1. Logistic回归
  2. KNN分类器
  3. Gaussian朴素贝叶斯
  4. 决策树
  5. 随机森林分类器
  6. 梯度提升分类器
  7. AdaBoost分类器
  8. XGBoost分类器

在项目中,我们将使用以下Python库来进行数据预处理、可视化和模型训练:

数据预处理和探索性数据分析(Preprocessing & EDA):

  • pandas
  • seaborn
  • matplotlib

模型训练(Model Training):

  • sklearn
  • xgboost

通过这个项目,我们将能够快速而准确地评估水的质量,并为决策制定者、供水公司和公众提供有关饮用水是否安全的重要信息。这将有助于确保人们享有高质量的饮用水,从而维护和提高健康水平。

代码实现

import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as pltfrom sklearn.model_selection import train_test_split, cross_val_score, cross_validate
from sklearn.metrics import confusion_matrix, classification_report, accuracy_score, precision_score, recall_score, f1_score, roc_auc_score, roc_curve
from sklearn.linear_model import LogisticRegression
from sklearn.svm import SVC
from sklearn.tree import DecisionTreeClassifier
from sklearn.neighbors import KNeighborsClassifier
from sklearn.naive_bayes import GaussianNB
from sklearn.ensemble import RandomForestClassifier, AdaBoostClassifier, GradientBoostingClassifier
from sklearn.neural_network import MLPClassifier
from xgboost import XGBClassifier
def warn(*args, **kwargs):pass
import warnings
warnings.warn = warn
data = pd.read_csv('water_potability.csv') print("{} rows and {} columns".format(*data.shape)) data.head(10)
3276 rows and 10 columns
phHardnessSolidsChloraminesSulfateConductivityOrganic_carbonTrihalomethanesTurbidityPotability
0NaN204.89045520791.3189817.300212368.516441564.30865410.37978386.9909702.9631350
13.716080129.42292118630.0578586.635246NaN592.88535915.18001356.3290764.5006560
28.099124224.23625919909.5417329.275884NaN418.60621316.86863766.4200933.0559340
38.316766214.37339422018.4174418.059332356.886136363.26651618.436524100.3416744.6287710
49.092223181.10150917978.9863396.546600310.135738398.41081311.55827931.9979934.0750750
55.584087188.31332428748.6877397.544869326.678363280.4679168.39973554.9178622.5597080
610.223862248.07173528749.7165447.513408393.663396283.65163413.78969584.6035562.6729890
78.635849203.36152313672.0917644.563009303.309771474.60764512.36381762.7983094.4014250
8NaN118.98857914285.5838547.804174268.646941389.37556612.70604953.9288463.5950170
911.180284227.23146925484.5084919.077200404.041635563.88548117.92780671.9766014.3705620
data.duplicated().sum()
# There are no duplicated rows

0

data.describe()
phHardnessSolidsChloraminesSulfateConductivityOrganic_carbonTrihalomethanesTurbidityPotability
count2785.0000003276.0000003276.0000003276.0000002495.0000003276.0000003276.0000003114.0000003276.0000003276.000000
mean7.080795196.36949622014.0925267.122277333.775777426.20511114.28497066.3962933.9667860.390110
std1.59432032.8797618768.5708281.58308541.41684080.8240643.30816216.1750080.7803820.487849
min0.00000047.432000320.9426110.352000129.000000181.4837542.2000000.7380001.4500000.000000
25%6.093092176.85053815666.6902976.127421307.699498365.73441412.06580155.8445363.4397110.000000
50%7.036752196.96762720927.8336077.130299333.073546421.88496814.21833866.6224853.9550280.000000
75%8.062066216.66745627332.7621278.114887359.950170481.79230416.55765277.3374734.5003201.000000
max14.000000323.12400061227.19600813.127000481.030642753.34262028.300000124.0000006.7390001.000000
data.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 3276 entries, 0 to 3275
Data columns (total 10 columns):#   Column           Non-Null Count  Dtype  
---  ------           --------------  -----  0   ph               2785 non-null   float641   Hardness         3276 non-null   float642   Solids           3276 non-null   float643   Chloramines      3276 non-null   float644   Sulfate          2495 non-null   float645   Conductivity     3276 non-null   float646   Organic_carbon   3276 non-null   float647   Trihalomethanes  3114 non-null   float648   Turbidity        3276 non-null   float649   Potability       3276 non-null   int64  
dtypes: float64(9), int64(1)
memory usage: 256.1 KB
data.isna().sum()
ph                 491
Hardness             0
Solids               0
Chloramines          0
Sulfate            781
Conductivity         0
Organic_carbon       0
Trihalomethanes    162
Turbidity            0
Potability           0
dtype: int64
# 使用Python的matplotlib库和seaborn库创建一个热力图(heatmap),用于可视化数据集中缺失值的情况。
plt.rcParams['figure.figsize'] = (10, 6)missing_val_heatmap = sns.heatmap(data.notna(), cbar=False, cmap="Blues", cbar_kws={'label': 'Missing Values'})
missing_val_heatmap.set_title("Missing Val Heatmap")
missing_val_heatmap.set_xlabel("Features")
missing_val_heatmap.set_ylabel("Rows")
Text(95.72222222222221, 0.5, 'Rows')

数据集中存在多个缺失值

  • 酸碱度(ph)
  • 硫酸盐(sulfate)
  • 三卤甲烷(Trihalomethanes)

数据分析

data['Potability'].value_counts()
0    1998
1    1278
Name: Potability, dtype: int64

数据集相对均衡,负样本偏多。

# Pie cart for Potability
data['Potability'].value_counts().plot.pie(autopct='%1.1f%%', startangle=90, explode=(0.1, 0), figsize=(12, 6),labels=['Not Potable', 'Potable'],colors=['coral', 'lightblue'],)
<Axes: ylabel='Potability'>

f"{data['Potability'].value_counts()[0]/data.shape[0] * 100 :.1f}% 的水不可饮用"
'61.0% 的水不可饮用'
特征分布的可视化
fig, ax= plt.subplots(nrows=3,ncols=3,figsize=(15,15), constrained_layout=True)plt.suptitle('Feature distribution by Potability of Water', weight='bold', size=20)for i, feature in enumerate(data.columns[:-1]):plt.subplot(3,3,i+1)sns.kdeplot(data[feature])sns.kdeplot(data = data ,hue ='Potability',x=feature, palette=['coral', 'lightblue'])

fig, ax= plt.subplots(nrows=3,ncols=3,figsize=(15,15), constrained_layout=True)plt.suptitle('Feature distribution by Potability of Water', weight='bold', size=20)for i, feature in enumerate(data.columns[:-1]):plt.subplot(3,3,i+1)sns.boxplot(data = data ,x ='Potability',y=feature, palette=['coral', 'lightblue'])

从箱型图中,我们可以看到分布可能存在有异常值。

corr = data.corr()
f, ax = plt.subplots(figsize=(12, 10))
cmap = 'YlGnBu'sns.heatmap(corr, annot=True, cmap=cmap, ax=ax)
<Axes: >

我们可以看到,没有一个特征彼此之间具有很高的相关性。 这使得预测缺失值变得困难。

sns.pairplot(data = data, hue = 'Potability', palette=['coral', 'lightblue'])
<seaborn.axisgrid.PairGrid at 0x1bdb78773d0>

特征工程

特征分布
missing_values = data.isna().sum()*100/data.shape[0]
missing_values = missing_values[missing_values>0]
missing_values.sort_values(inplace=True,ascending=False)sns.barplot(x=missing_values.index,y=missing_values.values)
plt.title('Missing Values %')
plt.show()

# Sulfate
upper_sul = data['Sulfate'].mean() + 3*data['Sulfate'].std()
lower_sul = data['Sulfate'].mean() - 3*data['Sulfate'].std()
sulfate_mean = data[(data['Sulfate']>=lower_sul) &(data['Sulfate']<=upper_sul)]['Sulfate'].mean()
# Replacing with mean
data['Sulfate'].fillna(sulfate_mean,inplace=True)
# PH
upper_ph = data['ph'].mean() + 3*data['ph'].std()
lower_ph = data['ph'].mean() - 3*data['ph'].std()
ph_mean = data[(data['ph']>=lower_ph) &(data['ph']<=upper_ph)]['ph'].mean()
# Replacing with mean
data['ph'].fillna(ph_mean,inplace=True)
# Trihalomethanes
upper_tri = data['Trihalomethanes'].mean() + 3*data['Trihalomethanes'].std()
lower_tri = data['Trihalomethanes'].mean() - 3*data['Trihalomethanes'].std()
trihalomethanes_mean = data[(data['Trihalomethanes']>=lower_tri) &(data['Trihalomethanes']<=upper_tri)]['Trihalomethanes'].mean()
# Replacing with mean
data['Trihalomethanes'].fillna(trihalomethanes_mean,inplace=True)
data.isna().sum()
ph                 0
Hardness           0
Solids             0
Chloramines        0
Sulfate            0
Conductivity       0
Organic_carbon     0
Trihalomethanes    0
Turbidity          0
Potability         0
dtype: int64
处理异常值

首先计算每个水质指标(除最后一个之外)的均值和标准差,然后使用均值减去三倍标准差和加上三倍标准差作为阈值,移除那些超出这个范围的异常值。最后,它打印出原始数据和经过清理后数据的行数,以及被移除的行数,并将清理后的数据集赋值给原始数据变量。

data_new = data.copy()
# for col in data_new.columns[:-1]:
#     mean = data_new[data_new[col].notna()][col].mean()
#     std = data_new[data_new[col].notna()][col].std()
#     low = mean - 3*std
#     high = mean + 3*std
#     data_new = data_new[(data_new[col] > low) & (data_new[col] < high)]# old_rows = data.shape[0]
# new_rows = data_new.shape[0]# print(f"Old rows: {old_rows}, New rows: {new_rows}, Removed rows: {old_rows - new_rows}")# data = data_new.copy()# This step is making the model perform worse

根据阈值设置的异常值删除后模型的性能反而下降,因此这里以结果为导向对异常值不进行处理

数据预处理


X = data_new.drop('Potability', axis=1).values
y = data_new['Potability'].values
划分数据集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)X_train.shape, X_test.shape, y_train.shape, y_test.shape
((2620, 9), (656, 9), (2620,), (656,))
标准化
from sklearn.preprocessing import StandardScalerscl = StandardScaler()
X_train = scl.fit_transform(X_train)
X_test = scl.transform(X_test)

创建模型

models = {'Logistic Regression': LogisticRegression(),'Knn': KNeighborsClassifier(),'Gaussian Naive Bayes': GaussianNB(),'Decision Tree': DecisionTreeClassifier(),'Random Forest': RandomForestClassifier(),'Adaboost': AdaBoostClassifier(),'Gradient Boosting': GradientBoostingClassifier(),'XGgboost': XGBClassifier(),'MLP': MLPClassifier(),
}
scoring = ['accuracy', 'precision', 'recall', 'f1', 'roc_auc']def get_model_result(model, X_train, y_train, X_test, y_test):scores = cross_validate(model, X_train, y_train, scoring=scoring, return_train_score=False, cv=5)result = {k.split('_')[1].title(): v.mean() for k, v in scores.items() if k not in ['fit_time', 'score_time']}return resultresults={}
for name,model in models.items():results[name] = get_model_result(model, X_train, y_train, X_test, y_test)results = pd.DataFrame(results).T
results = results.sort_values('Roc', ascending=False)
results
AccuracyPrecisionRecallF1Roc
MLP0.6763360.6342940.4293470.5108190.694688
Random Forest0.6637400.6328100.3568310.4550710.662103
XGgboost0.6335880.5442570.4439190.4884120.646361
Gradient Boosting0.6339690.5892470.2514380.3513970.632178
Knn0.6267180.5373780.3897710.4515480.625058
Gaussian Naive Bayes0.6209920.5500200.2398250.3326750.585986
Adaboost0.5919850.4684170.2059990.2851220.569846
Decision Tree0.5656490.4492550.4448760.4468260.544640
Logistic Regression0.6053440.3000000.0028990.0057150.501686

我们可以看到没有模型能够提供良好的精度。 这是可能因为特征之间的相关性非常低。

结论

  • 没有模型能够提供良好的精度,最大值约为 0.6。
  • 神经网络是该数据集的最佳模型。

代码和数据集下载

详情请见 判别饮用水可饮用的多机器学习模型-VenusAI (aideeplearning.cn)

这篇关于判别饮用水可饮用的多机器学习模型的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/922096

相关文章

0基础租个硬件玩deepseek,蓝耘元生代智算云|本地部署DeepSeek R1模型的操作流程

《0基础租个硬件玩deepseek,蓝耘元生代智算云|本地部署DeepSeekR1模型的操作流程》DeepSeekR1模型凭借其强大的自然语言处理能力,在未来具有广阔的应用前景,有望在多个领域发... 目录0基础租个硬件玩deepseek,蓝耘元生代智算云|本地部署DeepSeek R1模型,3步搞定一个应

Deepseek R1模型本地化部署+API接口调用详细教程(释放AI生产力)

《DeepseekR1模型本地化部署+API接口调用详细教程(释放AI生产力)》本文介绍了本地部署DeepSeekR1模型和通过API调用将其集成到VSCode中的过程,作者详细步骤展示了如何下载和... 目录前言一、deepseek R1模型与chatGPT o1系列模型对比二、本地部署步骤1.安装oll

Java深度学习库DJL实现Python的NumPy方式

《Java深度学习库DJL实现Python的NumPy方式》本文介绍了DJL库的背景和基本功能,包括NDArray的创建、数学运算、数据获取和设置等,同时,还展示了如何使用NDArray进行数据预处理... 目录1 NDArray 的背景介绍1.1 架构2 JavaDJL使用2.1 安装DJL2.2 基本操

Spring AI Alibaba接入大模型时的依赖问题小结

《SpringAIAlibaba接入大模型时的依赖问题小结》文章介绍了如何在pom.xml文件中配置SpringAIAlibaba依赖,并提供了一个示例pom.xml文件,同时,建议将Maven仓... 目录(一)pom.XML文件:(二)application.yml配置文件(一)pom.xml文件:首

如何在本地部署 DeepSeek Janus Pro 文生图大模型

《如何在本地部署DeepSeekJanusPro文生图大模型》DeepSeekJanusPro模型在本地成功部署,支持图片理解和文生图功能,通过Gradio界面进行交互,展示了其强大的多模态处... 目录什么是 Janus Pro1. 安装 conda2. 创建 python 虚拟环境3. 克隆 janus

本地私有化部署DeepSeek模型的详细教程

《本地私有化部署DeepSeek模型的详细教程》DeepSeek模型是一种强大的语言模型,本地私有化部署可以让用户在自己的环境中安全、高效地使用该模型,避免数据传输到外部带来的安全风险,同时也能根据自... 目录一、引言二、环境准备(一)硬件要求(二)软件要求(三)创建虚拟环境三、安装依赖库四、获取 Dee

DeepSeek模型本地部署的详细教程

《DeepSeek模型本地部署的详细教程》DeepSeek作为一款开源且性能强大的大语言模型,提供了灵活的本地部署方案,让用户能够在本地环境中高效运行模型,同时保护数据隐私,在本地成功部署DeepSe... 目录一、环境准备(一)硬件需求(二)软件依赖二、安装Ollama三、下载并部署DeepSeek模型选

Golang的CSP模型简介(最新推荐)

《Golang的CSP模型简介(最新推荐)》Golang采用了CSP(CommunicatingSequentialProcesses,通信顺序进程)并发模型,通过goroutine和channe... 目录前言一、介绍1. 什么是 CSP 模型2. Goroutine3. Channel4. Channe

Python基于火山引擎豆包大模型搭建QQ机器人详细教程(2024年最新)

《Python基于火山引擎豆包大模型搭建QQ机器人详细教程(2024年最新)》:本文主要介绍Python基于火山引擎豆包大模型搭建QQ机器人详细的相关资料,包括开通模型、配置APIKEY鉴权和SD... 目录豆包大模型概述开通模型付费安装 SDK 环境配置 API KEY 鉴权Ark 模型接口Prompt

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert