基本形式

给定由线性模型 - 图1个属性描述的示例线性模型 - 图2,其中线性模型 - 图3线性模型 - 图4在第线性模型 - 图5个属性上的取值,线性模型试图学得一个通过属性的线性组合来进行预测的函数:

线性模型 - 图6

一般用向量形式写成:

线性模型 - 图7

其中线性模型 - 图8线性模型 - 图9线性模型 - 图10学得后,模型得以确定。

线性回归

一元线性回归

当输入的属性的数目只有一个时,进行的线性回归模型为一元线性回归。一元线性回归试图学得:

线性模型 - 图11,使得线性模型 - 图12

通过减少线性模型 - 图13线性模型 - 图14的差别(即减少预测值与实际值的误差),就可以学得线性模型 - 图15线性模型 - 图16即获得模型。通常使用均方差(Mean Square Error)来做,均方差的几何意义其实就是欧式距离:

线性模型 - 图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个属性值,最后一个元素恒置为1,即:

线性模型 - 图53

再把标记也写成向量形式线性模型 - 图54,则有

线性模型 - 图55

线性模型 - 图56,对线性模型 - 图57求导得:

线性模型 - 图58

推导过程:将线性模型 - 图59展开可得:

线性模型 - 图60

线性模型 - 图61求导可得:

线性模型 - 图62

由向量的求导公式可得:

线性模型 - 图63
线性模型 - 图64

令上式为零可得线性模型 - 图65最优解的闭式解。

对数线性回归

当我们希望线性模型的预测值逼近真实标记线性模型 - 图66时,就得到了线性回归模型。可否令模型预测逼近线性模型 - 图67的衍生物呢?譬如说,假设我们认为示例所对应的输出标记是在指数尺度上变化,那就可以将输出标记的对数作为线性模型逼近的目标,即

线性模型 - 图68

这就是“对数线性回归”,他实际上是在试图让线性模型 - 图69逼近线性模型 - 图70。在形式上仍然是线性回归,但实质上已是在求取输入空间到输出空间的非线性函数映射。如下图所示,这里的对数函数起到了将线性回归模型的预测值与真实标记联系起来的作用

log-linear-regression.png

更一般地,考虑单调可微函数线性模型 - 图72,令

线性模型 - 图73

这样得到的模型称为“广义线性模型”,其中函数线性模型 - 图74称为“联系函数”。显然,对数线性回归是广义线性模型在线性模型 - 图75时的特例。

LASSO、岭回归和弹性网络

岭回归&LASSO回归

即在原始的损失函数后添加正则项,来尽量的减小模型学习到的参数线性模型 - 图76的大小,使得模型的泛化能力更强

岭回归(Ridge Regression):线性模型 - 图77

Lasso Regression:线性模型 - 图78

弹性网络(Elastic Net)

