★知识点概览
from sklearn.datasets import make_blobs # 用于伪造数据集
from sklearn.model_selection import train_test_split # 数据集切分
from sklearn.model_selection import cross_val_score # 交叉验证,可通过参数scoring选择模型评估指标MSE、MAE、R^2等
from sklearn.model_selection import KFold # 折数规则制定
from sklearn.model_selection import GridSearchCV # 网格搜索
from sklearn.feature_extraction.text import CountVectorizer # 文本向量化(词频)
from sklearn.feature_extraction.text import TfidfVectorizer # 文本向量化(权重)
from sklearn.preprocessing import MinMaxScaler # 归一化
from sklearn.preprocessing import StandardScaler # 标准化
from sklearn.preprocessing import PolynomialFeatures # 给特征增加n次项,解决欠拟合
from sklearn.feature_selection import VarianceThreshold # 方差过滤
from sklearn.decomposition import PCA # PCA降维
from sklearn.feature_selection import SelectKBest,f_regression,f_classif # F检验
from sklearn.feature_selection import SelectKBest,chi2 # 卡方检验
from sklearn.feature_selection import SelectKBest,mutual_info_classif,mutual_info_regression # 互信息
from sklearn.neighbors import KNeighborsClassifier # KNN
from sklearn.linear_model import LinearRegression # 线性回归(最小二乘) - 一元、多元、多项式都是它
from sklearn.linear_model import SGDRegressor # 线性回归(梯度下降)
from sklearn.linear_model import LogisticRegression # 逻辑回归
from sklearn.linear_model import Lasso # L1
from sklearn.linear_model import Ridge # L2
from sklearn.naive_bayes import MultinomialNB # 多项式朴素贝叶斯 -- 离散型特征 > 文本分类
from sklearn.naive_bayes import GaussianNB # 高斯分布朴素贝叶斯 -- 连续型特征 > 天气预测
# 回归模型评价指标
from sklearn.metrics import mean_squared_error as MSE, mean_absolute_error as MAE, r2_score
# 分类模型评价指标
from sklearn.metrics import recall_score,f1_score,accuracy_score # 召回率、f1、精确率
from sklearn.metrics import classification_report # 分类模型评价分析报告
from sklearn.svm import SVC # SVM分类
from sklearn.svm import SVR # SVM回归 - 处理非线性可分回归问题
from sklearn.svm import LinearSVR # SVM回归 - 处理线性可分回归问题
from sklearn.tree import DecisionTreeClassifier # 分类决策树
from sklearn.tree import DecisionTreeRegressor # 回归决策树
from sklearn.ensemble import RandomForestClassifier # 分类随机森林
from sklearn.ensemble import RandomForestRegressor # 回归随机森林
from sklearn.ensemble import AdaBoostClassifier # AdaBoost - 二分类任务专用!!效果嘎嘎好.
from sklearn.ensemble import GradientBoostingRegressor as GBR # GBDT回归
from sklearn.ensemble import GradientBoostingClassifier as GBC # GBDT分类
# 随机森林,里面是多个决策子树 warm_start=True代表打开增量模式
from sklearn.ensemble import RandomForestClassifier
from sklearn.cluster import KMeans # k-means聚类算法
from sklearn.metrics import silhouette_score # k-means的评估指标-轮廓系数
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
中文新闻分类(贝叶斯)
SVM实现人脸识别
HOG+SVM 书法字体识别
分类随机森林作特征选择
回归随机森林作缺失值预测
随机森林 - 离职分析项目.
聚类 - 广告推广优化
分类 - 电信用户流失分析
◎ 贝叶斯中文新闻分类!!
- 新闻数据集加载
- 中文文本分词
- 过滤停用词
- 构建文本特征 > 每一行就是一个新闻,特征是从所有新闻中提取的关键词,其值是关键词在该新闻中出现的次数,标签是该新闻的类别
- 多项式贝叶斯分类 > 会先对关键词进行统计,看其在不同类别的新闻中出现了多少次,还会统计标签每个类别的数量.接着进行贝叶斯分类!!
◎ SVM实现人脸识别
每张人脸上的每个像素点都是rgb三通道. 每张图片有n行m列个像素点. 那么一张图片就是三维的, 形状 (n,m,3)..
我们取每张图片红色通道的数据, 一张图片就从三维变为二维的了.. 形状 (n,m)
但这还不够, 在训练集的特征矩阵上, 一张图片应该就是一行数据, 所以还需要reshape降维. 形状 (n*m, )
最后, 构建的数据集的特征矩阵的形状 (一共有多少张图片,n*m)
◎ HOG+SVM 书法字体识别
HOG根据边缘信息可以对一张图像中物体的形状或轮廓进行提取.结果是一个一维的特征向量.
◎ 分类随机森林作特征选择
筛选出重要特征,但一般我们会先作下特征选择,以此减少下子树构建的难度.
◎ 回归随机森林作缺失值预测
看列缺失值缺失占比,大的话就使用预测出来的结果填充缺失值
◎ 随机森林 - 离职分析项目 标签类别:离职、在职
◎ 聚类 - 广告推广优化
最主要的是剖析每个簇内的显著特征是什么!!
◎ 分类 - 电信用户流失分析
★ 这是一个综合项目,需细品!!
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# 大体流程
★ 拿到一个项目,不管三七二十一,先作以下处理:
■ 数据预处理 ★只要是删行就记得重置索引!
1.加载数据集
2.清理重复行数据,记得重置索引
3.进行空值处理
- 查看每列空值占比
- 占比小的话,通常我们直接删除列空值所对应的行,记得重置索引! 当然也可以填充.
- 占比大的话,我们通过df[列名].value_counts()看看该列是否是连续型数据.
是的话,可以用均值、中位数等统计指标进行填充.
当然还可以通过回归随机森林来进行预测,用预测值来进行填充.
> 先找出除了目标列以外没有空值的行
然后在该数据集中,将目标列中非空Nan的那些行作为训练集,目标列中为空的行作为测试集,对缺失值进行预测.
> 随机森林可以自动处理特征间的非线性关系,且不需要手动处理缺失数据或类别问题
4.df.info()查看数据的类型
- 根据经验看该列的数据类型是否合理.
比如,总费用不能是object类型,而应该是float等数值型类型,因为数值型类型才能参与describe统计描述
> data['TotalCharges'].astype('float') # 报错: ValueError: could not convert string to float: ''
(data['TotalCharges'].str.match(r'^\s*$')).sum() # 使用该正则可以匹配一个或多个空格!!
若不多的话,可以直接删除该列空格所对应的行!!
- 列名不符合规范的,可以改一下(该操作是可选的 - 详看后面的"索引替换"小节内容
- 像ID字段,为了聚合时不运算它,将其转换成字符串类型或直接删除
- 看类型
- 根据需求转换成时间类型.
根据需求对字段进行扩展,比如:提取月份和年份等操作 - 详看后面的"时间序列"小节内容
5.异常值处理
- 数值型数据
df.describe()初步看下有无异常值 > 看的是数值型数据有无异常
- 查看数值型数据的统计描述,非数值型数据是看不到的哦!
主要观察 列的方差是否为0(为0就是常数列)、列的取值范围是否合理,是否能有负数
- 针对这些数值型数据,最常用的方式是画箱型图查看有无离散点的数据. 看下离散值占比,根据需求看是否删除!
- 非数值型数据
- 查看object类型的列有多少个不同元素组成. 若发现某列的元素组成有的元素含义是一样,则需要进行替换.
- 将object类型的字段全部转换成category类型(可选)
■ 特征工程
-1- 像‘渠道代号’之类的列,对聚类、分类、回归没帮助的列,直接删除掉!!
-2- 对数值型的特征根据相关性进行最初步的特征选择
> 拿到经过预处理后的数据集后,非数据值的特征先不管,对数值型的特征可先做初步的特征选择.
观察数值型的特征,大概率都是连续型数据,那么我们就可以用皮尔逊相关系数来观察它们的相关性,相关性较高的,就是冗余特征!
比如A列和B列相关性达到了0.75,那么删除A列和B列其中一列即可!!
ps: df.corr().abs() - 会自动拿df中数值型的列来计算,我们只关注相关性,不关注相关性的正负,所以abs了一下.
> 观察数值型特征的这些列,列与列之间的数值差异大不大,大的话需要进行无量纲化!
!注意:这一步根据建立的模型和实际情况来考虑,比如聚类模型肯定要进行这一步!
★ ★ ★ ★ 建议都先不做 emm 根据模型的结果来判定,这是最直接的!
-3- 对非数值性数据做特征值化
> 在前面数据预处理,我们就查看了object类型的数据各自的组成元素有哪些
元素组成1-3个map映射; -- ※ 数据类型会变成int64,原本一列还是一列
元素3个以上 one-hot映射 -- ※ 数据类型会变成uint8,原本一列会变成多列
(若只有两个元素组成,map、one-hot都可以
★ 若该数据集有标签列,是离散型的分类数据,那么我们最好也对其做 特征值化,以满足更多的模型训练的要求!!
■ 进一步剖析,进行特征选择
前提假设,该数据集有标签且标签是离散型的分类数据!!
-4- 经过上述的特征工程后,df.shape查看 若特征维度还是很大的话,我们就可以考虑进行进一步特征筛选
> 首先,要清楚不能将one-hot编码结果的某一列单独删除,要删也是将one-hot编码结果的多列一起删除.
在这里,我们暂且不管 one-hot编码后的 那些列. 先对其它列进行处理.
- 4.1对经过map映射的列进行探索 -
对这些列用pca降维?相关系数?方差过滤?用哪个特征选择的方案都不合适
因为这些特征值化的结果基本都在0和1之间分布,是一个较为稀疏的矩阵,对该矩阵统计相关性、方差等是没有意义的!
so,我们需要对这些列进行可视化分析,探究其对我们的标签分类结果是重要的还是不重要的!!
eg: 不同性别用户流失的占比是多少,若男的流失率比女的大很多,则证明性别跟用户流失是有关系的.
> pd.crosstab(df["gender"],df['Churn'],normalize="index")
Q: 差异的阈值控制在10以内还是15以内呢? A:看自己想要的特征力度选择大小了.
- 4.2对原始数据集中的"数值型"数据的列(还未经过无量纲化)进行探索 - PS:前面进行了无量钢化也没影响,拿原始数据中的来探索就好!
> 若元素类别组成只有2 3个,跟4.1的做法一样即可.
> 若元素类别组成有很多很多个,但跟样本数据相比,算少的.. 比如字段tenure表示入网月数,有72个元素类别.样本数据有7k个.
在4.1的基础上,我们还要对其进行画图,看流失率随着入网月数增加的"走势"!
> 若该列是连续型数据,组成元素有6k个,数据集样本7k个.
★ 这时,我们就需要对其进行cut分箱处理!!借此达到将连续型数据进行离散化的操作.
然后执行crosstab检查表操作,接着画图直观展示!
■ 建模
Q:建模后,多个模型的效果都不好,问题可能出现在哪呀?
A:可对样本标签进行一个探索
target.value_counts()
"""
0 5163
1 1869
Name: Churn, dtype: int64
"""
- 若当前数据集出现了标签类别分布不均匀的情况!需要对其进行处理.
解决方案:
- 有些模型自带有balance平衡相关的参数,设置它;
- 但有些模型没有,比如knn模型.如何是好?★使用"上采样"进行标签类别分布不均匀情况的处理!!
"""
from sklearn.neighbors import KNeighborsClassifier # KNN
from sklearn.linear_model import LogisticRegression # 逻辑回归
from sklearn.naive_bayes import MultinomialNB # 多项式朴素贝叶斯 -- 离散型特征 > 文本分类
from sklearn.svm import SVC # SVM分类
# svm本应不该这么低,svm默认使用的是rbf
# 经验之谈: 若 <数据集的特征> 分布不均匀, 在使用rbf核函数之前,应进行 无量钢化!! 这样可以有效提升其训练效果!!
# 看样子,逻辑回归不错,说明这组数据特征和标签的线性关系还是可以的. 接下来,就对逻辑回归的参数用网格搜索进行调优!
# 用集成算法也可以,但得到的结果应该不会比逻辑回归好太多
# 试了后.拿到一个最优模型进行保存!! 所有模型都是有迹可循的.
"""
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
特征工程相关代码.
op_data.select_dtypes(exclude=['object'])
的形式. 是我为了偷懒省事,
其实应该写指定的列名列表后,再处理, 这样不容易出错. emm 参照"电信用户流失"示例就明白了!!
-1-
op_data.drop(columns=['渠道代号'],inplace=True) # 删列
-2.1- 对数值型的列根据皮尔逊相关系数作初步的特征选择
corr_matrix = op_data.corr().abs() # 计算相关系数矩阵,abs取绝对值
sns.heatmap(corr_matrix,cmap='Reds',annot=True) # 绘制热力图
op_data.drop(columns=['平均停留时间'],inplace=True) # 根据热力图,删列
-2.2- 对数值型列进行无量纲化 (数值差异比较大的话
from sklearn.preprocessing import MinMaxScaler
d = op_data.select_dtypes(exclude=['object']) # d是一个df对象 注意这里是exclude 拿到数值型的列
tool = MinMaxScaler() # 参数feature_range表示缩放范围,通常使用默认值(0,1)
d_ = tool.fit_transform(d)
d_m = pd.DataFrame(d_,columns=d.columns)
# 先删除列,再把处理后的列拼接上去.(因为处理的列和拼接上去的列的列名是相同的!)
op_data.drop(columns=d.columns,inplace=True)
op_data = pd.concat((op_data,d_m),axis=1)
op_data
-3- 对非数值列批量进行特征值化 这里以one-hot编码为例
d = op_data.select_dtypes(include=['object']) # d是一个df对象 注意这里是include 拿到非数值型的列
for item in d.columns:
print(op_data[item].unique())
# 我们假设这里非数值型的列的类别元素组成都在3以上,批量one-hot即可!
# 若不是的话,需要筛选列,3以下的map映射,3以上的one-hot. 可以参照"电信用户流失"示例就晓得咋回事了!!
ret = pd.get_dummies(d)
op_data = pd.concat((op_data,ret),axis=1).drop(columns=d.columns)
op_data
# PS: 其实,2.2和3都做了的话,可以将上述处理后的列进行行拼接 2.2和3里的拼接工作就不用做了.
# new_data = pd.concat((d_m,ret),axis=1) # axis=1 根据行索引行行拼一起
# new_data
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# 一些概念
- 经验而言, [有度量单位的变量] 一般都是连续型变量.
- 方差: 一个特征/一列 的每一项与该列均值相减的平方之和除以该列个数 > 可表示信息量的大小
- 数据维度shape; 特征维度即有多少特征列
- 相似性: 通常是指两个变量在变化模式上的一致程度..
这不仅包括它们的方向(正向或负向变化), 还涉及它们的变化幅度和比例
- 协方差可以衡量[两个变量]的[变化趋势]是否一致.但不能体现两变量[变化幅度]的相似性!
比如:A从1000到10和B从1到0.01,同向且变化幅度一致! - 协方差只能衡量同向
- 变化幅度+同向一起衡量 需要用皮尔逊相关系数!
- 多重共线性: 特征与特征之间的关系,比如-楼层和高度.
- 线性关系与非线性关系
几何里的线性关系 > 一维必须是一条直线、二维必须是一个平面. 以此类推!
几何里的非线性关系 > 一维的曲线、多维的曲面
回归模型里的线性关系 指的是 权重与标签之间的关系是一条直线!
- 线性可分、非线性可分
使用几何里的线性关系,即n-1维的超平面(直线、平面、立体空间),对n维空间进行划分. 每一份里包含的数据属于某一个类别.
<提个醒:逻辑回归仅适用于于线性可分的数据集!! 逻辑回归=线性回归+sigmoid函数.>
- 回归预测 - 样本标签是连续型的; 分类 - 样本标签是离散型的!
- 分类模型每个轴都是特征;回归模型有一个轴是标签,其余轴是特征!
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 特征工程
切记, 测试新数据之前, 新数据需要进行跟构建模型的数据一样的特征工程!!
# 特征值化/特征抽取
- 特征值化/特征抽取: 数值变非数值
- 特征类别有4个及以上 > one-hot独热编码 "是可以批量对列进行one-hot的" (特征一般都是无序变量
- 1-3个 > 通常使用map映射,你用one-hot也行 (特征一般都是有序的
- 文本向量化 > 词频&权重(在语料库中的重要程度) 若是中文,需jieba分词后用空格拼接
只要2个的话,one-hot、map映射都可以.因为都只有 0 1
2
3
4
5
6
# 特征无量纲化
- 特征无量纲化: 消除 位数(5位数,2位数)/数值 大小纲量的影响,因为我们认为特征同等重要,但模型更偏爱大的
- 归一化([0,1]区间)对异常值敏感
- 标准化对异常值不敏感.
★ 建议先标准化,效果不好再归一化
★ 注意:
若先对数据集进行二八分,以标准化为例, 测试集特征的归一化,应使用训练集特征归一化得到的均值和标准差!!
因为测试集模拟的是真实环境,在该环境中是很难得到均值和标准差的!!
2
3
4
5
6
7
# 特征选择
补充:
决策树模型的feature_importances_属性可以看到哪些特征比较重要.
基于决策树的随机森林算法也可以.. - 也就是说, ★ 随机森林本身就可作为 特征选择 的一种技术..
- 剔除无意义的特征: 冗余的/多重共线性的、噪点(与标签分类无关的特征)
- 方差过滤:
通常用不到. 我们一般通过df.describe()重点关注下哪些列的方差为0. > 方差小,可能意味着这个特征大量取值都相同.
- PCA降维:
简单理解 >
原本数据是4维的,我pca将这些数据打乱重组,形成了一个新的4维数据,但是第一维/第一列的数据保留了原始数据绝大多数的特征.
然后 我pca若指定了n_components,是几就取前几个
注意 >
PCA是将已存在的特征进行压缩,降维完毕后的新特征不是原本的特征矩阵中的任何一个特征.
而是通过某些方式组合起来的新特征,新特征矩阵生成之后也不具有可读性!!
它无法解释的降维后的新特征和标签之间存在的关系是否和降维前是否一致!!
★ 因此需要特别注意,PCA一般不适用于探索特征和标签之间的关系的模型中(即有监督的模型都不适合!).
学术名词 > 可解释性方差、可解释性方差贡献率
- 皮尔逊相关系数:
协方差可以衡量[两个变量]的[变化趋势]是否一致.即协方差可以体现两变量相似性中的同向,但不能体现相似性中的变化幅度!
皮尔逊相关系数用来比较每个"特性"与"标签"的相关性!!值在[-1,1]之间,接近于1或-1的保留,相关性低的在特征选择中剔除.
★ "相关系数仅能捕捉两组连续性数据之间的线性关系, 意味着 特征和标签都得是 连续型变量"..
因此, 在回归预测中相关系数可以有一定的用武之处 ; 在分类场景中理论不允许,但使用后可能会有奇效,说不准..
★ 相关系数无法解决多重共线性问题. 比如数据集中存在高度相关的特征(房价预测中的高度和楼层).
★!!! 皮尔逊相关系数的过程消除了纲量的影响,但在实际操作过程中还是得先进行特征的无量纲化!!
- F检验
★ 在回归任务中,"特征"和"标签"之间存在线性关系可以使用相关系数进行特征选择,否则可以尝试使用F检测实现特征选择.
- 卡片过滤
通过计算"特征"和"目标变量"之间的卡方统计量来评估特征与目标变量之间的相关性.
★ 卡方过滤适用于特征和目标变量都是离散型的情况(分类任务).
- 互信息
互信息法是用来捕捉每个特征与标签之间的任意关系(包括线性和非线性关系)的过滤方法.
它会返回"每个特征与目标之间的互信息量的估计",这个估计量在[0,1]之间取值,为0表示两个变量独立,为1则表示两个变量完全相关.
★ 和F检验相似,它既可以做回归也可以做分类, 但互信息法比F检验更加强大.
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
特征选择 | 作用于 | 原理 | 应用 |
---|---|---|---|
方差过滤 | [特征] 之间方差比较 | ||
PCA降维 | [特征] 投影到新坐标, 尽可能保留多的信息 | 求协方差矩阵的特征值和特征向量 | 不适合监督模型 eg:不适合线性回归 |
皮尔逊相关系数 | [特征与标签] 线性强度和方向 | 协方差除以两者标准差的乘积 消除纲量的影响 | 回归模型 |
F检验 | [特征与标签] 本质是基于方差比较 | 不考虑特征和目标变量之间 是否存在线性关系. 具体公式原理无需了解!! | 回归模型、分类模型 |
卡方过滤 | [特征与标签] 卡方统计量 | 具体公式原理无需了解 | 分类模型 |
互信息 | [特征与标签] 互信息量 | 具体公式原理无需了解!! 互信息比F检验更强大!! | 回归模型、分类模型 |
上述仅是理论, 理论说 相关系数两个变量都得是连续的, 但有人在 连续型特征和离散型标签计算中应用相关系数取得了很好的结果..
这与理论是违背的呀, 所以 机器学习是玄学, 要多尝试 !!~_^
# HOG方向梯度直方图
在前面,我们都是对 结构化数据(表格形式的数据)在进行特征工程.
那针对 非结构化数据(图像数据、音频数据)如何进行特征工程呢? 可以用当下最为流行的图像特征提取技术 -- HOG (方向梯度直方图)
HOG 是一种在计算机视觉和图像处理中用于物体检测的 特征描述符.
特征描述符号是什么? 它可以通过提取图像的有用信息. 并且丢弃无关信息来简化图像的表示.
HOG+SVM分类器==图像识别中,尤其在行人检测中获得了极大的成功.
★ 简单来说HOG认为 图像的边缘信息是图像的核心特征!!根据边缘信息可以对一张图像中物体的形状或轮廓进行提取..
★ 若图片中识别的物体占图片的大部分区域,在这样的场景中,使用hog是没有问题的!!
若一张图片中 有桌子有人有小猫 占比都差不多..使用hog来识别小猫的效果可能就不是那么的好!!
HOG的超参数 > 详看示例就知道每个超参数什么意思啦!
- pixels_per_cell=(8, 8)
- orientations=9
- cells_per_block=(2, 2)
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 数据集切分
# 数据集二八分
- 数据集二八切分 训X、训y、测X、测y
- stratify = y 一般用在分类场景上, 确保 切分后 y_train 以及 y_test 中的 0 和 1 的比例与切分前 y 中的比例一致
(假如数据集标签的类别只有两类 用0和1表示)
2
3
# 交叉验证与学习曲线
- 交叉验证
因为只进行一次测试评估可能会存在一定的偶然因素. 因此,交叉验证申请出战!
★ 无需数据集手动二八分,无需手动fit,无需手动score,交叉验证内部就做了!!
- 学习曲线 > 可求得某一个超参数的最优值
for k in ks: # 学习曲线
model = KNeighborsClassifier(n_neighbors=k)
score = cross_val_score(model,m_feature,target,cv=5).mean() # 交叉验证
scores.append(score)
2
3
4
5
6
7
8
9
10
# 网格搜索
若我想对 决策树的那些重要超参数 选出重要的值, 如何是好?
用前面学过的 交叉验证+学习曲线吗? No, 该方案只能找到一个超参数的最优值.
若想找多个(模型的参数与参数之间是可能会相互影响的), 就得用 网格搜索Grid Search!! -- 本质也是穷举的过程
Grid Search是一种调参手段,也叫做穷举搜索.
> 在所有候选的参数选择中,通过循环遍历,尝试每一种可能性,表现最好的参数就是最终的结果. 其原理就像是在数组里找最大值.
> 为什么叫网格搜索?以有两个参数的模型为例,参数a有3种可能,参数b有4种可能,把所有可能性列出来,可以表示成一个3*4的表格
其中每个cell就是一个网格,循环过程就像是在每个网格里遍历、搜索,所以叫grid search!!
2
3
4
5
6
7
8
# KNN分类
- KNN分类模型的标签是离散型数据
- 未知根据已知进行分类
算未知距离所有已知点的距离,从小到大排,取前k个,看这k个哪个类别占比多,未知就属于哪个类别.
- k不同,可能会造成类别也就不同
- 超参数
- k值 用交叉验证+学习曲线求得
- 样本数量较少或数据类别分布不平衡的情况下,可考虑设置weights参数值为distance
- 距离度量用 欧式还是曼哈顿 看实际效果!
2
3
4
5
6
7
8
9
# 线性回归
!! 线性回归通过 y=w^T*X来得到预测值.
线性回归通过 MSE 来优化模型的参数 w(即特征的权重)并计算出最佳的权重值 -- 最小二乘、梯度下降等.
- 一元 -- 特征数变多了 -- 多元; 多项式 -- 特征升维/将多次的自变量看作一个变量,增加了特征个数 -- 多元
- 多元线性代数 - y = w1*x1 + w2*x2 + .. + wn*xn => y=W^T*X
竖着的权重系数乘以特征矩阵里的每一行,得到竖着的标签列!!
- 距离就是误差,误差最小的评判指标
-- 真实值与预测值相减之和 > 抵消正负,平方,平方导致扩大的误差 > 除以样本数 即得到均方误差MSE!
- 根据评判标准,要使MSE最小,即求解最小损失对应的参数向量w,方案有两个
-- 最小二乘法
-- 梯度下降
2
3
4
5
6
7
8
9
# 逻辑回归
!! 逻辑回归通过 Sigmoid 函数将线性回归的输出(对数几率)映射为一个概率值,从而进行分类.
逻辑回归通过 交叉熵损失 来优化模型的参数 w(即特征的权重)并计算出最佳的权重值, 从而使模型预测结果与真实标签尽可能一致.
-- 梯度下降等.
我们通常说,用逻辑回归来实现分类任务.既然是分类任务,为何算法名字里有回归两字呢?回归不是作预测的嘛?!
- 简单来说, 逻辑回归 = 线性方程 + sigmoid函数!!
- 原理:
step1 > 将线性回归输出的连续型预测值 - 视为 一个事件 几率的对数!
step2 > 将第一步的输出 代入 sigmoid函数 中 - 会映射成0-1之间的概率值!
- 解释:
- 几率: 设一件事发生的概率为P,则 几率=p/(1-p) 因为分母不能等于0,只能无限趋近于0,所以几率的取值范围是 [0,+∞)
- 几率的对数: 因为线性方程的预测值范围是(-∞,+∞),所以我们得求 ln(p/(1-p)), 即求e的多少次方等于p/(1-p)
- Sigmoid函数是一个S型的函数,它能够将任何实数映射到(0,1)区间!
实数越趋近正无穷,函数的值越趋近于1;实数越趋近负无穷,函数的值越趋近于0;
- 预测为1类别的概率是0.4,真实类别也是1,但只要预测概率不为100%,就会有损失.只不过,预测是1类别的概率越接近100%,损失的越少!!
同理,预测为1类别的概率是0.4,真实类别也是0,那么预测为0的概率就是1-0.4.
对数似然损失/交叉熵损失
当真实类别为1时, 损失函数 -log(预测为1类别的概率值), 0<预测为1类别的概率值<1
当真实类别为0时, 损失函数 -log(预测为0的概率=1-预测为1类别的概率值),0<预测为1类别的概率值<1
- 上述是二分类的原理,若是多分类任务呢? 有两个解决方案:
- One-Vs-Rest(ovr)
任一类别的实例作为正类(模型输出的就是正类的概率),其余类别的实例作为负类 > 有多少个类别就有多少个分类器 >
看结果哪个正类的概率高,该样本就是那个正类所在类别!
- 样本类别分布不平衡不行,可能导致模型对数量多的那个类别过度拟合,而对其他类别的性能较差;类别多的话,需要较多的计算资源
- softmax
softmax 只会构建出一个分类模型 且softmax会对 每个类别的得分 进行 指数化 处理.
并将它们进行类似归一化的操作, 得到每个类别的 概率值. 概率最高的类别将被视为预测结果.
> 过程详看笔记中的示例
> 注意:
线性回归中, 最终只会为所有维度特征产生一组权重系数W;
而softmax作用在逻辑回归中, 会为每一个维度特征产生“等于标签类别个数“这么多种的权重系数W
- 逻辑回归超参数
- penalty 默认L2正则
- C 正则化公式中的λ
- max_iter 梯度下降中能走的最大步数, 默认值为100.
- solver 求解最小损失/求最优w向量 的求解器 > liblinear、lbfgs、newton-cg、sag、saga
- multi_class 处理的是什么分类,二分类还是多分类
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# 朴素贝叶斯
贝叶斯定理
条件概率指的是在事件B已经发生的条件下, 事件A发生的概率 > P(A|B) = P(A,B) / P(B)
多事件条件概率指的是 在一个事件发生的情况下,另外多个事件发生的概率 > P(A1,A2 | B) = P(A1 | B) * P(A2 | B)
由此可得: P(A|B) = P(B|A)P(A) / P(B)
在公式中:
- P(B|A) 称作 似然度.
- P(A|B) 称作 后验概率.
- P(A)、P(B) 都叫作 先验概率.
Q:为什么P(A|B) 要通过 P(B|A) 来求呢? 因为在生活中, 似然度很容易得到, 后验概率不容易得到!!
A:举个例子,班上一共有10位女同学, 其中一位叫小美, 大家根据背影认出她的概率是10%.
班上女同学一共有3种发型,扎辫子的概率是30%. 小美自己扎辫子的概率高达70%.
求往后见到扎辫子的女同学是小美的概率!!
P(小美|辫子) = [P(辫子|小美) * P(小美)] / P(辫子) = 0.7*0.1 / 0.3 = 0.23
2
3
4
5
6
7
8
9
10
11
12
13
朴素贝叶斯算法
sklearn的多项式模型不接受输入负值(不要使用标准化对多项式模型的样本特征进行无量纲化, 因为标准化会返回负数)
SO. 若样本数据的特征为数值型数据(可能会存在负值)的话, 务必要进行归一化处理保证特征数据中无负值出现!!
- 首先明确一点,何为朴素?!
朴素是指 朴素贝叶斯只适用于特征之间是[条件独立]的情况下,否则分类效果不好!
条件独立是指每个特征之间没有必然关系的.
条件不独立指的是特征之间有关联的比如, 体重和是否喜欢吃零食这两个条件之间就有关联.
- 根据似然度的计算方法不同,朴素贝叶斯分为两种!!
多项式和高斯分布, 前者适用于离散的特征,公式用的是多项式;后者主要作用在特征为连续性变量的数据集中,公式用的是高斯函数!
Q: 一般情况下,样本中既有连续型特征又有离散型特征,怎么选呢?
A: 看比例,若大部分是离散型特征,就用多项式,否则用高斯!!
多项式朴素贝叶斯算法 > 具体计算过程详看笔记里的示例!!
P(C|W)=P(W|C)P(C) / P(W) = P(F1,F2,F3...|C)P(C) / P(F1,F2,F3...)
PS: 用 拉普拉斯平滑系数 来解决, 概率计算中零概率的问题!
- 文本分类任务中,使用多项式分布的原因之一是,因为特征(如单词的出现与否)本质上是离散的,而且每个单词的出现可以视作一个独立的事件
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# SVM支持向量机
分类场景
经验之谈: 若 <数据集的特征> 分布不均匀, 在使用rbf核函数之前,应进行 无量钢化!! 这样可以有效提升其训练效果!!
- 线性可分的二分类场景
可以想象,一个超平面(决策边界)将数据空间中的点划分为两个部分,决策边界进行左右平移,碰到数据点停下来,移动的距离大小称为边界.
边界越大,新的样本点加入时的泛化误差就越小!!
~_^ So,SVM支持向量机旨在找到有最大的边界的决策边界!
- 但实际绝大场景下,数据都是 偏线性可分、非线性可分 的!这时候就要用到SVM的核函数.
- 核函数: 核函数通过将数据点从低维度空间映射到高维度空间.在高维度空间中, SVM构建一个线性决策边界, 用于对数据点进行分类.
使我们能够处理非线性可分的数据集.
- 处理(偏)线性可分 - linear、poly
处理(偏)非线性可分 - sigmoid、rbf
★ 经验之谈: 遇事不决,否管数据集线性可分还是非线性可分, 先用rbf!! 如果rbf效果 不好, 那我们再试试看其他的核函数!!
- 若是多分类的问题呢? 线性可分与不可分都是这两个方案: OVO 和 OVR
- OVO: N个类别,两两组合 就有N(N-1)/2个分类器. 将测试样本带入这些分类器,哪个分类结果多,测试样本就是哪个类别!
- OVR: 逻辑回归的多分类问题那也提及了该方案.
不过逻辑回归评判标准是概率值;SVM中是得分,该得分是基于测试样本点到 支持向量 之间的距离计算得到的,不用深究.
- 硬间隔和软间隔是SVM在处理 线性可分和非线性可分 数据时所采用的不同策略!
硬间隔 要求完全正确分类训练集,不允许有任何的分类错误; 软间隔是指在处理非线性可分数据时, SVM允许一些训练数据被错误分类.
> svm采用的是软间隔!!软间隔使得svm具有更强的鲁棒性
- 鲁棒性表现为模型或算法能够在面对数据中的异常情况时表现出一定的弹性, 不至于产生过度的错误或偏差.
- ~_^ SVM不再是寻找最大边际了,而是寻找 最大边际与分错样本之间的平衡, 以获得更好的泛化能力!!
> svm软间隔力度,即对错误的容忍程度,通过松弛系数 ζ (zeta)来决定,该值越大,越能容忍! (一定程度解决了过拟合的情况).
注意:在svm函数中,C参数对应ζ, C越小,ζ越大!!是反着来的.
- svm分类场景的超参数
- C: 较小的C值会导致较大的松弛系数 ζ, 反之亦然
- kernel: 选择核函数
- degreeL: 作用与poly核函数,控制了多项式的度, 较高的度数意味着更复杂的决策边界.
- gamma: 作用于rbf核函数.用于调整高斯核函数的效果.
- max_iter: 用于设置迭代的最大次数.
- class_weight: 用于处理不平衡数据集的情况(不同类别的样本数不均衡)
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
回归场景
我们希望决策边界平移后,尽可能的 拟合 所有的数据点.也就是,其两条边际之间尽可能包含多的数据点!!
评判标准和线性回归一样,也是MSE(均方误差!!)
Q: 那我增大边界的大小,将所有的数据点都包含进去,拟合效果不就最好了吗??
A: No!! 这样是不行的.. 尽管其值越大, 模型泛化能力越强.. 泛化能力是解决过拟合的, 过于泛化了, 不就欠拟合了吗!!
> 增大边界意味着 增大 ε(epsilon)
如果 ε 太小, 模型将对训练数据的每个点都非常敏感, 过度拟合训练数据,从而导致 过拟合,使得模型无法泛化到新的测试数据上.
如果 ε 太大, 模型变得过于宽容, 无法很好地捕捉到数据的细节, 从而导致 欠拟合
- sklearn.svm.LinearSVR() 和 sklearn.svm.SVR()
前者适用于线性可分回归问题.后者可以灵活地处理线性可分和非线性可分回归问题
- 如果您的数据是线性可分的, 那么LinearSVR可能是一个更好的选择, 因为它拟合的速度较快.
而对于需要非线性特征变换的问题, 您可以选择SVR, 并选择合适的核函数.
- 超参数: epsilon 控制SVR模型的容忍度.
较大的epsilon值表示接受更大的误差. 默认值为0.1. 或者说是对margin的范围进⾏⼀个程度指定!
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 决策树
- 运用特征和标签,依照某个决策规则,以此来构建树状图结构,解决分类或回归问题!!
一般不会用到所有特征进行树的构建; 根节点和中间节点是与特征相关的节点; 叶子节点是与标签相关的节点.
- 决策树算法要解决的两个核心问题:
1> 如何从数据集中找出树的每一层的最佳节点和最佳分支?
2> 如何让树停止生长, 防止过拟合? (若树长的越大分支越细致,则对训练数据的描述越清楚,越依赖训练集数据,过拟合了,泛化差
- 决策规则/评估指标: 信息增益、信息增益比、基尼系数 > 关于这些指标具体如何计算的以及他们的优缺点,详见示例.
信息熵 越大越混乱,越不确定
信息增益 = 划分前的信息熵 - 划分后的信息熵
信息增益比 = 信息增益 / 信息度量
> 用信息增益比肯定比用信息增益好!!
- 决策树原理<以分类为例>: 假设评估指标是基尼系数!
1. 对原始数据集所有特征算基尼系数. 假如得到A特征为根节点t0特征.
2. 然后根据A特征的类别进行分裂得到了, 数据集合D1 和 数据集合D2.
3. 根据集合D1和集合D2,构建根节点的子节点t1和t2. !! ★ 注意: D1和D2 数据集合中 是不包含A这个特征的..!!
若t2节点因为达到了节点停止生长的条件.那么不用管.
来看t1节点. 同样的,对D1数据集合中的所有特征算基尼系数系数.以此类推.
- 分类决策树的超参数
- criterion: 'entropy'(熵 - 默认c4.5) 和 'gini'(基尼系数 - 默认cart), 默认gini
- max_depth: 默认不纯度为0时,停止生长. 设置了max_depth参数,哪怕不纯度没有达到0, 但达到了最大深度,也会停止生长!!
- min_samples_split:
该参数设置的是 节点分支后, 子节点应包含的最小样本数量是多少. 若没有达到该参数设置的值,那么该分支不会产生!
- min_samples_leaf:
该参数设置的是 节点应包含的最小样本数量是多少,若数量没达到,该节点就不能产生分支!!
- class_weight: 指定类别权重
> min_samples_split、min_samples_leaf 这两参数解决过拟合的,手动决定树什么时候停止生长!!
- ※ max_features这个参数,需要关注下!!
默认的决策树,决策树原理中提及的数据集合D1 和 数据集合D2,都是计算集合中所有的特征的基尼系数.
随机森林默认是 从数据集合的特征中 随机取 集合特征数开根号 这么多个特征.对其算基尼系数
> 意味着 随机森林将max_features的值设置为None 子树的构建过程就跟普通决策树的构建过程一摸一样.
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# 集成学习
# 集成学习理论
集成学习 就是通过一定的 “结合策略” 组合 这里的 多个弱评估器 一起 得到 一个更好更全面的 强评估器模型.
- 弱评估器: 在 某些数据集/某些方面 上表现的比较差. 这种不全面,有偏好的模型叫作 弱评估器!!
- 目标:学习出一个稳定的且在各个方面表现都较好的模型!
- Q:弱评估器怎么选?
A:经验而言,在集成学习中通常90%的情况下会选用【非线性模型】作为弱评估器
其中最常用的就是决策树, 也可以是SVM等非线性模型, 而通常几乎不会使用逻辑回归、岭回归等线性模型!!
- Q:集合策略如何定?
A:有两种思想 - Bagging、Boosting
> Bagging代表模型: 随机森林; > Boosting代表模型: Adaboost、GBDT、XGBoost和LightGBM
◎ Bagging过程如下:
1.抽取多组训练集:
每个样本集都是从原始样本集中随机且有放回的抽取n次,组成训练样本. 共进行m轮,得到m个子训练集,子训练集之间相互独立!
(在训练集中,有些样本可能被多次抽取到,而有些样本可能一次都没有被抽中)
2.个体学习器: 每次使用一个训练集训练得到一个弱评估器模型,m个训练集共得到m个模型! <★ 并行生成,即可以同时进行生成操作>
3.投票:
在分类分类问题中, 将上步得到的m个模型采用投票的方式得到分类结果;
回归问题问题中, 计算上述模型的均值作为最后的结果!
◎ Boosting过程如下:
- 通过提高那些在前一轮被弱分类器分错样例的权值, 减小前一轮分对样例的权值
(使得弱分类器可以对分错样例更敏感) . 来使得分类器对误分的数据有较好的效果!!
- 也就是说算法刚开始训练时对每一个训练样本赋相等的权重, 然后用该算法对训练集训练t轮.
每次训练后, 对训练错误的训练样本赋以较大的 "权重", 也就是让学习算法在每次学习以后更注意学错的样本.
然后获取t轮返回的结果, 融合制定出终极结果! <★ 各个弱评估器模型只能 串行[顺序] 生成, 因为后一个模型需要前一轮模型的结果>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# Bagging-随机森林
随机森林
- "森林"指的是决策树
- "随机"指的是两个随机,[数据集的随机选择]和[待选特征的随机选取]
前面那个随机相关超参数: bootstrap=True表示会采用 随机且放回的方案.
后面那个随机相关超参数: max_feature表示 子数据集合选择多少个特征,默认是开根号!
- 随机森林默认使用的决策树算法是cart,评判标准是基尼系数!
2
3
4
5
6
7
# Boosting-Adaboost
Adaboost仅实现二分类的任务, 若是多分类的任务的话, 表现的会很差..
Adaboost有两个权值
- 一个是训练集中每个样本的权值 > 简单理解,样本权值越高,可看作这个样本在整个样本集中的占比越大(算法中不是这样实现的.
- 一个是每一个弱评估器的权值
★ 在不断的迭代"前向分布算法"中,都会对这两种权重进行更新 -- 以便得到最小误差!
- Adaboost是Boosting决策中专门处理二分类问题的方案!! 标签类别是(-1,1)
假设训练样本量为N.
对于第一个弱评估器,则需要先初始化每一个 "训练样本的权值" 为1/N.将训练样本带入第一个弱评估器中,可以得到该训练集的分类情况.
根据分类情况的对错,降低分对样本的样本权值,升高分错样本的样本权值.然后将更新样本权值的训练集代入下一个弱评估器中.
以此类推! 注: m个弱评估器有m个分类结果向量!
特别注意: 串行 > 这m个弱评估器是一个个挨个生成的!!
◎ Adaboost的大体过程
-1- 首先,我们需要知道每个弱评估器的重要程度. - 即每一个弱评估器的权值
1.当前弱评估器的 "分类误差率" e = 当前弱评估器对分错样本的权值进行累加.
2.将 e 带入公式 1/2*log[1/e - 1] 可以得到 "当前弱评估器的权值"!!
> 通过公式不难看出,当前弱评估器的分类误差率越小,则当前弱评估器的权值越大,即当前弱评估器越重要!!
-2- 加法模型/加权多数表决 - 逐步构建强评估器
1. 前两个弱评估器的加权融合:
假如已经串行生成了两个弱评估器,就有两个分类结果向量,则 这两个分类结果向量 乘以 对应的弱评估器的权值, 然后相加.
eg: [1 -1 1] * 0.2 + [-1 -1 1] * 0.3 = [0.2 -0.2 0.2] + [-0.3 -0.3 0.3] = [-0.1 -0.5 0.5]
2. 加入第三个弱评估器: 然后又串行生成了一个弱评估器,则
eg: [-0.1 -0.5 0.5] + [-1 1 -1] * 0.1 = [-0.1 -0.5 0.5] + [-0.1 0.1 -0.1] = [-0.2 -0.4 0.4]
3. 以此类推
相当于 m个弱评估器就有m个分类结果向量!我们通过线性组合的方式(加法模型)将这m个分类结果进行了融合.
-3- 将通过融合得到的最终的 分类结果向量 代入 sign函数中.
该函数有一个特点
传入一个大于0的值,则函数返回的结果为正,说明是 1 类别;
传入一个小于0的值,则函数返回的结果为负,说明是 0 类别.
eg: [-0.2 -0.4 0.4] 代入sign函数中 得到分类结果的类别分别是 0 0 1
◎ Adaboost的损失函数
已知有三个弱评估器
其对应的分类结果向量分别是 [1 -1 1] [-1 -1 1] [-1 1 -1];
其对应的弱评估器权值分别是0.2 0.3 0.1;
其对应的真实标签是 y = [1 -1 1]
求这三个弱评估器组成的强评估器的Adaboost损失函数,计算过程如下:
- 我们可以计算得到这三个弱评估器的分类结果向量 通过加法模型 可以得到一个融合的结果 > [-0.2 -0.4 0.4]
- 我们将上一步融合的结果代入 指数损失函数exp中,并进行相加,结果就是Adaboost的损失:
exp = e^(-(真实标签结果)*(某个样本的融合结果))
e^(-(1)*(-0.2)) + e^(-(-1)*(-0.4)) + e^(-(1)*(0.4))
- 为啥要用"exp指数函数"作为Adaboost的损失函数呢?
首先,标签类别值是 1 和 -1, e^0 = 1 , e^x 函数是单调递增的. 当x小于0时,e^0 < 1; 当x大于0时,e^0 > 1
再看融合结果,里面的样本若是负值则代表预测类别为-1 若是正值则代表预测类别为1
看示例 e^x -- x=(-(1)*(-0.2)) ; x=(-(-1)*(-0.4)) ; x=(-(1)*(0.4))
第二个预测正确,x<0,e^x<1,给了一个小的损失; 第一个和第三个预测错误,X>0,e^x>1,给了一个大的损失!
◎ Adaboost的优化机制/最小损失 -- 本质就是对样本权值的更新
<前向分布算法> 新生成一个弱评估器时 就是一个迭代
弱评估器的权值 是由该评估器的分类误差率决定的,而分类误差率又是动态变化的, 依赖于之前迭代中更新的样本权值.
迭代优化的作用在于更新样本权值, 从而影响新生成弱评估器的分类误差率和权值.
这种逐步优化机制使得 Adaboost 能够专注于分类困难的样本,从而提高最终的分类性能。
★ 因此,生成新弱评估器时,不会重新计算之前弱评估器的权值
但之前的弱评估器通过样本权值的动态更新,间接影响了当前弱评估器的权值和分类能力.
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
对Adaboost的过程进行精简
1.为数据集的每个样本设置初始权重,将数据集代入分类决策树充当的弱评估器中
弱评估器输出一个标签向量 -- 借此可以得到当前弱评估器的分类误差率 -- 进而得到当前弱评估器的权重
2.将数据集的每个样本的权重重新洗牌,上一个弱评估器预测错的样本权重增加,预测对的样本权重减少.
样本权重重新洗牌后的数据集代入新的一个弱评估器中,同样的,当前弱评估器会输出一个标签向量、得到自身的一个分类误差率和权重.
3.每生成一个新的弱评估器可得到一个线性融合的输出结果.
每个弱评估器的线性组合结果都 = 当前弱评估器的权重 * 当前弱评估器输出的标签向量
第几个弱评估器,就将前几个弱评估器的线性组合的结果进行 融合/相加!!
> 将线性融合的结果代入sign函数中,就是样本集分类的结果!!
4.几个弱评估器得到的强评估器的 损失是由 exp指数函数 来计算的!
我们可以通过改变样本权重借此来影响分类误差和弱评估器的权重,进而改变exp指数函数的结果!!
So, ★在样本权重改变时,增加多少,减少多少.是有依据的. !!得让已有的弱评估器+新的这个弱评估器的整体损失最小.
(新生成弱评估器时,前几个弱评估器的组合结果是固定的,当前需要关注的是新的弱评估器如何进一步降低整体损失)
2
3
4
5
6
7
8
9
10
11
12
# ★ Boosting-GBDT
基于分类任务
- Adaboost - 弱评估器是分类器; GBDT - 弱评估器是回归器.
- Adaboost - 传入新的弱评估器是经过样本权重更新的特征矩阵和真实样本标签;
GBDT - 每个弱评估器的特征矩阵都是一样的, 传的标签是 真实标签减去上一个弱评估器的预测值.
那GBDT的每个预测结果不都是一样的吗? No, 会根据残差改变新弱评估器的预测值..
预测值经过sigmoid或softmax函数就会变成 类别标签.. 也就能算当前弱评估器的 分类误差率和权重..
梯度提升树(GBDT)是提升法中的代表性算法!
它即是当代强力的XGBoost、LightGBM等算法的基石,也是工业界应用最多、在实际场景中表现最稳定的机器学习算法之一!
★★★ GBDT的求解流程与AdaBoost大致相同!但由4点不同!
-1- 弱评估器不同
对于AdaBoost或随机森林算法来说,当集成算法执行的是回归任务时,弱评估器也是回归器.
当集成算法执行分类任务时,弱评估器也是分类器.
★ 但对于GBDT而言,无论GBDT整体在执行回归/分类任务,弱评估器一定是回归器!!
★ GBDT通过sigmoid或softmax函数将连续性的输出结果转换成具体的分类结果,但实际弱评估器一定是回归器!
<可以回忆,逻辑回归的本质是线性回归方程,为了作分类,加入了sigmoid函数作二分类,softmax函数作多分类
-2- 损失函数
在GBDT当中,损失函数范围不再局限于固定或单一的某个损失函数,而从数学原理上推广到了任意可微的函数
损失函数可微是指损失函数在其定义域内的各个点上都存在导数.可微使得我们可以进行梯度下降等优化算法的求解.
-3- 拟合残差
GBDT不修改样本权重,而是通过拟合残差来影响后续弱评估器结构.
★ 即每一轮的弱评估器都试图拟合当前模型的预测值与真实值之间的差异(即残差),从而逐步减少模型的整体损失
它通常会通过每次迭代拟合当前模型的负梯度方向,逐步优化模型性能
eg: 有m-1弱评估器 和m弱评估器
AdaBoost - m使用的数据集是在m-1训练完后,对数据集样本权重进行了调整之后的数据集.所以m会更关注错误的样本.
GBDT - 数据集不变了!m使用的标签变成了 y_t - y_p 即拟合残差,真实结果向量减去预测结果向量
-4- 抽样思想
GBDT加入了随机森林中随机抽样的思想,
在每次建树之前,允许对样本和特征进行抽样来增大弱评估器之间的独立性(也因此GBDT可以有袋外数据集).
随机抽样的方式可以进一步增加Boosting算法的稳定性!
GBDT实现二分类
- 其实大体上跟AdaBoost的二分类差不多,但注意一点,GBDT分类任务也使用的是回归器!
将加法模型最后的值 sigmoid函数,当p大于0.5时,样本xi的预测类别为1,反之为0.
GBDT实现多分类
- GBDT对于多分类也只能输出集成算法的加法模型返回的结果H(x),因此我们需要使用softmax函数帮我们将结果值转换为概率.
而softmax函数是要接受K个连续型的输入,并输出K个概率的函数
So,以OVR的形式构建多科回归树! 这个方法把多分类问题分解为多个二分类问题,并为每个类别训练一颗回归树
具体来说,当我们的问题是K分类且每个类别为[1,2,3...K]的时候,我们需要分别按照y=1,y=2...y=K进行建模,总共建立K课树
总共K个输出结果.然后,我们分别将H1(xi)到Hk(xi)的结果输入到softmax函数中,来计算出每个标签类别所对应的概率.
★ 意味着,模型 迭代10次/设置10个弱评估器, 多分类场景下,实际上会生成 k个标签类别乘以10 这么多个弱评估器!!
对于这一现象,我们可以通过 n_estimators_以及 estimators_属性 进行查看.
- n_estimators: 实际迭代次数
- estimators: 实际建立弱分类器的数量
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# 增量学习
当随机森林中的决策树个数很多时, 训练时需要的空间和时间会比较大. 那么, 此时"增量学习"就应运而生了!
数据集高达几百个G,无法一次性读取并训练,需要分批次读取训练.
增量学习是机器学习中非常常见的方法, 在有监督和无监督学习当中都普遍存在!
★它允许算法不断接入新数据来 [拓展] [当前的已有的模型] - 即允许巨量数据被分成若干个子集, 分别输入模型进行训练!!
(普通学习) 使用两组数据集分别对模型进行训练, 查看训练后的结果:
通常来说, 当一个模型经过一次训练之后, 如果再使用新数据对模型进行训练, 原始数据训练出的模型会被替代掉.
(增量学习) 对于随机森林这样的Bagging模型来说:
意味着之前的数据训练出的树会被保留, 新数据会训练出新的树, 新旧树互不影响!!
> 依据: model.estimators_ 查看每棵子树在学习后, 子树的随机种子序号变没变!
> 增量学习 一般会进行 model.n_estimators += 2 的操作, 新增的子树与新参与训练的数据集进行绑定.
- 使用cuML可加速训练.
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 聚类算法
- 无监督的学习算法
- 聚类算法追求 "簇内差异小,簇外(簇与簇之间)差异大"
- 当聚类完毕之后,我们就要分别去研究每个簇中的样本都有什么样的性质,从而根据业务需求制定不同的商业或者科技策略.
- 传统K-Means算法的原理很简单,给定一个数据集,按照样本之间的距离大小,通过不断地迭代将数据集划分为K个簇,具体实现步骤如下:
step1: 没有规律的选取K个质心(初始聚类中心),不一定要是数据集中的点;
step2: 针对数据集中的每个样本,记录它到K个聚类中心的距离(欧氏距离),将其划分到距离最小的聚类中心对应的cluster中.
简单来说,就是将每个样本指派到最近的质心;
step3: 重新计算K个cluster对应的质心(同一cluster中的样本点在二维坐标系上横坐标相加,纵坐标相加,都除以cluster中样本数)
这样就可以得到K个新的质心;
step4: 循环迭代step2和step3,不断进行收敛,直到质心不再改变.
- 若使用整体平方和,簇数增加,其值必定是减少的,数学可证明. 所以我们用轮廓系数判断分多少个簇更好!!
- ★ 探究每个簇的代表的类别的含义,详见示例!!
★ 注意:一定是基于原始数据集去挖掘,而不是基于特征工程后的数据集去挖掘!!
根据聚类结果的标识划分子集后,需要对每个子集里每个特征进行处理.
- 针对 数值型列,取每列的均值作为该列的值.
- 针对 非数值型列/类别列/离散型列 将出现频率最高的 元素/类别 作为该列的值.
> 汇总后,根据这些数据分析 每个簇的显著特征是什么!!
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 模型评价指标
knn分类模型 model.score是R^2; 逻辑回归模型 model.score是 准确率.
# 分类任务
> 逻辑回归的损失函数: 对数似然损失/交叉熵损失 -log(几率的对数经过sigmoid后的值)
> 准确率、正确率
召回率
精准率
f1-score
2
3
4
5
# 回归任务
RSS - MSE - MAE - R^2
距离就是误差,回归模型评价指标(两个角度)
-1- 是否预测到了正确或者接近正确的结果"损失函数"
- 真实值与预测值相减之和 > 抵消正负,平方 RSS > 平方导致扩大的误差,除以样本数 即得到均方误差MSE!
- MAE于MSE相比,仅是平方换成了绝对值!!
绝对值是真实的误差,进而我们可以将 平均误差(即MAE)与标签(即真实值)的平均值、最大值最小值、中位数等指标进行对比..
看看这个误差有多严重!! eg: MAE为2 标签的平均值是30,单纯从这个比例来看 误差相对较小, 表明模型的预测效果是比较可靠的.
-2- 是否拟合到了足够的信息"性能评估"
VAR方差 - 每个真实点减去均值的平方和除以样本数 -- 平均到每个标签的信息量大小
MSE均方误差 - 每个点真实值减去预测值的平方和除以样本数据 -- 平均到每个样本的损失
(前面大半部分拟合,后面小部分不拟合,误差均分了,mse就小了,但这样的模型是偏科的
一旦我的新样本是处于拟合曲线的后半段的,我的预测结果必然会有巨大的偏差,这不是我们希望看到的,所以需要评价指标R^2)
- R^2 = 1 - MSE/var -- 最终值越大越好,也表示拟合程度!!
- 注意: R-Square的取值范围是"负无穷到1"
很多资料说是0~1是不准确的,因为有预测错误巨大导致y_predict巨大,从而分子巨大,R-Square远小于0的情况
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 过拟合和欠拟合
直接用最小二乘和梯度下降实现的回归模型实现的效果不是很好..在实现的过程中会有很多 病灶/问题 -- 过拟合、欠拟合
◎ 欠拟合
- 现象:在训练集和测试集上的表现都不好
- 原因:模型学习到的样本的[特征太少]了,模型被训练的过于简单,模型考虑的太少,[导致区分标准太粗糙],出现了欠拟合!!
- 解决:多项式回归 > "将已知特征维度进行相乘、自乘或次方来构建新的维度"
◎ 过拟合
- 现象:在训练集上表现的好,在测试集上表现的不好,即泛化能力差!
- 原因:模型学习到样本的[特征太多],其中可能存在一些[嘈杂特征],模型被训练的过于复杂-机器学习到的特征[太依赖训练数据]了!!
- 解决:正则化
◎ 正则化
- 损失不是越小越好,一味追求最小损失,会造成过分依赖训练集数据,泛化能力差,过拟合.
- loss(w) = 原损失函数 + 惩罚项/额外项 > 尽可能的使等式右边的,两部分都尽可能的小!
- 额外项分为两种 L1-Lasso和L2-Ridge!
- L1 权重参数向量中每个w绝对值之和
- 目标:将不重要特征的权重系数压缩到0,只保留下重要的特征,从而实现了特征选择.而重要特征对应的权重系数则会保留较大的值!
- L2 权重参数向量中每个w的平方和
- 目标:
该惩罚项中的平方使得较大的权重系数被放大, 从而产生更大的惩罚效果.
SO,L2通过降低所有特征的权重系数(而非只针对不重要特征),但一般不会被压缩到零.
- L1和L2的表达式前面还有正则化参数λ,它控制着约束力度的大小
- 增大alpha会使得系数更加趋向于0 > 降低训练集性能,很可能会提高泛化性能
减小alpha可以让系数受到的限制更小.
- 注意,实践过程中,λ 值大了/约束大了,还可能造成欠拟合(训练集和测试集的效果都不好)的情况发生. 这时降低 λ 的值试一试!!
- 通过交叉验证+学习曲线来选择最优λ 值!
- 在实践中,一般首选L2岭回归.但如果特征很多,你认为只有其中几个是重要的,那么选择L1套索回归可能更好.
同样,如果你想要一个容易解释的模型,L1套索回归可以给出更容易理解的模型,因为它只选择了一部分输入特征!
- 这里要记住的是,如果有足够多的训练数据,正则化变得不那么重要,并且岭回归和线性回归将具有相同的性能!
训练数据足够多,最终线性回归的性能会追上了L1、L2.
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# 何为重要特征
A:与标签有较强的相关性(不管是线性关系还是非线性关系,只有特征与标签关系强即可)、能够显著降低损失、数值比较大的.
但有线性关系的特征通常是重要特征!!
- 如果某个特征与标签有很强的线性关系(即该特征对分类结果的影响非常显著).
那么在训练过程中, 该特征的权重 w 会相应地增大或减小, 以反映它对最终决策的影响.
如果某个特征与标签的关系较弱, 则其对应的权重 w 会接近零, 意味着该特征在预测中对结果的影响较小.
2
3
4
5
# 模型选择
# 线性关系探究
Q: 已知逻辑回归在具有线性关系较强的数据集上具有非常好的拟合效果, 我们如何得知一组样本数据特征与标签之间是否具有较强的线性关系?
A: 没有很好的办法. 一般来说, 我们会这样做:
1> 散点图可视化. 假设有10个特征,我们画出每个特征与标签的散点图,观察是否存在线性关系.
★★ 若10个中有5个观察出有线性关系, 则可以说整个样本的特征与标签之间存在一定的线性关系!
(当然可以使用散点图矩阵来同时观察多个特征之间和特征与目标之间的线性关系)
2> 相关系数.
计算特征变量和目标变量之间的相关系数. 如皮尔逊相关系数. 相关系数的绝对值越接近于1, 表示特征和目标之间具有更强的线性关系.
需要注意的是, 相关系数只能衡量线性关系的强度, 不一定能反映非线性关系.
3> 直接使用逻辑回归, 若无论怎么调试, 无论怎么做特征工程, 表现的效果都不好, 那么该样本的特征与标签之间的线性关系就不强!!
2
3
4
5
6
7
8
9
# 最小损失方案
- 求线性回归模型最小损失
-- 最小二乘法
- 原理:它认为模型的损失w是满足一个凹函数. 然后使用损失函数对w求导,让其一阶导数为0/斜率为0的点,即可找到最小损失!
- 解读:最小损失对应的w,生成w的公式中出现了y标签数据,因此标签参与了模型训练!
- ★使用最小二乘法求最优w向量的话,损失函数得是凹函数且数据集的特征维度不能太多!!因为矩阵逆运算的时间复杂度通常为 O(n³)
-- 梯度下降
- 可以把损失函数曲线当做是一个很大的一座山,道士只能不断往返(迭代)找寻更低处下山,所以是一个迭代的过程
- 关键参数,学习率、方向
- ★在实现梯度下降前,基本上都会先对样本数据进行归一化或者标准化的无量纲化操作,使得梯度下降算法更加稳定和快速!
逻辑回归 = 线性方程 + sigmoid函数 SO,逻辑回归的最小损失,也是求最优的w向量!! 在逻辑回归的函数中,可选的有5种!!
2
3
4
5
6
7
8
9
10
11
# 各个模型的优劣
分类 - KNN、逻辑回归、朴素贝叶斯、SVM、决策树-c4.5、决策树-cart、二分类Adaboost、GBDT 预测 - 线性回归、SVM、决策树-cart、GBDT
简单的二分类任务直接用 Adaboost; 想要更精准的二分类结果以及多分类任务试试GBDT, 它的调参空间蛮大的!!
◎ KNN 【分类】 > 点到点的距离
- 尽管KNN分类模型是有监督模型,但参与KNN的数据集的标签是数值非数值都行!!标签是数值还是非数值都不影响模型!
- knn常用于 样本量较小 或 特征空间/维度较小 的 分类 问题中; 不适合应用在样本类别分布不均衡的场景!
- 涉及距离的计算,务必对数据进行标准化或归一化处理,以消除各个特征的差异性!
◎ 线性回归 【预测】 > 点到线的距离
!!线性指的是权重 几何上是线性超平面,尽可能的包含所有的点
★★ “线性”指的是模型通过一个线性超平面拟合数据,尽量将所有数据点的误差最小化
- 有监督模型 特征和标签都参与了运算 以y=mx+b举例 要有两个xy值,才能求的m和b的值!所以线性回归模型的标签必须是数值
◎ 逻辑回归 【分类】
!!线性指的是权重 几何上是线性超平面,尽可能的将数据点一分为二,划分区域
★★ “线性”指的是模型通过一个线性超平面划分数据,将数据点分为不同的类别。
- 优
- 若特征与标签具有较强的线性关系的,使用逻辑回归效果好,因为逻辑回归的组成里就是线性方程嘛!
(★★ 若10个中有5个观察出有线性关系, 则可以说整个样本的特征与标签之间存在一定的线性关系!)
!! 逻辑回归假设特征与标签的 对数几率(log-odds)存在 线性关系,而不是直接假设标签与特征之间的线性关系
- 对于线性数据,逻辑回归的拟合和计算都非常快,计算效率优于SVM和随机森林,尤其是在大型数据集上能看出区别!
- 逻辑回归返回的分类结果不是固定的0和1,而是以小数形式呈现的类概率数字
- 逻辑回归具有较强的抗噪能力, 即对异常数据不敏感!
- 缺
- ★ 仅适用于[线性可分]问题
- 若数据分布呈现出某种非线性模式(如同心圆、弯曲的决策边界等),逻辑回归将难以准确地分类
因为它的模型结构无法适应这种复杂的决策边界.
- 若你事先知道你的数据之间的联系是非线性的,千万一定不要使用逻辑回归,还不如瞎猜!
- 对多重共线性敏感! > 逻辑回归可以通过正则化解决(逻辑回归的正则化与线性回归的正则化原理一模一样)
◎ 朴素贝叶斯 【分类】
- 根据似然度的计算方法不同,朴素贝叶斯分为两种!!
多项式和高斯分布, 前者适用于离散的特征,公式用的是多项式;后者主要作用在特征为连续性变量的数据集中,公式用的是高斯函数!
应用场景: 前者文本分类、后者天气预测!
- 朴素是指 朴素贝叶斯只适用于特征之间是[条件独立]的情况下,否则分类效果不好!
◎ SVM支持向量机 【分类、预测】
■ 分类
- 优
- 线性可分,非线性可分皆可以!
- 有松弛系数 ζ , 具有很强的鲁棒性&泛化能力强
- 核函数可以有效地处理高维数据
- 缺
- 计算时间和内存消耗较大
- 仅适用于有监督学习
- 对于样本不平衡问题表现一般(不同类别的样本数不均衡, SVM可能倾向于将决策边界偏向于样本量更多的类别
- SVM不会直接给出分类概率.
★ SVM 比较适应小样本的环境!! 特征维度可以多,但样本量别太多!!
◎ 决策树 【c4.5分类 cart分类以及回归】
c4.5
- 能够处理离散型和连续型的属性类型. 即可以处理取值较多的特征, 不会因为特征取值较多而对其有所偏好!
- 具有剪枝功能(即停止生长,处理过拟合), 可以解决模型出现过拟合的问题
- 对缺失值不敏感,可以直接处理缺失值
- 在数据集取值不平衡或特征划分能力较弱的情况下,对特征选择进行了更准确的考量
cart
- 不同之前的ID3和C4.5 [仅仅] 只能作用于 [分类任务] , CART还可以应用于 [回归任务] 的学习当中, 并且具备剪枝功能
◎ 集成学习-Bagging-随机森林
随机森林默认使用的决策树算法是cart,评判标准是基尼系数!
- 优
- 由于采用了集成算法,本身精度比大多数单个算法要好,所以 准确性高.
- 可解决分类问题,也可以解决回归问题. 因为决策树cart即可分类也可回归.
- 由于两个随机性的引入(样本随机,特征随机),使得随机森林不容易陷入过拟合 且 具有一定的抗噪声能力.
噪声,即噪点、异常数据.. 子树越多,噪点影响越小!
- 它能够处理很高维度(feature特征很多)的数据, 并且 不用做特征选择.
对数据集的适应能力强 - 既能处理离散型数据, 也能处理连续型数据!
<一般不做特征选择,当然你也可以作下特征选择,以此减少下子树构建的难度.>
- 随机森林本身就可作为 特征选择 的一种技术!!
- 缺
- 当随机森林中的决策树个数很多时,训练时需要的空间和时间会比较大!!
◎ 集成学习-Boosting-Adaboost ★仅作二分类的任务,但它的效果要比随机森林和决策树要好!!
- 优
- 高准确性: Adaboost能够通过迭代训练多个弱分类器,并将它们组合成一个强分类器,提高整体分类器的准确性.
- 不易过拟合: Adaboost通过调整样本权值和弱分类器的权值,更关注之前被错误分类的样本,减少了过拟合的风险.
- 简单易实现: Adaboost算法的实现相对简单,只需要选择一个基本的弱分类器,并进行迭代训练即可.
- 缺
- 对异常值敏感: Adaboost算法对异常值比较敏感,因为噪声数据可能会被错误分类,并且会在后续的迭代中受到更多的关注.
- 训练时间较长: Adaboost算法需要进行多次迭代训练,每一轮迭代都需要计算样本权值和弱分类器的权值,因此训练时间相对较长.
◎ 集成学习-Boosting-GBDT
不仅能作二分类,还可以作多分类!!当然,也可以进行回归任务.
◎ 增量学习
当随机森林中的决策树个数很多时, 训练时需要的空间和时间会比较大. 那么, 此时"增量学习"就应运而生了!
数据集高达几百个G,无法一次性读取并训练,需要分批次读取训练
◎ K-means算法
K-Means简单、快速、伸缩性好、有着近乎线性的时间复杂度、在大规模的数据挖掘中表现良好. 但也存在以下几个缺点:
1.面对大规模数据,K值难以确定
2.随机选取得K个聚类中心易造成聚类局部最优
3.对数据集中的离群点很敏感
4.通常的聚类结果都是圆状或球状簇
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101