为什么要写本文
机器学习涉及到很多数学相关基础知识,概率论,高数算法等,而直接去看这些课本或书籍,简直就是晦涩难懂,哪怕是西瓜书这种通俗易懂的书籍,对于数学不好的人来讲也有点像天书。为了让小白可以较轻松的掌握一些机器学习相关知识,还是要从案例出发,通过案例来学习用到的数学知识,熟悉各种算法的原理,顺便将用到的库和框架进行简单介绍,而且可以结合场景解决实际问题,提高初学者幸福感。
不过在此还是要列举一些书籍可供参考:
- 概率论和高数,直接大学课本就好
- 《机器学习》:俗称西瓜书,学习机器学习的经典书籍
- 《Python数据分析与挖掘实战》:从数据挖掘的应用出发,以电力、航空、医疗、互联网、生产制造以及公共服务等行业真实案例为主线,深入浅出介绍Python数据挖掘建模过程,实践性极强。
- 《TensorFlow技术解析与实战》:包揽TensorFlow1.1的新特性 人脸识别 语音识别 图像和语音相结合等热点一应俱全
机器学习是什么
机器学习是人工智能的一个分支。机器学习算法是一类从数据中自动分析获得规律,并利用规律对未知数据进行预测的算法。专门研究计算机怎样模拟或实现人类的学习行为,以获取新的知识或技能,重新组织已有的知识结构使之不断改善自身的性能。 它是人工智能的核心,是使计算机具有智能的根本途径,其应用遍及人工智能的各个领域,它主要使用归纳、综合而不是演绎。因为学习算法中涉及了大量的统计学理论,机器学习与推断统计学联系尤为密切,也被称为统计学习理论。
机器学习应用在哪些方面?
维基百科:机器学习已广泛应用于数据挖掘、计算机视觉、自然语言处理、生物特征识别、搜索引擎、医学诊断、检测信用卡欺诈、证券市场分析、DNA序列测序、语音和手写识别、战略游戏和机器人等领域。
新闻等应用上的推荐类功能,人脸识别相关功能:直播时的美颜、加装饰等等;
这里有一个集合,最具价值的50个机器学习应用[2017年]:https://bigquant.com/community/t/topic/6909
数据
python深度学习中,读取数据一般是通过pandas读取文件,之所以不读取数据库,是因为数据库读取速度会成为性能瓶颈。
可用数据集:
- Kaggle:1、大数据竞赛平台,真实数据,数据量巨大
- UCI:1,覆盖科学、生活、经济等领域
- scikit-learn:数据量小,方便学习
常用数据集结构:特征值+目标值
注:有些数据可以没有目标值
数据中对于特征的处理:
- pandas:一个数据读取非常方便以及基本的处理格式的工具
- 对于特征的处理提供了强大的接口
特征工程
什么是特征工程(目的)
一句话:特征工程是将原始数据转换为更好的代表预测模型的潜在问题的特征的过程,从而提高了对未知数据的预测准确性。
“数据决定了机器学习的上限,而算法只是尽可能逼近这个上限”,这里的数据指的就是经过特征工程得到的数据。特征工程指的是把原始数据转变为模型的训练数据的过程,它的目的就是获取更好的训练数据特征,使得机器学习模型逼近这个上限。特征工程能使得模型的性能得到提升,有时甚至在简单的模型上也能取得不错的效果。特征工程在机器学习中占有非常重要的作用,一般认为括特征构建、特征提取、特征选择三个部分。特征构建比较麻烦,需要一定的经验。 特征提取与特征选择都是为了从原始特征中找出最有效的特征。它们之间的区别是特征提取强调通过特征转换的方式得到一组具有明显物理或统计意义的特征;而特征选择是从特征集合中挑选一组具有明显物理或统计意义的特征子集。两者都能帮助减少特征的维度、数据冗余,特征提取有时能发现更有意义的特征属性,特征选择的过程经常能表示出每个特征的重要性对于模型构建的重要性。
特征工程的目的是筛选出更好的特征,获取更好的训练数据.
特征工程流程:
- 数据采集 / 清洗 / 采样
- 1.1:数据采集:数据采集前需要明确采集哪些数据,一般的思路为:哪些数据对最后的结果预测有帮助?数据我们能够采集到吗?线上实时计算的时候获取是否快捷?
- 1.2:数据清洗: 数据清洗也是很重要的一步,机器学习算法大多数时候就是一个加工机器,至于最后的产品如何,取决于原材料的好坏。数据清洗就是要去除脏数据,比如某些商品的刷单数据。
- 1.3:数据采样:采集、清洗过数据以后,正负样本是不均衡的,要进行数据采样。采样的方法有随机采样和分层抽样。但是随机采样会有隐患,因为可能某次随机采样得到的数据很不均匀,更多的是根据特征采用分层抽样。
- 数据采集 / 清洗 / 采样
- 2.特征处理
- 2.1:数值型
- 幅度调整/归一化:python中会有一些函数比如preprocessing.MinMaxScaler()将幅度调整到 [0,1] 区间。
- 统计值:包括max, min, mean, std等。python中用pandas库序列化数据后,可以得到数据的统计值。
- 2.2:类别型,类别型一般是文本信息,比如颜色是红色、黄色还是蓝色,我们存储数据的时候就需要先处理数据
- one-hot编码,编码后得到哑变量。统计这个特征上有多少类,就设置几维的向量,pd.get_dummies()可以进行one-hot编码。
- Hash编码成词向量
- Histogram映射:把每一列的特征拿出来,根据target内容做统计,把target中的每个内容对应的百分比填到对应的向量的位置。优点是把两个特征联系起来。
- 2.3:时间型
- 连续值
- 离散值
- 2.4:文本型
- 词袋:文本数据预处理后,去掉停用词,剩下的词组成的list,在词库中的映射稀疏向量。Python中用CountVectorizer处理词袋.
- 把词袋中的词扩充到n-gram:n-gram代表n个词的组合。
- 2.5:统计型
- 加减平均,商品价格高于平均价格多少,用户在某个品类下消费超过平均用户多少,用户连续登录天数超过平均多少…
- 分位线,商品属于售出商品价格的多少分位线处
- 次序型
- 比例类
- 2.6:组合特征
- 拼接型
- 模型特征组合
- 2.1:数值型
- 3.特征选择:特征选择,就是从多个特征中,挑选出一些对结果预测最有用的特征。特征选择和降维有什么区别呢?前者只踢掉原本特征里和结果预测关系不大的, 后者做特征的计算组合构成新特征。
3.1:过滤型,评估单个特征和结果值之间的相关程度, 排序留下Top相关的特征部分。
3.2:包裹型,把特征选择看做一个特征子集搜索问题, 筛选各种特征子集, 用模型评估效果。 典型算法:“递归特征删除算法”。
3.3:嵌入型,根据模型来分析特征的重要性,最常见的方式为用正则化方式来做特征选择。
scikit-learn工具
- Python语言的机器学习工具基于Numpy和Scipy
- 提供了大量用于数据挖掘和分析的工具,包括数据预处理、交叉验证、算法与可视化算法等一系列接口。
- 文档完善,容易上手
特征抽取
API:sklearn.feature_extraction
字典特征数据抽取:把字典中一些类别数据,转换为特征值,如One-hot编码形势。
- DictVectorizer
文本特征抽取:对文本数据进行特征值化
文本抽取默认不会对中文进行分词,而是按照空格逗号等进行分。所以在fit_transform之前要进行分词。
- CountVectorizer:简单的频率统计
- TfidfVectorizer:tf-idf算法
- 在将文本分词并向量化后,我们可以得到词汇表中每个词在各个文本中形成的词向量,但是这时候的词向量里,有一些类似”to”,”my”,”is”的词,出现的频率可能会高于文章的中心词汇,如果我们的向量化特征仅仅用词频表示就无法反应这一点。因此我们需要进一步的预处理来反应文本的这个特征,而这个预处理就是TF-IDF。
- TF-IDF是Term Frequency - Inverse Document Frequency的缩写,即“词频-逆文本频率”。它由两部分组成,TF和IDF。
- TF也就是词频,我们做的向量化也就是做了文本中各个词的出现频率统计。
词频(TF) = 某个词在文章中的出现次数
词频(TF) = 某个词在文章中的出现次数 / 文章总词数。这里是因为文章有长短之分,为了便于不同文章的比较,做”词频”标准化. - IDF,即“逆文本频率”,IDF反应了一个词在所有文本中出现的频率,如果一个词在很多的文本中出现,那么它的IDF值应该低,比如上文中的“to”。而反过来如果一个词在比较少的文本中出现,那么它的IDF值应该高。比如一些专业的名词
逆文档频率(IDF) = log(语料库的文档总数/包含该词的文档总数+1)
- TF也就是词频,我们做的向量化也就是做了文本中各个词的出现频率统计。
- TF-IDF = 词频(TF) * 逆文档频率(IDF),TF-IDF与一个词在文档中的出现次数成正比,与该词在整个语言中的出现次数成反比。
特征抽取简单demo及API如下:
1 | from sklearn.feature_extraction import DictVectorizer |
特征预处理
通过特定的统计方法讲数据转换为算法要求的数据。
sklearn.preprocessing
- 归一化,防止某个数据对结果影响太大 sklearn.preprocessing.MinMaxScaler
- 通过将原始数据进行变换,把原始数据映射到[0,1]之间
- 原理:作用于每一列,max为一列的最大值,min为一列的最小值
- 缺点:异常点对此影响较大,这种情况下要使用标准化来解决
- 标准化,异常值影响较小 sklearn.preprocessing.StandardScaler
- 通过对原始数据进行变换,把数据变换到均值为0,标准差为1的范围内
- 在已有样本足够多的情况下比较稳定,适合现代嘈杂的大数据场景
- 原理:
归一化与标准化示例如下:
1 | from sklearn.preprocessing import MinMaxScaler,StandardScaler |
数据降维
特征选择
特征选择原因:如果训练数据包含许多冗余或无关特征,因而移除这些特征并不会导致丢失信息
- 数据冗余:部分特征相关度高,容易消耗计算机性能
- 缩短训练时间
- 改善通用性、降低过拟合
特征选择是什么?
特征选择就是单纯的从提取到的所有特征中选择部分特征作为训练集特征,特征在选择前和选择后可以改变值、也可以不改变值,但是选择后的特征维数肯定比选择前小,因为只是选择了其中一部分特征。
主要方法:
- Filter(过滤式):
- VarianceThreshold(方差过滤):由于方差为0的时候,一列的数据是一样的,所以是对结果没用的数据,由此推论,当方差小于某个值的时候,这个特征是不具有参考性的,可以剔除。
- sklearn.feature_selection.VarianceThreshold
- VarianceThreshold(方差过滤):由于方差为0的时候,一列的数据是一样的,所以是对结果没用的数据,由此推论,当方差小于某个值的时候,这个特征是不具有参考性的,可以剔除。
- Embedded(嵌入式):正则化、决策树
- Wrapper(包裹式)
- 神经网络
主成分分析(PCA,principal Component Analysis)
背景:
在许多领域的研究与应用中,通常需要对含有多个变量的数据进行观测,收集大量数据后进行分析寻找规律。多变量大数据集无疑会为研究和应用提供丰富的信息,但是也在一定程度上增加了数据采集的工作量。更重要的是在很多情形下,许多变量之间可能存在相关性,从而增加了问题分析的复杂性。如果分别对每个指标进行分析,分析往往是孤立的,不能完全利用数据中的信息,因此盲目减少特征会损失很多有用的信息,从而产生错误的结论。因此需要找到一种合理的方法,在减少需要分析的特征同时,尽量减少信息的损失,以达到对所收集数据进行全面分析的目的。由于各变量之间存在一定的相关关系,因此可以考虑将关系紧密的变量变成尽可能少的新变量,使这些新变量是两两不相关的,那么就可以用较少的综合指标分别代表存在于各个变量中的各类信息。主成分分析与因子分析就属于这类降维算法。
说白了就是特征太多情况下,如果很多特征之间是有联系的,这时直接通过特征选择等方式来剔除掉某些特征,会导致失去一些有用信息。所以需要一种方法,在减少特征数量的同时,尽可能少的减少信息的损失。
PCA是什么?
是一种使用最广泛的数据压缩算法。在PCA中,数据从原来的坐标系转换到新的坐标系,由数据本身决定。转换坐标系时,以方差最大的方向作为坐标轴方向,因为数据的最大方差给出了数据的最重要的信息。第一个新坐标轴选择的是原始数据中方差最大的方法,第二个新坐标轴选择的是与第一个新坐标轴正交且方差次大的方向。重复该过程,重复次数为原始数据的特征维数。
通过这种方式获得的新的坐标系,我们发现,大部分方差都包含在前面几个坐标轴中,后面的坐标轴所含的方差几乎为0,于是,我们可以忽略余下的坐标轴,只保留前面的方差较大的坐标轴。事实上,这样也就相当于只保留包含绝大部分方差的维度特征,而忽略包含方差几乎为0的特征维度,也就实现了对数据特征的降维处理。
PCA里,特征数量会减少,但数据也会改变。一般特征数量达到上百才会用
作用:
可以削减回归分析或者聚类分析中特征的数量
原理:
一张结果图:
详细过程参考这里的‘3.5PCA算法两种实现方法’:https://blog.csdn.net/program_developer/article/details/80632779
数据降维的两个方法demo:
1 | from sklearn.feature_selection import VarianceThreshold |
机器学习基础
算法是核心,数据和计算是基础。
机器学习算法判别依据:数据类型
- 离散型数据:由记录不同类别个体的数目所得到的数据,又称计数数据,所有这些数据全部都是整数,而且不能再细分,也不能进一步提高他们的精确度。区间内不可分
- 连续型数据:变量可以在某个范围内取任一数,即变量的取值可以是连续的,如长度、时间、质量等,这类数值通常含有小数部分。区间内可分
机器学习算法分类:
- 监督学习(预测):有特征值和目标值,有标准答案
- 分类:对应数据类型为离散型
- k-近邻算法
- 贝叶斯分类
- 决策树与随机森林
- 逻辑回归
- 神经网络
- 回归:对应数据类型为连续型
- 线性回归
- 岭回归
- 标注
- 隐马尔科夫模型
- 分类:对应数据类型为离散型
- 无监督学习:只有特征值
- 聚类
- k-means
- 聚类
机器学习开发流程
- 获取数据
包括获取原始数据以及从原始数据中经过特征工程从原始数据中提取训练、测试数据
- 特征工程
包括从原始数据中特征构建、特征提取、特征选择。特征工程做的好能发挥原始数据的最大效力,往往能够使得算法的效果和性能得到显著的提升,有时能使简单的模型的效果比复杂的模型效果好。数据挖掘的大部分时间就花在特征工程上面,是机器学习非常基础而又必备的步骤。数据预处理、数据清洗、筛选显著特征、摒弃非显著特征等等都非常重要。
- 训练模型、诊断、调优
诊断中至关重要的是判断过拟合、欠拟合,常见的方法是绘制学习曲线,交叉验证。通过增加训练的数据量、降低模型复杂度来降低过拟合的风险,提高特征的数量和质量、增加模型复杂来防止欠拟合。诊断后的模型需要进行进一步调优,调优后的新模型需要重新诊断
- 模型验证、误差分析
主要是分析出误差来源与数据、特征、算法。
- 模型融合
提升算法的准确度主要方法是模型的前端(特征工程、清洗、预处理、采样)和后端的模型融合
- 上线运行
通过提供API等形式来上线
sklearn数据集
1.数据集划分
机器学习一般的数据集会划分为两个部分:
- 训练数据:用户训练、构建模型
- 测试数据:在模型检验时使用,用于评估模型是否有效
2.sklearn数据集API介绍
- sklearn.model_selection.train_test_split
- sklearn.datasets
- datasets.load_*(); 获取小规模数据集,数据包含在datasets里
- datasets.fetch_*(data_home=None); 获取大规模数据集,需要从网络上下载,第一个参数是data_home表示数据集下载的目录,默认 ‘~/scikit_learn_data/‘
- load*和fetch*返回的数据类型都是datasets.base.Bunch(字典格式)
- data:特征数据数组,是[n_samples * m_features]的二维numpy.ndarry数组
- target:标签数组,是n_samples的一维numpy.ndarray数组
- DESCR:数据描述
- feature_names:特征名,新闻数据、手写数字、回归数据集没有
- target_names:标签名
3.sklearn分类数据集,对应分类算法
此处以内置数据集 load_iris和20newsgroups 为例
1.load_iris()获取内置普通分类用的数据集
2.获取用于分类测试的大数据集,sklearn.datasets.fetch_20newgroups(),数据集收集了大约20,000左右的新闻组文档,均匀分为20个不同主题的新闻组集合。
datasets.clear
数据集进行分割:
sklearn.model_selection.train_test_split(arrays,*options)
- x:数据集的特征值
- y:数据集的标签值
- test_size:测试集大小,一般为float
- random_state:随机数种子
- return:训练集特征值,测试集特征值,训练标签,测试标签
下面为两个数据集的获取代码,目前仅为数据采集,至于特征提取、模型训练等后续再写
1 |
|
4.sklearn回归数据集,对应回归算法
此处以内置数据集 波士顿房价数据集为例
sklearn.datasets.load_boston()
1 |
|
转换器(Transformer)与估计器(estimator)
特征工程中,实例化出来的可调用fit_transform API的对象(如 DictVectorizer等)就是一个Transformer
- fit_transform():输入数据直接转换
- fit()+transform():fit是单纯的输入数据,然后进行一些预先处理,如计算平均值,方差等。transform是进行数据的转换
在sklearn中,估计器(estimator)是一个重要的角色,是一类实现了算法的API,这玩意不是知道接口是啥就可以,而是传入的算法参数- -。。
- 用于分类的估计器:
- sklearn.neighbors k-近邻算法
- sklearn.naive_bayes 贝叶斯
- sklearn.linear_model.logisticRegression 逻辑回归
- sklearn.tree 决策树与随机森林
- 用于分类的估计器:
- sklearn.linear_model.linearRegression 线性回归
- sklearn.linear_model.Ridge 岭回归