我们都听说过一个流行词——“数据科学”。我们大多数人都对“它是什么?我可以成为数据分析师或数据科学家吗?我需要什么技能?并不是很了解。例如:我想开始一个数据科学项目,但我却不知道如何着手进行。
我们大多数人都是通过一些在线课程了解了这个领域。我们对课程中布置的作业和项目感到游刃有余。但是,当开始分析全新或未知的数据集时,我们会迷失方向。为了在分析我们遇到的任何数据集和问题时,我们需要通过不断的练习。我觉得最好的方式之一就是在项目中进行学习。所以每个人都需要开始自己的第一个项目。因此,我准备写一个专栏,带大家一起完成数据科学项目,感兴趣的朋友可以一起交流完成,预计不会少于50篇文章。本专栏是一个以实战为主的专栏。
那么我们怎样去建立一个数据科学项目呢?
要在数据科学项目中取得成功,我们必须了解其流程并对其进行优化,以确保结果可靠,并且项目在必要时易于跟踪、维护和修改。因此,最好和最快的方法是使用一个规范模板来构建项目。在这里我总结了一个比较规范的流程,如下所示。
训练机器学习算法的过程有点像第一次教小孩子一个物体的名字,然后让他们在下次看到它时单独识别它。人类只需要几个例子就可以识别一个新物体。但对于机器来说并非如此,它需要成百上千个类似的例子来熟悉一个对象。而这些示例就是我们想要的数据集。
要训练机器学习算法,需要获得足够的数据。现在,问题来了,你从哪里收集你想要开展的任何项目的数据?
你可以从官方来源收集预先存在的数据集,你可以从数据库中导入数据,你可以直接从网页上抓取数据,你可以通过一些社交媒体渠道收集数据,你还可以利用在线表格进行数据收集。还有许多其他来源,你的数据收集方法取决于你的数据科学项目。如果你是第一次从事数据科学项目,请选择你感兴趣的数据集。它可以与运动、电影或音乐有关——任何你感兴趣的东西。在这里我推荐几个我平时获取数据的网站:
在这里,我选择了一个数据集来练习预测分析。我从 Kaggle 网站上提取了数据集
我的github上也上传了该项目的数据集: 数据集
# 首先安装kaggle
! pip install -q kaggle
# 将kaggle的json文件导入
!mkdir -p ~/.kaggle
!cp /content/kaggle.json ~/.kaggle/
!chmod 600 ~/.kaggle/kaggle.json
!kaggle config set -n path -v /content
# 下载数据集并解压。
! kaggle datasets download -d mirichoi0218/insurance
! unzip insurance.zip -d health-insurance
工欲善其事,必先利其器
在有了数据之后,我们下一步考虑使用什么工具来对数据进行处理,建模。选择一个你最熟悉的 IDE。如果你使用 Python语言,这里有几个常见的IDE
Pycharm – 它是一个旨在编写 Python 代码的 IDE。它提供了各种生产功能,例如智能代码完成、错误检查和代码修复。它通过提供与版本控制功能的集成,支持 Web 开发以及数据科学,使项目维护变得容易
Jupyter Notebook – 它是一个开源 Web 应用程序,允许您创建和共享包含实时代码、可视化的文档。它有助于简化工作并使协作更容易
Google Colab – 它允许用户编写和执行 Python 代码。它非常适合机器学习和数据科学项目,因为它免费提供计算资源。你可以在这里轻松运行重型机器学习算法,而不必担心基础设施或成本。
带有 .py 扩展名的简单文本文件 ,尽管上述选项很容易获得并且易于使用,但如果你最喜欢使用记事本编写代码,你可以使用它并使用 .py 扩展名保存文件。然后,你可以使用语法为“python .py”的命令行运行相同的命令。这将执行你的程序,但对于数据科学工作,这可能不是最佳选择,因为你无法即时看到代码或可视化的输出。
在这里,我选择了 Google Colab 作为工作环境
获取要使用的数据后,下一步是通过检查数据质量来获得对数据的第一印象。此阶段的主要目标是对数据进行完整性检查,而完成此任务的最佳方法是寻找不可能或极不可能的事情。检查异常值和缺失值,检查数据类型是否正确,并检查最极端的情况。它们有意义吗?一个好的做法是对数据运行一些简单的统计测试并将其可视化,以快速了解数据的统计属性并检测可能的异常值。
列出要在数据集上进行的操作,以便在开始之前有一个清晰的路径。我们在数据科学项目中执行的常见操作是
数据读取、数据清理、数据转换、探索性数据分析、模型构建、模型评估和模型部署。下面简要介绍这些步骤。
数据读取将数据读入到一个dataframe的结构,使用pandas
# 导入基本库
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from matplotlib.cbook import boxplot_stats
import statsmodels.api as sm
from sklearn.model_selection import train_test_split,GridSearchCV, cross_val_score, cross_val_predict
from statsmodels.stats.outliers_influence import variance_inflation_factor
from sklearn.tree import DecisionTreeRegressor
from sklearn import ensemble
import numpy as np
import pickle
# 读取数据,并总览一下数据情况。
health_ins_df = pd.read_csv("health-insurance/insurance.csv")
health_ins_df.head()
index | age | sex | bmi | children | smoker | region | charges |
---|---|---|---|---|---|---|---|
0 | 19 | female | 27.9 | 0 | yes | southwest | 16884.924 |
1 | 18 | male | 33.77 | 1 | no | southeast | 1725.5523 |
2 | 28 | male | 33.0 | 3 | no | southeast | 4449.462 |
3 | 33 | male | 22.705 | 0 | no | northwest | 21984.47061 |
4 | 32 | male | 28.88 | 0 | no | northwest | 3866.8552 |
数据清洗:识别和消除数据集中缺失值和异常值
# 查看缺失值
health_ins_df.isnull().sum()
# 可以看出数据集中没有缺失值
age 0
sex 0
bmi 0
children 0
smoker 0
region 0
charges 0
dtype: int64
数据转换——它涉及更改列的数据类型、创建派生列或删除重复数据等等
探索性数据分析——对数据集执行单变量和多变量分析,以发现其中隐藏的一些关系
下面我们来对数值和分类变量进行数据清理和探索性数据分析。
对于数值型变量的分析
#数值型变量的可视化
# 直方图绘制
fig,axes = plt.subplots(1,2,figsize=(12,6))
plt.style.use('ggplot')#使用ggplot主题,R语言的一个绘图包
sns.histplot( health_ins_df['age'] , color="skyblue",ax=axes[0])
sns.histplot( health_ins_df['bmi'] , color="olive",ax=axes[1])
plt.show()
我们可以把年龄进行分组转换为年龄段
BMI接近正态分布
# 箱线图
fig,axes=plt.subplots(1,2,figsize=(10,5))
sns.boxplot(x = 'age', data = health_ins_df, ax=axes[0])
sns.boxplot(x = 'bmi', data = health_ins_df, ax=axes[1])
plt.show()
可以看出BMI存在一些离群值 , 现在我们来看一下这些点
outlier_list = boxplot_stats(health_ins_df.bmi).pop(0)['fliers'].tolist()
print(outlier_list)
#查找包含异常值的行数
outlier_bmi_rows = health_ins_df[health_ins_df.bmi.isin(outlier_list)].shape[0]
print("bmi 中包含异常值的行数:", outlier_bmi_rows)
#离群值占比
#Percentage of rows which are outliers
percent_bmi_outlier = (outlier_bmi_rows/health_ins_df.shape[0])*100
print("bmi离群值异常值的百分比 : ", percent_bmi_outlier)
[49.06, 48.07, 47.52, 47.41, 50.38, 47.6, 52.58, 47.74, 53.13]
bmi 中包含异常值的行数: 9
bmi离群值异常值的百分比 : 0.672645739910314
数值变量的数据转换
# 将年龄转换为分桶的
print("Minimum value for age : ", health_ins_df['age'].min(),"\nMaximum value for age : ", health_ins_df['age'].max())
'''
18至40岁的年龄将属于青年
41至58岁的年龄将低于中年
58岁以上将落入老年
'''
health_ins_df.loc[(health_ins_df['age'] >=18) & (health_ins_df['age'] <= 40), 'age_group'] = '青年'
health_ins_df.loc[(health_ins_df['age'] >= 41) & (health_ins_df['age'] <= 58), 'age_group'] = '中年'
health_ins_df.loc[health_ins_df['age'] > 58, 'age_group'] = '老年'
Minimum value for age : 18
Maximum value for age : 64
# 去除BMI中的异常值
health_ins_df_clean = health_ins_df[~health_ins_df.bmi.isin(outlier_list)]
sns.boxplot(x = 'bmi', data = health_ins_df_clean)
对于分类型变量的分析
fig,axes=plt.subplots(1,5,figsize=(20,8))
sns.countplot(x = 'sex', data = health_ins_df_clean, palette = 'magma',ax=axes[0])
sns.countplot(x = 'children', data = health_ins_df_clean, palette = 'magma',ax=axes[1])
sns.countplot(x = 'smoker', data = health_ins_df_clean, palette = 'magma',ax=axes[2])
sns.countplot(x = 'region', data = health_ins_df_clean, palette = 'magma',ax=axes[3])
sns.countplot(x = 'age_group', data = health_ins_df_clean, palette = 'magma',ax=axes[4])
数据准备完成后,下一阶段是建模。选择合适的算法将取决于数据的类型。例如,如果数据是连续的,您将应用回归建模,如果数据是分类的,您将应用分类算法建模。作为一名数据科学家,您将尝试许多模型来获得最合适的模型。
在根据业务/技术限制选择正确的模型之前,尝试并测试数据集上所有可能的模型。在这个阶段,你也可以尝试一些 bagging 或 boosting 技术。在这里,我分别构建了线性回归模型、决策树回归、Gradient Boosting Regression.
在这里,我们首先使用线性回归模型作为基准模型。
from sklearn.linear_model import LinearRegression
lm = LinearRegression()
X = health_ins_df_processed.loc[:, health_ins_df_processed.columns != 'charges']#自闭哪里
y = health_ins_df_processed['charges']#因变量
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33)#划分训练集和测试集
lm.fit(X_train,y_train)
print("R-Squared on train dataset={}".format(lm.score(X_train,y_train)))#训练集R2
lm.fit(X_test,y_test)
print("R-Squaredon test dataset={}".format(lm.score(X_test,y_test)))#测试集R2
R-Squared on train dataset=0.7494776882061486
R-Squaredon test dataset=0.7372938495110573
从结果来看,使用简单的线性回归 R 2 R^2 R2为0.74,说明模型解释了数据74%的信息,我们下面来看一些更complex的模型
X = health_ins_df_processed.loc[:, health_ins_df_processed.columns != 'charges']
y = health_ins_df_processed['charges']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33)
dtr = DecisionTreeRegressor(max_depth=4,min_samples_split=5,max_leaf_nodes=10)#初始化参数
dtr.fit(X_train,y_train)
print("R-Squared on train dataset={}".format(dtr.score(X_train,y_train)))#训练集R2
dtr.fit(X_test,y_test)
print("R-Squaredon test dataset={}".format(dtr.score(X_test,y_test)))#测试集R2
R-Squared on train dataset=0.8594291626976573
R-Squaredon test dataset=0.8571718114547656
上面的参数是我随机设定,大家还可以对其进行调参能提高一定的效果,调参的代码我上传到github上了https://github.com/JoJoYao996/data-science-projects
梯度提升回归模型的主要调整参数
我使用了gridsearch来分别对这些参数调整,下面是调参之后的结果。
#最终的模型
f_model = ensemble.GradientBoostingRegressor(learning_rate=0.015,n_estimators=250,max_depth=2,min_samples_leaf=5,
min_samples_split=2,subsample=1,loss = 'squared_error')
f_model.fit(X_train, y_train)
print("Accuracy score (training): {0:.3f}".format(f_model.score(X_train, y_train)))
f_model.fit(X_test, y_test)
print("Accuracy score (test): {0:.3f}".format(f_model.score(X_test, y_test)))
Accuracy score (training): 0.866
Accuracy score (test): 0.818
查看特征的重要性
#查看变量的重要性
feature_importance = f_model.feature_importances_
sorted_idx = np.argsort(feature_importance)#得到重要性的排序索引
fig = plt.figure(figsize=(12, 6))
pos = np.arange(sorted_idx.shape[0]) + .5
plt.barh(pos, feature_importance[sorted_idx], align='center')
plt.yticks(pos, np.array(health_ins_df_processed.columns)[sorted_idx])
plt.show()
可以看出最重要的三个特征是:smoker_no,children_5,bmi
# 保存模型
filename = 'health_insurance_data_model.sav'
pickle.dump(f_model, open(filename, 'wb'))
# 加载模型
filename = 'health_insurance_data_model.sav'
loaded_model = pickle.load(open(filename, 'rb'))
result = loaded_model.score(X_test, y_test)
print(result) #测试集精度
0.8180114370687565
总结一份文档,简要说明项目以及完成项目所采取的步骤。尝试总结你设计的业务问题陈述和数据科学解决方案。 同时还可以提及有关该项目的生动细节,以供将来参考。
您可以使用简单的 word 文档或 powerpoint 演示文稿来准备摘要。它可以有5个部分。在第一部分,简要解释背景和问题。在第二部分中,提及您用于预测分析的数据集是什么以及数据的来源是什么。在第 3 部分提到,您执行的数据清理、数据转换和探索性数据分析是什么?然后,简要提及您尝试和测试过的不同预测模型的概念验证。最后,您可以提及业务问题的最终结果和解决方案。
这个项目完成后我会准备一个简短的总结
选择一个你想要发布项目摘要或代码的开源平台,例如github、gitee等,方便与更多的数据科学家沟通交流,不断完善自己的项目。
篇幅有限,完整代码可以在我的github上面查看,欢迎大家star,fork。
github地址:完整代码
如果访问不了github的可以私信我获取源码。