一、概述
1、什么是机器学习
机器学习是一门能够让编程计算机从数据中学习的计算机科学。 一个计算机程序在完成任务T之后,获得经验E,其表现效果为P,如果任务T的性能表现,也就是用以衡量的P,随着E增加而增加,那么这样计算机程序就被称为机器学习系统。
简而言之:自我完善,自我增进,自我适应。
2、为什么需要机器学习
1>自动化的升级和维护
2>解决那些算法过于复杂甚至跟本就没有已知算法的问题
3>在机器学习的过程中协助人类获得对事物的洞见
3、机器学习的问题
1>建模问题: 所谓机器学习,在形式上可这样理解:在数据对象中通过统计或推理的方法,寻找一个接受特定输入X,并给出预期输出Y的功能函数f,即Y=f(X)。
2>评估问题: 针对已知的输入,函数给出的输出(预测值)与实际输出(目标值)之间存在一定的误差,因此需要构建一个评估体系,根据误差的大小判定函数的优劣。
3>优化问题 :学习的核心在于改善性能,通过数据对算法的反复锤炼,不断提升函数预测的准确性,直至获得能够满足实际需求的最优解,这个过程就是机器学习。
4、机器学习的种类
监督学习、无监督学习、半监督学习、强化学习
1>有监督学习:用已知输出评估模型的性能。
2>无监督学习:在没有已知输出的情况下,仅仅根据输入信息的相关性,进行类别的划分。
3>半监督学习:先通过无监督学习划分类别,再根据人工标记通过有监督学习预测输出。
4>强化学习:通过对不同决策结果的奖励和惩罚,使机器学习系统在经过足够长时间的训练以后,越来越倾向于给出接近期望结果的输出。
批量学习和增量学习
1>批量学习:将学习的过程和应用的过程截然分开,用全部的训练数据训练模型,然后再在应用场景中实现预测,当预测结果不够理想时,重新回到学习过程,如此循环。
2>增量学习:将学习的过程和应用的过程统一起来,在应用的同时以增量的方式,不断学习新的内容,边训练边预测。
基于实例的学习和基于模型的学习
1>基于实例的学习:根据以往的经验,寻找与待预测输入最接近的样本,以其输出作为预测结果。-----概率论相关
2>基于模型的学习:根据以往的经验,建立用于联系输出和输入的某种数学模型,将待预测输入代入该模型,预测其结果。 输入 -> 输出 1 2 2 4 3 6 Y = 2 * X ... 9 ? -> 18 -------线性代数(数学公式)相关
5、机器学习的一般过程
1)数据处理:时间占比大,只有数据严格符合要求,模型精度才可能得到保障
1>数据收集 (数据检索、数据挖掘、爬虫)Hadoop storm hive
2>数据清洗 (随机数、插值、或直接扔掉)
2)机器学习
1>选择模型 (算法)
2>训练模型 (算法)
3>评估模型 (工具、框架、算法知识)
4>测试模型
3)业务运维
1>应用模型
2>维护模型
6、机器学习的典型应用
股价预测
推荐引擎
自然语言识别
语音识别
图像识别
人脸识别
7、机器学习的基本问题
1)回归问题:根据已知的输入和输出寻找某种性能最佳的模型,将未知输出的输入代入模型,得到连续的输出。
2)分类问题:根据已知的输入和输出寻找某种性能最佳的模型,将未知输出的输入代入模型,得到离散的输出。
3)聚类问题:根据已知输入的相似程度,将其划分为不同的群落。
4)降维问题:在性能损失尽可能小的前提下,降低数据的复杂度。
二、数据预处理
''' 数据预处理: 1.均值移除:由于一个样本的不同特征值差异较大(模型底层算法会偏向权重大的样本,导致模型预测不准),不利于使用现有机器学习算法进行样本处理。 均值移除可以让样本矩阵中的每一列的平均值为0,标准差为1。 1>如何使样本矩阵中的每一列的平均值为0呢? 例如有一列特征值表示年龄: 17, 20, 23 mean = (17 + 20 + 23)/3 = 20 a' = -3 b' = 0 c' = 3 完成! 2>如何使样本矩阵中的每一列的标准差为1呢? a' = -3 b' = 0 c' = 3 s' = std(a', b', c') [a'/s', b'/s', c'/s'] 3>均值移除API: import sklearn.preprocessing as sp A = sp.scale(array) scale函数用于对数据进行预处理,实现均值移除。 array为原数组,返回A为均值移除后的结果。 2.范围缩放:将样本矩阵中的每一列的最小值和最大值设定为相同的区间,统一各列特征值的范围。一般情况下会把特征值缩放至[0, 1]区间。 1>如何使一组特征值的最小值为0呢? 例如有一列特征值表示年龄: [17, 20, 23] 每个元素减去特征值数组所有元素的最小值即可:[0, 3, 6] 2>如何使一组特征值的最大值为1呢? [0, 3, 6] 把特征值数组的每个元素除以最大值即可:[0, 1/2, 1] 3>范围缩放API: # 创建MinMax缩放器 mms = sp.MinMaxScaler(feature_range=(0, 1)) # 调用mms对象的方法执行缩放操作, 返回缩放过后的结果 result = mms.fit_transform(原始样本矩阵) ''' import sklearn.preprocessing as sp import numpy as np # 整理样本矩阵 samples = np.array([[17, 100, 4000], [20, 80, 5000], [23, 75, 5500]]) # 均值移除(每一列均值为0,标准差为1) std_samples = sp.scale(samples) print(std_samples) print(std_samples.mean(axis=0)) print(std_samples.std(axis=0)) print('==================================') # 范围缩放,把每一列都缩放到[0,1]区间 mms = sp.MinMaxScaler(feature_range=(0, 1)) result = mms.fit_transform(samples) print(result) print('==================================') # 手动实现范围缩放 result = np.zeros_like(samples, dtype='f4') i = 0 for col in samples.T: # print(col) # 17k+b=0 # 23k+b=1 A = np.array([[col.min(), 1], [col.max(), 1]]) B = np.array([0, 1]) kb = np.linalg.solve(A, B) print(col * kb[0] + kb[1]) result[i] = col * kb[0] + kb[1] i += 1 print('=======================') print(result.T)
输出结果:
[[-1.22474487 1.38873015 -1.33630621]
[ 0. -0.46291005 0.26726124]
[ 1.22474487 -0.9258201 1.06904497]]
[ 0.00000000e+00 -3.70074342e-17 5.18104078e-16]
[1. 1. 1.]
==================================
[[0. 1. 0. ]
[0.5 0.2 0.66666667]
[1. 0. 1. ]]
==================================
[0. 0.5 1. ]
[1. 0.2 0. ]
[0. 0.66666667 1. ]
=======================
[[0. 1. 0. ]
[0.5 0.2 0.6666667]
[1. 0. 1. ]]
''' 数据预处理: 3.归一化(正则化):有些情况每个样本的每个特征值具体的值并不重要,但是每个样本特征值的占比更加重要。 Python Java PHP 2017 10 20 5 2018 8 5 0 所以归一化即是用每个样本的每个特征值除以该样本各个特征值绝对值的总和。 变换后的样本矩阵,每个样本的特征值绝对值之和为1。 1>归一化API: # array 原始样本矩阵 # norm 范数 # l1 - l1范数,向量中元素绝对值之和 # l2 - l2范数,向量中元素平方之和 # 返回归一化预处理后的样本矩阵 sp.normalize(array, norm='l1') 4.二值化:有些业务并不需要分析矩阵的详细完整数据(比如图像边缘识别只需要分析出图像边缘即可),可以根据一个事先给定的阈值, 用0和1表示特征值不高于或高于阈值。二值化后的数组中每个元素非0即1,达到简化数学模型的目的。 ----该数据处理方法一般业务为图像处理(边缘识别) 1>二值化API: # 给出阈值, 获取二值化器 bin = sp.Binarizer(threshold=阈值) # 调用transform方法对原始样本矩阵进行二值化预处理操作 result = bin.transform(原始样本矩阵) 5.独热编码(OneHot):为样本特征的每个值建立一个由一个1和若干个0组成的序列,用该序列对所有的特征值进行编码。 ----数字字符串也是可以编码的 1>比如: 两个数 三个数 四个数 1 3 2 7 5 4 1 8 6 7 3 9 为每一个数字进行独热编码: 1-10 3-100 2-1000 7-01 5-010 4-0100 8-001 6-0010 9-0001 编码完毕后得到最终经过独热编码后的样本矩阵: 101001000 010100100 100010010 011000001 2>独热编码API: 1)方法1: # 创建一个独热编码器 # sparse: 是否使用紧缩格式true(稀疏矩阵false) # dtype: 数据类型 ohe = sp.OneHotEncoder(sparse=是否采用紧缩格式, dtype=数据类型) # 对原始样本矩阵进行处理,返回独热编码后的样本矩阵。 result = ohe.fit_transform(原始样本矩阵) 2)方法2: # 创建一个独热编码器 ohe = sp.OneHotEncoder(sparse=是否采用紧缩格式, dtype=数据类型) # 对原始样本矩阵进行训练,得到编码字典 encode_dict = ohe.fit(原始样本矩阵) # 调用encode_dict字典的transform方法对样本矩阵进行独热编码 result = encode_dict.transform(原始样本矩阵) 6.标签编码:当样本矩阵中含有字符串,则需要把字符串转为数字。根据字符串形式的特征值在特征序列中的位置, 为其指定一个数字标签,用于提供给基于数值算法的学习模型。 1>标签编码API: # 获取标签编码器 lbe = sp.LabelEncoder() # 调用标签编码器的fit_transform方法训练并且为一个字符串数组进行标签编码 result = lbe.fit_transform(字符串数组) # 根据标签编码的结果矩阵反查字典 得到原始数据矩阵 samples = lbe.inverse_transform(result) ''' import sklearn.preprocessing as sp import numpy as np import warnings warnings.filterwarnings('ignore') # 整理样本矩阵 samples = np.array([[17, 100, 4000], [20, 80, 5000], [23, 75, 5500]]) print('==================================') # 归一化处理,每一行归一化后的特征值之和为1 result = sp.normalize(samples, norm='l1') print(result) print('==================================') # 二值化处理,使得样本矩阵中的值全为0或1 # 侯建二值化器对象 b = sp.Binarizer(threshold=80) result = b.transform(samples) print(result) print('==================================') # 独热编码(OneHot)---方法1 samples = np.array([[1, 3, 2], [7, 5, 4], [1, 8, 6], [7, 3, 9]]) # 构建独热编码器---使用紧缩格式 ohe = sp.OneHotEncoder(sparse=True, dtype='i4') result = ohe.fit_transform(samples) print(result, type(result)) print(result.toarray()) print('==================================') # 构建独热编码器---使用稀疏矩阵 ohe = sp.OneHotEncoder(sparse=False, dtype='i4') result = ohe.fit_transform(samples) print(result, type(result)) print('==================================') # 独热编码(OneHot)---方法2 ohe = sp.OneHotEncoder(sparse=False, dtype='i4') encode_dict = ohe.fit(samples) print(encode_dict) result = encode_dict.transform(samples) print(result) print('==================================') # 标签编码 # 假设获取一组特征---在样本矩阵中为一列 features = np.array(['bmw', 'ford', 'toyota', 'audi', 'auto', 'ford', 'toyota', 'HAVAL', 'bmw']) # 对这组特征进行标签编码 lbe = sp.LabelEncoder() result = lbe.fit_transform(features) print(result) # 根据标签编码结果反查字典 inver = lbe.inverse_transform(result) print(inver, type(inver)) 输出结果: ================================== [[0.00412922 0.02428953 0.97158125] [0.00392157 0.01568627 0.98039216] [0.00410861 0.01339764 0.98249375]] ================================== [[0 1 1] [0 0 1] [0 0 1]] ================================== (0, 5) 1 (0, 2) 1 (0, 0) 1 (1, 6) 1 (1, 3) 1 (1, 1) 1 (2, 7) 1 (2, 4) 1 (2, 0) 1 (3, 8) 1 (3, 2) 1 (3, 1) 1 <class 'scipy.sparse.csr.csr_matrix'> [[1 0 1 0 0 1 0 0 0] [0 1 0 1 0 0 1 0 0] [1 0 0 0 1 0 0 1 0] [0 1 1 0 0 0 0 0 1]] ================================== [[1 0 1 0 0 1 0 0 0] [0 1 0 1 0 0 1 0 0] [1 0 0 0 1 0 0 1 0] [0 1 1 0 0 0 0 0 1]] <class 'numpy.ndarray'> ================================== OneHotEncoder(categorical_features=None, categories=None, drop=None, dtype='i4', handle_unknown='error', n_values=None, sparse=False) [[1 0 1 0 0 1 0 0 0] [0 1 0 1 0 0 1 0 0] [1 0 0 0 1 0 0 1 0] [0 1 1 0 0 0 0 0 1]] ================================== [3 4 5 1 2 4 5 0 3] ['bmw' 'ford' 'toyota' 'audi' 'auto' 'ford' 'toyota' 'HAVAL' 'bmw'] <class 'numpy.ndarray'>