数据科学完整流程概述
数据科学交流群,QQ群号:189158789 ,欢迎各位对数据科学感兴趣的小伙伴的加入!
此文章的目的旨在统一各种分析过程中的术语以及流程,并试图构建更为完整、更为详尽的处理流程,针对不同场景下不同规模的数据集,此框架应该根据实际情况进行适当的裁剪!!!
注意:此版本只是一个粗糙的版本,随着学习的深入,后续可能会不断更新,如果有什么问题,请在评论区留言,或者进入我新建的数据科学群一起讨论!
目录
〇、商业理解(Business Understanding)
本节内容内容照搬CRISP-DM1.0中的内容,不过该阶段更多时候是一个仁者见仁、智者见智的状态,毕竟商业上很多知识都来自于各行业从业者或者管理者们的实践而得,没有一个统一的标准。
更多细节内容可以参照这份文档进行学习:
点击以上链接即可下载!!!
一、数据收集(Data Collection)
1.1.收集方法
关于数据采集的方式和方法,可以参照我之前写的一篇文档:
常用的数据采集方法有哪些? - PurStar - 博客园
https://www.cnblogs.com/purstar/p/14224062.html
2.2.原始数据收集报告
可以在收集数据的时候写出一份原始数据收集报告,大概内容如下:
列出获得的数据集(或多个数据集),包括它们在项目中的位置,获得的方法及遇到的问题。记录遇到的问题和解决方案有助于迁移到将来项目或者推进类似项目。 ……
二、数据理解(Data Understanding)
2.1.数据描述
描述数据可以采用如下相关的一些概念,当然根据实际情况,可能还有其他更多数据的属性可以用作描述:
数据来源(一手数据、二手数据)
数据存储(文件系统、数据库、云存储……)
数据格式(CSV、TXT、PDF、……)
数据字符编码(ASCII、UTF-8、GBK 和 GB2312、Unicode、……)
数据规模(数据规模的大小可能会决定后面数据处理或分析的工具):
- 单表行数
- 单表列数
- 多表之间的关系
- 整体所占空间的大小
数据结构类型:结构化、半结构化、非结构化(一般流程是将半结构化或者非结构化的数据转换为结构化数据再进行处理,详细概念可以参考这篇内容 数据类型的多样性:结构化数据、半结构化数据、非结构化数据 - PurStar - 博客园)
数据粒度:细化程度越高,粒度越小;细化程度越低,粒度越大。例如具体城市比省份或者国家更精细等等……
数据的精确含义:查看列或者行所代表的含义,一般数据比较大的情况下,会查看前几行或后几行等等,如果有数据字典那就更好了!
数据字典:数据字典是指对数据的数据项、数据结构、数据流、数据存储、处理逻辑等进行定义和描述。
变量类型:
- 名义变量:统计学术语,是以货币单位为基准的变量。
- 实际变量:实际变量不包含价格变动因素,名义的包含;把名义变量剔除价格变动因素就是实际变量 。
- 定量数据:定量数据本质上是数值,应该是衡量某样东西的数量。
- 定性数据:定性数据本质上是类别,应该是描述某样东西的性质。
- 定类变量:又称“定类尺度”。根据定性的原则区分总体各个案类别的变量。
- 定序变量:定序变量是变量的一种,区别同一类别个案中等级次序的变量。
- 定距变量:定距变量也称间距变量,是取值具有"距离”特征的变量。
- 定比变量:定比变量又称“定比尺度”或“比率尺度”。区别同一类别个案中等级次序及其距离的变量。
数据等级的总结:
下表总结里 每个等级上可行与不可行的操作:
下表展示了每个等级上可行与不可行的统计类型:
下表显示了每个等级上可以或不可以绘制的图表:
当你拿到一个新的数据集时,下面是针对变量理解和处理的基工作流程:
(1)数据有没有组织?数据是以表格形式存在、有不同的行列,还是以非结构化的文本格式存在?
(2)每列的数据是定量的还是定性的?单元格中的数代表的是数值还是字符串?
(3)每列处于哪个等级?是定类、定序、定距,还是定比?
(4)我们可以用什么图表?条形图、饼图、茎叶图、箱型图、直方图,还是其他?
下图是对以上逻辑的可视化:
冗余变量:一般指重复或者多余的变量
完整性:取值范围、取值的一致性、异常值、整体完整性
缺省值、默认值:指一个属性、参数在被修改前的初始值。
关键字:
- 公共关键字:公共关键字指的是在关系数据库中,关系之间的联系是通过相容或相同的属性或属性组来表示的。
- 外关键字:如果公共关键字在一个关系中是主关键字,那么这个公共关键字被称为另一个关系的外关键字。
- 侯选关键字:如果一个超关键字去掉其中任何一个字段后不再能唯一地确定记录,则称它为“候选关键字”(Candidate Key)。
- 主关键字:关键字(primary key)是表中的一个或多个字段,它的值用于唯一的标识表中的某一条记录。
……
2.2.探索性数据分析(EDA)
2.2.1.CDA与EDA的区别
传统的多元分析方法采用的是“假定—模拟—检验”的证实性数据分析策略(confirmatory data analysis,CDA),即首先需要假设数据总体服从某种分布(如正态分布)。然而,在实际问题中有许多数据并不满足这一前提假设,因而需要使用稳健的或非参数的方法去解决。但是,但数据维数很高时,这些方法都将面临一些困难。
为了克服CDA这种分析策略所具有的一些困难,需要对数据不做假设或者只做很少的假设,进而“直观审视数据——通过计算机模拟数据结构——检验”这样一种探索性数据分析策略(exploratory data analysis,EDA)。
探索性数据分析是在尽量少的先验假定下对数据进行处理,通过作图、制表等形式以及方程拟合、计算某些特征量等手段,探索数据的结构和规律的一种数据分析方法。与证实性数据分析相比,探索性数据分析具有如下特点:
(1)研究从原始数据人手,完全以实际数据为依据,而不必对数据的分布进行假设。
(2)分析方法从实际出发,不以某种理论为依据。探索性数据分析在寻求数据内在的数量特征、数量关系和数量变化时,什么方法可以达到这一目的就采用什么方法,方法的选择完全取决于数据的特点和研究目的。
(3)分析工具简单直观,更易于普及。探索性数据分析强调直观及数据可视化,使分析者能一日了然地看出数据中隐含的有价值的信息,显示出其遵循的普遍规律及与众不同的突出特点,促进发现规律,得到启迪,满足分析者的多方而要求,这也是探索性数据分析策略对于数据分析工作的主要贡献。
2.2.2.基本统计分析
1.描述统计分析
1)描述集中趋势的指标:
常用的有算术均数(mean)、几何均数(geometric mean)和中位数(median)等
其中算术均数适用于正态分布和对称分布的资料;
几何均数适用于经对数转换后呈对称分布的资料,它不能用本章讲解的模块直接求出;
中位数适用于各种分布类型的资料,尤其是偏态分布资料和一端或两端无确切数值的资料。
2) 描述离散趋势的指标:
常用的有极差(range)、四分位数间距(quartile range)、方差(variance)、标准差(standard deviation)等。
极差反映一组变量值最大值和最小值之差;
四分位数间距一般和中位数一起描述偏态分布资料的分布特征;
方差和标准差只适合于正态分布的资料。
3)百分位数指标(Percentile):
是一种位置指标,适合于各种分布类型的资料。
4)描述数据分布的统计量(Distribution):
偏度系数、峰度系数。用来说明数据偏离正态分布的程度。
2.频数分析
1)频数表:频数表是数理统计中由于所观测的数据较多,为简化计算,将这些数据按等间隔分组,然后按选举唱票法数出落在每个组内观测值的个数,称为(组)频数。
2)列联表:列联表(contingency table)是观测数据按两个或更多属性(定性变量)分类时所列出的频数表。它是由两个以上的变量进行交叉分类的频数分布表。
3)独立性检验
①卡方检验。检验多个总体比率的相等性、检验两个分类变量的独立性、检验一个总体的概率分布是否服从一个历史概率分布。
②Fisher精确检验,原假设:边界固定的列联表中行和列是相互独立的,不能用于2*2列联表。
③CMH检验的原假设是两个名义变量在第三个变量的每一层中都是条件独立的。
3、相关
在完成独立性检验后,如果拒绝原假设,那么两变量之间的相关性如何?使用assocstats总体来说,较大的值意味着强的相关性。
- 相关系数:相关系数是最早由统计学家卡尔·皮尔逊设计的统计指标,是研究变量之间线性相关程度的量,一般用字母 r 表示。由于研究对象的不同,相关系数有多种定义方式,较为常用的是皮尔逊相关系数。
- 协方差:协方差(Covariance)在概率论和统计学中用于衡量两个变量的总体误差。而方差是协方差的一种特殊情况,即当两个变量是相同的情况。
- 偏相关系数:亦称“净相关”、“纯相关”、“条件相关”。偏相关系数不为零的两个随机变量称做偏相关(参见“偏相关系数”)。偏相关性,是两个随机变量在排除了其余部分或全部随机变量影响情形下的净相关性或纯相关性,是两个随机变量在处于同一体系的其余部分或全部随机变量取给定值的情形下的条件相关性。偏相关分析的主要作用在于,在所有的自变量中,判断哪些自变量对因变量的影响较大,从而选择作为必需的自变量。
4.T检验:
在探究中,我们最常见的行为是对两组进行比较,如果结果变量是类别型的就使用前面学过的相关性的显著性检验进行检验,如果是连续型的并且假设其称正态分布,使用t检验。
5.组间差异的非参数检验
①两组的比较
Wilcoxon秩和检验是依据两总体中位数之差的一种非参数方法,还有一种是符号检验。目的是通过中位数比较两组是否相同。
②多于两组的比较
如果没有满足方差设计的假设,Kruskal是一种在各组独立的情况下的方式,Friedman是在各组不独立时的方式。也是通过中位数进行检验。
通过以上检验虽然可以拒绝原假设,但检验并没有告诉你哪些地区显著的与其他地区不同。使用U检验可以对两组间进行比较。
③组间差异的可视化
箱线图和核密度图
2.2.3.模式发现
降维——线性方法:
- 主成分分析——PCA
- 奇异值分解——SVD
- 非负矩阵分解
- Fisher线性判别
- 本征维数
- 最近邻法
- 关联维数
- 最大似然估计
- 包数估计
降维——非线性方法:
- 多维尺度分析——MDS
- 度量MDS
- 非度量MDS
- 流形学习
- 局部线性嵌入
- 等距特征映射
- 海赛特征映射
- 人工神经网络方法
- 自组织映射
- 生成式拓扑映射
- 曲元分析
数据巡查
- 总体巡查法
- 插值巡查法
- 投影追踪法
- 独立成分分析
发现类——各种聚类技术……
平滑散点图
……
2.2.4.数据可视化
最有价值的图表系列
深度好文 | Matplotlib可视化最有价值的 50 个图表(附完整 Python 源代码)
http://liyangbit.com/pythonvisualization/matplotlib-top-50-visualizations/
聚类可视化:
- 树状图
- 树图
- 矩形图
- ReClus图
- 数据图像
分布图形:
- 直方图(一元、二元、……)
- 箱线图
- 分位数图
- 概率图
- q-q图
- 分位数图
- 袋状图
- 测距仪箱线图
多元可视化:
- 象形图
- 散点图
- 动态图
- 协同图
- 点阵图
- 绘点为线
- 数据巡查
- 双标图
2.3.数据质量评价
说明:
- 规范性——数据符合数据标准、数据模型、业务规则、无数据或权威参考数据的程度。
- 完整性——按照数据规则要求,数据元素被赋予数值的程度。
- 准确性——数据准确表示其所描述的其实实体(实际对象)真实值的程度。
- 一致性——数据与其他特定上下文中使用的数据无矛盾的程度。
- 时效性——数据在时间变化中的正确程度。
- 可访问性—— 数据能被访问的程度。
更为详细的内容请参考国家标准:
三、数据准备(Data preparation)、数据预处理
3.1.选择数据、数据抽取:
总体与样本:
对总体进行逐个数据采样或记录动态过程中的每一个阶段,在大多数时候是不可能的或不合实际的。正如:
- 研究海豚交流方式的海洋生物学家不可能测试每一只海豚
- 制造商要想知道一种建筑材料在室外降解的速度有多快
他们不能因为测试而抓获所有生物或者摧毁所有产品。
由于海量数据库和功能强大的软件的帮助,金融分析师往追踪特定股票的未来表现时,可以分析某只股票过去的每一手交易,但是他们无法对还未发生的交易进行研究。
数据的代表性
如果我们想通过一个项目对总体或全过程做概括性总结,对样本的代表性作出合理的预期是十分关键的。无论何时,当我们依赖样本信息时,都冒着样本可能无法代表总体的风险(一般来说,我们称为抽样误差)。
统计学家对抽样样本有一些标准方法,但没有一种方法可以保证某一样本可以准确代表总体,仅有一些方法可以相对减小发生抽样误差的风险。此外,某些方法可以预测抽样误差。
如果我们能够预测风险的范围,那么我们就可以从样本中概括总体。反之,则不能!
抽样技术:
概率抽样的类型
- 简单随机抽样
- 系统抽样
- 分层抽样
- 整群抽样
非概率抽样的类型
- 简单抽样
- 配额抽样
- 判断抽样
- 雪球采样
3.2.数据清洗、数据清理:
数据清洗是指发现并纠正数据文件中可识别的错误的一道程序,包括检查数据一致性,处理无效值和缺失值等。与问卷审核不同,录入后的数据清理一般是由计算机而不是人工完成。
需要着重处理以下类型的数据:
- 重复值
- 遗漏值或空值
- 噪音数据(错误值或异常值)
- 不一致数据
3.3.构造数据、数据派生:
该任务包括构造性的数据准备操作,如派生属性、全新记录的生成、或现有属性的值转换。
1)属性派生(Derived attributes ):
派生属性或者数据是在原有属性和数据的基础上构建出来的。例如: area=length*width。
2)单一属性转化(Single-attribute transformations )
有时把区间值转换成离散字段(例,年龄到年龄段),有时离散字段(如, “绝对正确”, “正确”, “不知道”, “错误” )转换成数值型。这取决于建模工具或算法的要求。
3)生成新纪录:
生成的记录是全新的记录,它引入了新知识或表示了还没有表示过的数据,例如,已聚类的数据有助于生成一条记录来表示聚类的成员模板,以做进一步的处理。
3.4.整合数据、数据集成:
在企业中,由于开发时间或开发部门的不同,往往有多个异构的、运行在不同的软硬件平台上的信息系统同时运行,这些系统的数据源彼此独立、相互封闭,使得数据难以在系统之间交流、共享和融合,从而形成了"信息孤岛"。随着信息化应用的不断深入,企业内部、企业与外部信息交互的需求日益强烈,急切需要对已有的信息进行整合,联通“信息孤岛”,共享信息。
数据集成:数据集成通过应用间的数据交换从而达到集成,主要解决数据的分布性和异构性的问题,其前提是被集成应用必须公开数据结构,即必须公开表结构,表间关系,编码的含义等。
实体识别:
实体就是名词,也就是说人名、地名、物名都是实体。在计算机领域进行实体识别是一个大活,好在我们并不想弄明白里面的机理,因而只需要清楚在数据清洗的过程中我们需要怎么对待实体即可。
例如,数据分析者或计算机如何才能确信一个数据库中的 customer_id 和另一个数据库中的 cust_number 指的是同一实体?通常,数据库和数据仓库有元数据——关于数据的数据。这种元数据可以帮助避免模式集成中的错误。
大致说来,我们需要在数据清洗的时候把两个本来不是同一个东西的实体区别开,也需要把本来是一个东西的实体对的上。大致工作有如下几项:
-
同名异义:例如苹果既可以代表手机也可以代表水果。再譬如姓名王伟是一个很普通的名字,但是它却表示不同的实体。
-
异名同义:例如我们的团队中有个“涛哥”,名字叫做“张涛”,很多场合下我们得知道这是一个人。又譬如“李白”和“李太白”指的就是一个人。又譬如我们会习惯性的给某个人加上职位性的称谓,譬如说“陈主任”、“王博士”、“周院长”等等。我们需要能够将这些称谓与之真姓名对应起来。
-
单位统一:用于描述同一个实体的属性有的时候可能会出现单位不统一的情况,也需要能够统一起来,譬如1200cm与1.2m,要知道计算机在进行处理的时候是没有量纲的,要么统一量纲,要么去量纲化(归一化)。
-
ID-Mapping:ID-Mapping实际上是一个互联网领域的术语,意思是将不同数据库或者帐号系统中的人对应起来。譬如说你办了中国移动的手机卡,他们就会知道你用的是某个手机号,而如果你使用今日头条你就会留下各种浏览新闻的痕迹,如果现在中国移动要和今日头条合作,那么就得打通两边的数据,“打通”的第一步就是知道中国移动的张三就是今日头条的张三,这个过程在当下可以通过设备的IMIS号码进行比照进行,其他的ID-Mapping需要采取不同的策略。归根到底,ID-Mapping需要的是采用唯一识别号(学号,学校-年级-班级-姓名,设备号等)进行帐号的用户匹配。这在大数据强调的数据孤岛问题解决上有着重要的意义。
数据冗余:
数据冗余可能来源于数据属性命名的不一致,在解决数据冗余的过程中对于数值属性可以利用皮尔逊积矩Ra,b来衡量,它是一个位于[-1,1]之间的数值,大于零那么属性之间呈现正相关,否则为反相关。绝对值越大表明两者之间相关性越强。对于离散数据可以利用卡方检验来检测两个属性之间的关联。
冗余可以被相关分析检测到。例如,给定两个属性,根据可用的数据,这种分析可以度量一个属性能在多大程度上蕴涵另一个。对于标称数据,我们使用卡方检验。对于数值属性,我们使用相关系数和协方差,它们都评估一个属性的值如何随另一个变化。
数据冲突:
成的第三个重要问题是数据值冲突的检测与处理。例如,对于现实世界的同一实体,来自不同数据源的属性值可能不同。这可能是因为表示、比例或编码不同。例如,重量属性可能在一个系统中以公制单位存放,而在另一个系统中以英制单位存放。不同旅馆的价格不仅可能涉及不同的货币,而且可能涉及不同的服务(如免费早餐)和税。数据这种语义上的异种性,是数据集成的巨大挑战。
仔细将多个数据源中的数据集成起来,能够减少或避免结果数据集中数据的冗余和不一致性。这有助于提高其后挖掘的精度和速度。
3.5.数据变换:
1)平滑:
去掉数据中的噪音。这种技术包括
- 分箱:分箱方法通过考察“邻居”(即,周围的值)来平滑存储数据的值。存储的值被分布到一些“桶”或箱中。由于分箱方法导致值相邻,因此它进行局部平滑。
- 聚类:局外者可以被聚类检测。聚类将类似的值组织成群或“聚类”。直观地,落在聚类集合之外的值被视为局外者。
- 回归:可以通过让数据适合一个函数(如回归函数)来平滑数据。线性回归涉及找出适合两个变量的“最佳”直线,使得一个变量能够预测另一个。
2)聚集(颗粒度转化):
对数据进行汇总和聚集。例如,可以聚集日销售数据,计算月和年销售额。通常,这一步用来为多粒度数据分析构造数据方。
3)数据泛化:
使用概念分层,用高层次概念替换低层次“原始”数据。例如,分类的属性,如 street,可以泛化为较高层的概念,如 city 或 country。类似地,数值属性,如 age,可以映射到较高层
概念,如 young, middle-age 和 senior。
4)规范化:
将属性数据按比例缩放,使之落入一个小的特定区间,如-1.0 到 1.0 或 0.0 到 1.0。
- 最小-最大规范化
- z-score 规范化
- 按小数定标规范化
5)属性构造(或特征构造):
可以构造新的属性并添加到属性集中,以帮助挖掘过程。
属性构造是由给定的属性构造和添加新的属性,以帮助提高精度和对高维数据结构的理解。例如,我们可能根据属性 height 和 width 添加属性 area。属性结构可以帮助平缓使用判定树算法分类的分裂问题。那里,沿着导出判定树9的一条路径重复地测试一个属性。属性构造操作符的例子包括二进位属性的 and 和名字属性的 product。通过组合属性,属性构造可以发现关于数据属性间联系
的丢失信息,这对知识发现是有用的。
6)格式化
如改变数据排列顺序或次序
3.6.数据规约:
1. 数据方聚集: 聚集操作用于数据方中的数据。
2. 维归约:可以检测并删除不相关、弱相关或冗余的属性或维。
3. 数据压缩: 使用编码机制压缩数据集。
在数据压缩时,应用数据编码或变换,以便得到原数据的归约或“压缩”表示。如果原数据可以由压缩数据重新构造而不丢失任何信息,则所使用的数据压缩技术是无损的。如果我们只能重新构造原数据的近似表示,则该数据压缩技术是有损的。有一些很好的串压缩算法。尽管它们是无损的,但它们只允许有限的数据操作。
两种有效的有损数据压缩方法:
- 离散小波变换(DWT)
- 主要成分分析(PCA)
4. 数值压缩: 用替代的、较小的数据表示替换或估计数据,如参数模型(只需要存放模型参数,而不是实际数据)或非参数方法,如聚类、选样和使用直方图。
5. 离散化和概念分层产生: 属性的原始值用区间值或较高层的概念替换。概念分层允许挖掘多个抽象层上的数据,是数据挖掘的一种强有力的工具。
四、特征工程(feature engineering)
4.1.特征构建、特征创建
- 填充分类特征
- 编码分类变量
- 扩展数值特征
4.2.特征提取、特征抽取
- 针对文本特征的提取
- 词袋法
- CountVectorizer
- TF-IDF向量化器
- 针对图像特征的提取
4.3.特征选择
特征太少,不足以描述数据,造成偏差过高;特征太多,一是增大计算成本,二是造成维度灾难(方差过高导致过拟合)。
爱因斯坦:“尽量让事情简单,但不能过于简单。”机器学习算法性能的上限,取决于特征的选择。
特征选择技术可以精简掉无用的特征,以降低最终模型的复杂性,它的最终目的是得到一个简约模型,在不降低预测准确率或对预测准确率影响不大的情况下提高计算速度。
为了得到这样的模型,有些特征选择技术需要训练不止一个待选模型。换言之,特征选择不是为了减少训练时间(实际上,一些技术会增加总体训练时间),而是为了减少模型评分时间。
粗略地说,特征选择技术可以分为以下三类。
1)过滤器法、Filter
过滤技术对特征进行预处理,以除去那些不太可能对模型有用处的特征。例如,我们可以计算出每个特征与响应变量之间的相关性或互信息,然后过滤掉那些在某个阈值之下的特征。过滤技术的成本比下面描述的打包技术低廉得多,但它们没有考虑我们要使用的模型,因此,它们有可能无法为模型选择出正确的特征。我们最好谨慎地使用预过滤技术,以免在有用特征进入到模型训练阶段之前不经意地将其删除。
2)打包方法、封装器法、Wrapper
这些技术的成本非常高昂,但它们可以试验特征的各个子集,这意味着我们不会意外地删除那些本身不提供什么信息但和其他特征组合起来却非常有用的特征。打包方法将模型视为一个能对推荐的特征子集给出合理评分的黑盒子。它们使用另外一种方法迭代地对特征子集进行优化。
3)嵌入式方法、Embedded
这种方法将特征选择作为模型训练过程的一部分。例如,特征选择是决策树与生俱来的一种功能,因为它在每个训练阶段都要选择一个特征来对树进行分割。另一个例子是ℓ1 正则项,它可以添加到任意线性模型的训练目标中。 ℓ1 正则项鼓励模型使用更少的特征,而不是更多的特征,所以又称为模型的稀疏性约束。嵌入式方法将特征选择整合为模型训练过程的一部分。它们不如打包方法强大,但成本也远不如打包方法那么高。与过滤技术相比,嵌入式方法可以选择出特别适合某种模型的特征。从这个意义上说,嵌入式方法在计算成本和结果质量之间实现了某种平衡。
4.4.特征变换、特征转换
- 主成分分析PCA
- 线性判别分析LDA
4.5.特征学习-以AI促AI
- 受限玻尔兹曼机 RBM
- 伯努利受限玻尔兹曼机BernoulliRBM
- 学习文本特征:
- Word2vec
- GloVe
五、建模(Modeling)
5.1.选择建模技术
自己生成了一张思维导图:
点击即可下载
5.2.生成测试设计
略,可参照
点击以上链接即可下载!!!
5.3.建立模型
略,可参照
点击以上链接即可下载!!
5.4.评估模型
略,可参照
点击以上链接即可下载!!
六、评价(Evaluation)
略,可参照
点击以上链接即可下载!!
七、部署(Deployment)
略,可参照
点击以上链接即可下载!!
数据科学交流群,QQ群号:189158789 ,欢迎各位对数据科学感兴趣的小伙伴的加入!
深信积累的力量,时间就是你最好的朋友,否则它就是你最大的敌人。
如果你想分享此文章,请注明:作者:PurStar 出处:www.cnblogs.com/purstar