使用 MongoDB 在 Python 中编写面向对象的决策树
使用 MongoDB 在 Python 中编写面向对象的决策树
Source: 约翰普莱纽斯
介绍
面向对象程序 (OOP) 受益于其模块化,因为可以隔离部分以进行故障排除。也可以调用函数在其他函数中使用,从而减少所需的编码时间。
决策树是一种流行的算法,因为与神经网络相比,它降低了计算成本。尽管由于参数固定,它们的适应性较差,但它们对于不易更改的数据结构很有用。
MongoDB 是一个安全的文档数据库,可以连接到 Python 以构建安全的、支持数据库的程序。它是一个 NoSQL 数据库,这意味着它以列表格式存储数据以实现多功能性。
在这个项目中,我们使用 Python 开发了一个面向对象的程序,该程序使用决策树来预测中风的风险,使用 MongoDB 进行数据库存储。
为了数据安全,任何敏感信息都将被审查。
第一步:获取数据。
我使用 Kaggle 找到了一个具有高票数和高可用性的数据集,以防止任何有关数据完整性的问题。我下载了 中风预测数据集 经过 费德索里亚诺 ,谁已将 30 个数据集上传到 Kaggle,所有数据集的可用性均为 10.0,请查看!该文件以逗号分隔值 (.csv) 格式提供。
步骤 2:配置 MongoDB 客户端。
要使用 MongoDB,您需要创建一个 帐户 .它是完全免费的,他们提供 订阅 如果需要。注册后,您将被定向到 MongoDB 仪表板的“项目”部分。点击“新建项目”。
MongoDB dashboard projects section.
命名您的项目(我命名为 0),然后按“下一步”。
Name your project
添加成员并为您的项目设置权限,方法是添加他们的电子邮件地址以向他们发送邀请。这样做时,您可以使用下拉框设置角色,以确保项目的安全性。点击“创建项目”。
Add members and set permissions.
您将被带到项目仪表板的“数据库部署”部分,并会提示您创建数据库。点击“建立数据库”。
Data
然后,您将部署一个免费的云数据库,它将使用共享服务器。单击共享服务器框上的“创建”。
Cloud database deployment options
MongoDB 将自动配置您的集群。您可以自定义云提供商、更改服务器、升级集群大小、探索备份选项并命名您的集群。我使用了默认设置。
Cluster configuration
设置集群的登录详细信息。或者,x.509 证书可用于无密码身份验证。完成后,登录方法将出现在表格中。
Security configuration
接下来,选择是要在本地连接还是通过云连接。我选择在本地连接以进行演示。单击“添加您当前的 IP 地址”以连接到集群,然后单击“完成并关闭”。
Connection configuration
出现提示时,单击“转到数据库”。
Congratulations prompt
您将返回“数据库部署”页面以查找新集群。点击“连接”。
Database Deployments
要连接到 Python 应用程序,请单击“连接您的应用程序”。
Application connection options
使用以下代码检查您的 Python 版本。
从平台导入 python_version
python_version()
在 MongoDB 上选择您的版本并选择“包含完整的驱动程序代码示例”。将代码复制到剪贴板。
Connecting the Python application to the cluster
在与数据集相同的文件夹中创建一个空白的 Jupyter 笔记本。导入 pymongo,然后将 MongoDB 中的代码粘贴到下一行,更改“
# MongoDB 连接。
# 导入 pymongo 以连接到 MongoDB。
导入pymongo # 使用 MongoDB 中的代码,将帐户连接到客户端。
客户端 = pymongo.MongoClient("mongodb+srv://user:<password> @cluster0.2z3xdjn.mongodb.net/?retryWrites=true&w=majority") # 尝试连接到客户端。
db = client.test
现在通过在下一行输入“db”并运行它来测试您的连接。在输出中,您应该会看到“connect=True”(如果有效)。
Testing the client connection
做得好!如果您已经做到了这一点,那么您已经成功配置了 MongoDB 客户端。
第 3 步:将数据集上传到 MongoDB。
使用以下代码片段加载笔画数据集,将其转换为字典格式,创建数据库并上传转换后的数据。如果要使用替代数据集,您只需更改文件名以匹配。
# 上传数据到 MongoDB。
# Pandas 被导入以读取 (.csv) 文件。
将熊猫导入为 pd # 数据集是使用 pandas 的 read_csv 函数加载的。
df = pd.read_csv('healthcare-dataset-stroke-data.csv') # 数据集被转换为字典格式。
数据 = df.to_dict(orient = 'records') # 在客户端创建数据库。
db = 客户端['数据库'] # 转换后的数据被插入到MongoDB数据库中
db.stroke.insert_many(数据)
PyMongo 确认上传成功。
Successful upload comment
返回到 MongoDB 上的“数据库部署”,然后在您的集群上单击“浏览集合”。不出所料,数据传输成功。
Dataset uploaded to MongoDB
第 4 步:设计面向对象的程序。
将类定义为“模型”。
# 该类已定义并托管了任务所需的所有功能。
班级型号:
通过添加整个类中使用的任何变量来配置类的“init”函数。数据集从 MongoDB 加载并转换为 Pandas 数据框。导入并定义决策树,固定随机种子以确保可重复性。数据集已预览。
要使用您自己的详细信息登录,请从前面描述的连接向导中复制代码并用它替换我的详细信息。
要使用替代模型,请将“DecisionTreeClassifier”更改为替代模型。
# 数据集和模型的初始化。
def __init__(self):
# 导入必要的库
import pandas as pd # 用于数据操作。
from sklearn.tree import DecisionTreeClassifier # 用作分类算法。 # 用于 MongoDB 集成的 Pymongo 库。
import pymongo # 与 MongoDB 通信。
from pymongo.mongo_client import MongoClient # 登录 MongoDB。
from pymongo.server_api import ServerApi # 与 MongoDB 服务器通信。
# 使用 mongoDB 的用户名和密码登录客户端。
客户端 = pymongo.MongoClient("mongodb+srv://jayparekh:<password> @cluster0.m6t3kym.mongodb.net/?retryWrites=true&w=majority", server_api=ServerApi('1'))
# 创建数据库
db = 客户端['CMP6221']
# 在数据库中创建一个集合。
测试 = db.stroke
#将集合转换为 Pandas 数据框。
测试 = pd.DataFrame(list(test.find()))
# 定义转换后的数据框。
self.df = 测试
# 定义决策树设置随机状态的可重复性。
self.classifier = DecisionTreeClassifier(random_state=100)
# 显示数据集。
print('原始数据集:\n', self.df.head())
Dataset preview.
配置一个名为“corr”的函数,以使用数据框生成相关矩阵,从而深入了解数据。将矩阵绘制为热图以获得更好的可视化效果。
如果您的数据集被称为“df”以外的名称,请更改函数中的文件名。
# 可视化数据。
def corr(自我):
from matplotlib import pyplot as plt # 可视化数据。
import seaborn as sns # 绘制可视化图。
# 使用 corr 函数计算数据集中的相关性,并定义它们以在热图中使用。
corrdata = self.df.corr()
# 绘制热图以显示数据集中名为相关热图的数据的相关性。
fig = plt.subplots (figsize = (10,10))
plt.title("相关热图")
sns.heatmap(corrdata)
plt.show()
配置一个名为“clean”的函数以删除空值并将字符串变量编码为二进制格式,以便决策树可以解释它们。
如果您的数据集被称为“df”以外的名称,请更改函数中的文件名。
如果您要在另一个数据集中对特征进行编码,则“ever_married”等特征将更改为您的特征,请根据需要复制脚本。
# 数据清理,删除空值和编码字符串变量。
def 清洁(自我):
from sklearn import preprocessing # 用于标签编码。
self.df = self.df.dropna()
le = preprocessing.LabelEncoder()
self.df['ever_married'] = le.fit_transform(self.df['ever_married'])
self.df['work_type'] = le.fit_transform(self.df['work_type'])
self.df['吸烟状态'] = le.fit_transform(self.df['吸烟状态'])
self.df['Residence_type'] = le.fit_transform(self.df['Residence_type'])
self.df['gender'] = le.fit_transform(self.df['gender'])
print('清理的数据集:\n', self.df.head())
配置一个名为“split”的函数,将从查看相关热图中选择的必要特征数据与标签数据分开,然后使用“train-test split”将数据拆分为训练集和测试集。
使用“test_size”作为变量,以便用户可以在不修改脚本的情况下更改拆分的大小。
如果您的数据集被称为“df”以外的名称,请更改函数中的文件名。
如果要更改用于特征数据的变量,可以在“self.X”部分中选择它们。使用“self.y”设置标签变量。
# train-test-split 以 70:30 的比例由变量 test_size 设置。由于未显示相关性,因此省略了居住状况和性别。
def 拆分(自我,test_size):
import numpy as np # 用于操作数组。
from sklearn.model_selection import train_test_split # 用于准备拟合数据。
self.X = np.array(self.df[['age', 'hypertension', 'heart_disease', 'ever_married', 'work_type', 'avg_glucose_level', 'bmi', 'Smoking_status']])
self.y = np.array(self.df['stroke'])
self.X_train,self.X_test,self.y_train,self.y_test = train_test_split(self.X,self.y,test_size = test_size,random_state = 42)
配置一个名为“fit”的函数,使用训练特征和标签数据训练决策树模型。
如果您配置的算法有另一个名称,请将“分类器”替换为该名称。
# 使用训练数据拟合模型。
默认适合(自我):
self.model = self.classifier.fit(self.X_train, self.y_train)
配置一个名为“predict”的函数,以使用经过训练的模型使用测试数据来预测结果。
如果您配置的算法有另一个名称,请将“分类器”替换为该名称。
# 使用测试数据测试的模型。
def 预测(自我):
self.predictions = self.classifier.predict(self.X_test)
返回自我预测
配置一个名为“cvscoring”的函数以使用 10 倍交叉验证对模型进行评分。
如果您配置的算法有另一个名称,请将“分类器”替换为该名称。
# 原始模型的交叉验证。
def cvscoring(自我):
from sklearn.model_selection import cross_val_score # 用于模型的交叉验证。
from matplotlib import pyplot as plt # 可视化数据。
import seaborn as sns # 绘制可视化。
orig_cv_scores = cross_val_score(estimator = self.classifier, X = model_instance.X, y= model_instance.y, cv = 10)
fig = plt.subplots(1, figsize=(5, 5))
sns.boxplot(数据 = orig_cv_scores)
plt.title("初始交叉验证分数 DT")
plt.show()
print('\n 初始平均 CV 分数:', model_instance.model.score(model_instance.X_test, model_instance.y_test))
配置一个名为“initial_params”的函数来获取模型的参数。
如果您配置的算法有另一个名称,请将“分类器”替换为该名称。
# pprint 获取初始模型的参数。
定义初始参数(自我):
from pprint import pprint # 评估模型参数。
print('\n 初始参数:')
pprint(self.classifier.get_params())
配置一个名为“tune”的函数来调整原始模型,对其进行 10 倍交叉验证,并返回新模型的改进百分比。
要更改调优中使用的参数,请修改 param_dist 表。
如果您配置的算法有另一个名称,请将“分类器”替换为该名称。
# 模型调整。该模型通过各种合适的组合进行了调整,这些组合使用 RandomizedSearchCV 进行实施。
# max_depth 考虑在预测之前可以进行的分割数。
# max_features 确定考虑的特征数量。
# min_samples_leaf 定义了节点分裂所需的最小样本。
# 标准确定用于测量拆分纯度的函数。
def 曲调(自我):
from pprint import pprint # 评估模型参数
from sklearn.model_selection import RandomizedSearchCV # 调整模型。
import pandas as pd # 用于数据操作。
from matplotlib import pyplot as plt # 可视化数据。
import seaborn as sns # 绘制可视化。
from sklearn.metrics import accuracy_score # 计算准确率。
param_dist = {"max_depth": [5, 7, 10, 15, 无],
"max_features": [无, 2, 4, 6, 8, 10],
"min_samples_leaf": (1, 2, 4),
“标准”:[“基尼”,“熵”]}
self.tree_cv = RandomizedSearchCV(self.classifier, param_dist, cv=10)
# 调整后的模型适合数据。
self.tuned_tree = self.tree_cv.fit(model_instance.X_train, model_instance.y_train)
# 使用'.cv_results_'以表格形式获得交叉验证结果数组。
tune_results = self.tree_cv.cv_results_ # “DataFrame”函数用于将结果数组转换为定义为“Tuned_Results”的数据帧。
Tuned_Results = pd.DataFrame(tuned_results) # 绘制箱线图,显示获得的平均交叉验证分数。
fig = plt.subplots(1, figsize=(5, 5))
sns.boxplot(数据 = Tuned_Results,y = 'mean_test_score')
plt.title("调谐平均 CV 分数 DT")
plt.show()
# 显示调整后的模型参数。
print('\n 最优参数:')
打印(self.tree_cv.best_params_)
# 显示了调整模型的平均交叉验证分数。
print("\n 调整后的平均 CV 分数:")
打印(self.tree_cv.best_score_)
# 显示了相对于原始模型参数的百分比改进。
print("\n 使用 RandomizedSearchCV 的百分比改进")
print(((self.tree_cv.best_score_-accuracy_score(model_instance.y_test, model_instance.predictions))/accuracy_score(model_instance.y_test, model_instance.predictions))*100)
配置一个名为“confmatrix”的函数来评估调整后的模型并可视化其预测。
# 一个混淆矩阵表示模型输出。
def confmatrix(自我):
from sklearn.metrics import chaos_matrix # 可视化结果。
import seaborn as sns # 绘制可视化。
from matplotlib import pyplot as plt # 可视化数据。
ConfMatrix = 混淆矩阵(model_instance.y_test,model_instance.predictions)
sns.heatmap(ConfMatrix,不=真)
plt.title("优化决策树混淆矩阵")
配置一个名为“classreport”的函数,获取调优模型的分类报告。
# 调优模型的分类报告。
def 类报告(自我):
from sklearn.metrics import classification_report # 打印性能指标。
print('调整后的模型分类报告:\n', classification_report(model_instance.y_test,model_instance.predictions))
配置一个名为“treeviz”的函数来可视化决策树。
如果您配置的算法有另一个名称,请将“分类器”替换为该名称。
# 可视化决策树。
def treeviz(自我):
from matplotlib import pyplot as plt # 可视化数据。
from sklearn import tree # 绘制决策树。
fig = plt.figure(figsize=(25,20))
plt.suptitle("决策树可视化")
_ = tree.plot_tree(self.classifier, feature_names=self.df.columns.values, class_names='stroke',filled=True)
第 5 步:设计 main 函数,执行模型。
每个函数都按所需的顺序调用,并在使用它们的地方添加变量。要更改训练-测试拆分,请将变量“0.3”更改为所需的测试数据大小,介于 0 和 1 之间。
# main: 函数已定义。每个阶段调用函数来执行模型。
如果 __name__ == '__main__':
模型实例 = 模型()
model_instance.corr()
model_instance.clean()
model_instance.split(0.3)
model_instance.fit()
model_instance.predict()
model_instance.initial_params()
model_instance.cvscoring()
model_instance.tune()
model_instance.confmatrix()
model_instance.classreport()
model_instance.treeviz()
结果
原始数据集:
_id id 性别 年龄 高血压 heart_disease \
0 630c2d66ccb4d1494b0bba11 9046 男 67.0 0 1
1 630c2d66ccb4d1494b0bba12 51676 女 61.0 0 0
2 630c2d66ccb4d1494b0bba13 31112 男 80.0 0 1
3 630c2d66ccb4d1494b0bba14 60182 女 49.0 0 0
4 630c2d66ccb4d1494b0bba15 1665 女 79.0 1 0
ever_married work_type Residence_type avg_glucose_level bmi \
0 是 民营 城市 228.69 36.6
1 是 个体户 农村 202.21 NaN
2 是 民营 农村 105.92 32.5
3 是 民营 城市 171.23 34.4
4 是 个体户 农村 174.12 24.0
吸烟状态中风
0 以前吸过 1
1 从不吸烟 1
2 从不吸烟 1
3 抽 1
4 从不吸烟 1
Correlation heatmap
清理数据集:
_id id 性别 年龄 高血压 heart_disease \
0 630c2d66ccb4d1494b0bba11 9046 1 67.0 0 1
2 630c2d66ccb4d1494b0bba13 31112 1 80.0 0 1
3 630c2d66ccb4d1494b0bba14 60182 0 49.0 0 0
4 630c2d66ccb4d1494b0bba15 1665 0 79.0 1 0
5 630c2d66ccb4d1494b0bba16 56669 1 81.0 0 0
ever_married work_type Residence_type avg_glucose_level bmi \
0 1 2 1 228.69 36.6
2 1 2 0 105.92 32.5
3 1 2 1 171.23 34.4
4 1 3 0 174.12 24.0
5 1 2 1 186.21 29.0
吸烟状态中风
0 1 1
2 2 1
3 3 1
4 2 1
5 1 1
初始参数:
{'ccp_alpha': 0.0,
'class_weight':无,
“标准”:“基尼”,
“最大深度”:无,
'max_features':无,
'max_leaf_nodes':无,
'min_impurity_decrease': 0.0,
'min_samples_leaf': 1,
'min_samples_split': 2,
'min_weight_fraction_leaf':0.0,
“随机状态”:100,
“分离器”:“最佳”} 初始平均 CV 分数:0.9205702647657841
Initial cross validation score
最佳参数:
{'min_samples_leaf':1,'max_features':4,'max_depth':5,'criterion':'gini'}
调整后的平均 CV 分数:
0.9540180690216286 使用 RandomizedSearchCV 的百分比改进
3.6333787366415136
Tuned cross validation score
调整后的模型分类报告:
精确召回 f1 分数支持
0 0.97 0.95 0.96 1413
1 0.15 0.20 0.17 60
精度 0.92 1473
宏平均 0.56 0.58 0.56 1473
加权平均 0.93 0.92 0.93 1473
Tuned confusion matrix
Decision tree visualization
结论
总之,该模型的交叉验证分数增加了 3.63%(至 2 dp)。该模型使用了面向对象的编程,尽管大多数函数没有输入,例如,这会使更改数据集变得困难。一种改进的方法是使用一个名为“config”的文件来存储每个函数的参数,以便可以安全地控制程序。
参考
[
scikit-学习
“我们使用 scikit-learn 来支持前沿基础研究 [...]”
scikit-learn.org
](https://scikit-learn.org/stable/index.html)
[
MongoDB:开发者数据平台 | MongoDB
产品解决方案客户故事了解企业如何利用 MongoDB 白皮书和演示文稿……
www.mongodb.com
[
数字货币
为什么选择 NumPy?强大的 n 维数组。数值计算工具。可互操作。高性能。开源。
numpy.org
[
熊猫
pandas 是一个快速、强大、灵活且易于使用的开源数据分析和操作工具,建立在...
pandas.pydata.org
[
seaborn:统计数据可视化 - seaborn 0.11.2 文档
Seaborn 是一个基于 matplotlib 的 Python 数据可视化库。它为绘图提供了一个高级界面……
seaborn.pydata.org
](https://seaborn.pydata.org/)
[
pprint - 数据漂亮的打印机 - Python 3.10.6 文档
源代码:Lib/pprint.py 该模块提供了“漂亮打印”任意 Python 数据结构的能力。
docs.python.org
](https://docs.python.org/3/library/pprint.html)
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明