概述
机器学习定义
机器学习是一门能够让编程计算机从数据中学习的计算机科学。
一个计算机程序在完成任务T之后,获得经验E,其表现效果为P,如果任务T的性能表现,也就是用来衡量的P,随着E增加而增加,那么这样计算机程序就被称为机器学习系统。
自我完善,自我增进,自我适应。
机器学习的问题
- 建模问题
接收特定的输入X,并给出预期输出Y的功能函数f,即Y=f(x)。 - 评估问题
针对已知的输入,函数给出的预测值与目标值之间存在的误差,因此需要构建一个评估体系,根据误差大小判定函数的优劣。 - 优化问题
学习的核心在于改善性能,通过数据对算法的反复锤炼,不断提升函数预测的准确性,直至获得能够满足实际需求的最优解。
机器学习分类
监督学习、无监督学习、半监督学习、强化学习
- 监督学习:用已知输出评估模型的性能;
- 无监督学习:没有已知输出的情况下,从数据中寻找数据之间的内在规律和信息的相关性;
- 半监督学习:先通过无监督学习划分类别,在根据人工标记通过有监督学习预测输出;
半监督学习的步骤如下- 利用labeled data训练一个模型,训练方法没有任何限制
- 利用训练好的模型,对unlabled data进行predict,得到标注,称为pseudo label
- 从pseudo label中选取一些样本,放入labelled data中。选取方法也是自定义的,比如可以放入置信度比较高
- 重新训练模型,然后继续迭代。
- 强化学习:通过对不同决策结果的奖励和惩罚,是机器学习系统在经过足够长时间的训练之后,越来越倾向于给定期望结果的输出。
批量学习和增量学习
- 批量学习:将学习的过程和应用过程截然分开,用全部的训练数据训练模型,然后再应用场景中实现预测,当预测结果不够理想时,重新回到学习过程,如此循环;
- 增量学习:将学习的过程和应用的过程统一起来,在应用的同时以增量的方式,不断学习新的内容,边训练边预测。
基于实例的学习和基于模型的学习
- 基于实例的学习:根据以往的经验,寻找与待输入最接近的样本,以其输出为预测结果;
- 基于模型的学习:根据以往的经验,建立用于连续输出和输入的某种数学模型,将待预测输入带入该模型,预测其结果。
机器学习一般过程
数据处理
- 数据收集(数据检索、数据挖掘、爬虫等)
- 数据清洗:数据整理
- 特征工程:特征压缩和提取
机器学习
- 选择模型(算法)
- 训练模型(算法)
- 评估模型(工具、框架、算法知识)
- 测试模型
业务运维
- 应用模型
- 维护模型(版本控制)
机器学习基本问题
- 回归问题:连续的输出
- 分类问题:离散的输出
- 聚类问题:根据输入的相似程度,将其划分为不同的群落
- 降维问题:在性能尽可能小的前提下,降低数据的复杂度
数据预处理
数据预处理的过程:输入数据->模型->输出数据。(一行一样本,一列一特征)
1. 均值移除(标准化)
由于一个样本的不同特征值差异较大,不利于使用现有机器学习算法进行样本处理。均值移除可以让样本矩阵汇总的每一列的平均值为0,标准差为1。均值移除是为了减少不同特征之间的数量级的差别。
均值为0:求均值,每个数减去均值;
标准差为1:求标准差,每个数除以标准差。
# 均值移除API
import numpy as np
import sklearn.preprocessing as sp
raw_samples = np.array(
[[17., 90., 4000],
[20., 80., 5000],
[23., 75., 5500]])
# scale函数用于对函数进行预处理,实现均值移除
# array为原数组,返回std_samples为均值移除后的结果
std_samples = sp.scale(raw_samples)
print("均值移除结果:\n", std_samples)
print("均值为:\n", std_samples.mean(axis=0))
print("方差为:\n", std_samples.std(axis=0))
均值移除结果:
[[-1.22474487 1.33630621 -1.33630621]
[ 0. -0.26726124 0.26726124]
[ 1.22474487 -1.06904497 1.06904497]]
均值为:
[ 0.00000000e+00 -8.14163551e-16 5.18104078e-16]
方差为:
[1. 1. 1.]
2.范围缩放
将样本矩阵中的每一列的最小值和最大值设定为相同的区间,统一各列特征值的范围。一般情况下会把特征值缩放至[0, 1]区间。
步骤:
- 所有特征减去特征中最小值
- 所有特征除以特征中最大值
# 范围缩放
import numpy as np
import sklearn.preprocessing as sp
raw_samples = np.array(
[[17., 90., 4000],
[20., 80., 5000],
[23., 75., 5500]])
# 创建缩放器
mms = sp.MinMaxScaler(feature_range=(0, 1))
# 调用缩放对象mms的方法,缩放数据
result = mms.fit_transform(raw_samples)
print(result)
[[0. 1. 0. ]
[0.5 0.33333333 0.66666667]
[1. 0. 1. ]]
# 范围缩放——手动计算
import numpy as np
import sklearn.preprocessing as sp
raw_samples = np.array(
[[17., 90., 4000],
[20., 80., 5000],
[23., 75., 5500]])
out_samples = []
for col in raw_samples.T:
col_min = col.min()
col_max = col.max()
A = np.array([
[col_min, 1],
[col_max, 1]
])
B = np.array([0, 1])
x = np.linalg.solve(A, B)
new_col = col*x[0] + x[1]
out_samples.append(new_col)
out_samples = np.array(out_samples).T
print("范围缩放结果:\n", out_samples)
范围缩放结果:
[[ 0.00000000e+00 1.00000000e+00 0.00000000e+00]
[ 5.00000000e-01 3.33333333e-01 6.66666667e-01]
[ 1.00000000e+00 -8.88178420e-16 1.00000000e+00]]
3.归一化
有些情况每个样本的每个特征值具体的值并不重要,但是每个样本特征值的占比更加重要。
归一化就是用每个样本的每个特征值除以该样本各个特征值绝对值的总和。变换后的样本矩阵,每个样本的特征值之和为1。
对行进行归一化,并非对特征进行归一化。
# norm 范数
# l1范数,向量中各元素的绝对值之和
# l2范数,向量中各元素平方和
import numpy as np
import sklearn.preprocessing as sp
ary = np.array([
[10, 21, 5],
[2, 4, 1],
[11, 18, 18]
])
# 归一化
result = sp.normalize(ary, norm='l1')
print(result)
[[0.27777778 0.58333333 0.13888889]
[0.28571429 0.57142857 0.14285714]
[0.23404255 0.38297872 0.38297872]]
# 手动实现归一化
import numpy as np
raw_samples = np.array([
[10., 21., 5.],
[2., 4., 1.],
[11., 18., 18.]
])
norm_samples = raw_samples.copy()
for row in norm_samples:
row /= abs(row).sum()
print(norm_samples)
print(abs(norm_samples).sum(axis=1))
[[0.27777778 0.58333333 0.13888889]
[0.28571429 0.57142857 0.14285714]
[0.23404255 0.38297872 0.38297872]]
[1. 1. 1.]
4.二值化
用0或1表示不高于或者高于阈值。非0即1。
import sklearn.preprocessing as sp
import numpy as np
raw_samples = np.array([
[10., 21., 5.],
[2., 4., 1.],
[11., 18., 18.]
])
# 二值化对象
bin = sp.Binarizer(threshold=5)
# 二值化对象的方法
result = bin.transform(raw_samples)
print(result)
[[1. 1. 0.]
[0. 0. 0.]
[1. 1. 1.]]
5.独热编码(one-hot Encoding)
为样本特征的每个值建立一个由一个1和若干个0的序列,用该序列对所有的特征值进行编码。
import sklearn.preprocessing as sp
import numpy as np
raw_samples = np.array([
[10., 21., 5.],
[2., 4., 1.],
[11., 18., 18.]
])
# sparse是否采用紧缩格式(稀疏矩阵),dtype数据类型
ohe = sp.OneHotEncoder(sparse=False, dtype='int32')
# 参数为原始样本矩阵
result = ohe.fit_transform(raw_samples)
print(result)
[[0 1 0 0 0 1 0 1 0]
[1 0 0 1 0 0 1 0 0]
[0 0 1 0 1 0 0 0 1]]
import sklearn.preprocessing as sp
import numpy as np
raw_samples = np.array([
[10., 21., 5.],
[2., 4., 1.],
[11., 18., 18.]
])
ohe = sp.OneHotEncoder(sparse=False, dtype='int32')
# 对原始样本矩阵进行训练,得到编码字典
encode_dict = ohe.fit(raw_samples)
# 调用encode_dict字典的ftransform方法,对数据样本矩阵进行独热编码
result = encode_dict.transform(raw_samples)
print(result)
[[0 1 0 0 0 1 0 1 0]
[1 0 0 1 0 0 1 0 0]
[0 0 1 0 1 0 0 0 1]]
6.标签编码
将字母用数字标签表示,一般每列(每个特征)都有一个标签编码器。
import sklearn.preprocessing as sp
import numpy as np
raw_samples = np.array([
'audi', 'ford', 'audi', 'toyota', 'ford', 'bmw', 'ford', 'redflag', 'audi'
])
print(raw_samples)
# 获取标签编码器
lbe = sp.LabelEncoder()
# 调用标签编码器的fit_transform方法训练并且为原始样本数组进行标签编码——编码
result = lbe.fit_transform(raw_samples)
print(result)
# 根据标签编码的结果矩阵反查字典,得到原始数据矩阵——解码
samples = lbe.inverse_transform(result)
print(samples)
# 假设训练之后得到一组测试样本结果
test = np.array([0, 0, 1, 1, 4])
test_samples = lbe.inverse_transform(test)
print(test_samples)
['audi' 'ford' 'audi' 'toyota' 'ford' 'bmw' 'ford' 'redflag' 'audi']
[0 2 0 4 2 1 2 3 0]
['audi' 'ford' 'audi' 'toyota' 'ford' 'bmw' 'ford' 'redflag' 'audi']
['audi' 'audi' 'bmw' 'bmw' 'toyota']