即在原始的损失函数后添加了线性模型 - 图79线性模型 - 图80正则项,解决模型训练过程中的过拟合问题,同时结合了岭回归和LASSO回归的优势。线性模型 - 图81是新的超参数,表示添加的两个正则项的比例(分别为线性模型 - 图82线性模型 - 图83

线性模型 - 图84

逻辑回归(对数几率回归)

二项逻辑回归

考虑分类任务,比如二分类任务,其输出标记线性模型 - 图85,而线性回归模型产生的预测值线性模型 - 图86是实值,于是,我们需将实值线性模型 - 图87转换为线性模型 - 图88值。最理想的是“单位阶跃函数”(unit-step function)

线性模型 - 图89

即若预测值线性模型 - 图90大于零就判为正例,小于零就判为反例,预测值为临界值零则可任意判别。如下图所示

sigmoid.png

单位阶跃函数(上图红线)不连续,因此不能直接用作联系函数线性模型 - 图92。于是我们希望找到能在一定程度上近似单位阶跃函数的“替代函数”,并希望它单调可微。对数几率函数(logistic function)正是这样一个常用的替代函数:

线性模型 - 图93

对数几率函数是一种“Sigmoid函数”,它将线性模型 - 图94值转化为一个接近0或1的线性模型 - 图95值,并且其输出值在线性模型 - 图96附近变化很陡,将对数几率函数作为联系函数线性模型 - 图97,得到

线性模型 - 图98
线性模型 - 图99
线性模型 - 图100

即可变化为:

线性模型 - 图101

若将线性模型 - 图102视为样本线性模型 - 图103作为正例的可能性,则线性模型 - 图104是其反例的可能性,两者比值线性模型 - 图105称为“几率”,反映了线性模型 - 图106作为正例的相对可能性。对几率取对数则得到“对数几率”:

线性模型 - 图107

由此可看出,实际上是在用线性回归模型的预测结果去逼近真实标记的对数几率,因此,其对应的模型称为“逻辑回归”或“对数几率回归”。特别注意的是,虽然名字是“回归”,但实际它却是一种分类学习方法。这种方法有很多优点,例如它是直接对分类可能性进行建模。无需事先假设数据分布,这样就避免了假设分布不准确所带来的问题;它不是仅预测出“类别”,而是可得到近似概率预测,这对许多需利用概率辅助决策的任务很有用。此外,对数几率是任意阶可导的凸函数,有很好的数学性质,现有的许多数值优化算法都可以直接用于求取最优解。

如何确定上式中的线性模型 - 图108线性模型 - 图109。若将线性模型 - 图110视为类后验概率估计线性模型 - 图111,则

线性模型 - 图112

线性模型 - 图113

线性模型 - 图114

线性模型 - 图115

线性模型 - 图116

线性模型 - 图117

线性模型 - 图118

当然,我们也可通过极大似然法来估计线性模型 - 图119线性模型 - 图120,设线性模型 - 图121线性模型 - 图122给定数据集线性模型 - 图123,似然函数为:

线性模型 - 图124

对数似然函数为:

线性模型 - 图125

线性模型 - 图126

线性模型 - 图127

线性模型 - 图128求极大值,得到线性模型 - 图129的估计值。这样,问题就变成了以对数似然函数为目标的最优化问题,逻辑回归学习中通常采用的方法是梯度下降法及牛顿法。假设线性模型 - 图130的极大似然估计值是线性模型 - 图131,那么学到的逻辑回归模型为:

线性模型 - 图132 线性模型 - 图133

多项逻辑回归

上面介绍的逻辑回归模型是二项分类模型,用于二分类。可以将其推广为多项逻辑回归模型,用于多分类任务。假设离散型随机变量线性模型 - 图134的取值集合是线性模型 - 图135,那么多项逻辑回归模型是:

线性模型 - 图136 线性模型 - 图137

二项逻辑回归的参数估计法也可以推广到多项逻辑回归。

线性判别分析

线性判别分析(Linear Discriminant Analysis,LDA)是一种监督学习的降维技术也可以做分类任务,也就是说它的数据集的每个样本是有类别输出的,这点和PCA不同。PCA是不考虑样本类别输出的无监督降维技术。LDA的思想可以用一句话概括,就是“投影后类内方差最小,类间方差最大”,如下图所示。我们要将数据在低维度上进行投影,我们投影后希望

  1. 每一种类别数据的投影点尽可能的接近
  2. 不同类别的数据的类别中心之间的距离尽可能的大

LDA1.jpg

给定数据集线性模型 - 图139线性模型 - 图140

线性模型 - 图141类的集合线性模型 - 图142,第线性模型 - 图143类的均值向量线性模型 - 图144,第线性模型 - 图145类的协方差矩阵线性模型 - 图146线性模型 - 图147即一共就两类

两类样本的中心在直线线性模型 - 图148上的投影,即直线与原均值向量的内积线性模型 - 图149线性模型 - 图150。所有样本点都投影到直线上,则两类样本的协方差为线性模型 - 图151线性模型 - 图152

  1. 投影后类内方差最小,即线性模型 - 图153尽可能小
  2. 类间方差最大,即线性模型 - 图154尽可能大

同时考虑优化二者,则可得到欲最大化的目标:

线性模型 - 图155

定义“类内散度矩阵”:线性模型 - 图156

定义“类间散度矩阵”:线性模型 - 图157

所以,我们可将最大化目标函数线性模型 - 图158写为:

线性模型 - 图159

这就是LDA欲最大化的目标,即线性模型 - 图160线性模型 - 图161的“广义瑞利商”(Generalized Rayleigh Quotient)

如何确定线性模型 - 图162呢?注意到上式的分子和分母都是关于线性模型 - 图163的二次项,因此上式的解线性模型 - 图164的长度无关,只与其方向有关。不失一般性,令线性模型 - 图165,上式等价于

线性模型 - 图166

由拉格朗日乘子法,上式等价于

线性模型 - 图167

其中线性模型 - 图168是拉格朗日乘子。注意到线性模型 - 图169的方向恒为线性模型 - 图170,不妨令线性模型 - 图171代入上式

线性模型 - 图172

考虑到数值解的稳定性,在实践中通常是对线性模型 - 图173进行奇异值分解,即线性模型 - 图174,这里线性模型 - 图175是一个对角矩阵,其对角线上的元素是线性模型 - 图176的奇异值,然后再由线性模型 - 图177得到线性模型 - 图178。值得一提的是,LDA可从贝叶斯决策理论的角度来阐述,并可证明,当两类数据同先验,满足高斯分布且协方差相等时,LDA可达到最优分类。

多类别映射(分类)

若有很多类别,还是基于LDA基本思想,每个类间距离最大,类内距离最小。假定存在线性模型 - 图179个类,且第线性模型 - 图180类示例数为线性模型 - 图181,我们先定义“全局散度矩阵”:

线性模型 - 图182

其中线性模型 - 图183是所有示例的均值向量,将类内散度矩阵线性模型 - 图184重新定义为每个类别的散度矩阵之和,即

线性模型 - 图185

整理上面两式可得

线性模型 - 图186

显然,多分类LDA可以有多种实现方法:使用线性模型 - 图187线性模型 - 图188线性模型 - 图189三者中的任何两个即可,常见的一种实现是采用优化目标:

线性模型 - 图190

其中线性模型 - 图191,上式可通过广义特征值问题求解:线性模型 - 图192线性模型 - 图193的闭式解则是线性模型 - 图194线性模型 - 图195个最大非零广义特征值所对应的特征向量组成的矩阵,线性模型 - 图196

线性模型 - 图197视为一个投影矩阵,则多分类LDA将样本投影到线性模型 - 图198维空间。线性模型 - 图199通常远小于数据原有的属性数线性模型 - 图200于是,可通过这个投影来减少样本点的维数,且投影过程中采用了类别信息,因此LDA也常被视为一种经典的监督降维技术。

Code实现

逻辑回归模型:线性模型 - 图201,其中线性模型 - 图202

数据

  1. from math import exp
  2. import numpy as np
  3. import pandas as pd
  4. import matplotlib.pyplot as plt
  5. %matplotlib inline
  6. from sklearn.datasets import load_iris
  7. from sklearn.model_selection import train_test_split
  8. # data
  9. def create_data():
  10. iris = load_iris()
  11. df = pd.DataFrame(iris.data, columns=iris.feature_names)
  12. df['label'] = iris.target
  13. df.columns = ['sepal length', 'sepal width', 'petal length', 'petal width', 'label']
  14. data = np.array(df.iloc[:100, [0,1,-1]])
  15. # print(data)
  16. return data[:,:2], data[:,-1]
  17. X, y = create_data()
  18. X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3)

