VS Code 中的数据科学教程
本教程演示了如何使用Visual Studio Code和Microsoft Python扩展与常见的数据科学库一起探索一个基本的数据科学场景。具体来说,使用泰坦尼克号的乘客数据,您将学习如何设置数据科学环境,导入和清理数据,创建一个用于预测泰坦尼克号生存情况的机器学习模型,并评估生成模型的准确性。
先决条件
完成本教程需要以下安装。如果尚未安装,请确保安装它们。
-
VS Code 的 Python 扩展 和 VS Code 的 Jupyter 扩展 可以从 Visual Studio Marketplace 获取。有关安装扩展的更多详细信息,请参阅 扩展市场。这两个扩展均由 Microsoft 发布。
-
注意: 如果你已经安装了完整的Anaconda发行版,你不需要安装Miniconda。另外,如果你不想使用Anaconda或Miniconda,你可以创建一个Python虚拟环境,并使用pip安装教程所需的包。如果你选择这种方式,你需要安装以下包:pandas、jupyter、seaborn、scikit-learn、keras和tensorflow。
设置数据科学环境
Visual Studio Code 和 Python 扩展为数据科学场景提供了一个出色的编辑器。结合 Anaconda 对 Jupyter 笔记本的原生支持,入门变得非常容易。在本节中,您将为教程创建一个工作区,创建一个包含教程所需数据科学模块的 Anaconda 环境,并创建一个用于构建机器学习模型的 Jupyter 笔记本。
-
首先为数据科学教程创建一个Anaconda环境。打开Anaconda命令提示符并运行
conda create -n myenv python=3.10 pandas jupyter seaborn scikit-learn keras tensorflow
来创建一个名为myenv的环境。有关创建和管理Anaconda环境的更多信息,请参阅Anaconda文档。 -
接下来,在一个方便的位置创建一个文件夹,作为本教程的VS Code工作区,将其命名为
hello_ds
。 -
在VS Code中打开项目文件夹,通过运行VS Code并使用文件 > 打开文件夹命令。您可以安全地信任打开该文件夹,因为它是您创建的。
-
一旦VS Code启动,创建将用于教程的Jupyter笔记本。打开命令面板(⇧⌘P (Windows, Linux Ctrl+Shift+P))并选择创建:新建Jupyter笔记本。
注意: 或者,从 VS Code 文件资源管理器中,您可以使用新建文件图标来创建一个名为
hello.ipynb
的 Notebook 文件。 -
将文件保存为
hello.ipynb
,使用 文件 > 另存为...。 -
创建文件后,您应该会在笔记本编辑器中看到打开的Jupyter notebook。有关原生Jupyter笔记本支持的更多信息,您可以阅读Jupyter Notebooks主题。
-
现在在笔记本的右上角选择选择内核。
-
选择您在上面创建的Python环境来运行您的内核。
-
要从VS Code的集成终端管理您的环境,请使用(⌃` (Windows, Linux Ctrl+`))打开它。如果您的环境未激活,您可以像在终端中一样激活它(
conda activate myenv
)。
准备数据
本教程使用泰坦尼克号数据集,该数据集可在OpenML.org上获取,数据来源于范德比尔特大学生物统计系https://hbiostat.org/data。泰坦尼克号数据提供了关于泰坦尼克号乘客生存情况的信息以及乘客的特征,如年龄和票务等级。使用这些数据,本教程将建立一个模型,用于预测给定乘客是否会在泰坦尼克号沉船事件中幸存。本节展示了如何在Jupyter笔记本中加载和操作数据。
-
首先,从hbiostat.org下载泰坦尼克号数据作为CSV文件(右上角的下载链接),命名为
titanic3.csv
,并将其保存到你在上一节中创建的hello_ds
文件夹中。 -
如果您还没有在VS Code中打开文件,请通过转到文件 > 打开文件夹来打开
hello_ds
文件夹和Jupyter笔记本(hello.ipynb
)。 -
在你的Jupyter笔记本中,首先导入pandas和numpy库,这两个库常用于数据操作,并将泰坦尼克号数据加载到pandas的DataFrame中。为此,将下面的代码复制到笔记本的第一个单元格中。有关在VS Code中使用Jupyter笔记本的更多指导,请参阅使用Jupyter笔记本文档。
import pandas as pd import numpy as np data = pd.read_csv('titanic3.csv')
-
现在,使用运行单元格图标或Shift+Enter快捷键运行单元格。
-
单元格运行完成后,您可以使用变量资源管理器和数据查看器查看加载的数据。首先选择笔记本上方工具栏中的变量图标。
-
一个JUPYTER: 变量面板将在VS Code的底部打开。它包含了一个列表,列出了到目前为止在你的运行内核中定义的变量。
-
要查看先前加载的Pandas DataFrame中的数据,请选择
data
变量左侧的数据查看器图标。 -
使用数据查看器查看、排序和筛选数据行。在查看数据后,绘制一些方面的图表有助于可视化不同变量之间的关系。
或者,您可以使用其他扩展提供的数据查看体验,例如Data Wrangler。Data Wrangler 扩展提供了一个丰富的用户界面,用于显示有关数据的洞察,并帮助您执行数据剖析、质量检查、转换等操作。了解更多关于我们文档中的 Data Wrangler 扩展。
-
在数据可以被绘制成图表之前,你需要确保它没有任何问题。如果你查看泰坦尼克号的csv文件,你会注意到一个问题标记("?")被用来标识数据不可用的单元格。
虽然Pandas可以将此值读取到DataFrame中,但对于像age这样的列,结果是其数据类型将被设置为object而不是数值类型,这对于绘图是有问题的。
这个问题可以通过将问号替换为pandas能够理解的缺失值来纠正。在您的笔记本的下一单元格中添加以下代码,以将age和fare列中的问号替换为numpy NaN值。请注意,替换值后我们还需要更新列的数据类型。
提示: 要添加一个新单元格,您可以使用现有单元格左下角的插入单元格图标。或者,您也可以使用 Esc 进入命令模式,然后按 B 键。
data.replace('?', np.nan, inplace= True) data = data.astype({"age": np.float64, "fare": np.float64})
注意: 如果你需要查看某列使用的数据类型,你可以使用 DataFrame dtypes 属性。
-
现在数据已经整理好了,你可以使用 seaborn 和 matplotlib 来查看数据集的某些列与生存率的关系。将以下代码添加到你的笔记本的下一个单元格中并运行它,以查看生成的图表。
import seaborn as sns import matplotlib.pyplot as plt fig, axs = plt.subplots(ncols=5, figsize=(30,5)) sns.violinplot(x="survived", y="age", hue="sex", data=data, ax=axs[0]) sns.pointplot(x="sibsp", y="survived", hue="sex", data=data, ax=axs[1]) sns.pointplot(x="parch", y="survived", hue="sex", data=data, ax=axs[2]) sns.pointplot(x="pclass", y="survived", hue="sex", data=data, ax=axs[3]) sns.violinplot(x="survived", y="fare", hue="sex", data=data, ax=axs[4])
提示: 要快速复制您的图表,您可以将鼠标悬停在图表的右上角,然后点击出现的复制到剪贴板按钮。您也可以通过点击展开图像按钮来更好地查看图表的细节。
-
这些图表有助于观察生存率与数据输入变量之间的一些关系,但也可以使用pandas来计算相关性。为此,所有用于相关性计算的变量都需要是数值型的,而目前性别是以字符串形式存储的。要将这些字符串值转换为整数,请添加并运行以下代码。
data.replace({'male': 1, 'female': 0}, inplace=True)
-
现在,您可以分析所有输入变量之间的相关性,以确定哪些特征最适合作为机器学习模型的输入。值越接近1,该值与结果之间的相关性越高。使用以下代码来关联所有变量与生存之间的关系。
data.corr(numeric_only=True).abs()[["survived"]]
-
查看相关性结果时,您会注意到一些变量(如性别)与生存率有相当高的相关性,而其他变量(如亲属:sibsp = 兄弟姐妹或配偶,parch = 父母或子女)似乎相关性很小。
让我们假设sibsp和parch在影响生存率方面是相关的,并将它们分组到一个名为“relatives”的新列中,看看它们的组合是否与生存率有更高的相关性。为此,您将检查给定乘客的sibsp和parch数量是否大于0,如果是,那么您可以说他们在船上有亲属。
使用以下代码在数据集中创建一个名为
relatives
的新变量和列,并再次检查相关性。data['relatives'] = data.apply (lambda row: int((row['sibsp'] + row['parch']) > 0), axis=1) data.corr(numeric_only=True).abs()[["survived"]]
-
你会注意到,实际上从一个人是否有亲属的角度来看,与有多少亲属相比,生存率有更高的相关性。有了这些信息,你现在可以从数据集中删除低价值的sibsp和parch列,以及任何包含NaN值的行,最终得到一个可以用于训练模型的数据集。
data = data[['sex', 'pclass','age','relatives','fare','survived']].dropna()
注意:尽管年龄的直接相关性较低,但由于它可能与其他输入结合时仍具有相关性,因此保留了它。
训练和评估模型
数据集准备就绪后,您现在可以开始创建模型。在本节中,您将使用scikit-learn库(因为它提供了一些有用的辅助函数)来对数据集进行预处理,训练一个分类模型以确定泰坦尼克号上的生存率,然后使用该模型与测试数据来确定其准确性。
-
训练模型的常见第一步是将数据集划分为训练数据和验证数据。这允许你使用一部分数据来训练模型,另一部分数据来测试模型。如果你使用所有数据来训练模型,你将无法估计模型在面对未见过的数据时的实际表现。scikit-learn库的一个优点是它提供了一个专门用于将数据集分割为训练数据和测试数据的方法。
在笔记本中添加并运行一个包含以下代码的单元格以拆分数据。
from sklearn.model_selection import train_test_split x_train, x_test, y_train, y_test = train_test_split(data[['sex','pclass','age','relatives','fare']], data.survived, test_size=0.2, random_state=0)
-
接下来,您将对输入进行归一化,以便所有特征都被平等对待。例如,在数据集中,年龄的值范围大约为0-100,而性别仅为1或0。通过归一化所有变量,您可以确保值的范围都相同。在新的代码单元格中使用以下代码来缩放输入值。
from sklearn.preprocessing import StandardScaler sc = StandardScaler() X_train = sc.fit_transform(x_train) X_test = sc.transform(x_test)
-
有许多不同的机器学习算法可供选择来建模数据。scikit-learn库也提供了对许多它们的支持,并提供了一个图表来帮助选择适合您场景的算法。现在,使用朴素贝叶斯算法,这是分类问题中常用的算法。添加一个包含以下代码的单元格来创建和训练算法。
from sklearn.naive_bayes import GaussianNB model = GaussianNB() model.fit(X_train, y_train)
-
有了一个训练好的模型,你现在可以尝试用它来测试那些在训练时被保留的测试数据集。添加并运行以下代码来预测测试数据的结果,并计算模型的准确性。
from sklearn import metrics predict_test = model.predict(X_test) print(metrics.accuracy_score(y_test, predict_test))
查看测试数据的结果,你会发现训练后的算法在估计生存率方面有大约75%的成功率。
(可选)使用神经网络
神经网络是一种使用权重和激活函数的模型,模拟人类神经元的某些方面,根据提供的输入确定结果。与之前看到的机器学习算法不同,神经网络是深度学习的一种形式,其中你不需要提前知道问题集的理想算法。它可以用于许多不同的场景,分类是其中之一。在本节中,你将使用Keras库与TensorFlow来构建神经网络,并探索它如何处理泰坦尼克号数据集。
-
第一步是导入所需的库并创建模型。在这种情况下,您将使用一个Sequential神经网络,这是一种分层神经网络,其中有多个层按顺序相互输入。
from keras.models import Sequential from keras.layers import Dense model = Sequential()
-
定义模型后,下一步是添加神经网络的层。现在,让我们保持简单,只使用三层。添加以下代码以创建神经网络的层。
model.add(Dense(5, kernel_initializer = 'uniform', activation = 'relu', input_dim = 5)) model.add(Dense(5, kernel_initializer = 'uniform', activation = 'relu')) model.add(Dense(1, kernel_initializer = 'uniform', activation = 'sigmoid'))
- The first layer will be set to have a dimension of 5, since you have five inputs: sex, pclass, age, relatives, and fare.
- The last layer must output 1, since you want a 1-dimensional output indicating whether a passenger would survive.
- The middle layer was kept at 5 for simplicity, although that value could have been different.
修正线性单元(relu)激活函数被用作前两层的良好通用激活函数,而最后一层则需要sigmoid激活函数,因为您想要的输出(乘客是否生存)需要在0-1范围内进行缩放(乘客生存的概率)。
你也可以通过这行代码查看你构建的模型的摘要:
model.summary()
-
一旦模型创建完成,就需要进行编译。在这个过程中,你需要定义将使用哪种类型的优化器,如何计算损失,以及应该优化哪个指标。添加以下代码来构建和训练模型。你会注意到,训练后准确率约为61%。
注意:此步骤可能需要几秒钟到几分钟的时间来运行,具体取决于您的机器。
model.compile(optimizer="adam", loss='binary_crossentropy', metrics=['accuracy']) model.fit(X_train, y_train, batch_size=32, epochs=50)
-
现在模型已经构建并训练完成,我们可以看看它在测试数据上的表现如何。
y_pred = np.rint(model.predict(X_test).flatten()) print(metrics.accuracy_score(y_test, y_pred))
与训练类似,你会注意到现在你在预测乘客生存方面的准确率达到了79%。使用这个简单的神经网络,结果比之前尝试的朴素贝叶斯分类器的75%准确率要好。
下一步
既然你已经熟悉了在Visual Studio Code中执行机器学习的基础知识,这里有一些其他的Microsoft资源和教程可以查看。
- Data Science 配置文件模板 - 使用一组精选的扩展、设置和代码片段创建一个新的配置文件。
- 了解更多关于在Visual Studio Code中使用Jupyter Notebooks的信息(视频)。
- 开始使用 Azure Machine Learning for VS Code 以利用 Azure 的强大功能部署和优化您的模型。
- 在Azure Open Data Sets上探索更多数据。