概念:利用回归方程(函数)对一个或多个自变量(特征值)和因变量(目标值)之间关系进行建模
特点:只有一个自变量的情况称为单变量回归,多于一个自变量情况的叫做多元回归
数学公式:
线性回归当中主要有两种模型,一种是线性关系,另一种是非线性关系。
由于目标值时连续的,无法根据正确率进行判别,而是计算 损失量(预测值和真实值差的平方和) 来判断
损失越小,回归模型越好
通过优化各个自变量的权重(w
),使得损失降到最小
常见的优化算法:
X
为特征值矩阵,y
为目标值矩阵对其求解关于w
的最小值,起止y,X
均已知二次函数直接求导,导数为零的位置,即为最小值。
sklearn API
代码实现
导入模块:from sklearn.linear_model import LinearRegression
正规方程API:LinearRegression(fit_intercept=True)
fit_intercept
:是否计算偏置normalize
:数据是否进行标准化,默认不标准化preprocessing.StandardScaler
标准化数据LinearRegression对象.coef_
:回归系数LinearRegression对象.intercept_
:偏置梯度:
梯度下降:以随机位置为基准,寻找这个位置梯度,往下移动,都反复采用该方法,最后就能成功的抵达(微分为0)最小值位置
常见的梯度下降算法有:
FG
)SG
)SAG
)SG
获得的梯度,每次训练结果:新样本与旧样本 所得 所有梯度的平均值,进而更新了参数Mini-batch
)FG
迭代获取权重batch_size
),通常设置为2
的幂次方,更有利于GPU
加速处理FG
运算效率低成本大和SG
收敛效果不稳定的缺点sklearn API
代码实现
SGDRegressor
类实现了随机梯度下降学习,它支持不同的loss
函数和 正则化拟合线性回归模型
导入模块:from sklearn.linear_model import SGDRegressor
梯度下降API:SGDRegressor(loss="squared_loss", fit_intercept=True,penalty='l2', learning_rate ='optimal', eta0=0.01)
参数:
loss
:损失函数类型
loss="squared_loss"
:普通最小二乘法fit_intercept
:是否计算偏置penalty='l2'
:正则化方式。{‘l2’, ‘l1’, ‘elasticnet’}
l2
岭回归 常用l2
Lasso
回归 少用elasticnet
:弹性网络,综合了岭回归
和Lasso回归
用于少数特征有效时normalize
:数据是否进行标准化,默认不标准化preprocessing.StandardScaler
标准化数据learning_rate
: 学习率(α
)填充方式
constant
: 学习率为常数,并通过eta0=0.01
指定optimal
:学习率= 1.0 / (alpha * (t + t0))
默认使用invscaling
: 学习率= eta0 / pow(t, power_t)
、power_t=0.25
:存在父类当中max_iter=1000
: int
,通过训练数据的最大次数tol = 1e-3
:停止训练的精度标准专属属性:
SGDRegressor.coef_
:回归系数 (线性回归方程中的权重W
)SGDRegressor.intercept_
:偏置 (线性回归方程中的常数项b
)概念:算法在学习时尽量减少 影响模型复杂度或者异常点较多 的特征(甚至删除)
岭回归(具有L2
正则化的线性回归)
在原来的线性回归的方程 中添加 正则项,使不重要特征 和 高次项特征 的权重 尽可能小:
sklearn API
代码实现
导入模块:from sklearn.linear_model import Ridge, RidgeCV
岭回归API:Ridge(alpha=1.0, *, fit_intercept=True, normalize=False , solver='auto', random_state=None)
带有交叉验证的岭回归API:RidgeCV(alphas=(0.1, 1.0, 10.0),...)
alpha
:正则化力度,也叫 λ
,λ
取值:0~1
、1~10
fit_intercept=True
:计算偏置solver
:会根据数据自动选择优化方法。{'auto','svd','cholesky','lsqr','sparse_cg','sag','saga'}
sag
:如果数据集、特征都比较大,选择该随机梯度下降优化normalize
:数据是否进行标准化,默认不标准化preprocessing.StandardScaler
标准化数据max_iter=1000
: int
,通过训练数据的最大次数tol = 1e-3
:停止训练的精度标准Ridge/RidgeCV.coef_
:回归系数 (线性回归方程中的权重W
)Ridge/RidgeCV.intercept_
:偏置 (线性回归方程中的常数项b
)Ridge.n_iter_
:每个目标的实际迭代次数RidgeCV.alpha_
:估计的正则化参数RidgeCV.best_score_
:具有最佳alpha
值的基本估算器 得分RidgeCV.cv_values_
:每个Alpha
的交叉验证值(仅当store_cv_values=True
和cv=None
时可用 )注:Ridge
方法相当于SGDRegressor(penalty='l2', loss="squared_loss")
,只不过SGDRegressor
实现了一个普通的随机梯度下降学习(SG
),而Ridge
实现了SAG
Lasso
回归
在原来的线性回归的方程 中添加 L1
正则项,将 不重要特征 和 高次项特征 的权重 置为0
也就是说,Lasso回归
能够自动进行特征选择,输出一个稀疏模型(只有少数 特征权重 不是零)
Elastic Net
(弹性网络)
弹性网络在岭回归
和Lasso回归
中进行了折中,通过 混合比r
进行控制:
r=0
:弹性网络变为岭回归r=1
:弹性网络便为Lasso回归核心为:样本在特征空间中的 k个最相邻样本 中的大多数属于某一个类别,则该样本也属于这个类别,并具有这个类别的特性。
如图所示:
样本a在特征空间中的5(K值)个最相邻样本中大多数属于类别1,因此我们就认为样本a属于类别1,并具有类别1的特性
算法工作流程
选出最近k
个临近样本点的方法:
线型扫描(穷举搜索)
计算 所有已知类别样本点 与 当前预测样本点之间的距离,按距离递增次序排序,从而获取k
个最邻近样本点
缺点:计算量过大,耗时
kd 树
(类似二叉树的数据结构)
把距离信息保存在一棵树里,这样在计算之前从树里查询距离信息,尽量避免重新计算
一维
二维
kd 树
导包:from sklearn.neighbors import KNeighborsClassifier
实例化API:estimator = KNeighborsClassifier(n_neighbors=5, weights=’uniform’, algorithm=’auto’, leaf_size=30, **kwargs)
参数:
n_neighbors
便是K值
,其中的数值是自定义的,但K值
的数值直接影响预测结果,
K值
过小:k值
过大:K值
一般取一个比较小的数值,然后采用交叉验证法(简单来说,就是把训练数据在分成两组:训练集和验证集)来选择最优的K值
weights
: 预测时使用的权重、可选、默认为uniform
uniform
:平权,每个邻域中所有点的权重均相等。distance
:权重点按其距离的倒数表示。在这种情况下,查询点的近邻比远处的近邻具有更大的影响力。callable
:用户定义的函数,它接受距离数组,并返回包含权重的相同形状的数组。algorithm
: 用于计算最近邻居的算法,可选{'auto','ball_tree','kd_tree','brute'}
:
kd_tree
将使用 KD-树
ball_tree
将使用 BallTree
,对kd- 树
高维失效现象进行了优化brute
将使用线型扫描暴力搜索,仅限小数据集使用auto
将 尝试根据传递给fit方法的值来决定最合适的算法leaf_size
: BallTree
或KDTree
的叶大小、int型
、可选、默认为30优点:
缺点:
惰性学习
KNN算法是懒散学习方法(lazy learning,基本上不学习),一些积极学习的算法要快很多
类别评分不是规格化
不像一些通过概率评分的分类
输出可解释性不强
对不均衡的样本不擅长
当样本不平衡时,如一个类的样本容量很大,而其他类样本容量很小时,有可能导致当输入一个新样本时,该样本的K个邻居中大容量类的样本占多数。该算法只计算“最近的”邻居样本,某一类的样本数量很大,那么或者这类样本并不接近目标样本,或者这类样本很靠近目标样本。无论怎样,数量并不能影响运行结果。可以采用权值的方法(和该样本距离小的邻居权值大)来改进。
计算量较大
目前常用的解决方法是事先对已知样本点进行剪辑,事先去除对分类作用不大的样本。
使用概率学知识进行计算 类别概率,并将其分到 发生概率最大的类别中
在贝叶斯算法的基础上进行了相应的简化(特征 相互独立)
有坚实的数学基础,以及稳定的分类效率
超参数很少,对缺失数据不太敏感
算法也比较简单。理论上,具有最小的误差率
特征之间相互独立,在实际应用中往往是不成立的
概率学知识
以文章分类去理解别贝叶斯公式:
P(科技|文章) = P(科技|词1, 词2, 词3, 词4, 词5,... ) 一个文章中存在很多词
= P(词1, 词2, 词3, 词4, 词5,... | 科技) P(科技) / P(词1, 词2, 词3, 词4, 词5,... )
P(娱乐|文章) = P(娱乐|词1, 词2, 词3, 词4, 词5,... )
= P(词1, 词2, 词3, 词4, 词5,... | 娱乐) P(娱乐) / P(词1, 词2, 词3, 词4, 词5,... )
因为同一篇文章 且 是 比较概率,所以分母相同 且可以 忽略
P(科技|文章) = P(词1, 词2, 词3, 词4, 词5,... | 科技) P(科技)
P(娱乐|文章) = P(词1, 词2, 词3, 词4, 词5,... | 娱乐) P(娱乐)
其中:
P(词1, 词2, 词3, 词4, 词5,... | 科技) 似然函数
表示:原文章中的词 在 科技类文章中 出现的概率
P(科技) 先验概率。不考虑 文章差异,根据以往经验得到文章属于科技的概率
表示:所有文章 中 科技文章所占的比重
若 原文章中还有 明星 一词,但其 在 科技文章中出现的次数为零
很明显 若原文章中的某词在某类别中没有出现,就视为 其属于该类别的概率为零 是不合理的
sklearn
sklearn.naive_bayes.MultinomialNB(alpha=1.0)
参数:
alpha:拉普拉斯平滑系数。float, 默认为1.0
案例:
# 实例化朴素贝叶斯API
mlt = MultinomialNB(alpha=1.0)
# 训练数据
mlt.fit(x_train, y_train)
# 预测
y_predict =mlt.predict(x_test)
# 评估
print ("预测的文章类别为:y_predict) # 得出准确率
print("准确率为: ", mlt.score(x_test, y_test) )
应用场景:是否为垃圾邮件、是否患病、是否是虚假账号
输入:逻辑回归的输入就是 一个线性回归的结果
输出:[0,1]之间的概率值
将线性回归的结果作为输出,经过sigmoid
函数将其转化为[0,1]之间的数作为概率,若其大于阈值则分为正例,小于阈值则为反例
逻辑回归中阈值是超参数,可以自定义,并且阈值直接影响模型结果,因此需要最佳阈值从而减少损失
逻辑回归的损失,称之为对数似然损失,公式如下:
合并之后的完整损失函数:
其中:其中y
为真实值,hθ(x)
为预测值
优化原理:减小损失值(提升原本属于1类别的概率,降低原本是0类别的概率)
优化方法:优化线性回归的方法(梯度下降和正则化),去减少损失函数的值。这样去更新逻辑回归前面对应算法的权重参数
sklearn
API函数:sklearn.linear_model.LogisticRegression(solver='liblinear', penalty=‘l2’, C = 1.0)
参数:
solver
可选参数:{'liblinear', 'sag', 'saga','newton-cg', 'lbfgs'}
liblinear
;用于优化问题的算法,适合小数据集,仅限于one-versus-rest
分类sag
和saga
更适合大型数据集newton-cg
, sag
, saga
和lbfgs
penalty
:正则化的种类,L1
表示岭回归、L2
为Lasso
回归C
:正则化力度属性
LogisticRegression.coef_
:回归系数 (逻辑回归方程中的权重W
)LogisticRegression.intercept_
:偏置 (逻辑回归方程中的常数项b
),若fit_intercept=False
,则截距设置为零LogisticRegression.classes_
:分类器已知的类别标签列表LogisticRegression.n_iter_
:所有类的实际迭代数y_pred = lr_model.predict_proba(x)[:,1]
:获取各样本的概率默认将类别数量少的当做正例
LogisticRegression
方法相当于 SGDClassifier(loss="log", penalty=" ")
,SGDClassifier
实现了一个普通的随机梯度下降学习。而使用LogisticRegression(实现了SAG)
Spark ML
:训练逻辑回归模型
from pyspark.ml.feature import VectorAssembler
# 根据特征字段计算特征向量
datasets_1 = VectorAssembler().setInputCols(useful_cols[2:]).setOutputCol("features").transform(datasets_1)
# 训练数据集: 约7天的数据
train_datasets_1 = datasets_1.filter(datasets_1.timestamp<=(1494691186-24*60*60))
# 测试数据集:约1天的数据量
test_datasets_1 = datasets_1.filter(datasets_1.timestamp>(1494691186-24*60*60))
from pyspark.ml.classification import LogisticRegression
lr = LogisticRegression()
# 设置目标字段、特征值字段并训练
model = lr.setLabelCol("clk").setFeaturesCol("features").fit(train_datasets_1)
# 对模型进行存储
model.save("hdfs://192.168.19.137:9000/models/CTRModel_Normal.obj")
# 载入训练好的模型
from pyspark.ml.classification import LogisticRegressionModel
model = LogisticRegressionModel.load("hdfs://192.168.19.137:9000/models/CTRModel_Normal.obj")
# 根据测试数据进行预测
result_1 = model.transform(test_datasets_1)
# 按probability升序排列数据,probability表示预测结果的概率
# 如果预测值是0,其概率是0.9248,那么反之可推出1的可能性就是1-0.9248=0.0752,即点击概率约为7.52%
# 因为前面提到广告的点击率一般都比较低,所以预测值通常都是0,因此通常需要反减得出点击的概率
result_1.select("clk", "price", "probability", "prediction").sort("probability").show(100)
result_1.filter(result_1.clk==1).select("clk", "price", "probability", "prediction").sort("probability").show(100)
决策树:是一个由多个判断节点组成的树形结构
构造决策树的重点:
三种构树原理
ID3
)(熵)C4.5
)(熵)CART树
(基尼值 和 基尼指数)熵(Entropy
):信息的混乱程度度量,系统信息越有序,熵值越低;越混乱或者分散,熵值越高
基尼值(Gini
):随机抽取两个样本,其类别不一致的概率。故基尼值越小,数据集纯度越高
信息增益:以某特征划分数据集前后熵的差值,差值越大表示划分所获得的"纯度提升"越大,即该特征更重要,应优先划分
增益率:增益率是用前面的信息增益Gain(D, a)
和属性a
对应的"固有值" 的比值来共同定义
缺点:
注意:CART 树
是二叉树,因此多分类问题应转换成(分类1 和 其他 ; 分类2 和 其他 ;…)
计算基尼指数案例:
第一个大循环
对数据集非序列标号属性{是否有房,婚姻状况,年收入}分别计算它们的Gini
指数,取Gini`指数最小的属性作为决策树的根节点属性
若按婚姻状况属性来划分(多分类特征计算基尼值)
属性婚姻状况有三个可能的取值{married,single,divorced}
,分别计算划分后的Gini系数
增益
对比计算结果,根据婚姻状况属性来划分根节点时取 Gini指数 最小的分组作为划分结果,即: {married} | {single,divorced}
根据 年收入计算Gini指数
(连续数据 计算基尼值 并确定 分隔点)
对于年收入属性为数值型属性,首先需要对数据按升序排序,然后从小到大依次用相邻值的中间值作为分隔将样本划分为两组。例如当面对年收入为60
和70
这两个值时,我们算得其中间值为65
。以中间值65
作为分割点求出Gini指数
根据计算知道,三个属性划分根节点的指数最小的有两个:年收入属性和婚姻状况,他们的指数都为0.3
。此时,选取首先出现的属性married
作为第一次划分
第三次大循环(应去除掉,在前两次循环被分数的数据)
cart
剪枝)出现这种情况的原因:
改进:
bagging
+ 决策树)sklearn
决策数 API:sklearn.tree.DecisionTreeClassifier(criterion=’gini’, max_depth=None,random_state=None)
criterion
特征选择标准gini
或者 熵entropy
,默认gini
,即CART
算法min_samples_split
:预剪枝时,内部节点再划分所需最小样本数min_samples_split
,则不会继续再尝试选择最优特征来进行划分。 默认是2。参考:10
万样本,min_samples_split=10
。min_samples_leaf
:预剪枝时,叶子节点最少样本数10
万样本项目使用min_samples_leaf
的值为5
max_depth
:预剪枝时,决策树最大深度random_state
随机数种子决策树可视化 API
:sklearn.tree.export_graphviz(决策树模型,out_file='保存路径/文件名.dot’)
该函数能够导出DOT
格式
参数:
feature_names=[‘’特征列表’’]
:每个特征的名字,便于观看。feature_names=分类器.get_feature_names
filled
:指定是否为节点上色max_depth
: 指定展示出来的树的深度,可以用来控制图像大小查看dot文件
,需要使用Graphviz
这个工具,一种是执行pip install graphviz
,然后可以在pyhton
调用,另一种是使用命令行,这里我们采用第二种,但是是在python里调用的外部命令行
# 临时将Graphviz添加到环境变量中
import os
os.environ["PATH"]+= os.pathsep + 'C:/Program Files (x86)/Graphviz2.38/bin/'
# 将tree.dot文件转化为tree.png
with open("tree.dot", "w") as f:
tree.export_graphviz(dtree, out_file=f)
dot_data = StringIO()
tree.export_graphviz(dtree, out_file=dot_data,
feature_names=x.columns,
class_names=['bad_ind'],
filled=True, rounded=True,
special_characters=True)
graph = pydotplus.graph_from_dot_data(dot_data.getvalue())
Image(graph.create_png())
一种无监督学习算法,主要用于将相似的样本自动归到一个类别中。
在聚类算法中根据样本之间的相似性,将样本划分到不同的类别中,不同的相似度计算方法(聚类准则),会得到不同的聚类结果,常用的相似度计算方法有欧式距离法
k-means
聚类其实包含两层内容:
K值
: 初始中心点个数(计划聚类数)means
:求中心点到其他数据点距离的平均值k-means
聚类步骤:
K
,常数K
意味着最终的聚类的 类别数K
个特征空间内的点作为 初始的聚类中心(质心)K-Means停止迭代条件
注意:由于每次都要计算所有的样本与每一个质心之间的距离,故在大规模的数据集上,K-Means
算法的收敛速度比较慢
sklearn.cluster.KMeans(n_clusters = 8,*,init ='k-means ++',n_init = 10,max_iter = 300,tol = 0.0001,random_state = None,algorithm ='auto' )
参数:
n_clusters
:聚类中心数量,int型
,默认为8,生成的聚类数,即产生的质心数init
:初始质心的位置 {‘k-means++’, ‘random’, ndarray, callable}
,默认为’k-means++’
k-means++
:让选择的质心尽可能的分散,防止陷入局部最优解random
:随机,可能陷入局部最优解ndarray
,则其形状应为(n_clusters,n_features)
,给定初始中心callable
:则应使用参数X
,n_clusters
和 随机状态并返回初始化n_init
: k均值算法将在不同质心种子下运行的次数,默认值为10max_iter
: 单次运行的k均值算法的最大迭代次数,默认为300tol
: 迭代停止条件,默认为1e-4
random_state
随机数种子属性:
cluster_centers_
:ndarray of shape (n_clusters, n_features)tol
和max_iter
),则这些将与labels_
不一致labels_
:ndarray of shape (n_samples,)inertia_
:floatn_iter_
:int方法:
estimator.fit(x)
计算聚类中心estimator.predict(x)
预测estimator.fit_predict(x)
计算聚类中心并预测每个样本属于哪个类别,相当于先调用fit(x)
,然后再调用predict(x)
estimator.get_params([deep])
:获取此估计量的参数注意:K-Means
算法对异常值和异常纲量比较敏感,因此需要去除异常值和标准化
SSE
图最终的结果,对图松散度的衡量.(eg
: SSE
(左图)<SSE
(右图))
SSE
随着聚类迭代,其值会越来越小,直到最后趋于稳定:
但是如果质心的初始值选择欠佳,SSE
可能会达到局部最优解
结合了聚类的凝聚度(Cohesion
)和分离度(Separation
),用于评估聚类的效果:
a
:组内距离 越小越好
b
:组之间距离 越大越好
S
:(-1,1)之间
越接近1 越好;越接近-1 效果差
每次聚类后,每个样本都会得到一个轮廓系数
求出所有样本的轮廓系数后再求平均值就得到了平均轮廓系数([-1,1],系数越大,聚类效果越好)
sklearn API
:
sklearn.metrics.silhouette_score(X, labels, *, metric='euclidean', sample_size=None, random_state=None, **kwds)
参数:
X:样本之间的成对距离数组 或 特征值数组
labels:被聚类标记的目标值(预测后的数据集)
sample_size:子集样本大小(随机抽取一部分计算轮廓系数)默认使用所有数据
在决定什么时候停止训练时,肘形判据同样有效,数据通常有更多的噪音,在增加分类无法带来更多回报时,我们停止增加类别。
import matplotlib.pyplot as plt
wcss =[]
for i in range (1, 11): # 循环使用不同k测试结果
kmeans =KMeans (n_clusters =i, init ='k-meanst++', random_state = 42)
kmeans.fit_predict(X)
wcss.append(kmeans.inertia_) # inertia 簇内误差平方和
plt.plot(range(1, 11), wcss)
plt.show()
类别内部数据的协方差越小越好,类别之间的协方差越大越好(即:类别内部数据的距离平方和越小越好,类别之间的距离平方和越大越好),
这样的Calinski-Harabasz
分数s
会高,分数s
高则聚类效果越好
CH
需要达到的目的: 用尽量少的类别聚类尽量多的样本,同时获得较好的聚类效果
模型的 CH指数
也大越好
sklearn API
from sklearn.metrics import calinski_harabaz_score # 导包
y_pred = KMeans(n_clusters=2, random_state=9).fit_predict(X) # 使用 K-means 对数据集X进行聚类
calinski_harabaz_score(X, y_pred) # 获取 CH 指数;y_pred
k-means优缺点
K-medoids
和K-means
最大的区别是中心点的选取方式
K-means
中,根据当前簇所有数据点的平均值确定中心点,小数据集对异常点很敏感K-medoids
中,根据点与当前簇其他所有点的距离之和最小确定中心点算法流程:
n
个样本点中任意选取k
个点作为medoids
medoids
最近的原则,将剩余的n-k
个点分配到当前最佳的medoids
代表的类中i
个类中除对应medoids
点外的所有其他点,按顺序计算当其为新的medoids
时,代价函数的值,遍历所有可能,选取代价函数最小时对应的点作为新的medoids
2-3
的过程,直到所有的medoids
点不再发生变化或已达到设定的最大迭代次数适合大数据的聚类算法
样本量大于1万时,就需要考虑选用Mini Batch K-Means
算法
使用了Mini Batch
(分批处理)的方法对数据点之间的距离进行计算
Mini Batch
计算过程中不必使用所有的数据样本,而是从不同类别的样本中抽取一部分样本来代表各自类型进行计算。由于计算样本量少,所以会相应的减少运行时间,但另一方面抽样也必然会带来准确度的下降。
该算法的迭代步骤:
与Kmeans
相比,数据的更新在每一个小的样本集上。对于每一个小批量,通过计算平均值得到更新质心,并把小批量里的数据分配给该质心,随着迭代次数的增加,这些质心的变化是逐渐减小的,直到质心稳定或者达到指定的迭代次数,停止计算
sklearn.cluster.MiniBatchKMeans(n_clusters = 8,*,init ='k-means ++',max_iter = 100,batch_size = 100,
random_state = None,tol = 0.0,max_no_improvement = 10,init_size = None,n_init = 3)
参数:
n_clusters:聚类中心数量,int型,默认为8,生成的聚类数,即产生的质心数
init:初始质心的位置 {‘k-means++’, ‘random’, ndarray, callable} ,默认为’k-means++’
k-means++:让选择的质心尽可能的分散,防止陷入局部最优解
random:随机,可能陷入局部最优解
ndarray:则其形状应为(n_clusters,n_features),给定初始中心
callable:则应使用参数 X , n_clusters 和 随机状态并返回初始化
n_init : k均值算法将在不同质心种子下运行的次数,默认值为10
max_iter : 单次运行的k均值算法的最大迭代次数,默认为300
batch_size: Mini 批次的大小,默认为100
compute_labels: 一旦小批量优化收敛到合适状态,就可以为整个数据集计算 标签 和inertia,默认为True
max_no_improvement: 基于连续的小批量数量来控制提前停止,默认为10
tol : 迭代停止条件,默认为 1e-4
random_state :随机数种子
reassignment_ratio: float,默认= 0.01
控制重新分配的中心的最大计数数量的分数。值越大越容易重新分配计数较低的中心,
模型将花费更长的时间进行收敛,但是收敛效果更好。
属性:
cluster_centers_:ndarray of shape (n_clusters, n_features)
集群中心的坐标。如果算法在完全收敛之前停止( tol 和 max_iter ),则这些将与 labels_ 不一致
labels_ :ndarray of shape (n_samples,) 。每个点的标签
inertia_ :float 。样本到其最近的聚类中心的平方距离的总和
优化方法 | 思路 | 作用 |
---|---|---|
Canopy +k-means |
Canopy 粗聚类配合k-means |
找到最优初始中⼼,减少噪点干扰 |
kmeans++ |
选择的质心尽可能的分散 | 避免陷入局部最优解 |
二分k-means |
拆除SSE最大的簇 | 使数据点更接近于其质心,提高聚类效果 |
k-medoids |
根据点的距离之和最小确定中心点 | 提高噪声鲁棒性,用于小数据集 |
kernel kmeans |
映射到高维空间然后k-means 处理 |
- |
ISODATA |
动态聚类,可以更改K值大小 | - |
Mini-batch K-Means |
大数据集分批聚类 | - |
DBSCAN
的 几个定义:
MinPts
(超参数),则称该对象为核心对象;n
个样本的数据集,E
领域半径e
,形成核心对象的最少样本数MinPts
n
个样本皆为 未标记数据E
领域
注意:DBSCAN
对超参数(e
、MinPts
)很敏感,细微的不同都可能导致差别很大的结果,并且参数的选择无规律可循,只能靠经验确定
超参数确定
E
领域 半径 e
MinPts
sklearn API
:
sklearn.cluster.DBSCAN(eps=0.5, *, min_samples=5, metric='euclidean', algorithm='auto', leaf_size=30, n_jobs=None)
参数:
eps:E领域的半径;float, default=0.5
min_samples:形成核心领域的最少样本数(包括本身点);int, default=5
metric:计算距离的方法;string, or callable, 默认为’euclidean’(欧氏距离)
若是 string or callable,则它必须是 sklearn.metrics.pairwise_distancesmetric 参数允许的选项之一
若是“precomputed”,则X被视为距离矩阵,并且必须为方阵。若X是词汇表,则只有“非零”元素可以被视为DBSCAN的邻居
algorithm:查找最近的邻居的方法;{‘auto’, ‘ball_tree’, ‘kd_tree’, ‘brute’}, default=’auto’
kd_tree :建立 kd树(候选超球 和 回溯对列)(具体查看KNN算法的工作流程)
ball_tree :将使用 BallTree ,对 kd- 树 高维失效现象进行了优化
brute : 将使用线型扫描**暴力搜索**,仅限小数据集使用
auto:将 尝试根据传递给 fit 方法的值 来决定最合适的算法
leaf_size:叶大小;int, default=30
传递给BallTree或cKDTree。会影响构造和查询的速度,以及存储树所需的内存。最佳值取决于问题的性质
n_jobs:并行运行的作业数;int, default=None
None除非joblib.parallel_backend上下文中,否则表示1 。 -1表示使用所有处理器
属性:
core_sample_indices_:核心对象指标;ndarray of shape (n_core_samples,)
components_:核心样本的副本;ndarray of shape (n_core_samples, n_features)
labels_:聚类标签;ndarray of shape (n_samples)
赋予fit()的数据集中每个点的聚类标签。噪声样本的标签为-1
一种适用于连续数据的无监督异常检测方法
从高维不详解业务的数据中找到异常数据
对特征的要求低,不需要去空、离散化、标准化,不需要做特征过滤和筛选
孤立森林的原理:
iTree
孤立树的建立
from sklearn.ensemble import IsolationForest
model_isof = IsolationForest(n_estimators=20, n_jobs=1) # n_estimators树个数,
outlier_label = model_isof.fit_predict(数据集)
结果:异常数据标为-1,正常数据标为1
工作原理:生成多个分类器/模型,各自独立地学习和作出预测,然后通过组合或投票 得出最终预测,因此优于任何一个单分类的做出预测
注意:集成学习并不是一种算法,而是一种可以配合多种算法使用的思想
目标:把下面的圈和方块进行分类
bagging
集成优点
Bagging + 决策树/线性回归/逻辑回归/深度学习… = bagging集成学习方法
经过上面方式组成的集成学习方法:
sklearn
bagging 分类器 API:
sklearn.ensemble.BaggingClassifier(base_estimator=None, n_estimators=10, *, max_samples=1.0, max_features=1.0,
bootstrap=True, oob_score=False, warm_start=False, n_jobs=None, random_state=None, verbose=0)
参数:
base_estimator:基于那种模型做集成学习,默认为决策树
n_estimators:训练的小模型数量,默认= 10
max_samples:随机抽取的最大样本数
如果为int,则抽取max_samples个样本
如果为float,则抽取样品数:max_samples * X.shape[0]
max_features:随机抽取的最大特征数
如果为int,则抽取的max_features个特征
如果为float,抽取最大特征数:max_features * X.shape[1]
bootstrap:是否又放回抽取,默认为 True
oob_score:是否使用现成的样本来估计泛化误差
n_jobs:并行运行的作业数
random_state:随机数种子
随机森林API:bagging + 决策树
sklearn.ensemble.RandomForestClassifier(n_estimators=10, criterion=’gini’, max_depth=None, bootstrap=True,
random_state=None, min_samples_split=2)
参数:
n_estimators:integer,可选(默认为10)森林里的树木数量120,200,300,500,800,1200
Criterion:{“gini”, “entropy”},默认为“gini” 建 CART 树。“entropy”表示建立 C4.5 决策树
max_depth:integer或None,可选(默认=无)树的最大深度 5,8,15,25,30
max_features="auto”,每个决策树的最大特征数量
如果 = "auto、sqrt、None", 则max_features=sqrt(n_features) 开根号
如果 = "log2", 则 max_features=log2(n_features)
如果为 int,则max_features在每个拆分处考虑要素
如果为float,则每次拆分时考虑特征个数为:int(max_features * n_features)
bootstrap:boolean,可选(default = True)是否在构建树时使用放回抽样
min_samples_split:节点划分最少样本数
min_samples_leaf:叶子节点的最小样本
n_jobs:int,(默认=无) 要并行运行的作业数
random_state:随机数种子
超参数:n_estimator, max_depth, min_samples_split,min_samples_leaf
属性:
base_estimator_ :最优模型
estimators_ :决策树列表
classes_ :类标签(单个输出问题)或类标签数组列表(多输出问题)
n_classes_ :类数(单个输出问题),或包含每个输出的类数的列表(多输出问题)
超参数可用网格搜索筛选最优参数
# 实例化随机森林API
rf = RandomForestClassifier()
# 定义超参数的选择列表
param = {"n_estimators": [120,200,300,500,800,1200], "max_depth": [5, 8, 15, 25, 30]}
# 使用GridSearchCV进行网格搜索 进行 超参数调优
gc = GridSearchCV(rf, param_grid=param, cv=2)
# 训练模型
gc.fit(x_train, y_train)
# 模型评估
print("随机森林预测的准确率为:", gc.score(x_test, y_test))
spark
from pyspark.mllib.regression import LabeledPoint
# Labeled point 标记点是与标签/响应相关联的密集或稀疏的局部矢量
# 在MLlib中,标记点用于监督学习算法。我们使用double来存储标签,因此我们可以在回归和分类中使用标记点
# 对于二分类情况,目标值应为0(负)或1(正)。对于多分类,标签应该是从零开始的类索引:0, 1, 2, …。 标记点表示为 LabeledPoint。
# 选出new_user_class_level全部的
data2 = data1.rdd.map(
lambda r:LabeledPoint(r.class_level - 1, [r.cms_segid, r.cms_group_id, 特征3 ...]))
# 将标签列class_level 变成从零开始
from pyspark.mllib.tree import RandomForest
model2 = RandomForest.trainClassifier(data2, 4, {}, 10) # 训练集数据 四个分类 不标明目标列 10颗树
model2.predict()
集成原理:随着学习的积累从弱到强,分段拟合
简而言之:每新加入一个弱学习器,整体能力就会得到提升
代表算法:Adaboost
,GBDT
,XGBoost
sklearn
sklearn.ensemble.AdaBoostClassifier(base_estimator=None, *, n_estimators=50, learning_rate=1.0,
algorithm='SAMME.R', random_state=None)
参数:
base_estimator : 对象,可选。用于构建增强后的基本模型,默认基本估计量为决策树
n_estimators : int,可选(默认值为50)终止增强的估计器的最大数量。在完美配合的情况下,学习程序会尽早停止
learning_rate : float,可选(默认为1.)学习率缩小了每个分类器的贡献 learning_rate。
random_state : 随机数种子
梯度提升决策树(GBDT Gradient Boosting Decision Tree
):一种迭代的决策树算法,该算法由多棵决策树组成,所有树的结论累加起来做最终答案。具有较强的泛化能力,多用于搜索排序的机器学习模型而
GBDT = 梯度下降 + Boosting + 决策树
boosting
思想进行集成sklearn
sklearn.ensemble.GradientBoostingClassifier(*,learning_rate = 0.1,n_estimators = 100,subsample = 1.0,min_samples_split = 2,min_samples_leaf = 1,max_depth = 3,init = None,random_state = None,tol = 0.0001,ccp_alpha = 0.0 )
参数:
learning_rate:梯度下降的学习率,也时每个弱学习器的权重缩减系数 float,默认= 0.1
n_estimators:也就是弱学习器的最大迭代次数,或者说最大的弱学习器的个数 int,默认= 100
subsample:采样比例,默认= 1.0,即全采样;如果小于1.0,会导致方差减少和偏差增加。推荐在[0.5, 0.8]之间
max_depth:integer或None,可选(默认=无)树的最大深度 5,8,15,25,30
max_features="auto”,每个决策树的最大特征数量
如果 = "auto、sqrt、None", 则max_features=sqrt(n_features) 开根号
如果 = "log2", 则 max_features=log2(n_features)
如果为 int,则max_features在每个拆分处考虑要素
如果为float,则每次拆分时考虑特征个数为:int(max_features * n_features)
min_samples_split:节点划分最少样本数
min_samples_leaf:叶子节点的最小样本
tol:迭代提前终止条件 float,默认= 1e-4
当损失至少不能改善n_iter_no_change迭代次数(如果设置为数字)时,训练将停止
random_state:随机数种子
XGBoost/lightGBM= 二阶泰勒展开+boosting+决策树+正则化
Boosting
:XGBoost
使用Boosting
提升思想对多个弱学习器进行迭代式学习XGBoost
对损失函数进行二阶泰勒展开,使用一阶和二阶梯度进行优化。XGBoost
使用决策树算法作为弱学习进行优化。XGBoost
为防止过拟合,在损失函数中加入惩罚项,限制决策树的叶子节点个数以及决策树叶子节点的值。原理:每一棵树学的是之前所有回归树 结论和 的 残差
import xgboost as xgb
from sklearn.externals import joblib
# 初始化模型
xgb_classifier = xgb.XGBClassifier(n_estimators=20,\
max_depth=4, \
learning_rate=0.1, \
subsample=0.7, \
colsample_bytree=0.7)
# 拟合模型
xgb_classifier.fit(train_X, train_y)
# 使用模型预测
preds = xgb_classifier.predict(test_X)
# 判断准确率
print ('错误类为%f' %((preds!=test_y).sum()/float(test_y.shape[0])))
# 模型存储
joblib.dump(xgb_classifier, '2.model')
参数:
booster [default=gbtree]
:gbtree
和 gblinear
silent [default=0]
:0表示输出信息, 1表示安静模式nthread
:跑xgboost的线程数,默认最大线程数eta [default=0.3]
:学习率(新模型的权重占比),取值范围为:[0,1]gamma [default=0, alias: min_split_loss]
:叶子节点进一步的分割的最小损失值,该值越大,算法越保守max_depth [default=6]
:树的最大深度min_child_weight [default=1]
:子树权重之和的最小值,如果树的生长时的某一步所生成的叶子结点,其权重之和小于min_child_weight
,那么可以放弃该步生长,。该值越大,算法越保守subsample [default=1]
:子样本的占比,范围(0,1]colsample_bytree [default=1]
:构造每棵树时 选取的特征占比,范围 (0,1]lambda [default=1, alias: reg_lambda]
:L2 权重的L2正则化项alpha [default=0, alias: reg_alpha]
: L1 权重的L1正则化项scale_pos_weight, [default=1]
:样本不均衡时,把这个参数设定为一个正值,可以使算法更快收敛objective [ default=reg:linear ]
:定义需要被最小化的损失函数
reg:linear
--线性回归reg:logistic
--逻辑回归binary:logistic
--二分类的逻辑回归,返回预测的概率(不是类别)binary:logitraw
--输出归一化前的得分seed [ default=0 ]
:随机种子xgboost
用的是预排序 的方法, 空间消耗大LightGBM
用的是直方图 的决策树算法,直方图算法的基本思想是先把连续的浮点特征值离散化成k个整数,同时构造一个宽度为k的直方图。在遍历数据的时候,根据离散化后的值作为索引在直方图中累积统计量,当遍历一次数据后,直方图累积了需要的统计量,然后根据直方图的离散值,遍历寻找最优的分割点。xgboost
通过level(depth)-wise
策略生长树, Level-wise
过一次数据可以同时分裂同一层的叶子,容易进行多线程优化,也好控制模型复杂度,不容易过拟合。但实际上Level-wise
是一种低效的算法,因为它不加区分的对待同一层的叶子,带来了很多没必要的开销,因为实际上很多叶子的分裂增益较低,没必要进行搜索和分裂。LightGBM
通过leaf-wise(best-first)
策略来生长树, Leaf-wise
则是一种更为高效的策略,每次从当前所有叶子中,找到分裂增益最大的一个叶子,然后分裂,如此循环。因此同Level-wise
相比,在分裂次数相同的情况下,Leaf-wise
可以降低更多的误差,得到更好的精度。Leaf-wise
的缺点是可能会长出比较深的决策树,产生过拟合。因此LightGBM
在Leaf-wise
之上增加了一个最大深度的限制,在保证高效率的同时防止过拟合。xgboost
不支持直接导入类别型变量,需要预先对类别型变量作亚编码等处理。如果类别型特征较多,会导致哑变量处理后衍生后的特征过多,学习树会生长的非常不平衡,并且需要非常深的深度才能来达到较好的准确率。LightGBM
可以支持直接导入类别型变量(导入前需要将字符型转为整数型,并且需要声明类别型特征的字段名),它没有对类别型特征进行独热编码,因此速度比独热编码快得多。LightGBM
使用了一个特殊的算法来确定属性特征的分割值。基本思想是对类别按照与目标标签的相关性进行重排序,具体一点是对于保存了类别特征的直方图根据其累计值(sum_gradient/sum_hessian)
重排序,在排序好的直方图上选取最佳切分位置。boosting
解决欠拟合问题,通过多个小模型 逐步增强学习 分段拟合Bagging
解决过拟合问题,通过多个小模型 对同一模型投票 ,相互遏制变强Bagging
:对数据进行采样训练;Boosting
:根据前一轮学习结果调整数据的重要性。Bagging
:所有学习器平权投票;Boosting
:对学习器进行加权投票。Bagging
学习是并行,每个学习器没有依赖关系;Boosting
学习是串行,学习有先后顺序。Bagging
中的模型是 强模型(偏差低,方差高)boosting
中的模型是 弱模型(偏差高,方差低)Bagging
主要用于提高泛化性能(解决过拟合,也可以说降低方差)Boosting
主要用于提高训练精度 (解决欠拟合,也可以说降低偏差)交叉验证:将数据分成n份,一份作为验证集。经 n 次(组)测试,每次都更换验证集。即得到 n次 模型结果,取平均值作为最终结果
作用:使获得的模型结果更准确,不优化模型
网格搜索:为超参数指定多个值,轮训训练模型,从而获取其中最优的参数和最佳模型
sklearn API
:sklearn.model_selection.GridSearchCV(estimator, param_grid=None,cv=None)
参数:
estimator
:实例化的估计器对象param_grid
:估计器需要的参数字典 {"参数1":[值1,值2,值3], "参数2":[值1,值2,值3],...}
cv
:指定几折交叉验证(与训练集和测试集比例有关,4 为 7.5:2.5
)结果分析:
模型训练结果.best_score_
:在交叉验证中验证的最好结果模型训练结果.best_estimator_
:最好的参数模型模型训练结果.cv_results_
:查看所有模型的每次交叉验证结果