手写实现

  1. class LogisticReressionClassifier:
  2. def __init__(self, max_iter=200, learning_rate=0.01):
  3. self.max_iter = max_iter
  4. self.learning_rate = learning_rate
  5. def sigmoid(self, x):
  6. return 1 / (1 + exp(-x))
  7. def data_matrix(self, X):
  8. data_mat = []
  9. for d in X:
  10. data_mat.append([1.0, *d])
  11. return data_mat
  12. def fit(self, X, y):
  13. # label = np.mat(y)
  14. data_mat = self.data_matrix(X) # m*n
  15. self.weights = np.zeros((len(data_mat[0]),1), dtype=np.float32)
  16. for iter_ in range(self.max_iter):
  17. for i in range(len(X)):
  18. result = self.sigmoid(np.dot(data_mat[i], self.weights))
  19. error = y[i] - result
  20. self.weights += self.learning_rate * error * np.transpose([data_mat[i]])
  21. print('LogisticRegression Model(learning_rate={},max_iter={})'.format(self.learning_rate, self.max_iter))
  22. # def f(self, x):
  23. # return -(self.weights[0] + self.weights[1] * x) / self.weights[2]
  24. def score(self, X_test, y_test):
  25. right = 0
  26. X_test = self.data_matrix(X_test)
  27. for x, y in zip(X_test, y_test):
  28. result = np.dot(x, self.weights)
  29. if (result > 0 and y == 1) or (result < 0 and y == 0):
  30. right += 1
  31. return right / len(X_test)
  32. lr_clf = LogisticReressionClassifier()
  33. lr_clf.fit(X_train, y_train)
  34. lr_clf.score(X_test, y_test)
  35. x_ponits = np.arange(4, 8)
  36. y_ = -(lr_clf.weights[1]*x_ponits + lr_clf.weights[0])/lr_clf.weights[2]
  37. plt.plot(x_ponits, y_)
  38. #lr_clf.show_graph()
  39. plt.scatter(X[:50,0],X[:50,1], label='0')
  40. plt.scatter(X[50:,0],X[50:,1], label='1')
  41. plt.legend()

LogisticRegression.png

sklearn实现

https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LogisticRegression.html

solver参数决定了我们对逻辑回归损失函数的优化方法,有四种算法可以选择,分别是:

  • liblinear:使用了开源的liblinear库实现,内部使用了坐标轴下降法来迭代优化损失函数。
  • lbfgs:拟牛顿法的一种,利用损失函数二阶导数矩阵即海森矩阵来迭代优化损失函数。
  • newton-cg:也是牛顿法家族的一种,利用损失函数二阶导数矩阵即海森矩阵来迭代优化损失函数。
  • sag:即随机平均梯度下降,是梯度下降法的变种,和普通梯度下降法的区别是每次迭代仅仅用一部分的样本来计算梯度,适合于样本数据多的时候。
  1. from sklearn.linear_model import LogisticRegression
  2. clf = LogisticRegression(max_iter=200)
  3. clf.fit(X_train, y_train)
  4. clf.score(X_test, y_test)
  5. print(clf.coef_, clf.intercept_)
  6. x_ponits = np.arange(4, 8)
  7. y_ = -(clf.coef_[0][0]*x_ponits + clf.intercept_)/clf.coef_[0][1]
  8. plt.plot(x_ponits, y_)
  9. plt.plot(X[:50, 0], X[:50, 1], 'bo', color='blue', label='0')
  10. plt.plot(X[50:, 0], X[50:, 1], 'bo', color='orange', label='1')
  11. plt.xlabel('sepal length')
  12. plt.ylabel('sepal width')
  13. plt.legend()

sklearn.png

Source

https://www.cnblogs.com/volcao/p/9306821.html