• 【数据科学项目1】:构建你的第一个数据科学项目


    【数据科学项目1】:构建你的第一个数据科学项目

    请添加图片描述

    引言

    我们都听说过一个流行词——“数据科学”。我们大多数人都对“它是什么?我可以成为数据分析师或数据科学家吗?我需要什么技能?并不是很了解。例如:我想开始一个数据科学项目,但我却不知道如何着手进行。
    我们大多数人都是通过一些在线课程了解了这个领域。我们对课程中布置的作业和项目感到游刃有余。但是,当开始分析全新或未知的数据集时,我们会迷失方向。为了在分析我们遇到的任何数据集和问题时,我们需要通过不断的练习。我觉得最好的方式之一就是在项目中进行学习。所以每个人都需要开始自己的第一个项目。因此,我准备写一个专栏,带大家一起完成数据科学项目,感兴趣的朋友可以一起交流完成,预计不会少于50篇文章。本专栏是一个以实战为主的专栏。

    那么我们怎样去建立一个数据科学项目呢?
    要在数据科学项目中取得成功,我们必须了解其流程并对其进行优化,以确保结果可靠,并且项目在必要时易于跟踪、维护和修改。因此,最好和最快的方法是使用一个规范模板来构建项目。在这里我总结了一个比较规范的流程,如下所示。

    • 第一步:收集数据
    • 第二步:选择一个合适的IDE
    • 第三步:列出在数据集上要进行的活动
    • 第四步:项目总结
    • 第五步:在开源平台上分享你的项目

    1.数据获取

    训练机器学习算法的过程有点像第一次教小孩子一个物体的名字,然后让他们在下次看到它时单独识别它。人类只需要几个例子就可以识别一个新物体。但对于机器来说并非如此,它需要成百上千个类似的例子来熟悉一个对象。而这些示例就是我们想要的数据集。

    要训练机器学习算法,需要获得足够的数据。现在,问题来了,你从哪里收集你想要开展的任何项目的数据?

    你可以从官方来源收集预先存在的数据集,你可以从数据库中导入数据,你可以直接从网页上抓取数据,你可以通过一些社交媒体渠道收集数据,你还可以利用在线表格进行数据收集。还有许多其他来源,你的数据收集方法取决于你的数据科学项目。如果你是第一次从事数据科学项目,请选择你感兴趣的数据集。它可以与运动、电影或音乐有关——任何你感兴趣的东西。在这里我推荐几个我平时获取数据的网站:

    在这里,我选择了一个数据集来练习预测分析。我从 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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    2.选择一个IDE

    工欲善其事,必先利其器

    在有了数据之后,我们下一步考虑使用什么工具来对数据进行处理,建模。选择一个你最熟悉的 IDE。如果你使用 Python语言,这里有几个常见的IDE

    • Pycharm – 它是一个旨在编写 Python 代码的 IDE。它提供了各种生产功能,例如智能代码完成、错误检查和代码修复。它通过提供与版本控制功能的集成,支持 Web 开发以及数据科学,使项目维护变得容易

    • Jupyter Notebook – 它是一个开源 Web 应用程序,允许您创建和共享包含实时代码、可视化的文档。它有助于简化工作并使协作更容易

    • Google Colab – 它允许用户编写和执行 Python 代码。它非常适合机器学习和数据科学项目,因为它免费提供计算资源。你可以在这里轻松运行重型机器学习算法,而不必担心基础设施或成本。

    • 带有 .py 扩展名的简单文本文件 ,尽管上述选项很容易获得并且易于使用,但如果你最喜欢使用记事本编写代码,你可以使用它并使用 .py 扩展名保存文件。然后,你可以使用语法为“python .py”的命令行运行相同的命令。这将执行你的程序,但对于数据科学工作,这可能不是最佳选择,因为你无法即时看到代码或可视化的输出。

    在这里,我选择了 Google Colab 作为工作环境

    获取要使用的数据后,下一步是通过检查数据质量来获得对数据的第一印象。此阶段的主要目标是对数据进行完整性检查,而完成此任务的最佳方法是寻找不可能或极不可能的事情。检查异常值和缺失值,检查数据类型是否正确,并检查最极端的情况。它们有意义吗?一个好的做法是对数据运行一些简单的统计测试并将其可视化,以快速了解数据的统计属性并检测可能的异常值。

    3.列出在数据集要进行的活动

    列出要在数据集上进行的操作,以便在开始之前有一个清晰的路径。我们在数据科学项目中执行的常见操作是

    数据读取、数据清理、数据转换、探索性数据分析、模型构建、模型评估和模型部署。下面简要介绍这些步骤。

    数据读取将数据读入到一个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()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    indexagesexbmichildrensmokerregioncharges
    019female27.90yessouthwest16884.924
    118male33.771nosoutheast1725.5523
    228male33.03nosoutheast4449.462
    333male22.7050nonorthwest21984.47061
    432male28.880nonorthwest3866.8552

    数据清洗:识别和消除数据集中缺失值和异常值

    # 查看缺失值
    health_ins_df.isnull().sum()
    # 可以看出数据集中没有缺失值
    
    • 1
    • 2
    • 3
    age         0
    sex         0
    bmi         0
    children    0
    smoker      0
    region      0
    charges     0
    dtype: int64
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    数据转换——它涉及更改列的数据类型、创建派生列或删除重复数据等等

    探索性数据分析——对数据集执行单变量和多变量分析,以发现其中隐藏的一些关系

    下面我们来对数值和分类变量进行数据清理和探索性数据分析。

    探索性数据分析

    对于数值型变量的分析

    #数值型变量的可视化
    # 直方图绘制
    
    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()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    image-20220817095825845

    • 我们可以把年龄进行分组转换为年龄段

    • 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()
    
    • 1
    • 2
    • 3
    • 4
    • 5

    可以看出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)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    [49.06, 48.07, 47.52, 47.41, 50.38, 47.6, 52.58, 47.74, 53.13]
    bmi 中包含异常值的行数: 9
    bmi离群值异常值的百分比 :  0.672645739910314
    
    • 1
    • 2
    • 3

    数值变量的数据转换

    # 将年龄转换为分桶的
    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'] = '老年'
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    Minimum value for age :  18 
    Maximum value for age :  64
    
    • 1
    • 2
    # 去除BMI中的异常值
    health_ins_df_clean = health_ins_df[~health_ins_df.bmi.isin(outlier_list)]
    sns.boxplot(x = 'bmi', data = health_ins_df_clean)
    
    • 1
    • 2
    • 3

    image-20220817100340013

    对于分类型变量的分析

    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])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    image-20220817101258434

    数据准备完成后,下一阶段是建模。选择合适的算法将取决于数据的类型。例如,如果数据是连续的,您将应用回归建模,如果数据是分类的,您将应用分类算法建模。作为一名数据科学家,您将尝试许多模型来获得最合适的模型。

    模型构建

    在根据业务/技术限制选择正确的模型之前,尝试并测试数据集上所有可能的模型。在这个阶段,你也可以尝试一些 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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    R-Squared on train dataset=0.7494776882061486
    R-Squaredon test dataset=0.7372938495110573
    
    • 1
    • 2

    从结果来看,使用简单的线性回归 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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    R-Squared on train dataset=0.8594291626976573
    R-Squaredon test dataset=0.8571718114547656
    
    • 1
    • 2

    上面的参数是我随机设定,大家还可以对其进行调参能提高一定的效果,调参的代码我上传到github上了https://github.com/JoJoYao996/data-science-projects

    Gradient Boosting Regression

    梯度提升回归模型的主要调整参数

    • learning_rate:学习率,默认为0.1
    • n_estimators:默认为100
    • max_depth:单个回归估计器的最大深度。最大深度限制了树中的节点数。调整此参数以获得最佳性能;最佳值取决于输入变量的相互作用。值必须在 [1, inf) 范围内。
    • min_samples_split:拆分内部节点所需的最小样本数:
    • min_samples_leaf:叶节点最小样本数,这个参数会影响模型的平滑效果,尤其是在回归中。

    我使用了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)))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    Accuracy score (training): 0.866
    Accuracy score (test): 0.818
    
    • 1
    • 2

    查看特征的重要性

    #查看变量的重要性
    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()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    image-20220817165712023
    可以看出最重要的三个特征是:smoker_no,children_5,bmi

    保存模型

    # 保存模型
    filename = 'health_insurance_data_model.sav'
    pickle.dump(f_model, open(filename, 'wb'))
    
    • 1
    • 2
    • 3
    # 加载模型
    filename = 'health_insurance_data_model.sav'
    loaded_model = pickle.load(open(filename, 'rb'))
    result = loaded_model.score(X_test, y_test)
    print(result) #测试集精度
    
    • 1
    • 2
    • 3
    • 4
    • 5
    0.8180114370687565
    
    • 1

    4.准备总结

    总结一份文档,简要说明项目以及完成项目所采取的步骤。尝试总结你设计的业务问题陈述和数据科学解决方案。 同时还可以提及有关该项目的生动细节,以供将来参考。

    您可以使用简单的 word 文档或 powerpoint 演示文稿来准备摘要。它可以有5个部分。在第一部分,简要解释背景和问题。在第二部分中,提及您用于预测分析的数据集是什么以及数据的来源是什么。在第 3 部分提到,您执行的数据清理、数据转换和探索性数据分析是什么?然后,简要提及您尝试和测试过的不同预测模型的概念验证。最后,您可以提及业务问题的最终结果和解决方案。

    这个项目完成后我会准备一个简短的总结

    5.在开源平台上分享

    选择一个你想要发布项目摘要或代码的开源平台,例如github、gitee等,方便与更多的数据科学家沟通交流,不断完善自己的项目。

    篇幅有限,完整代码可以在我的github上面查看,欢迎大家star,fork。

    github地址完整代码

    如果访问不了github的可以私信我获取源码。

  • 相关阅读:
    Html 之 fieldset legend details summary 试验2207281650
    Web开发:Web开发中的域概念整理与解读
    【算法】数组中出现次数超过一半的数字
    使用VS Code 进行.NET 开发
    人工神经网络的算法原理,人工神经网络算法优点
    idea自动添加作者、日期等信息
    ⑨ vuex状态管理
    mysql 8.0 date、datetime time, timestamp的区别
    探讨MySQL存储过程返回记录集
    外贸建站选择用简站wordrpess模板的优势
  • 原文地址:https://blog.csdn.net/weixin_45052363/article/details/126390668