如果将AI工程分为两块, 数据处理 模型相关 那么,特征工程就是处理数据的,将业务数据转化为模型需要的数据
图片类数据看看图片什么样,以便后继标注;这里说的特征工程主要指二维数表,图像处理请移驾CV专栏 二维数据表,则观察不同列的数据分布: 空值处理 编码:字符串转数字 将数据全部转为数字后,后面就观察其分布: 均值,方差,min,max,25%,50%,75%,90%,99%附近的数据 离群点,异常处理数据 如果列比较多,则会分析一下列之间的线性关系,是否有严重重复的,也就是特征选择: 卡方 IV值 共线性 看完数据什么样后,对数据的规模,行数,列数,列的含义等数据特点有所了解之后, 确认业务是分类问题还是回归问题, 标签是什么 以便考虑选择什么样的模型
将全体数据集的整个尺度 映射到 [0,1]的范围 或者是[-1,1]这种以0为中心,绝对值在1以内的范围内 最大最小标准化,离散标准化,将数据映射到0-1之间 X = (X - min)/(max - min) 如果最大值 与 最小值中出现异常值,对结果会产生较大的影响 适合 波动不大 的小量数据处理 由于是两个极值想减,有的地方也叫 极差化 也叫线性归一化 折中处理 为了防止min,max出现异常对数据处理造成较大影响 采用99%分位数作为new_max,超出的部分抹去,最大为new_max 采用1%分位数作为new_min ,低于的部分抹去,最小为new_min from sklearn.preprocessing import MinMaxScaler preprocess = MinMaxScaler() raw_data = [[1, 1, 1], [3, 3, 3], [1, 2, 3]] data = preprocess.fit_transform(raw_data) data array([[0. , 0. , 0. ], [1. , 1. , 1. ], [0. , 0.5, 1. ]]) 以向量,向量组的角度看这个矩阵: 第一个向量为 [ 1, 3, 1 ] 默认是列向量,min=1,max=3,max - min = 2 代入公式,会得到一个 [ 0, 1, 0] 的向量 |
(数据-均值)/(标准差 + 1e-6) 标准差就是方差的开平方, 是一个数据分布内部离散量的累加值, 可近似看作 整体数据离“数据中心点”的距离之和 这么一系列操作后,得到的是啥? 将数据转化为均值为0,标准差为1 的正态分布,即标准正态分布 为什么要这么做?为什么呢? 因为数据处理时,处理的多个数据分布,要对比就得有个统一的量纲, 处理方法就是,不管你原来是什么分布,数据的均值多少,离散程度怎么样, 我统一给你转成均值为1方差为1的标准正态分布 这是能够多列一起处理的 基石/起点/前提 这种方法,在数据量大时,异常点对数据处理影响不大 在统计学中,也叫z-score标准化 from sklearn.preprocessing import StandardScaler preprocess = StandardScaler() raw_data = [[1, 1, 1], [3, 3, 3], [1, 2, 3]] data = preprocess.fit_transform(raw_data) data array([[-0.70710678, -1.22474487, -1.41421356], [ 1.41421356, 1.22474487, 0.70710678], [-0.70710678, 0. , 0.70710678]]) 海量数据通常都是以正态分布的形式呈现 |
首先是算法层面决定了标签没有归一化的必要 比如, KNN,近邻思想,它取的是训练集X中离样本最近数据的索引, 直接按此索引在标签中取最近n个数 至于这几个数的值是多少,算法根本就不关心,不涉及 又比如决策树,是按某种方法去划分训练集X, 找到一些分支可以更好地分类标签,至于标签的值也不参与计算 再比如神经网络的分类问题,标签onehot编码都是0与1,形成E矩阵, 这是彻底归一了,不需要你再做归一化了 对于连续型变量, 机器学习中基本是近邻思想找到附近的值,取均值 深度学习中,则是会自动计算参数w,该放大就放大,该缩小就缩小, 会自动向标签靠近 另外,除了0与1,其他数据归一后,再返回原形式,前后未必完全相等 比如 >>> 1/3 0.3333333333333333 >>> 1/0.333333 3.0000030000030002 >>> 1/0.3333333 3.00000030000003 >>> 1/333 0.003003003003003003 >>> 1/0.0030030 333.000333000333 标签通常不需要归一化,这主要由算法决定 如果实际场景中需要归一化,也是可以的 |
统一量纲 不是非得归一 重在归于一个统一的数值,1可以,10也可,100也可 由于计算机计算[0,1]之间的数据更容易,两者结合后,归于[0,1] 但思维上不应该限定于1,认为非1不可,可根据场景调整 一些算法将该场景抽离成参数,由用户决定归于一个什么样的数值 大部分情况下,归于0.9完全可行,就是将数据再往下压10%, 这样在计算的过程中数据爆炸的风险就会再低一点 |
虽然对于模型来说,都是在计算数字, 但在输入模型的数据,是会区分哪些特征是连续型,哪此是离散型的 统一量纲只针对连续型特征 对于离散型特征,通常以编码的方式转为数字,然后再决定是否进行归一化处理 |
预处理针对所有数据,包括但不限于训练集,预测集,验证集等 默认训练集的数据包含了业务所需要的全部, 预测集的本意是未来出现的数据,虽然未出现,但它的规律与训练集的规律是一样的 用于归一化的min,max,mean,std等都来自训练集, 将来验证,预测的时候,第一步就是要对数据做同样的预处理 因此,预处理的数据,要做成统一的接口,与模型训练是分开的,是针对所有数据的 |
import numpy as np np.random.seed(73) #向量默认为列向量 a1=np.random.randint(low=0,high=10,size=(7,1)) a2=np.random.randint(low=10,high=100,size=(7,1)) a3=np.random.randint(low=100,high=1000,size=(7,1)) #矩阵index=0即第1个维度为列,第2个维度为行 aa = np.concatenate((a1,a2,a3),axis=1) aa array([ [ 6, 81, 935], [ 2, 63, 662], [ 0, 17, 930], [ 8, 62, 984], [ 3, 53, 456], [ 1, 63, 679], [ 6, 56, 953]]) min_ = aa.min(axis=0) max_ = aa.max(axis=0) std_ = aa.std(axis=0) min_,max_,std_ ( array([ 0, 17, 456]), array([ 8, 81, 984]), array([ 2.76272566, 18.07806202, 186.85779816])) #aa是2维矩阵,min_是与aa某个维度相同的向量,这就存在一个广播机制 aa - min_ array([[ 6, 64, 479], [ 2, 46, 206], [ 0, 0, 474], [ 8, 45, 528], [ 3, 36, 0], [ 1, 46, 223], [ 6, 39, 497]]) #这里存在两次广播机制 (aa - min_)/(max_ - min_) array([[0.75 , 1. , 0.90719697], [0.25 , 0.71875 , 0.39015152], [0. , 0. , 0.89772727], [1. , 0.703125 , 1. ], [0.375 , 0.5625 , 0. ], [0.125 , 0.71875 , 0.42234848], [0.75 , 0.609375 , 0.94128788]]) mean_ = aa.mean(axis=0) #这里存在3次广播机制,std+1e-6 也是一次 (aa-mean_)/(std_+1e-6) array([[ 0.82734 , 1.35918481, 0.72323905], [-0.620505 , 0.36350291, -0.73776499], [-1.34442751, -2.18101748, 0.69648073], [ 1.55126251, 0.30818725, 0.98547054], [-0.25854375, -0.18965369, -1.8402076 ], [-0.98246626, 0.36350291, -0.64678672], [ 0.82734 , -0.02370671, 0.81956899]]) |
保留训练集的以下列信息,与模型一起交付: 连续型数据列:最大值,最小值,均值,标准差 离散型数据列:不重复值 以及个数 如果数据量大,需要分批计算后合并 ------------------------------------------------------------ |
|
|
开始训练的时候,模型的精度 在训练集上不断增加 在测试集上不断增加 并且训练集与测试集增长幅度近似 过拟合: 当训练到一定程度,训练集上的精度还在增加, 但测试集上的精度不再增加,甚至出现下降, 此时,模型把不通用的事物也学了,结果在测试集上并不应验...