-
撤销(Ctrl+Z)
-
重做(Ctrl+Y)
-
清空
-
H
标题(Ctrl+1~6)
- 一级标题
- 二级标题
- 三级标题
- 四级标题
- 五级标题
- 六级标题
-
粗体(Ctrl+B)
-
斜体(Ctrl+I)
-
删除线
-
插入引用(Ctrl+Q)
-
无序列表(Ctrl+U)
-
有序列表(Ctrl+O)
-
表格
-
插入分割线
-
插入链接(Ctrl+L)
-
插入图片
- 添加图片链接
-
插入代码块
-
保存(Ctrl+S)
-
开启预览
-
开启目录导航
-
关闭同步滚动
-
全屏(按ESC还原)
#### MAS 方法 * Multi-Dimension:想要掌握一个事物,就要从多个角度去认识它。 * Ask:不懂就问,程序员大多都很羞涩,突破这一点,不懂就问最重要。 * Sharing:最好的学习就是分享。用自己的语言讲出来,是对知识的进一步梳理。 #### 数据分析的组成 ![](https://upload-images.jianshu.io/upload_images/21643577-60c9d29e8441c40f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/600) * 数据采集。它是我们的原材料,也是最“接地气”的部分,因为任何分析都要有数据源。 ![](https://upload-images.jianshu.io/upload_images/21643577-dad404622e289c4c.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/600) * 数据挖掘。它可以说是最“高大上”的部分,也是整个商业价值所在。之所以要进行数据分析,就是要找到其中的规律,来指导我们的业务。因此数据挖掘的核心是挖掘数据的商业价值,也就是我们所谈的商业智能 BI。 ![](https://upload-images.jianshu.io/upload_images/21643577-681929369345a300.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/600) * 数据可视化。它可以说是数据领域中万金油的技能,可以让我们直观地了解到数据分析的结果。 1. 第一种就是使用 Python。在 Python 对数据进行清洗、挖掘的过程中,我们可以使用 Matplotlib、Seaborn 等第三方库进行呈现。 1. 第二种就是使用第三方工具。如果你已经生成了 csv 格式文件,想要采用所见即所得的方式进行呈现,可以采用微图、DataV、Data GIF Maker 等第三方工具,它们可以很方便地对数据进行处理,还可以帮你制作呈现的效果。 ![](https://upload-images.jianshu.io/upload_images/21643577-98d4d9198f926d5c.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/600) #### 数据挖掘的基本流程 * 商业理解:数据挖掘不是我们的目的,我们的目的是更好地帮助业务,所以第一步我们要从商业的角度理解项目需求,在这个基础上,再对数据挖掘的目标进行定义。 * 数据理解:尝试收集部分数据,然后对数据进行探索,包括数据描述、数据质量验证等。这有助于你对收集的数据有个初步的认知。 * 数据准备:开始收集数据,并对数据进行清洗、数据集成等操作,完成数据挖掘前的准备工作。 * 模型建立:选择和应用各种数据挖掘模型,并进行优化,以便得到更好的分类结果。 * 模型评估:对模型进行评价,并检查构建模型的每个步骤,确认模型是否实现了预定的商业目标。 * 上线发布:模型的作用是从数据中找到金矿,也就是我们所说的“知识”,获得的知识需要转化成用户可以使用的方式,呈现的形式可以是一份报告,也可以是实现一个比较复杂的、可重复的数据挖掘过程。数据挖掘结果如果是日常运营的一部分,那么后续的监控和维护就会变得重要。 ![](https://upload-images.jianshu.io/upload_images/21643577-e645c26003433456.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/600) #### 商业智能 BI、数据仓库 DW、数据挖掘 DM 三者之间的关系 * 商业智能的英文是 Business Intelligence,缩写是 BI。相比于数据仓库、数据挖掘,它是一个更大的概念。商业智能可以说是基于数据仓库,经过了数据挖掘后,得到了商业价值的过程。所以说数据仓库是个金矿,数据挖掘是炼金术,而商业报告则是黄金。 * 数据仓库的英文是 Data Warehouse,缩写是 DW。它可以说是 BI 这个房子的地基,搭建好 DW 这个地基之后,才能进行分析使用,最后产生价值。 数据仓库将原有的多个数据来源中的数据进行汇总、整理而得。数据进入数据仓库前,必须消除数据中的不一致性,方便后续进行数据分析和挖掘。 * 数据挖掘的英文是 Data Mining,缩写是 DM。在商业智能 BI 中经常会使用到数据挖掘技术。数据挖掘的核心包括分类、聚类、预测、关联分析等任务,通过这些炼金术,我们可以从数据仓库中得到宝藏,比如商业报告。 #### 元数据 VS 数据元 * 元数据(MetaData):描述其它数据的数据,也称为“中介数据”。 * 数据元(Data Element):就是最小数据单元。 #### 数据挖掘的流程 * 数据挖掘的一个英文解释叫 Knowledge Discovery in Database,简称 KDD,也就是数据库中的知识发现。 1. 分类 就是通过训练集得到一个分类模型,然后用这个模型可以对其他数据进行分类。 这里需要说明下训练集和测试集的概念。一般来说数据可以划分为训练集和测试集。训练集是用来给机器做训练的,通常是人们整理好训练数据,以及这些数据对应的分类标识。通过训练,机器就产生了自我分类的模型,然后机器就可以拿着这个分类模型,对测试集中的数据进行分类预测。同样如果测试集中,人们已经给出了测试结果,我们就可以用测试结果来做验证,从而了解分类器在测试环境下的表现。 2. 聚类 人以群分,物以类聚。聚类就是将数据自动聚类成几个类别,聚到一起的相似度大,不在一起的差异性大。我们往往利用聚类来做数据划分。 3. 预测 顾名思义,就是通过当前和历史数据来预测未来趋势,它可以更好地帮助我们识别机遇和风险。 4. 关联分析 就是发现数据中的关联规则,它被广泛应用在购物篮分析,或事务数据分析中。比如我们开头提到的那个案例。 ![](https://upload-images.jianshu.io/upload_images/21643577-0b7b47c82187e3b2.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/600) ###### 数据预处理 1. 数据清洗 主要是为了去除重复数据,去噪声(即干扰数据)以及填充缺失值。 2. 数据集成 是将多个数据源中的数据存放在一个统一的数据存储中。 3. 数据变换 就是将数据转换成适合数据挖掘的形式。比如,通过归一化将属性数据按照比例缩放,这样就可以将数值落入一个特定的区间内,比如 0~1 之间。 #### 用户画像 ![](https://upload-images.jianshu.io/upload_images/21643577-b4a0ef7b54f84c9a.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/600) ###### 第一步,统一化 * 用户唯一标识是整个用户画像的核心。 ###### 第二步,标签化 * 给用户打标签。用户消费行为分析 * 用户标签:它包括了性别、年龄、地域、收入、学历、职业等。这些包括了用户的基础属性。 * 消费标签:消费习惯、购买意向、是否对促销敏感。这些统计分析用户的消费习惯。 * 行为标签:时间段、频次、时长、访问路径。这些是通过分析用户行为,来得到他们使用 App 的习惯。 * 内容分析:对用户平时浏览的内容,尤其是停留时间长、浏览次数多的内容进行分析,分析出用户对哪些内容感兴趣,比如,金融、娱乐、教育、体育、时尚、科技等。 ###### 第三步,业务化 1. 获客:如何进行拉新,通过更精准的营销获取客户。 1. 粘客:个性化推荐,搜索排序,场景运营等。 1. 留客:流失率预测,分析关键节点降低流失率。 * 按照数据流处理的阶段来划分用户画像建模的过程 1. 数据层指的是用户消费行为里的标签。我们可以打上“事实标签”,作为数据客观的记录。 1. 算法层指的是透过这些行为算出的用户建模。我们可以打上“模型标签”,作为用户画像的分类标识。 1. 业务层指的是获客、粘客、留客的手段。我们可以打上“预测标签”,作为业务关联的结果。 * 在获客上,我们可以找到优势的宣传渠道,如何通过个性化的宣传手段,吸引有潜在需求的用户,并刺激其转化。 * 在粘客上,如何提升用户的单价和消费频次,方法可以包括购买后的个性化推荐、针对优质用户进行优质高价商品的推荐、以及重复购买,比如通过红包、优惠等方式激励对优惠敏感的人群,提升购买频次。 * 在留客上,预测用户是否可能会从平台上流失。在营销领域,关于用户留存有一个观点——如果将顾客流失率降低 5%,公司利润将提升 25%~85%。可以看出留存率是多么的重要。用户流失可能会包括多种情况,比如用户体验、竞争对手、需求变化等,通过预测用户的流失率可以大幅降低用户留存的运营成本。 * **我们的最终目的不是处理这些数据,而是理解、使用这些数据挖掘的结果。** #### 数据采集 * 开放数据源,一般是针对行业的数据库。比如美国人口调查局开放了美国的人口信息、地区分布和教育情况数据。除了政府外,企业和高校也会开放相应的大数据,这方面北美相对来说做得好一些。国内,贵州做了不少大胆尝试,搭建了云平台,逐年开放了旅游、交通、商务等领域的数据量。 * 爬虫抓取,一般是针对特定的网站或 App。如果我们想要抓取指定的网站数据,比如购物网站上的购物评价等,就需要我们做特定的爬虫抓取。 * 传感器,它基本上采集的是物理信息。比如图像、视频、或者某个物体的速度、热度、压强等。 * 日志采集,这个是统计用户的操作。我们可以在前端进行埋点,在后端进行脚本收集、统计,来分析网站的访问情况,以及使用瓶颈等。 ###### 抓取工具 * **[火车采集器](http://www.locoy.com/)** * **[八爪鱼](http://www.bazhuayu.com/)** * **[集搜客](http://www.gooseeker.com/)** ###### 日志采集的形式。 1. 通过 Web 服务器采集,例如 httpd、Nginx、Tomcat 都自带日志记录功能。同时很多互联网企业都有自己的海量数据采集工具,多用于系统日志采集,如 Hadoop 的 Chukwa、Cloudera 的 Flume、Facebook 的 Scribe 等,这些工具均采用分布式架构,能够满足每秒数百 MB 的日志数据采集和传输需求。 2. 自定义采集用户行为,例如用 JavaScript 代码监听用户的行为、AJAX 异步请求后台记录日志等。 ###### 埋点 * 埋点是日志采集的关键步骤 * 埋点就是在有需要的位置采集相应的信息,进行上报。比如某页面的访问情况,包括用户信息、设备信息;或者用户在页面上的操作行为,包括时间长短等。这就是埋点,每一个埋点就像一台摄像头,采集用户行为数据,将数据进行多维度的交叉分析,可真实还原出用户使用场景,和用户使用需求。 #### 数据清洗规则:“完全合一” ##### 完整性: * 单条数据是否存在空值,统计的字段是否完善。 ###### 问题 1:缺失值缺失值 * 删除:删除数据缺失的记录; * 均值:使用当前列的均值; * 高频:使用当前列出现频率最高的数据。 ``` # 填充平均值 df['Age'].fillna(df['Age'].mean(), inplace=True) # 填充高频值 age_maxf = train_features['Age'].value_counts().index[0] train_features['Age'].fillna(age_maxf, inplace=True) ``` ###### 问题 2:空行 ``` # 删除全空的行 df.dropna(how='all',inplace=True) ``` ##### 全面性 * 观察某一列的全部数值,比如在 Excel 表中,我们选中一列,可以看到该列的平均值、最大值、最小值。我们可以通过常识来判断该列是否有问题,比如:数据定义、单位标识、数值本身。 ###### 问题:列数据的单位不统一 ##### 合法性 * 数据的类型、内容、大小的合法性。比如数据中存在非 ASCII 字符,性别存在了未知,年龄超过了 150 岁等。 ###### 问题:非 ASCII 字符 ``` # 删除非 ASCII 字符 df['first_name'].replace({r'[^\x00-\x7F]+':''}, regex=True, inplace=True) df['last_name'].replace({r'[^\x00-\x7F]+':''}, regex=True, inplace=True) ``` ##### 唯一性 * 数据是否存在重复记录,因为数据通常来自不同渠道的汇总,重复的情况是常见的。行数据、列数据都需要是唯一的,比如一个人不能重复记录多次,且一个人的体重也不能在列指标中重复记录多次。 ###### 问题 1:一列有多个参数 ``` # 切分名字,删除源数据列 df[['first_name','last_name']] = df['name'].str.split(expand=True) df.drop('name', axis=1, inplace=True) ``` ###### 问题 2:重复数据 ``` # 删除重复数据行 df.drop_duplicates(['first_name','last_name'],inplace=True) ``` #### 数据集成的两种架构:ELT 和 ETL ![](https://upload-images.jianshu.io/upload_images/21643577-b311e9f898ccaa23.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/600) #### 决策树的工作原理 ###### 构造 * 构造的过程就是选择什么属性作为节点的过程,那么在构造过程中,会存在三种节点: 1. 根节点:就是树的最顶端,最开始的那个节点。在上图中,“天气”就是一个根节点; 1. 内部节点:就是树中间的那些节点,比如说“温度”、“湿度”、“刮风”; 1. 叶节点:就是树最底部的节点,也就是决策结果。 * 那么在构造过程中,你要解决三个重要的问题: 1. 选择哪个属性作为根节点; 1. 选择哪些属性作为子节点; 1. 什么时候停止并得到目标状态,即叶节点。 ###### 剪枝 * **剪枝**:就是给决策树瘦身,这一步想实现的目标就是,不需要太多的判断,同样可以得到不错的结果。之所以这么做,是为了防止“过拟合”(Overfitting)现象的发生。 * **过拟合**:模型的训练结果“太好了”,以至于在实际应用的过程中,会存在“死板”的情况,导致分类错误。造成过拟合的原因之一就是因为训练集中样本量较小。 * **欠拟合**:模型拟合程度不高,数据距离拟合曲线较远。 * **泛化能力**:指的分类器是通过训练集抽象出来的分类能力,你也可以理解是举一反三的能力。如果我们太依赖于训练集的数据,那么得到的决策树容错率就会比较低,泛化能力差。因为训练集只是全部数据的抽样,并不能体现全部数据的特点。 * **预剪枝Pre-Pruning**:是在决策树构造时就进行剪枝。方法是在构造的过程中对节点进行评估,如果对某个节点进行划分,在验证集中不能带来准确性的提升,那么对这个节点进行划分就没有意义,这时就会把当前节点作为叶节点,不对其进行划分。 * **后剪枝Post-Pruning**:就是在生成决策树之后再进行剪枝,通常会从决策树的叶节点开始,逐层向上对每个节点进行评估。如果剪掉这个节点子树,与保留该节点子树在分类准确性上差别不大,或者剪掉该节点子树,能在验证集中带来准确性的提升,那么就可以把该节点子树进行剪枝。方法是:用这个节点子树的叶子节点来替代该节点,类标记为这个节点子树中最频繁的那个类。 * **纯度**:你可以把决策树的构造过程理解成为寻找纯净划分的过程。数学上,我们可以用纯度来表示,纯度换一种方式来解释就是让目标变量的分歧最小。 * **信息熵(entropy)**:它表示了信息的不确定度。 在信息论中,随机离散事件出现的概率存在着不确定性。为了衡量这种信息的不确定性,信息学之父香农引入了信息熵的概念,并给出了计算信息熵的数学公式: ![](https://upload-images.jianshu.io/upload_images/21643577-fb9c29ddc9fef605.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/600) * p(i|t) 代表了节点 t 为分类 i 的概率,其中 log2 为取以 2 为底的对数。这里我们不是来介绍公式的,而是说存在一种度量,它能帮我们反映出来这个信息的不确定度。当不确定性越大时,它所包含的信息量也就越大,信息熵也就越高。 * 我举个简单的例子,假设有 2 个集合 1. 集合 1:5 次去打篮球,1 次不去打篮球; 2. 集合 2:3 次去打篮球,3 次不去打篮球。 * 在集合 1 中,有 6 次决策,其中打篮球是 5 次,不打篮球是 1 次。那么假设:类别 1 为“打篮球”,即次数为 5;类别 2 为“不打篮球”,即次数为 1。那么节点划分为类别 1 的概率是 5/6,为类别 2 的概率是 1/6,带入上述信息熵公式可以计算得出: ![](https://upload-images.jianshu.io/upload_images/21643577-84b3b20c8c9301fa.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/600) * 同样,集合 2 中,也是一共 6 次决策,其中类别 1 中“打篮球”的次数是 3,类别 2“不打篮球”的次数也是 3,那么信息熵为多少呢?我们可以计算得出: ![](https://upload-images.jianshu.io/upload_images/21643577-49b27c99440d22ca.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/600) 从上面的计算结果中可以看出,**信息熵越大,纯度越低。当集合中的所有样本均匀混合时,信息熵最大,纯度最低。** #### “不纯度”的指标 * 有三种,分别是信息增益(ID3 算法)、信息增益率(C4.5 算法)以及基尼指数(Cart 算法)。 * **信息增益 ID3**:划分可以带来纯度的提高,信息熵的下降。它的计算公式,是父亲节点的信息熵减去所有子节点的信息熵。在计算的过程中,我们会计算每个子节点的归一化信息熵,即按照每个子节点在父节点中出现的概率,来计算这些子节点的信息熵。所以信息增益的公式可以表示为: ![](https://upload-images.jianshu.io/upload_images/21643577-cbb3c43a0532205a.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/600) * 公式中 D 是父亲节点,Di 是子节点,Gain(D,a) 中的 a 作为 D 节点的属性选择。 * 你可以在下面的图例中直观地了解这几个概念。 ![](https://upload-images.jianshu.io/upload_images/21643577-e1c870ce50a9b66f.jpeg?imageMogr2/auto-orient/strip%7CimageView2/2/w/600) * 比如针对图上这个例子,D 作为节点的信息增益为: ![](https://upload-images.jianshu.io/upload_images/21643577-6876b72569c0a77b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/600) * 也就是 D 节点的信息熵 -2 个子节点的归一化信息熵。2 个子节点归一化信息熵 =3/10 的 D1 信息熵 +7/10 的 D2 信息熵。 我们基于 ID3 的算法规则,完整地计算下我们的训练集,训练集中一共有 7 条数据,3 个打篮球,4 个不打篮球,所以根节点的信息熵是: ![](https://upload-images.jianshu.io/upload_images/21643577-0a25983777c26b78.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/600) ###### ID3的缺陷 * 有些属性可能对分类任务没有太大作用,但是他们仍然可能会被选为最优属性。所以改进之后采用信息增益率。 * ID3 构造决策树的时候,容易产生过拟合的情况。在 C4.5 中,会在决策树构造之后采用悲观剪枝(PEP),这样可以提升决策树的泛化能力。 * 悲观剪枝:后剪枝技术中的一种,通过递归估算每个内部节点的分类错误率,比较剪枝前后这个节点的分类错误率来决定是否对其进行剪枝。这种剪枝方法不再需要一个单独的测试数据集。 #### C4.5 算法(信息增益率) 信息增益率 = 信息增益 / 属性熵 * C4.5 选择具有最高信息增益的划分所对应的阈值。 * 可以处理缺失值 ###### 总结 ID3和C4.5总结 * 首先 ID3 算法的优点是方法简单,缺点是对噪声敏感。训练数据如果有少量错误,可能会产生决策树分类错误。C4.5 在 ID3 的基础上,用信息增益率代替了信息增益,解决了噪声敏感的问题,并且可以对构造树进行剪枝、处理连续数值以及数值缺失等情况,但是由于 C4.5 需要对数据集进行多次扫描,算法效率相对较低。 ![](https://upload-images.jianshu.io/upload_images/21643577-2a8d7ed8da641a66.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/600) #### CART 算法 * 英文全称叫做 Classification And Regression Tree,中文叫做分类回归树。 ID3 和 C4.5 算法可以生成二叉树或多叉树,而 CART 只支持二叉树。同时 CART 决策树比较特殊,既可以作分类树,又可以作回归树。 * 分类树:基于现在数据判断样本的属于哪个分类。 适合处理离散的数据,它输出样本的类别。 * 回归树:基于现在数据预测样本的未来值。适合处理连续型数据,它输出预测的一个数值。 ###### 基尼系数 * 经济学中用来衡量一个国家收入差距的常用指标。当基尼系数大于 0.4 的时候,说明财富差异悬殊。基尼系数在 0.2-0.4 之间说明分配合理,财富差距不大。 基尼系数本身反应了样本的不确定度。当基尼系数越小的时候,说明样本之间的差异性小,不确定程度低。 ![](https://upload-images.jianshu.io/upload_images/21643577-b31c7767fa7f8b61.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/600) #### 构造CART分类树 ``` # encoding = utf-8 from sklearn.model_selection import train_test_split from sklearn.metrics import accuracy_score from sklearn.tree import DecisionTreeClassifier from sklearn.datasets import load_iris # 准备数据 iris = load_iris() # 获取特征集和分类标识 features = iris.data labels = iris.target # 随机抽取 33% 的数据作为测试集,其余为训练集 train_features, test_features, train_labels, test_labels \ = train_test_split(features, labels, test_size=0.33, random_state=0) # 创建 CART 分类树 clf = DecisionTreeClassifier(criterion='gini') # 拟合构造 CART 分类树 cart = clf.fit(train_features, train_labels) # 用 CART 分类树做预测 test_predict = clf.predict(test_features) # 预测结果与测试集结果作比对 score = accuracy_score(test_labels, test_predict) print("CART 分类树准确率 %.4lf " % score) ``` #### CART 回归树 * CART 回归树划分数据集的过程和分类树的过程是一样的,只是回归树得到的预测结果是连续值,而且评判“不纯度”的指标不同。在 CART 分类树中采用的是基尼系数作为标准,那么在 CART 回归树中,如何评价“不纯度”呢?实际上我们要根据样本的混乱程度,也就是样本的离散程度来评价“不纯度”。 ``` from sklearn.metrics import mean_squared_error from sklearn.model_selection import train_test_split from sklearn.datasets import load_boston from sklearn.metrics import r2_score,mean_absolute_error,mean_squared_error from sklearn.tree import DecisionTreeRegressor # 准备数据集 boston = load_boston() # 探索数据 print(boston.feature_names) # 获取特征集和房价 features = boston.data prices = boston.target # 随机抽取 33% 的数据作为测试集,其余为训练集 train_features, test_features, train_price, test_price = train_test_split(features, prices, test_size=0.33) # 创建 CART 回归树 dtr = DecisionTreeRegressor() # 拟合构造 CART 回归树 dtr.fit(train_features, train_price) # 预测测试集中的房价 predict_price = dtr.predict(test_features) # 测试集的结果评价 print('回归树二乘偏差均值:', mean_squared_error(test_price, predict_price)) print('回归树绝对值偏差均值:', mean_absolute_error(test_price, predict_price)) ``` #### CART 决策树的剪枝 * CART 决策树的剪枝主要采用的是 CCP 方法,它是一种后剪枝的方法,英文全称叫做 cost-complexity prune,中文叫做代价复杂度。这种剪枝方式用到一个指标叫做节点的表面误差率增益值,以此作为剪枝前后误差的定义。用公式表示则是: ![](https://upload-images.jianshu.io/upload_images/21643577-106f658770c703d6.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/600) * 其中 Tt 代表以 t 为根节点的子树,C(Tt) 表示节点 t 的子树没被裁剪时子树 Tt 的误差,C(t) 表示节点 t 的子树被剪枝后节点 t 的误差,|Tt|代子树 Tt 的叶子数,剪枝后,T 的叶子数减少了|Tt|-1。 #### 三种决策树 * **ID3 算法,基于信息增益做判断;** * **C4.5 算法,基于信息增益率做判断;** * **CART 算法,分类树是基于基尼系数做判断。回归树是基于偏差做判断。** ![](https://upload-images.jianshu.io/upload_images/21643577-6e8162e94977aab2.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/600) #### 决策树模型 ![](https://upload-images.jianshu.io/upload_images/21643577-51081b1e5b874d1c.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/600) #### 贝叶斯原理 * 这当你不能准确知悉一个事物的本质时,你可以依靠与事物特定本质相关的事件出现的多少去判断其本质属性的概率。用数学语言表达就是:支持某项属性的事件发生得愈多,则该属性成立的可能性就愈大。 * 逆向概率:在我们不了解所有客观事实的情况下,同样可以先估计一个值,然后根据实际结果不断进行修正。 * 先验概率:通过经验来判断事情发生的概率。 * 后验概率:后验概率就是发生结果之后,推测原因的概率。 * 条件概率:事件 A 在另外一个事件 B 已经发生条件下的发生概率,表示为 P(A|B),读作“在 B 发生的条件下 A 发生的概率”。 * 似然函数(likelihood function):你可以把概率模型的训练过程理解为求参数估计的过程。举个例子,如果一个硬币在 10 次抛落中正面均朝上。那么你肯定在想,这个硬币是均匀的可能性是多少?这里硬币均匀就是个参数,似然函数就是用来衡量这个模型的参数。似然在这里就是可能性的意思,它是关于统计参数的函数。 ![](https://upload-images.jianshu.io/upload_images/21643577-94ebe6fb05677efe.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/600) #### 朴素贝叶斯 * 它是一种简单但极为强大的预测建模算法。之所以称为朴素贝叶斯,是因为它假设每个输入变量是独立的。这是一个强硬的假设,实际情况并不一定,但是这项技术对于绝大部分的复杂问题仍然非常有效。 * 朴素贝叶斯模型由两种类型的概率组成: 1. 每个类别的概率P(Cj); 2. 每个属性的条件概率P(Ai|Cj)。 ![](https://upload-images.jianshu.io/upload_images/21643577-565f21f634404bbf.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/600) ![](https://upload-images.jianshu.io/upload_images/21643577-afa4cca89d8813fb.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/600) * 朴素贝叶斯分类最适合的场景就是文本分类、情感分析和垃圾邮件识别。这三个场景本质上都是文本分类,这也是朴素贝叶斯最擅长的地方。所以朴素贝叶斯也常用于自然语言处理 NLP 的工具。 #### sklearn 机器学习包 * sklearn 的全称叫 Scikit-learn,它给我们提供了 3 个朴素贝叶斯分类算法,分别是高斯朴素贝叶斯(GaussianNB)、多项式朴素贝叶斯(MultinomialNB)和伯努利朴素贝叶斯(BernoulliNB)。 * 高斯朴素贝叶斯:特征变量是连续变量,符合高斯分布,比如说人的身高,物体的长度。 * 多项式朴素贝叶斯:特征变量是离散变量,符合多项分布,在文档分类中特征变量体现在一个单词出现的次数,或者是单词的 TF-IDF 值等。 * 伯努利朴素贝叶斯:特征变量是布尔变量,符合 0/1 分布,在文档分类中特征是单词是否出现。 ###### 词频 TF * 计算了一个单词在文档中出现的次数,它认为一个单词的重要性和它在文档中出现的次数呈正比。 ###### 逆向文档频率 IDF * 指一个单词在文档中的区分度。它认为一个单词出现在的文档数越少,就越能通过这个单词把该文档和其他文档区分开。IDF 越大就代表该单词的区分度越大。 * 所以 TF-IDF 实际上是词频 TF 和逆向文档频率 IDF 的乘积。 #### TF-IDF 计算 ![](https://upload-images.jianshu.io/upload_images/21643577-2e0010764d61c920.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/600) ![](https://upload-images.jianshu.io/upload_images/21643577-4332bce9d1e45854.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/600) ![](https://upload-images.jianshu.io/upload_images/21643577-38aa85060a0685e8.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/600) #### SVM * SVM 的英文叫 Support Vector Machine,中文名为支持向量机。它是常见的一种分类方法,在机器学习中,SVM 是有监督的学习模型。 * 它在文本分类尤其是针对二分类任务性能卓越。同样,针对多分类的情况,我们可以采用一对多,或者一对一的方法,多个二值分类器组合成一个多分类器。 * 核函数:它可以将样本从原始空间映射到一个更高维的特质空间中,使得样本在新的空间中线性可分。 * 另外关于 SVM 分类器的概念,我希望你能掌握以下的三个程度: 1. 完全线性可分情况下的线性分类器,也就是线性可分的情况,是最原始的 SVM,它最核心的思想就是找到最大的分类间隔; 2. 大部分线性可分情况下的线性分类器,引入了软间隔的概念。软间隔,就是允许一定量的样本分类错误; 3. 线性不可分情况下的非线性分类器,引入了核函数。它让原有的样本空间通过核函数投射到了一个高维的空间中,从而变得线性可分。 #### 如何在 sklearn 中使用 SVM * 线性核函数,是在数据线性可分的情况下使用的,运算速度快,效果好。不足在于它不能处理线性不可分的数据。 * 多项式核函数可以将数据从低维空间映射到高维空间,但参数比较多,计算量大。 * 高斯核函数同样可以将样本映射到高维空间,但相比于多项式核函数来说所需的参数比较少,通常性能不错,所以是默认使用的核函数。 * sigmoid核函数经常用在神经网络的映射中,SVM 实现的是多层神经网络。 ![](https://upload-images.jianshu.io/upload_images/21643577-03d7c27e4a424e80.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/600) #### KNN * KNN 的英文叫 K-Nearest Neighbor,应该算是数据挖掘算法中最简单的一种,主要思想是 近朱者赤,近墨者黑。 * 工作原理 1. 计算待分类物体与其他物体之间的距离; 2. 统计距离最近的 K 个邻居; 3. 对于 K 个最近的邻居,它们属于哪个分类最多,待分类物体就属于哪一类。在工程上,我们一般采用交叉验证的方式选取 K 值。 * 计算距离的方法 1. 欧氏距离; 1. 曼哈顿距离; 1. 闵可夫斯基距离; 1. 切比雪夫距离; 1. 余弦距离。 ![](https://upload-images.jianshu.io/upload_images/21643577-431546741dc5b5ac.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/600) #### K-Means * K-Means 是一种非监督学习,解决的是聚类问题。K 代表的是 K 类,Means 代表的是中心,你可以理解这个算法的本质是确定 K 类的中心点,当你找到了这些中心点,也就完成了聚类。 1. 选取 K 个点作为初始的类中心点,这些点一般都是从数据集中随机抽取的; 1. 将每个点分配到最近的类中心点,这样就形成了 K 个类,然后重新计算每个类的中心点; 1. 重复第二步,直到类不发生变化,或者你也可以设置最大迭代次数,这样即使类中心点发生变化,但是只要达到最大迭代次数就会结束。 ![](https://upload-images.jianshu.io/upload_images/21643577-a31e18d036a240ef.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/600) #### EM 聚类 * EM 的英文是 Expectation Maximization,所以 EM 算法也叫最大期望算法。 * 初始化参数、观察预期、重新估计。首先是先给每个碟子初始化一些菜量,然后再观察预期,这两个步骤实际上就是期望步骤(Expectation)。如果结果存在偏差就需要重新估计参数,这个就是最大化步骤(Maximization)。这两个步骤加起来也就是 EM 算法的过程。 * EM 算法最直接的应用就是求参数估计。如果我们把潜在类别当做隐藏变量,样本看做观察值,就可以把聚类问题转化为参数估计问题。这也就是 EM 聚类的原理。 ![](https://upload-images.jianshu.io/upload_images/21643577-ec2faa9e525c5817.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/600) * K-Means 是通过距离来区分样本之间的差别的,且每个样本在计算的时候只能属于一个分类,称之为是硬聚类算法。 * 而 EM 聚类在求解的过程中,实际上每个样本都有一定的概率和每个聚类相关,叫做软聚类算法。 * 在 EM 这个框架中,E 步骤相当于是通过初始化的参数来估计隐含变量。M 步骤就是通过隐含变量反推来优化参数。最后通过 EM 步骤的迭代得到模型参数。 * GMM(高斯混合模型) 是通过概率密度来进行聚类,聚成的类符合高斯分布(正态分布)。 * HMM(隐马尔科夫模型) 用到了马尔可夫过程,在这个过程中,我们通过状态转移矩阵来计算状态转移的概率。HMM 在自然语言处理和语音识别领域中有广泛的应用。 ![](https://upload-images.jianshu.io/upload_images/21643577-368046e39560607d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/600) #### 监督学习 * 定义:根据已有的数据集,知道输入和输出结果之间的关系。根据这种已知的关系,训练得到一个最优的模型。也就是说,在监督学习中训练数据既有特征(feature)又有标签(label),通过训练,让机器可以自己找到特征和标签之间的联系,在面对只有特征没有标签的数据时,可以判断出标签。 * 通俗一点,可以把机器学习理解为我们教机器如何做事情。 * 监督学习的分类:回归(Regression)、分类(Classification) #### 无监督学习 * 定义:我们不知道数据集中数据、特征之间的关系,而是要根据聚类或一定的模型得到数据之间的关系。 * 可以这么说,比起监督学习,无监督学习更像是自学,让机器学会自己做事情,是没有标签(label)的。 #### 关联规则Apriori 算法 * 支持度:是个百分比,它指的是某个商品组合出现的次数与总次数之间的比例。支持度越高,代表这个组合出现的频率越大。 * 置信度:是个条件概念,就是说在 A 发生的情况下,B 发生的概率是多少。 * 提升度:“商品 A 的出现,对商品 B 的出现概率提升的”程度。 * 提升度 (A→B)= 置信度 (A→B)/ 支持度 (B) 1. 提升度 (A→B)>1:代表有提升; 1. 提升度 (A→B)=1:代表有没有提升,也没有下降; 1. 提升度 (A→B)<1:代表有下降。 #### Apriori 的工作原理 * Apriori 算法其实就是查找频繁项集 (frequent itemset) 的过程。 * 频繁项集就是支持度大于等于最小支持度 (Min Support) 阈值的项集,所以小于最小值支持度的项目就是非频繁项集,而大于等于最小支持度的项集就是频繁项集。 * 项集这个概念,英文叫做 itemset,它可以是单个的商品,也可以是商品的组合。 #### FP-Growth 算法 * Apriori 算法会浪费很多计算空间和计算时间,为此人们提出了 FP-Growth 算法,它的特点是: 1. 创建了一棵 FP 树来存储频繁项集。在创建前对不满足最小支持度的项进行删除,减少了存储空间。 2. 整个生成过程只遍历数据集 2 次,大大减少了计算量。 ###### FP-Growth 的原理 1. 创建项头表(item header table) * 创建项头表的作用是为 FP 构建及频繁项集挖掘提供索引。 这一步的流程是先扫描一遍数据集,对于满足最小支持度的单个项(K=1 项集)按照支持度从高到低进行排序,这个过程中删除了不满足最小支持度的项。 2. 构造 FP 树 * FP 树的根节点记为 NULL 节点。 整个流程是需要再次扫描数据集,对于每一条数据,按照支持度从高到低的顺序进行创建节点(也就是第一步中项头表中的排序结果),节点如果存在就将计数 count+1,如果不存在就进行创建。同时在创建的过程中,需要更新项头表的链表。 3. 通过 FP 树挖掘频繁项集 * 我们可以通过项头表来挖掘出每个频繁项集。 具体的操作会用到一个概念,叫“条件模式基”,它指的是以要挖掘的节点为叶子节点,自底向上求出 FP 子树,然后将 FP 子树的祖先节点设置为叶子节点之和。 ![](https://upload-images.jianshu.io/upload_images/21643577-51287114102a6ee7.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/600) ![](https://upload-images.jianshu.io/upload_images/21643577-2d33f998f221ed9e.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/600) #### PageRank * 适用于关系网中,对个体的权重进行计算。 * Google 的两位创始人都是斯坦福大学的博士生,他们提出的 PageRank 算法受到了论文影响力因子的评价启发。当一篇论文被引用的次数越多,证明这篇论文的影响力越大。正是这个想法解决了当时网页检索质量不高的问题。 * 一个网页的影响力 = 所有入链集合的页面的加权影响力之和,用公式表示为: ![](https://upload-images.jianshu.io/upload_images/21643577-1b6d0dd79e2f2402.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/600) ###### 可能会面临的问题 1. 等级泄露(Rank Leak):如果一个网页没有出链,就像是一个黑洞一样,吸收了其他网页的影响力而不释放,最终会导致其他网页的 PR 值为 0。 2. 等级沉没(Rank Sink):如果一个网页只有出链,没有入链(如下图所示),计算的过程迭代下来,会导致这个网页的 PR 值为 0(也就是不存在公式中的 V)。 ###### PageRank 的随机浏览模型 * 定义了阻尼因子 d,这个因子代表了用户按照跳转链接来上网的概率,通常可以取一个固定值 0.85,而 1-d=0.15 则代表了用户不是通过跳转链接的方式来访问网页的,比如直接输入网址。 ![](https://upload-images.jianshu.io/upload_images/21643577-02e68640ab9b0679.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/600) 其中 N 为网页总数,这样我们又可以重新迭代网页的权重计算了,因为加入了阻尼因子 d,一定程度上解决了等级泄露和等级沉没的问题。 通过数学定理(这里不进行讲解)也可以证明,最终 PageRank 随机浏览模型是可以收敛的,也就是可以得到一个稳定正常的 PR 值。 ![](https://upload-images.jianshu.io/upload_images/21643577-8ad7b175aa16d0cb.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/600) ![](https://upload-images.jianshu.io/upload_images/21643577-0614e1760cea245c.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/600) #### AdaBoost 算法 ##### 集成算法 * 在数据挖掘中,分类算法可以说是核心算法,其中 AdaBoost 算法与随机森林算法一样都属于分类算法中的集成算法。 ##### 集成算法的方式 1. **投票选举(bagging)** 投票选举的场景类似把专家召集到一个会议桌前,当做一个决定的时候,让 K 个专家(K 个模型)分别进行分类,然后选择出现次数最多的那个类作为最终的分类结果。 2. **再学习(boosting)** 再学习相当于把 K 个专家(K 个分类器)进行加权融合,形成一个新的超级专家(强分类器),让这个超级专家做判断。 每一次训练的时候都对上一次的训练进行改进提升,在训练的过程中这 K 个“专家”之间是有依赖性的,当引入第 K 个“专家”(第 K 个分类器)的时候,实际上是对前 K-1 个专家的优化。 而 bagging 做投票选举的时候可以并行计算,相互独立的,不存在依赖性。 ##### AdaBoost 算法 * AdaBoost 的英文全称是 Adaptive Boosting,中文含义是自适应提升算法。它由 Freund 等人于 1995 年提出,是对 Boosting 算法的一种实现。 ###### Boosting 算法 * Boosting 算法是集成算法中的一种,同时也是一类算法的总称。这类算法通过**训练多个弱分类器,将它们组合成一个强分类器**,也就是我们俗话说的“三个臭皮匠,顶个诸葛亮”。 因此要打造一个诸葛亮,最好的方式就是训练多个臭皮匠,然后让这些臭皮匠组合起来,这样往往可以得到很好的效果。这就是 Boosting 算法的原理。 * 假设弱分类器为 Gi(x),它在强分类器中的权重 αi,那么就可以得出强分类器 f(x): ![](https://upload-images.jianshu.io/upload_images/21643577-8b04789df9fac429.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/600) * 实际上在一个由 K 个弱分类器中组成的强分类器中,如果弱分类器的分类效果好,那么权重应该比较大,如果弱分类器的分类效果一般,权重应该降低。所以我们需要**基于这个弱分类器对样本的分类错误率来决定它的权重**,用公式表示就是: ![](https://upload-images.jianshu.io/upload_images/21643577-a7d4183d02b3532a.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/600) ###### 如何在每次训练迭代的过程中选择最优的弱分类器 * AdaBoost 算法是通过改变样本的数据分布来实现的。 AdaBoost 会判断每次训练的样本是否正确分类,对于正确分类的样本,降低它的权重,对于被错误分类的样本,增加它的权重。 再基于上一次得到的分类准确率,来确定这次训练样本中每个样本的权重。然后将修改过权重的新数据集传递给下一层的分类器进行训练。 这样做的好处就是,通过每一轮训练样本的动态权重,可以让训练的焦点集中到难分类的样本上,最终得到的弱分类器的组合更容易得到更高的分类准确率。 我们可以用 Dk+1 代表第 k+1 轮训练中,样本的权重集合,其中 Wk+1,1 代表第 k+1 轮中第一个样本的权重,以此类推 Wk+1,N 代表第 k+1 轮中第 N 个样本的权重,因此用公式表示为: ![](https://upload-images.jianshu.io/upload_images/21643577-c831a8f10025cfe3.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/600) 第 k+1 轮中的样本权重,是根据该样本在第 k 轮的权重以及第 k 个分类器的准确率而定,具体的公式为: ![](https://upload-images.jianshu.io/upload_images/21643577-13219f9b66cb23df.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/600) ![](https://upload-images.jianshu.io/upload_images/21643577-c955cf9879fb6f2d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/600) ##### AdaBoost 工具使用 使用 AdaBoostClassifier(base_estimator=None, n_estimators=50, learning_rate=1.0, algorithm=’SAMME.R’, random_state=None) 这个函数,其中有几个比较主要的参数,我分别来讲解下: 1. base_estimator:代表的是弱分类器。在 AdaBoost 的分类器和回归器中都有这个参数,在 AdaBoost 中默认使用的是决策树,一般我们不需要修改这个参数,当然你也可以指定具体的分类器。 1. n_estimators:算法的最大迭代次数,也是分类器的个数,每一次迭代都会引入一个新的弱分类器来增加原有的分类器的组合能力。默认是 50。 1. learning_rate:代表学习率,取值在 0-1 之间,默认是 1.0。如果学习率较小,就需要比较多的迭代次数才能收敛,也就是说学习率和迭代次数是有相关性的。当你调整 learning_rate 的时候,往往也需要调整 n_estimators 这个参数。 1. algorithm:代表我们要采用哪种 boosting 算法,一共有两种选择:SAMME 和 SAMME.R。默认是 SAMME.R。这两者之间的区别在于对弱分类权重的计算方式不同。 1. random_state:代表随机数种子的设置,默认是 None。随机种子是用来控制随机模式的,当随机种子取了一个值,也就确定了一种随机规则,其他人取这个值可以得到同样的结果。如果不设置随机种子,每次得到的随机数也就不同。 ![](https://upload-images.jianshu.io/upload_images/21643577-0dfd4c3485069166.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/600) #### Selenium 自动化测试工具 * 如果我们想定位一个元素,可以通过 id、name、class、tag、链接上的全部文本、链接上的部分文本、XPath 或者 CSS 进行定位,在 Selenium Webdriver 中也提供了这 8 种方法方便我们定位元素。 1. 通过 id 定位:我们可以使用 find_element_by_id() 函数。比如我们想定位 id=loginName 的元素,就可以使用 browser.find_element_by_id(“loginName”)。 1. 通过 name 定位:我们可以使用 find_element_by_name() 函数,比如我们想要对 name=key_word 的元素进行定位,就可以使用 browser.find_element_by_name(“key_word”)。 1. 通过 class 定位:可以使用 find_element_by_class_name() 函数。 1. 通过 tag 定位:使用 find_element_by_tag_name() 函数。 1. 通过 link 上的完整文本定位:使用 find_element_by_link_text() 函数。 1. 通过 link 上的部分文本定位:使用 find_element_by_partial_link_text() 函数。有时候超链接上的文本很长,我们通过查找部分文本内容就可以定位。 1. 通过 XPath 定位:使用 find_element_by_xpath() 函数。使用 XPath 定位的通用性比较好,因为当 id、name、class 为多个,或者元素没有这些属性值的时候,XPath 定位可以帮我们完成任务。 1. 通过 CSS 定位:使用 find_element_by_css_selector() 函数。CSS 定位也是常用的定位方法,相比于 XPath 来说更简洁。 * 在我们获取某个元素之后,就可以对这个元素进行操作了,对元素进行的操作包括: 1. 清空输入框的内容:使用 clear() 函数; 1. 在输入框中输入内容:使用 send_keys(content) 函数传入要输入的文本; 1. 点击按钮:使用 click() 函数,如果元素是个按钮或者链接的时候,可以点击操作; 1. 提交表单:使用 submit() 函数,元素对象为一个表单的时候,可以提交表单; ![](https://upload-images.jianshu.io/upload_images/21643577-4b2cb93b528839f8.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/600) #### 做词云展示 ![](https://upload-images.jianshu.io/upload_images/21643577-75792c29aaafc5de.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/600) #### 构建随机森林分类器 * 随机森林的英文是 Random Forest,英文简写是 RF。它实际上是一个包含多个决策树的分类器,每一个子分类器都是一棵 CART 分类回归树。所以随机森林既可以做分类,又可以做回归。当它做分类的时候,输出结果是每个子分类器的分类结果中最多的那个。你可以理解是每个分类器都做投票,取投票最多的那个结果。当它做回归的时候,输出结果是每棵 CART 树的回归结果的平均值。 ##### 操作步骤 1. 加载数据; 1. 准备阶段:探索数据,采用数据可视化方式可以让我们对数据有更直观的了解,比如我们想要了解信用卡违约率和不违约率的人数。因为数据集没有专门的测试集,我们还需要使用 train_test_split 划分数据集。 1. 分类阶段:之所以把数据规范化放到这个阶段,是因为我们可以使用 Pipeline 管道机制,将数据规范化设置为第一步,分类为第二步。因为我们不知道采用哪个分类器效果好,所以我们需要多用几个分类器,比如 SVM、决策树、随机森林和 KNN。然后通过 GridSearchCV 工具,找到每个分类器的最优参数和最优分数,最终找到最适合这个项目的分类器和该分类器的参数。 ![](https://upload-images.jianshu.io/upload_images/21643577-900960707848ae5f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/600) #### 构建逻辑回归分类器 * 逻辑回归,也叫作 logistic 回归。虽然名字中带有“回归”,但它实际上是分类方法,主要解决的是二分类问题,当然它也可以解决多分类问题,只是二分类更常见一些。 在逻辑回归中使用了 Logistic 函数,也称为 Sigmoid 函数。Sigmoid 函数是在深度学习中经常用到的函数之一,函数公式为: ![](https://upload-images.jianshu.io/upload_images/21643577-613653c09973d7dc.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/600) ![](https://upload-images.jianshu.io/upload_images/21643577-2c51346203f09509.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/600) * 逻辑回归模型的求解这里不做介绍,我们来看下如何使用 sklearn 中的逻辑回归工具。在 sklearn 中,我们使用 LogisticRegression() 函数构建逻辑回归分类器,函数里有一些常用的构造参数: 1. penalty:惩罚项,取值为 l1 或 l2,默认为 l2。当模型参数满足高斯分布的时候,使用 l2,当模型参数满足拉普拉斯分布的时候,使用 l1; 1. solver:代表的是逻辑回归损失函数的优化方法。有 5 个参数可选,分别为 liblinear、lbfgs、newton-cg、sag 和 saga。默认为 liblinear,适用于数据量小的数据集,当数据量大的时候可以选用 sag 或 saga 方法。 1. max_iter:算法收敛的最大迭代次数,默认为 10。 1. n_jobs:拟合和预测的时候 CPU 的核数,默认是 1,也可以是整数,如果是 -1 则代表 CPU 的核数。 ![拉普拉斯分布](https://upload-images.jianshu.io/upload_images/21643577-6719fe6326e1e78d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/600) ![高斯分布](https://upload-images.jianshu.io/upload_images/21643577-2972c61fb29cfd3a.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) #### 模型评估指标 * TP:预测为正,判断正确; FP:预测为正,判断错误; TN:预测为负,判断正确; FN:预测为负,判断错误。 * 我们知道样本总数 =TP+FP+TN+FN,预测正确的样本数为 TP+TN,因此准确率 Accuracy = (TP+TN)/(TP+TN+FN+FP)。 * 实际上,对于分类不平衡的情况,有两个指标非常重要,它们分别是精确度和召回率。 * 精确率 P = TP/ (TP+FP),对应上面恐怖分子这个例子,在所有判断为恐怖分子的人数中,真正是恐怖分子的比例。 * 召回率 R = TP/ (TP+FN),也称为查全率。代表的是恐怖分子被正确识别出来的个数与恐怖分子总数的比例。 * 有一个指标综合了精确率和召回率,可以更好地评估模型的好坏。这个指标叫做 F1,用公式表示为: ![](https://upload-images.jianshu.io/upload_images/21643577-6ff0cf440940b67c.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/600) * F1 作为精确率 P 和召回率 R 的调和平均,数值越大代表模型的结果越好。 ![](https://upload-images.jianshu.io/upload_images/21643577-bdfe34876dfd6757.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) #### 时间序列分析 * AR 的英文全称叫做 Auto Regressive,中文叫自回归模型。这个算法的思想比较简单,它认为过去若干时刻的点通过线性组合,再加上白噪声就可以预测未来某个时刻的点。 在我们日常生活环境中就存在白噪声,在数据挖掘的过程中,你可以把它理解为一个期望为 0,方差为常数的纯随机过程。AR 模型还存在一个阶数,称为 AR(p)模型,也叫作 p 阶自回归模型。它指的是通过这个时刻点的前 p 个点,通过线性组合再加上白噪声来预测当前时刻点的值。 * MA 的英文全称叫做 Moving Average,中文叫做滑动平均模型。它与 AR 模型大同小异,AR 模型是历史时序值的线性组合,MA 是通过历史白噪声进行线性组合来影响当前时刻点。AR 模型中的历史白噪声是通过影响历史时序值,从而间接影响到当前时刻点的预测值。同样 MA 模型也存在一个阶数,称为 MA(q) 模型,也叫作 q 阶移动平均模型。我们能看到 AR 和 MA 模型都存在阶数,在 AR 模型中,我们用 p 表示,在 MA 模型中我们用 q 表示,这两个模型大同小异,与 AR 模型不同的是 MA 模型是历史白噪声的线性组合。 * ARMA 的英文全称是 Auto Regressive Moving Average,中文叫做自回归滑动平均模型,也就是 AR 模型和 MA 模型的混合。相比 AR 模型和 MA 模型,它有更准确的估计。同样 ARMA 模型存在 p 和 q 两个阶数,称为 ARMA(p,q) 模型。 * ARIMA 的英文全称是 Auto Regressive Integrated Moving Average 模型,中文叫差分自回归滑动平均模型,也叫求合自回归滑动平均模型。相比于 ARMA,ARIMA 多了一个差分的过程,作用是对不平稳数据进行差分平稳,在差分平稳后再进行建模。ARIMA 的原理和 ARMA 模型一样。相比于 ARMA(p,q) 的两个阶数,ARIMA 是一个三元组的阶数 (p,d,q),称为 ARIMA(p,d,q) 模型。其中 d 是差分阶数。 ![](https://upload-images.jianshu.io/upload_images/21643577-7351be887ecabaeb.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/600) #### 数据挖掘,机器学习,深度学习的区别是什么? * 数据挖掘通常是从现有的数据中提取规律模式(pattern)以及使用算法模型(model)。核心目的是找到这些数据变量之间的关系,因此我们也会通过数据可视化对变量之间的关系进行呈现,用算法模型挖掘变量之间的关联关系。通常情况下,我们只能判断出来变量 A 和变量 B 是有关系的,但并不一定清楚这两者之间有什么具体关系。在我们谈论数据挖掘的时候,更强调的是从数据中挖掘价值。 * 机器学习是人工智能的一部分,它指的是通过训练数据和算法模型让机器具有一定的智能。一般是通过已有的数据来学习知识,并通过各种算法模型形成一定的处理能力,比如分类、聚类、预测、推荐能力等。这样当有新的数据进来时,就可以通过训练好的模型对这些数据进行预测,也就是通过机器的智能帮我们完成某些特定的任务。 * 深度学习属于机器学习的一种,它的目标同样是让机器具有智能,只是与传统的机器学习算法不同,它是通过神经网络来实现的。神经网络就好比是机器的大脑,刚开始就像一个婴儿一样,是一张白纸。但通过多次训练之后,“大脑”就可以逐渐具备某种能力。这个训练过程中,我们只需要告诉这个大脑输入数据是什么,以及对应的输出结果是什么即可。通过多次训练,“大脑”中的多层神经网络的参数就会自动优化,从而得到一个适应于训练数据的模型。 **深度学习会自己找到数据的特征规律!而传统机器学习往往需要专家(我们)来告诉机器采用什么样的模型算法,这就是深度学习与传统机器学习最大的区别。** #### FNN * **FNN**(Fully-connected Neural Network)指的是全连接神经网络,全连接的意思是每一层的神经元与上一层的所有神经元都是连接的。不过在实际使用中,全连接的参数会过多,导致计算量过大。因此在实际使用中全连接神经网络的层数一般比较少。 ![](https://upload-images.jianshu.io/upload_images/21643577-d8d680af261f5d3b.jpeg?imageMogr2/auto-orient/strip%7CimageView2/2/w/600) #### CNN * CNN叫作卷积神经网络,在图像处理中有广泛的应用,CNN 网络中,包括了卷积层、池化层和全连接层。 1. 卷积层相当于一个滤镜的作用,它可以把图像进行分块,对每一块的图像进行变换操作。实际上每个卷积核都是一种滤波器,它们把图像中符合条件的部分筛选出来,也就相当于做了某种特征提取。 1. 池化层相当于对神经元的数据进行降维处理,这样输出的维数就会减少很多,从而降低整体的计算量。 1. 全连接层通常是输出层的上一层,它将上一层神经元输出的数据转变成一维的向量。 #### RNN RNN称为循环神经网络,它的特点是神经元的输出可以在下一个时刻作用到自身,这样 RNN 就可以看做是在时间上传递的神经网络。它可以应用在语音识别、自然语言处理等与上下文相关的场景。 #### 深度学习的应用领域 图像识别 语音识别 NLP自然语言处理 ![](https://upload-images.jianshu.io/upload_images/21643577-7da49b9c7e259051.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/600) #### 如何理解 CNN 网络中的卷积作用 ![](https://upload-images.jianshu.io/upload_images/21643577-ba44f948faa377fd.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/600) 我简单说下计算的原理。 1. 第一步,我们需要将卷积核翻转 180 度(只有翻转之后才能做矩阵运算),也就是变成: ![](https://upload-images.jianshu.io/upload_images/21643577-2545687810389a2c.jpeg?imageMogr2/auto-orient/strip%7CimageView2/2/w/600) 2. 第二步,将卷积核的第一个元素,对准矩阵 X 左上角的第一个元素,对应元素相乘,然后再相加可以就可以得到 10*1+10*1+10*0+10*1+5*0+5*-1+10*0+5*-1+5*-1=15。 ![](https://upload-images.jianshu.io/upload_images/21643577-8489513581802a87.jpeg?imageMogr2/auto-orient/strip%7CimageView2/2/w/600) 3. 第三步,每个元素都重复第二步的计算过程,可以得到如下的矩阵结果 Z: ![](https://upload-images.jianshu.io/upload_images/21643577-d182dab834781932.jpeg?imageMogr2/auto-orient/strip%7CimageView2/2/w/600) ``` import pylab import numpy as np from scipy import signal # 设置原图像 img = np.array([[10, 10, 10, 10, 10], [10, 5, 5, 5, 10], [10, 5, 5, 5, 10], [10, 5, 5, 5, 10], [10, 10, 10, 10, 10]]) # 设置卷积核 fil = np.array([[ -1,-1, 0], [ -1, 0, 1], [ 0, 1, 1]]) # 对原图像进行卷积操作 res = signal.convolve2d(img, fil, mode='valid') # 输出卷积后的结果 print(res) ``` * 实际上每个卷积核都是一种滤波器,它们把图像中符合条件的部分筛选出来,也就相当于做了某种特征提取。 * 在 CNN 的卷积层中可以有多个卷积核,以 LeNet 为例,它的第一层卷积核有 6 个,因此可以帮我们提取出图像的 6 个特征,从而得到 6 个特征图(feature maps)。 ##### 激活函数的作用 * 做完卷积操作之后,通常还需要使用激活函数对图像进一步处理。在逻辑回归中,我提到过 Sigmoid 函数,它在深度学习中有广泛的应用,除了 Sigmoid 函数作为激活函数以外,tanh、ReLU 都是常用的激活函数。 * 这些激活函数通常都是非线性的函数,使用它们的目的是把线性数值映射到非线性空间中。卷积操作实际上是两个矩阵之间的乘法,得到的结果也是线性的。只有经过非线性的激活函数运算之后,才能映射到非线性空间中,这样也可以让神经网络的表达能力更强大。 ##### 池化层的作用 * 池化层通常在两个卷积层之间,它的作用相当于对神经元的数据做降维处理,这样就能降低整体计算量。 * 在神经网络中,我们可以叠加多个卷积层和池化层来提取更抽象的特征。经过几次卷积和池化之后,通常会有一个或多个全连接层。 ##### 全连接层的作用 * 全连接层将前面一层的输出结果与当前层的每个神经元都进行了连接。 ##### CNN 网络结构中每一层的作用: * **它通过卷积层提取特征,通过激活函数让结果映射到非线性空间,增强了结果的表达能力,再通过池化层压缩特征图,降低了网络复杂度,最后通过全连接层归一化,然后连接 Softmax 分类器进行计算每个类别的概率。** ![](https://upload-images.jianshu.io/upload_images/21643577-3e3bdeb1602e3658.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/600) ![](https://upload-images.jianshu.io/upload_images/21643577-c9d8a6ee3673b886.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/600)
MAS 方法
-
Multi-Dimension:想要掌握一个事物,就要从多个角度去认识它。
-
Ask:不懂就问,程序员大多都很羞涩,突破这一点,不懂就问最重要。
-
Sharing:最好的学习就是分享。用自己的语言讲出来,是对知识的进一步梳理。
数据分析的组成
- 数据采集。它是我们的原材料,也是最“接地气”的部分,因为任何分析都要有数据源。
- 数据挖掘。它可以说是最“高大上”的部分,也是整个商业价值所在。之所以要进行数据分析,就是要找到其中的规律,来指导我们的业务。因此数据挖掘的核心是挖掘数据的商业价值,也就是我们所谈的商业智能 BI。
- 数据可视化。它可以说是数据领域中万金油的技能,可以让我们直观地了解到数据分析的结果。
- 第一种就是使用 Python。在 Python 对数据进行清洗、挖掘的过程中,我们可以使用 Matplotlib、Seaborn 等第三方库进行呈现。
- 第二种就是使用第三方工具。如果你已经生成了 csv 格式文件,想要采用所见即所得的方式进行呈现,可以采用微图、DataV、Data GIF Maker 等第三方工具,它们可以很方便地对数据进行处理,还可以帮你制作呈现的效果。
数据挖掘的基本流程
-
商业理解:数据挖掘不是我们的目的,我们的目的是更好地帮助业务,所以第一步我们要从商业的角度理解项目需求,在这个基础上,再对数据挖掘的目标进行定义。
-
数据理解:尝试收集部分数据,然后对数据进行探索,包括数据描述、数据质量验证等。这有助于你对收集的数据有个初步的认知。
-
数据准备:开始收集数据,并对数据进行清洗、数据集成等操作,完成数据挖掘前的准备工作。
-
模型建立:选择和应用各种数据挖掘模型,并进行优化,以便得到更好的分类结果。
-
模型评估:对模型进行评价,并检查构建模型的每个步骤,确认模型是否实现了预定的商业目标。
-
上线发布:模型的作用是从数据中找到金矿,也就是我们所说的“知识”,获得的知识需要转化成用户可以使用的方式,呈现的形式可以是一份报告,也可以是实现一个比较复杂的、可重复的数据挖掘过程。数据挖掘结果如果是日常运营的一部分,那么后续的监控和维护就会变得重要。
商业智能 BI、数据仓库 DW、数据挖掘 DM 三者之间的关系
-
商业智能的英文是 Business Intelligence,缩写是 BI。相比于数据仓库、数据挖掘,它是一个更大的概念。商业智能可以说是基于数据仓库,经过了数据挖掘后,得到了商业价值的过程。所以说数据仓库是个金矿,数据挖掘是炼金术,而商业报告则是黄金。
-
数据仓库的英文是 Data Warehouse,缩写是 DW。它可以说是 BI 这个房子的地基,搭建好 DW 这个地基之后,才能进行分析使用,最后产生价值。
数据仓库将原有的多个数据来源中的数据进行汇总、整理而得。数据进入数据仓库前,必须消除数据中的不一致性,方便后续进行数据分析和挖掘。 -
数据挖掘的英文是 Data Mining,缩写是 DM。在商业智能 BI 中经常会使用到数据挖掘技术。数据挖掘的核心包括分类、聚类、预测、关联分析等任务,通过这些炼金术,我们可以从数据仓库中得到宝藏,比如商业报告。
元数据 VS 数据元
- 元数据(MetaData):描述其它数据的数据,也称为“中介数据”。
- 数据元(Data Element):就是最小数据单元。
数据挖掘的流程
- 数据挖掘的一个英文解释叫 Knowledge Discovery in Database,简称 KDD,也就是数据库中的知识发现。
-
分类
就是通过训练集得到一个分类模型,然后用这个模型可以对其他数据进行分类。
这里需要说明下训练集和测试集的概念。一般来说数据可以划分为训练集和测试集。训练集是用来给机器做训练的,通常是人们整理好训练数据,以及这些数据对应的分类标识。通过训练,机器就产生了自我分类的模型,然后机器就可以拿着这个分类模型,对测试集中的数据进行分类预测。同样如果测试集中,人们已经给出了测试结果,我们就可以用测试结果来做验证,从而了解分类器在测试环境下的表现。 -
聚类
人以群分,物以类聚。聚类就是将数据自动聚类成几个类别,聚到一起的相似度大,不在一起的差异性大。我们往往利用聚类来做数据划分。 -
预测
顾名思义,就是通过当前和历史数据来预测未来趋势,它可以更好地帮助我们识别机遇和风险。 -
关联分析
就是发现数据中的关联规则,它被广泛应用在购物篮分析,或事务数据分析中。比如我们开头提到的那个案例。
数据预处理
-
数据清洗
主要是为了去除重复数据,去噪声(即干扰数据)以及填充缺失值。 -
数据集成
是将多个数据源中的数据存放在一个统一的数据存储中。 -
数据变换
就是将数据转换成适合数据挖掘的形式。比如,通过归一化将属性数据按照比例缩放,这样就可以将数值落入一个特定的区间内,比如 0~1 之间。
用户画像
第一步,统一化
- 用户唯一标识是整个用户画像的核心。
第二步,标签化
- 给用户打标签。用户消费行为分析
- 用户标签:它包括了性别、年龄、地域、收入、学历、职业等。这些包括了用户的基础属性。
- 消费标签:消费习惯、购买意向、是否对促销敏感。这些统计分析用户的消费习惯。
- 行为标签:时间段、频次、时长、访问路径。这些是通过分析用户行为,来得到他们使用 App 的习惯。
- 内容分析:对用户平时浏览的内容,尤其是停留时间长、浏览次数多的内容进行分析,分析出用户对哪些内容感兴趣,比如,金融、娱乐、教育、体育、时尚、科技等。
第三步,业务化
- 获客:如何进行拉新,通过更精准的营销获取客户。
- 粘客:个性化推荐,搜索排序,场景运营等。
- 留客:流失率预测,分析关键节点降低流失率。
- 按照数据流处理的阶段来划分用户画像建模的过程
- 数据层指的是用户消费行为里的标签。我们可以打上“事实标签”,作为数据客观的记录。
- 算法层指的是透过这些行为算出的用户建模。我们可以打上“模型标签”,作为用户画像的分类标识。
- 业务层指的是获客、粘客、留客的手段。我们可以打上“预测标签”,作为业务关联的结果。
-
在获客上,我们可以找到优势的宣传渠道,如何通过个性化的宣传手段,吸引有潜在需求的用户,并刺激其转化。
-
在粘客上,如何提升用户的单价和消费频次,方法可以包括购买后的个性化推荐、针对优质用户进行优质高价商品的推荐、以及重复购买,比如通过红包、优惠等方式激励对优惠敏感的人群,提升购买频次。
-
在留客上,预测用户是否可能会从平台上流失。在营销领域,关于用户留存有一个观点——如果将顾客流失率降低 5%,公司利润将提升 25%~85%。可以看出留存率是多么的重要。用户流失可能会包括多种情况,比如用户体验、竞争对手、需求变化等,通过预测用户的流失率可以大幅降低用户留存的运营成本。
-
我们的最终目的不是处理这些数据,而是理解、使用这些数据挖掘的结果。
数据采集
- 开放数据源,一般是针对行业的数据库。比如美国人口调查局开放了美国的人口信息、地区分布和教育情况数据。除了政府外,企业和高校也会开放相应的大数据,这方面北美相对来说做得好一些。国内,贵州做了不少大胆尝试,搭建了云平台,逐年开放了旅游、交通、商务等领域的数据量。
- 爬虫抓取,一般是针对特定的网站或 App。如果我们想要抓取指定的网站数据,比如购物网站上的购物评价等,就需要我们做特定的爬虫抓取。
- 传感器,它基本上采集的是物理信息。比如图像、视频、或者某个物体的速度、热度、压强等。
- 日志采集,这个是统计用户的操作。我们可以在前端进行埋点,在后端进行脚本收集、统计,来分析网站的访问情况,以及使用瓶颈等。
抓取工具
日志采集的形式。
-
通过 Web 服务器采集,例如 httpd、Nginx、Tomcat 都自带日志记录功能。同时很多互联网企业都有自己的海量数据采集工具,多用于系统日志采集,如 Hadoop 的 Chukwa、Cloudera 的 Flume、Facebook 的 Scribe 等,这些工具均采用分布式架构,能够满足每秒数百 MB 的日志数据采集和传输需求。
-
自定义采集用户行为,例如用 JavaScript 代码监听用户的行为、AJAX 异步请求后台记录日志等。
埋点
- 埋点是日志采集的关键步骤
- 埋点就是在有需要的位置采集相应的信息,进行上报。比如某页面的访问情况,包括用户信息、设备信息;或者用户在页面上的操作行为,包括时间长短等。这就是埋点,每一个埋点就像一台摄像头,采集用户行为数据,将数据进行多维度的交叉分析,可真实还原出用户使用场景,和用户使用需求。
数据清洗规则:“完全合一”
完整性:
- 单条数据是否存在空值,统计的字段是否完善。
问题 1:缺失值缺失值
- 删除:删除数据缺失的记录;
- 均值:使用当前列的均值;
- 高频:使用当前列出现频率最高的数据。
# 填充平均值
df['Age'].fillna(df['Age'].mean(), inplace=True)
# 填充高频值
age_maxf = train_features['Age'].value_counts().index[0]
train_features['Age'].fillna(age_maxf, inplace=True)
问题 2:空行
# 删除全空的行
df.dropna(how='all',inplace=True)
全面性
- 观察某一列的全部数值,比如在 Excel 表中,我们选中一列,可以看到该列的平均值、最大值、最小值。我们可以通过常识来判断该列是否有问题,比如:数据定义、单位标识、数值本身。
问题:列数据的单位不统一
合法性
- 数据的类型、内容、大小的合法性。比如数据中存在非 ASCII 字符,性别存在了未知,年龄超过了 150 岁等。
问题:非 ASCII 字符
# 删除非 ASCII 字符
df['first_name'].replace({r'[^\x00-\x7F]+':''}, regex=True, inplace=True)
df['last_name'].replace({r'[^\x00-\x7F]+':''}, regex=True, inplace=True)
唯一性
- 数据是否存在重复记录,因为数据通常来自不同渠道的汇总,重复的情况是常见的。行数据、列数据都需要是唯一的,比如一个人不能重复记录多次,且一个人的体重也不能在列指标中重复记录多次。
问题 1:一列有多个参数
# 切分名字,删除源数据列
df[['first_name','last_name']] = df['name'].str.split(expand=True)
df.drop('name', axis=1, inplace=True)
问题 2:重复数据
# 删除重复数据行
df.drop_duplicates(['first_name','last_name'],inplace=True)
数据集成的两种架构:ELT 和 ETL
决策树的工作原理
构造
- 构造的过程就是选择什么属性作为节点的过程,那么在构造过程中,会存在三种节点:
- 根节点:就是树的最顶端,最开始的那个节点。在上图中,“天气”就是一个根节点;
- 内部节点:就是树中间的那些节点,比如说“温度”、“湿度”、“刮风”;
- 叶节点:就是树最底部的节点,也就是决策结果。
- 那么在构造过程中,你要解决三个重要的问题:
- 选择哪个属性作为根节点;
- 选择哪些属性作为子节点;
- 什么时候停止并得到目标状态,即叶节点。
剪枝
- 剪枝:就是给决策树瘦身,这一步想实现的目标就是,不需要太多的判断,同样可以得到不错的结果。之所以这么做,是为了防止“过拟合”(Overfitting)现象的发生。
- 过拟合:模型的训练结果“太好了”,以至于在实际应用的过程中,会存在“死板”的情况,导致分类错误。造成过拟合的原因之一就是因为训练集中样本量较小。
- 欠拟合:模型拟合程度不高,数据距离拟合曲线较远。
- 泛化能力:指的分类器是通过训练集抽象出来的分类能力,你也可以理解是举一反三的能力。如果我们太依赖于训练集的数据,那么得到的决策树容错率就会比较低,泛化能力差。因为训练集只是全部数据的抽样,并不能体现全部数据的特点。
- 预剪枝Pre-Pruning:是在决策树构造时就进行剪枝。方法是在构造的过程中对节点进行评估,如果对某个节点进行划分,在验证集中不能带来准确性的提升,那么对这个节点进行划分就没有意义,这时就会把当前节点作为叶节点,不对其进行划分。
- 后剪枝Post-Pruning:就是在生成决策树之后再进行剪枝,通常会从决策树的叶节点开始,逐层向上对每个节点进行评估。如果剪掉这个节点子树,与保留该节点子树在分类准确性上差别不大,或者剪掉该节点子树,能在验证集中带来准确性的提升,那么就可以把该节点子树进行剪枝。方法是:用这个节点子树的叶子节点来替代该节点,类标记为这个节点子树中最频繁的那个类。
- 纯度:你可以把决策树的构造过程理解成为寻找纯净划分的过程。数学上,我们可以用纯度来表示,纯度换一种方式来解释就是让目标变量的分歧最小。
- 信息熵(entropy):它表示了信息的不确定度。
在信息论中,随机离散事件出现的概率存在着不确定性。为了衡量这种信息的不确定性,信息学之父香农引入了信息熵的概念,并给出了计算信息熵的数学公式:
-
p(i|t) 代表了节点 t 为分类 i 的概率,其中 log2 为取以 2 为底的对数。这里我们不是来介绍公式的,而是说存在一种度量,它能帮我们反映出来这个信息的不确定度。当不确定性越大时,它所包含的信息量也就越大,信息熵也就越高。
-
我举个简单的例子,假设有 2 个集合
- 集合 1:5 次去打篮球,1 次不去打篮球;
- 集合 2:3 次去打篮球,3 次不去打篮球。
- 在集合 1 中,有 6 次决策,其中打篮球是 5 次,不打篮球是 1 次。那么假设:类别 1 为“打篮球”,即次数为 5;类别 2 为“不打篮球”,即次数为 1。那么节点划分为类别 1 的概率是 5/6,为类别 2 的概率是 1/6,带入上述信息熵公式可以计算得出:
- 同样,集合 2 中,也是一共 6 次决策,其中类别 1 中“打篮球”的次数是 3,类别 2“不打篮球”的次数也是 3,那么信息熵为多少呢?我们可以计算得出:
从上面的计算结果中可以看出,信息熵越大,纯度越低。当集合中的所有样本均匀混合时,信息熵最大,纯度最低。
“不纯度”的指标
- 有三种,分别是信息增益(ID3 算法)、信息增益率(C4.5 算法)以及基尼指数(Cart 算法)。
- 信息增益 ID3:划分可以带来纯度的提高,信息熵的下降。它的计算公式,是父亲节点的信息熵减去所有子节点的信息熵。在计算的过程中,我们会计算每个子节点的归一化信息熵,即按照每个子节点在父节点中出现的概率,来计算这些子节点的信息熵。所以信息增益的公式可以表示为:
-
公式中 D 是父亲节点,Di 是子节点,Gain(D,a) 中的 a 作为 D 节点的属性选择。
-
你可以在下面的图例中直观地了解这几个概念。
- 比如针对图上这个例子,D 作为节点的信息增益为:
- 也就是 D 节点的信息熵 -2 个子节点的归一化信息熵。2 个子节点归一化信息熵 =3/10 的 D1 信息熵 +7/10 的 D2 信息熵。
我们基于 ID3 的算法规则,完整地计算下我们的训练集,训练集中一共有 7 条数据,3 个打篮球,4 个不打篮球,所以根节点的信息熵是:
ID3的缺陷
-
有些属性可能对分类任务没有太大作用,但是他们仍然可能会被选为最优属性。所以改进之后采用信息增益率。
-
ID3 构造决策树的时候,容易产生过拟合的情况。在 C4.5 中,会在决策树构造之后采用悲观剪枝(PEP),这样可以提升决策树的泛化能力。
-
悲观剪枝:后剪枝技术中的一种,通过递归估算每个内部节点的分类错误率,比较剪枝前后这个节点的分类错误率来决定是否对其进行剪枝。这种剪枝方法不再需要一个单独的测试数据集。
C4.5 算法(信息增益率)
信息增益率 = 信息增益 / 属性熵
- C4.5 选择具有最高信息增益的划分所对应的阈值。
- 可以处理缺失值
总结 ID3和C4.5总结
- 首先 ID3 算法的优点是方法简单,缺点是对噪声敏感。训练数据如果有少量错误,可能会产生决策树分类错误。C4.5 在 ID3 的基础上,用信息增益率代替了信息增益,解决了噪声敏感的问题,并且可以对构造树进行剪枝、处理连续数值以及数值缺失等情况,但是由于 C4.5 需要对数据集进行多次扫描,算法效率相对较低。
CART 算法
- 英文全称叫做 Classification And Regression Tree,中文叫做分类回归树。
ID3 和 C4.5 算法可以生成二叉树或多叉树,而 CART 只支持二叉树。同时 CART 决策树比较特殊,既可以作分类树,又可以作回归树。 - 分类树:基于现在数据判断样本的属于哪个分类。
适合处理离散的数据,它输出样本的类别。 - 回归树:基于现在数据预测样本的未来值。适合处理连续型数据,它输出预测的一个数值。
基尼系数
- 经济学中用来衡量一个国家收入差距的常用指标。当基尼系数大于 0.4 的时候,说明财富差异悬殊。基尼系数在 0.2-0.4 之间说明分配合理,财富差距不大。
基尼系数本身反应了样本的不确定度。当基尼系数越小的时候,说明样本之间的差异性小,不确定程度低。
构造CART分类树
# encoding = utf-8
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from sklearn.tree import DecisionTreeClassifier
from sklearn.datasets import load_iris
# 准备数据
iris = load_iris()
# 获取特征集和分类标识
features = iris.data
labels = iris.target
# 随机抽取 33% 的数据作为测试集,其余为训练集
train_features, test_features, train_labels, test_labels \
= train_test_split(features, labels, test_size=0.33, random_state=0)
# 创建 CART 分类树
clf = DecisionTreeClassifier(criterion='gini')
# 拟合构造 CART 分类树
cart = clf.fit(train_features, train_labels)
# 用 CART 分类树做预测
test_predict = clf.predict(test_features)
# 预测结果与测试集结果作比对
score = accuracy_score(test_labels, test_predict)
print("CART 分类树准确率 %.4lf " % score)
CART 回归树
- CART 回归树划分数据集的过程和分类树的过程是一样的,只是回归树得到的预测结果是连续值,而且评判“不纯度”的指标不同。在 CART 分类树中采用的是基尼系数作为标准,那么在 CART 回归树中,如何评价“不纯度”呢?实际上我们要根据样本的混乱程度,也就是样本的离散程度来评价“不纯度”。
from sklearn.metrics import mean_squared_error
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_boston
from sklearn.metrics import r2_score,mean_absolute_error,mean_squared_error
from sklearn.tree import DecisionTreeRegressor
# 准备数据集
boston = load_boston()
# 探索数据
print(boston.feature_names)
# 获取特征集和房价
features = boston.data
prices = boston.target
# 随机抽取 33% 的数据作为测试集,其余为训练集
train_features, test_features, train_price, test_price = train_test_split(features, prices, test_size=0.33)
# 创建 CART 回归树
dtr = DecisionTreeRegressor()
# 拟合构造 CART 回归树
dtr.fit(train_features, train_price)
# 预测测试集中的房价
predict_price = dtr.predict(test_features)
# 测试集的结果评价
print('回归树二乘偏差均值:', mean_squared_error(test_price, predict_price))
print('回归树绝对值偏差均值:', mean_absolute_error(test_price, predict_price))
CART 决策树的剪枝
- CART 决策树的剪枝主要采用的是 CCP 方法,它是一种后剪枝的方法,英文全称叫做 cost-complexity prune,中文叫做代价复杂度。这种剪枝方式用到一个指标叫做节点的表面误差率增益值,以此作为剪枝前后误差的定义。用公式表示则是:
- 其中 Tt 代表以 t 为根节点的子树,C(Tt) 表示节点 t 的子树没被裁剪时子树 Tt 的误差,C(t) 表示节点 t 的子树被剪枝后节点 t 的误差,|Tt|代子树 Tt 的叶子数,剪枝后,T 的叶子数减少了|Tt|-1。
三种决策树
- ID3 算法,基于信息增益做判断;
- C4.5 算法,基于信息增益率做判断;
- CART 算法,分类树是基于基尼系数做判断。回归树是基于偏差做判断。
决策树模型
贝叶斯原理
- 这当你不能准确知悉一个事物的本质时,你可以依靠与事物特定本质相关的事件出现的多少去判断其本质属性的概率。用数学语言表达就是:支持某项属性的事件发生得愈多,则该属性成立的可能性就愈大。
- 逆向概率:在我们不了解所有客观事实的情况下,同样可以先估计一个值,然后根据实际结果不断进行修正。
- 先验概率:通过经验来判断事情发生的概率。
- 后验概率:后验概率就是发生结果之后,推测原因的概率。
- 条件概率:事件 A 在另外一个事件 B 已经发生条件下的发生概率,表示为 P(A|B),读作“在 B 发生的条件下 A 发生的概率”。
- 似然函数(likelihood function):你可以把概率模型的训练过程理解为求参数估计的过程。举个例子,如果一个硬币在 10 次抛落中正面均朝上。那么你肯定在想,这个硬币是均匀的可能性是多少?这里硬币均匀就是个参数,似然函数就是用来衡量这个模型的参数。似然在这里就是可能性的意思,它是关于统计参数的函数。
朴素贝叶斯
- 它是一种简单但极为强大的预测建模算法。之所以称为朴素贝叶斯,是因为它假设每个输入变量是独立的。这是一个强硬的假设,实际情况并不一定,但是这项技术对于绝大部分的复杂问题仍然非常有效。
- 朴素贝叶斯模型由两种类型的概率组成:
- 每个类别的概率P(Cj);
- 每个属性的条件概率P(Ai|Cj)。
- 朴素贝叶斯分类最适合的场景就是文本分类、情感分析和垃圾邮件识别。这三个场景本质上都是文本分类,这也是朴素贝叶斯最擅长的地方。所以朴素贝叶斯也常用于自然语言处理 NLP 的工具。
sklearn 机器学习包
-
sklearn 的全称叫 Scikit-learn,它给我们提供了 3 个朴素贝叶斯分类算法,分别是高斯朴素贝叶斯(GaussianNB)、多项式朴素贝叶斯(MultinomialNB)和伯努利朴素贝叶斯(BernoulliNB)。
-
高斯朴素贝叶斯:特征变量是连续变量,符合高斯分布,比如说人的身高,物体的长度。
-
多项式朴素贝叶斯:特征变量是离散变量,符合多项分布,在文档分类中特征变量体现在一个单词出现的次数,或者是单词的 TF-IDF 值等。
-
伯努利朴素贝叶斯:特征变量是布尔变量,符合 0/1 分布,在文档分类中特征是单词是否出现。
词频 TF
- 计算了一个单词在文档中出现的次数,它认为一个单词的重要性和它在文档中出现的次数呈正比。
逆向文档频率 IDF
- 指一个单词在文档中的区分度。它认为一个单词出现在的文档数越少,就越能通过这个单词把该文档和其他文档区分开。IDF 越大就代表该单词的区分度越大。
- 所以 TF-IDF 实际上是词频 TF 和逆向文档频率 IDF 的乘积。
TF-IDF 计算
SVM
-
SVM 的英文叫 Support Vector Machine,中文名为支持向量机。它是常见的一种分类方法,在机器学习中,SVM 是有监督的学习模型。
-
它在文本分类尤其是针对二分类任务性能卓越。同样,针对多分类的情况,我们可以采用一对多,或者一对一的方法,多个二值分类器组合成一个多分类器。
-
核函数:它可以将样本从原始空间映射到一个更高维的特质空间中,使得样本在新的空间中线性可分。
-
另外关于 SVM 分类器的概念,我希望你能掌握以下的三个程度:
-
完全线性可分情况下的线性分类器,也就是线性可分的情况,是最原始的 SVM,它最核心的思想就是找到最大的分类间隔;
-
大部分线性可分情况下的线性分类器,引入了软间隔的概念。软间隔,就是允许一定量的样本分类错误;
-
线性不可分情况下的非线性分类器,引入了核函数。它让原有的样本空间通过核函数投射到了一个高维的空间中,从而变得线性可分。
如何在 sklearn 中使用 SVM
-
线性核函数,是在数据线性可分的情况下使用的,运算速度快,效果好。不足在于它不能处理线性不可分的数据。
-
多项式核函数可以将数据从低维空间映射到高维空间,但参数比较多,计算量大。
-
高斯核函数同样可以将样本映射到高维空间,但相比于多项式核函数来说所需的参数比较少,通常性能不错,所以是默认使用的核函数。
-
sigmoid核函数经常用在神经网络的映射中,SVM 实现的是多层神经网络。
KNN
- KNN 的英文叫 K-Nearest Neighbor,应该算是数据挖掘算法中最简单的一种,主要思想是 近朱者赤,近墨者黑。
- 工作原理
- 计算待分类物体与其他物体之间的距离;
- 统计距离最近的 K 个邻居;
- 对于 K 个最近的邻居,它们属于哪个分类最多,待分类物体就属于哪一类。在工程上,我们一般采用交叉验证的方式选取 K 值。
- 计算距离的方法
- 欧氏距离;
- 曼哈顿距离;
- 闵可夫斯基距离;
- 切比雪夫距离;
- 余弦距离。
K-Means
- K-Means 是一种非监督学习,解决的是聚类问题。K 代表的是 K 类,Means 代表的是中心,你可以理解这个算法的本质是确定 K 类的中心点,当你找到了这些中心点,也就完成了聚类。
- 选取 K 个点作为初始的类中心点,这些点一般都是从数据集中随机抽取的;
- 将每个点分配到最近的类中心点,这样就形成了 K 个类,然后重新计算每个类的中心点;
- 重复第二步,直到类不发生变化,或者你也可以设置最大迭代次数,这样即使类中心点发生变化,但是只要达到最大迭代次数就会结束。
EM 聚类
- EM 的英文是 Expectation Maximization,所以 EM 算法也叫最大期望算法。
- 初始化参数、观察预期、重新估计。首先是先给每个碟子初始化一些菜量,然后再观察预期,这两个步骤实际上就是期望步骤(Expectation)。如果结果存在偏差就需要重新估计参数,这个就是最大化步骤(Maximization)。这两个步骤加起来也就是 EM 算法的过程。
- EM 算法最直接的应用就是求参数估计。如果我们把潜在类别当做隐藏变量,样本看做观察值,就可以把聚类问题转化为参数估计问题。这也就是 EM 聚类的原理。
- K-Means 是通过距离来区分样本之间的差别的,且每个样本在计算的时候只能属于一个分类,称之为是硬聚类算法。
- 而 EM 聚类在求解的过程中,实际上每个样本都有一定的概率和每个聚类相关,叫做软聚类算法。
- 在 EM 这个框架中,E 步骤相当于是通过初始化的参数来估计隐含变量。M 步骤就是通过隐含变量反推来优化参数。最后通过 EM 步骤的迭代得到模型参数。
- GMM(高斯混合模型) 是通过概率密度来进行聚类,聚成的类符合高斯分布(正态分布)。
- HMM(隐马尔科夫模型) 用到了马尔可夫过程,在这个过程中,我们通过状态转移矩阵来计算状态转移的概率。HMM 在自然语言处理和语音识别领域中有广泛的应用。
监督学习
- 定义:根据已有的数据集,知道输入和输出结果之间的关系。根据这种已知的关系,训练得到一个最优的模型。也就是说,在监督学习中训练数据既有特征(feature)又有标签(label),通过训练,让机器可以自己找到特征和标签之间的联系,在面对只有特征没有标签的数据时,可以判断出标签。
* 通俗一点,可以把机器学习理解为我们教机器如何做事情。 - 监督学习的分类:回归(Regression)、分类(Classification)
无监督学习
- 定义:我们不知道数据集中数据、特征之间的关系,而是要根据聚类或一定的模型得到数据之间的关系。
- 可以这么说,比起监督学习,无监督学习更像是自学,让机器学会自己做事情,是没有标签(label)的。
关联规则Apriori 算法
- 支持度:是个百分比,它指的是某个商品组合出现的次数与总次数之间的比例。支持度越高,代表这个组合出现的频率越大。
- 置信度:是个条件概念,就是说在 A 发生的情况下,B 发生的概率是多少。
- 提升度:“商品 A 的出现,对商品 B 的出现概率提升的”程度。
- 提升度 (A→B)= 置信度 (A→B)/ 支持度 (B)
- 提升度 (A→B)>1:代表有提升;
- 提升度 (A→B)=1:代表有没有提升,也没有下降;
- 提升度 (A→B)<1:代表有下降。
Apriori 的工作原理
- Apriori 算法其实就是查找频繁项集 (frequent itemset) 的过程。
- 频繁项集就是支持度大于等于最小支持度 (Min Support) 阈值的项集,所以小于最小值支持度的项目就是非频繁项集,而大于等于最小支持度的项集就是频繁项集。
- 项集这个概念,英文叫做 itemset,它可以是单个的商品,也可以是商品的组合。
FP-Growth 算法
- Apriori 算法会浪费很多计算空间和计算时间,为此人们提出了 FP-Growth 算法,它的特点是:
- 创建了一棵 FP 树来存储频繁项集。在创建前对不满足最小支持度的项进行删除,减少了存储空间。
- 整个生成过程只遍历数据集 2 次,大大减少了计算量。
FP-Growth 的原理
- 创建项头表(item header table)
- 创建项头表的作用是为 FP 构建及频繁项集挖掘提供索引。
这一步的流程是先扫描一遍数据集,对于满足最小支持度的单个项(K=1 项集)按照支持度从高到低进行排序,这个过程中删除了不满足最小支持度的项。
- 构造 FP 树
- FP 树的根节点记为 NULL 节点。
整个流程是需要再次扫描数据集,对于每一条数据,按照支持度从高到低的顺序进行创建节点(也就是第一步中项头表中的排序结果),节点如果存在就将计数 count+1,如果不存在就进行创建。同时在创建的过程中,需要更新项头表的链表。
- 通过 FP 树挖掘频繁项集
- 我们可以通过项头表来挖掘出每个频繁项集。
具体的操作会用到一个概念,叫“条件模式基”,它指的是以要挖掘的节点为叶子节点,自底向上求出 FP 子树,然后将 FP 子树的祖先节点设置为叶子节点之和。
PageRank
- 适用于关系网中,对个体的权重进行计算。
- Google 的两位创始人都是斯坦福大学的博士生,他们提出的 PageRank 算法受到了论文影响力因子的评价启发。当一篇论文被引用的次数越多,证明这篇论文的影响力越大。正是这个想法解决了当时网页检索质量不高的问题。
- 一个网页的影响力 = 所有入链集合的页面的加权影响力之和,用公式表示为:
可能会面临的问题
- 等级泄露(Rank Leak):如果一个网页没有出链,就像是一个黑洞一样,吸收了其他网页的影响力而不释放,最终会导致其他网页的 PR 值为 0。
- 等级沉没(Rank Sink):如果一个网页只有出链,没有入链(如下图所示),计算的过程迭代下来,会导致这个网页的 PR 值为 0(也就是不存在公式中的 V)。
PageRank 的随机浏览模型
- 定义了阻尼因子 d,这个因子代表了用户按照跳转链接来上网的概率,通常可以取一个固定值 0.85,而 1-d=0.15 则代表了用户不是通过跳转链接的方式来访问网页的,比如直接输入网址。
其中 N 为网页总数,这样我们又可以重新迭代网页的权重计算了,因为加入了阻尼因子 d,一定程度上解决了等级泄露和等级沉没的问题。
通过数学定理(这里不进行讲解)也可以证明,最终 PageRank 随机浏览模型是可以收敛的,也就是可以得到一个稳定正常的 PR 值。
AdaBoost 算法
集成算法
- 在数据挖掘中,分类算法可以说是核心算法,其中 AdaBoost 算法与随机森林算法一样都属于分类算法中的集成算法。
集成算法的方式
- 投票选举(bagging)
投票选举的场景类似把专家召集到一个会议桌前,当做一个决定的时候,让 K 个专家(K 个模型)分别进行分类,然后选择出现次数最多的那个类作为最终的分类结果。 - 再学习(boosting)
再学习相当于把 K 个专家(K 个分类器)进行加权融合,形成一个新的超级专家(强分类器),让这个超级专家做判断。
每一次训练的时候都对上一次的训练进行改进提升,在训练的过程中这 K 个“专家”之间是有依赖性的,当引入第 K 个“专家”(第 K 个分类器)的时候,实际上是对前 K-1 个专家的优化。
而 bagging 做投票选举的时候可以并行计算,相互独立的,不存在依赖性。
AdaBoost 算法
- AdaBoost 的英文全称是 Adaptive Boosting,中文含义是自适应提升算法。它由 Freund 等人于 1995 年提出,是对 Boosting 算法的一种实现。
Boosting 算法
- Boosting 算法是集成算法中的一种,同时也是一类算法的总称。这类算法通过训练多个弱分类器,将它们组合成一个强分类器,也就是我们俗话说的“三个臭皮匠,顶个诸葛亮”。
因此要打造一个诸葛亮,最好的方式就是训练多个臭皮匠,然后让这些臭皮匠组合起来,这样往往可以得到很好的效果。这就是 Boosting 算法的原理。 - 假设弱分类器为 Gi(x),它在强分类器中的权重 αi,那么就可以得出强分类器 f(x):
- 实际上在一个由 K 个弱分类器中组成的强分类器中,如果弱分类器的分类效果好,那么权重应该比较大,如果弱分类器的分类效果一般,权重应该降低。所以我们需要基于这个弱分类器对样本的分类错误率来决定它的权重,用公式表示就是:
如何在每次训练迭代的过程中选择最优的弱分类器
- AdaBoost 算法是通过改变样本的数据分布来实现的。
AdaBoost 会判断每次训练的样本是否正确分类,对于正确分类的样本,降低它的权重,对于被错误分类的样本,增加它的权重。
再基于上一次得到的分类准确率,来确定这次训练样本中每个样本的权重。然后将修改过权重的新数据集传递给下一层的分类器进行训练。
这样做的好处就是,通过每一轮训练样本的动态权重,可以让训练的焦点集中到难分类的样本上,最终得到的弱分类器的组合更容易得到更高的分类准确率。
我们可以用 Dk+1 代表第 k+1 轮训练中,样本的权重集合,其中 Wk+1,1 代表第 k+1 轮中第一个样本的权重,以此类推 Wk+1,N 代表第 k+1 轮中第 N 个样本的权重,因此用公式表示为:
第 k+1 轮中的样本权重,是根据该样本在第 k 轮的权重以及第 k 个分类器的准确率而定,具体的公式为:
AdaBoost 工具使用
使用 AdaBoostClassifier(base_estimator=None, n_estimators=50, learning_rate=1.0, algorithm=’SAMME.R’, random_state=None) 这个函数,其中有几个比较主要的参数,我分别来讲解下:
- base_estimator:代表的是弱分类器。在 AdaBoost 的分类器和回归器中都有这个参数,在 AdaBoost 中默认使用的是决策树,一般我们不需要修改这个参数,当然你也可以指定具体的分类器。
- n_estimators:算法的最大迭代次数,也是分类器的个数,每一次迭代都会引入一个新的弱分类器来增加原有的分类器的组合能力。默认是 50。
- learning_rate:代表学习率,取值在 0-1 之间,默认是 1.0。如果学习率较小,就需要比较多的迭代次数才能收敛,也就是说学习率和迭代次数是有相关性的。当你调整 learning_rate 的时候,往往也需要调整 n_estimators 这个参数。
- algorithm:代表我们要采用哪种 boosting 算法,一共有两种选择:SAMME 和 SAMME.R。默认是 SAMME.R。这两者之间的区别在于对弱分类权重的计算方式不同。
- random_state:代表随机数种子的设置,默认是 None。随机种子是用来控制随机模式的,当随机种子取了一个值,也就确定了一种随机规则,其他人取这个值可以得到同样的结果。如果不设置随机种子,每次得到的随机数也就不同。
Selenium 自动化测试工具
- 如果我们想定位一个元素,可以通过 id、name、class、tag、链接上的全部文本、链接上的部分文本、XPath 或者 CSS 进行定位,在 Selenium Webdriver 中也提供了这 8 种方法方便我们定位元素。
- 通过 id 定位:我们可以使用 find_element_by_id() 函数。比如我们想定位 id=loginName 的元素,就可以使用 browser.find_element_by_id(“loginName”)。
- 通过 name 定位:我们可以使用 find_element_by_name() 函数,比如我们想要对 name=key_word 的元素进行定位,就可以使用 browser.find_element_by_name(“key_word”)。
- 通过 class 定位:可以使用 find_element_by_class_name() 函数。
- 通过 tag 定位:使用 find_element_by_tag_name() 函数。
- 通过 link 上的完整文本定位:使用 find_element_by_link_text() 函数。
- 通过 link 上的部分文本定位:使用 find_element_by_partial_link_text() 函数。有时候超链接上的文本很长,我们通过查找部分文本内容就可以定位。
- 通过 XPath 定位:使用 find_element_by_xpath() 函数。使用 XPath 定位的通用性比较好,因为当 id、name、class 为多个,或者元素没有这些属性值的时候,XPath 定位可以帮我们完成任务。
- 通过 CSS 定位:使用 find_element_by_css_selector() 函数。CSS 定位也是常用的定位方法,相比于 XPath 来说更简洁。
- 在我们获取某个元素之后,就可以对这个元素进行操作了,对元素进行的操作包括:
- 清空输入框的内容:使用 clear() 函数;
- 在输入框中输入内容:使用 send_keys(content) 函数传入要输入的文本;
- 点击按钮:使用 click() 函数,如果元素是个按钮或者链接的时候,可以点击操作;
- 提交表单:使用 submit() 函数,元素对象为一个表单的时候,可以提交表单;
做词云展示
构建随机森林分类器
- 随机森林的英文是 Random Forest,英文简写是 RF。它实际上是一个包含多个决策树的分类器,每一个子分类器都是一棵 CART 分类回归树。所以随机森林既可以做分类,又可以做回归。当它做分类的时候,输出结果是每个子分类器的分类结果中最多的那个。你可以理解是每个分类器都做投票,取投票最多的那个结果。当它做回归的时候,输出结果是每棵 CART 树的回归结果的平均值。
操作步骤
- 加载数据;
- 准备阶段:探索数据,采用数据可视化方式可以让我们对数据有更直观的了解,比如我们想要了解信用卡违约率和不违约率的人数。因为数据集没有专门的测试集,我们还需要使用 train_test_split 划分数据集。
- 分类阶段:之所以把数据规范化放到这个阶段,是因为我们可以使用 Pipeline 管道机制,将数据规范化设置为第一步,分类为第二步。因为我们不知道采用哪个分类器效果好,所以我们需要多用几个分类器,比如 SVM、决策树、随机森林和 KNN。然后通过 GridSearchCV 工具,找到每个分类器的最优参数和最优分数,最终找到最适合这个项目的分类器和该分类器的参数。
构建逻辑回归分类器
- 逻辑回归,也叫作 logistic 回归。虽然名字中带有“回归”,但它实际上是分类方法,主要解决的是二分类问题,当然它也可以解决多分类问题,只是二分类更常见一些。
在逻辑回归中使用了 Logistic 函数,也称为 Sigmoid 函数。Sigmoid 函数是在深度学习中经常用到的函数之一,函数公式为:
- 逻辑回归模型的求解这里不做介绍,我们来看下如何使用 sklearn 中的逻辑回归工具。在 sklearn 中,我们使用 LogisticRegression() 函数构建逻辑回归分类器,函数里有一些常用的构造参数:
- penalty:惩罚项,取值为 l1 或 l2,默认为 l2。当模型参数满足高斯分布的时候,使用 l2,当模型参数满足拉普拉斯分布的时候,使用 l1;
- solver:代表的是逻辑回归损失函数的优化方法。有 5 个参数可选,分别为 liblinear、lbfgs、newton-cg、sag 和 saga。默认为 liblinear,适用于数据量小的数据集,当数据量大的时候可以选用 sag 或 saga 方法。
- max_iter:算法收敛的最大迭代次数,默认为 10。
- n_jobs:拟合和预测的时候 CPU 的核数,默认是 1,也可以是整数,如果是 -1 则代表 CPU 的核数。
模型评估指标
-
TP:预测为正,判断正确;
FP:预测为正,判断错误;
TN:预测为负,判断正确;
FN:预测为负,判断错误。 -
我们知道样本总数 =TP+FP+TN+FN,预测正确的样本数为 TP+TN,因此准确率 Accuracy = (TP+TN)/(TP+TN+FN+FP)。
-
实际上,对于分类不平衡的情况,有两个指标非常重要,它们分别是精确度和召回率。
-
精确率 P = TP/ (TP+FP),对应上面恐怖分子这个例子,在所有判断为恐怖分子的人数中,真正是恐怖分子的比例。
-
召回率 R = TP/ (TP+FN),也称为查全率。代表的是恐怖分子被正确识别出来的个数与恐怖分子总数的比例。
-
有一个指标综合了精确率和召回率,可以更好地评估模型的好坏。这个指标叫做 F1,用公式表示为:
- F1 作为精确率 P 和召回率 R 的调和平均,数值越大代表模型的结果越好。
时间序列分析
-
AR 的英文全称叫做 Auto Regressive,中文叫自回归模型。这个算法的思想比较简单,它认为过去若干时刻的点通过线性组合,再加上白噪声就可以预测未来某个时刻的点。
在我们日常生活环境中就存在白噪声,在数据挖掘的过程中,你可以把它理解为一个期望为 0,方差为常数的纯随机过程。AR 模型还存在一个阶数,称为 AR(p)模型,也叫作 p 阶自回归模型。它指的是通过这个时刻点的前 p 个点,通过线性组合再加上白噪声来预测当前时刻点的值。 -
MA 的英文全称叫做 Moving Average,中文叫做滑动平均模型。它与 AR 模型大同小异,AR 模型是历史时序值的线性组合,MA 是通过历史白噪声进行线性组合来影响当前时刻点。AR 模型中的历史白噪声是通过影响历史时序值,从而间接影响到当前时刻点的预测值。同样 MA 模型也存在一个阶数,称为 MA(q) 模型,也叫作 q 阶移动平均模型。我们能看到 AR 和 MA 模型都存在阶数,在 AR 模型中,我们用 p 表示,在 MA 模型中我们用 q 表示,这两个模型大同小异,与 AR 模型不同的是 MA 模型是历史白噪声的线性组合。
-
ARMA 的英文全称是 Auto Regressive Moving Average,中文叫做自回归滑动平均模型,也就是 AR 模型和 MA 模型的混合。相比 AR 模型和 MA 模型,它有更准确的估计。同样 ARMA 模型存在 p 和 q 两个阶数,称为 ARMA(p,q) 模型。
-
ARIMA 的英文全称是 Auto Regressive Integrated Moving Average 模型,中文叫差分自回归滑动平均模型,也叫求合自回归滑动平均模型。相比于 ARMA,ARIMA 多了一个差分的过程,作用是对不平稳数据进行差分平稳,在差分平稳后再进行建模。ARIMA 的原理和 ARMA 模型一样。相比于 ARMA(p,q) 的两个阶数,ARIMA 是一个三元组的阶数 (p,d,q),称为 ARIMA(p,d,q) 模型。其中 d 是差分阶数。
数据挖掘,机器学习,深度学习的区别是什么?
- 数据挖掘通常是从现有的数据中提取规律模式(pattern)以及使用算法模型(model)。核心目的是找到这些数据变量之间的关系,因此我们也会通过数据可视化对变量之间的关系进行呈现,用算法模型挖掘变量之间的关联关系。通常情况下,我们只能判断出来变量 A 和变量 B 是有关系的,但并不一定清楚这两者之间有什么具体关系。在我们谈论数据挖掘的时候,更强调的是从数据中挖掘价值。
- 机器学习是人工智能的一部分,它指的是通过训练数据和算法模型让机器具有一定的智能。一般是通过已有的数据来学习知识,并通过各种算法模型形成一定的处理能力,比如分类、聚类、预测、推荐能力等。这样当有新的数据进来时,就可以通过训练好的模型对这些数据进行预测,也就是通过机器的智能帮我们完成某些特定的任务。
- 深度学习属于机器学习的一种,它的目标同样是让机器具有智能,只是与传统的机器学习算法不同,它是通过神经网络来实现的。神经网络就好比是机器的大脑,刚开始就像一个婴儿一样,是一张白纸。但通过多次训练之后,“大脑”就可以逐渐具备某种能力。这个训练过程中,我们只需要告诉这个大脑输入数据是什么,以及对应的输出结果是什么即可。通过多次训练,“大脑”中的多层神经网络的参数就会自动优化,从而得到一个适应于训练数据的模型。
深度学习会自己找到数据的特征规律!而传统机器学习往往需要专家(我们)来告诉机器采用什么样的模型算法,这就是深度学习与传统机器学习最大的区别。
FNN
- FNN(Fully-connected Neural Network)指的是全连接神经网络,全连接的意思是每一层的神经元与上一层的所有神经元都是连接的。不过在实际使用中,全连接的参数会过多,导致计算量过大。因此在实际使用中全连接神经网络的层数一般比较少。
CNN
- CNN叫作卷积神经网络,在图像处理中有广泛的应用,CNN 网络中,包括了卷积层、池化层和全连接层。
- 卷积层相当于一个滤镜的作用,它可以把图像进行分块,对每一块的图像进行变换操作。实际上每个卷积核都是一种滤波器,它们把图像中符合条件的部分筛选出来,也就相当于做了某种特征提取。
- 池化层相当于对神经元的数据进行降维处理,这样输出的维数就会减少很多,从而降低整体的计算量。
- 全连接层通常是输出层的上一层,它将上一层神经元输出的数据转变成一维的向量。
RNN
RNN称为循环神经网络,它的特点是神经元的输出可以在下一个时刻作用到自身,这样 RNN 就可以看做是在时间上传递的神经网络。它可以应用在语音识别、自然语言处理等与上下文相关的场景。
深度学习的应用领域
图像识别
语音识别
NLP自然语言处理
如何理解 CNN 网络中的卷积作用
我简单说下计算的原理。
- 第一步,我们需要将卷积核翻转 180 度(只有翻转之后才能做矩阵运算),也就是变成:
- 第二步,将卷积核的第一个元素,对准矩阵 X 左上角的第一个元素,对应元素相乘,然后再相加可以就可以得到 101+101+100+101+50+5-1+100+5-1+5*-1=15。
- 第三步,每个元素都重复第二步的计算过程,可以得到如下的矩阵结果 Z:
import pylab
import numpy as np
from scipy import signal
# 设置原图像
img = np.array([[10, 10, 10, 10, 10],
[10, 5, 5, 5, 10],
[10, 5, 5, 5, 10],
[10, 5, 5, 5, 10],
[10, 10, 10, 10, 10]])
# 设置卷积核
fil = np.array([[ -1,-1, 0],
[ -1, 0, 1],
[ 0, 1, 1]])
# 对原图像进行卷积操作
res = signal.convolve2d(img, fil, mode='valid')
# 输出卷积后的结果
print(res)
-
实际上每个卷积核都是一种滤波器,它们把图像中符合条件的部分筛选出来,也就相当于做了某种特征提取。
-
在 CNN 的卷积层中可以有多个卷积核,以 LeNet 为例,它的第一层卷积核有 6 个,因此可以帮我们提取出图像的 6 个特征,从而得到 6 个特征图(feature maps)。
激活函数的作用
-
做完卷积操作之后,通常还需要使用激活函数对图像进一步处理。在逻辑回归中,我提到过 Sigmoid 函数,它在深度学习中有广泛的应用,除了 Sigmoid 函数作为激活函数以外,tanh、ReLU 都是常用的激活函数。
-
这些激活函数通常都是非线性的函数,使用它们的目的是把线性数值映射到非线性空间中。卷积操作实际上是两个矩阵之间的乘法,得到的结果也是线性的。只有经过非线性的激活函数运算之后,才能映射到非线性空间中,这样也可以让神经网络的表达能力更强大。
池化层的作用
- 池化层通常在两个卷积层之间,它的作用相当于对神经元的数据做降维处理,这样就能降低整体计算量。
- 在神经网络中,我们可以叠加多个卷积层和池化层来提取更抽象的特征。经过几次卷积和池化之后,通常会有一个或多个全连接层。
全连接层的作用
- 全连接层将前面一层的输出结果与当前层的每个神经元都进行了连接。
CNN 网络结构中每一层的作用:
- 它通过卷积层提取特征,通过激活函数让结果映射到非线性空间,增强了结果的表达能力,再通过池化层压缩特征图,降低了网络复杂度,最后通过全连接层归一化,然后连接 Softmax 分类器进行计算每个类别的概率。