基本形式
线性模型(linear model)试图学得一个通过属性的线性组合来进行预测的函数:
写成向量模式则为:
只要求出w和b则可以确定线性模型。
线性模型有较好的解释性,Wi的大小表示着第i个特征的重要程度。线性模型蕴涵着机器学习中一些重要的基本思想,非线性模型可在线性模型的基础上通过引入层级结构或高维映射而得。
线性回归
线性回归模型是一个一次方程方程,通过自变量尽可能准确地预测因变量的值。
线性回归的标签是一个数值,而分类则是类似于one-hot编码。
线性回归的模型:
怎么样的模型是我们想要的?
其实就是预测值与真实值的均方误差(平方误差)最小。满足这个要求的w,b即可求得模型。
对数几率回归
对数几率回归(logistics regression),虽然名字是回归,但解决的是分类问题。
在二分类任务中,线性回归模型产生预测值,然后通过一个映射函数,得到对应的类别。这个映射函数最理想的是“单位阶跃函数”
但是单位阶跃函数并不连续,我们则用对数几率函数进行替代,sigmoid函数:
多分类学习
三种策略:
①“一对一” One vs One(OvO):将N个类别两两配对,产生N(N-1)/2个二分类器。测试时需要产生N(N-1)/2个结果,然后这些分类器选择最多的结果,作为最终结果。
②“一对其余”One vs Rest(OvR):每次将一类作为正例,其他作为反例,只需向量N个分类器。测试时,若只有一个分类器预测为正类,则标记为最终分类;若有多个分类器预测为正类,则选择置信度最大的。
③“多对多”Many vs Many(MvM):每次将若干类作为正类,其他作为反类。正反类不能随机选取,常用用“纠错输出码”。
对比①和②
OvO分类器更多存储开销和测试时间开销较大大。OvR每次训练都是使用全部数据,训练时间较大。哪个方法更好?着取决于数据的分布,多数情况下两者相差不大。
类别不均衡
解决办法
①欠采样undersampling:去掉一些反例,使得正反例数目接近。常用算法EasyEnsemble:每次从多数类中抽样出和少数类数目差不多的样本共同组合作为训练集。
②过采用oversampling:增加一些正例使得正反数目接近。若简单的从初始样本中重复采样(随机过采样),则模型容易过拟合。常用的是SMOTE(合成少数类过采样技术),改算法对少数类别样本进行KNN模拟的新样本添加到数据集中,使类别均衡。SMOTE通过插值来生成正样本,特征值和标签的关系是单调的时候,效果更佳。
imblearn实现SMOTE
%matplotlib inline
import numpy as np
from collections import Counter
from sklearn.datasets import make_classification
import matplotlib.pyplot as plt
from imblearn.over_sampling import SMOTE
from sklearn.svm import LinearSVC as svc
#绘制决策边界函数
def plot_decision_function(X, y, clf, ax):
plot_step = 0.02
x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
xx, yy = np.meshgrid(np.arange(x_min, x_max, plot_step),
np.arange(y_min, y_max, plot_step))
Z = clf.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
ax.contourf(xx, yy, Z, alpha=0.4)
ax.scatter(X[:, 0], X[:, 1], alpha=0.8, c=y, edgecolor='k')
#创建数据
## 参数说明:n_samples样本个数,n_features特征个数,n_classes标签类别数量,
##n_clusters_per_class每个类别的簇的个数,weights标签比例,
##class_sep类别间的分散程度 越大区分度越高
X, y = make_classification(n_samples=200, n_features=2, n_informative=2,
n_redundant=0, n_repeated=0, n_classes=2,
n_clusters_per_class=2,
weights=[ 0.1, 0.9],
class_sep=1)
print("原始数据分布",Counter(y))
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(15, 12))
# 绘制原始数据集的决策边界
clf = svc().fit(X,y)
plot_decision_function(X,y,clf,ax1)
# 通过SMOTE生成新数据集
##radio可指定对应类别要生成的数据的数量;random_state随机种子
smo = SMOTE(sampling_strategy={0: 300},random_state=42)
X_smo, y_smo = smo.fit_resample(X, y)
# 绘制过采样后的曲线
clf = svc().fit(X_smo, y_smo)
plot_decision_function(X_smo, y_smo,clf,ax2)
print("SMOTE后数据分布",Counter(y_smo))
fig.tight_layout()
plt.show()
结果:
原始数据分布 Counter({1: 180, 0: 20})
SMOTE后数据分布 Counter({0: 300, 1: 180})
③阈值移动threshold-moving:在原数据上进行训练,但在预测时调整阈值。例如往数量少的类别调整sigmoid函数取值为0.5的位置。
参考资料
《机器学习公式详解》–谢文睿 秦州
《机器学习》–周志华
《机器学习公式详解》(南瓜书)与西瓜书公式推导直播合集:https://www.bilibili.com/video/BV1Mh411e7VU?from=search&seid=5668978625426231562
imblearn:随机过采样(过采样):https://blog.csdn.net/qq_30636613/article/details/86422589