本文为课程对应的学习笔记
地址http://www.auto-mooc.com/mooc/detail?mooc_id=F51511B0209FB73D81EAC260B63B2A21
课件资料存放地址:待更新
修订:2020-2-10:增加损失函数内容
文章目录
4.1SVM
因为SVM的发展,推迟了神经网络的发展
特点:鲁棒性强、适用范围广、最好的现成的分类器
属于分类算法,从已有样本中学会一个分类函数,从而将新的样本分类出来。
4.2 基本算法
- 点与向量,线与超平面,拉格朗日
- 使用拉格朗日函数核因子的计算过程
上图中两个橙色点+一个蓝色点就是支持向量;-----》SVM支持向量机
详细讲解参考:blog.csdn.net/v_july_v/article/details/7624837
4.3 SMO
SMO算法每次循环选择2个数据点进行优化.
4.4 非线性
【采用的是多项式核函数】
将低维向高维映射,从而将非线性可分的情况,转换成立线性可分,画出了超平面。
import numpy as np
from math import sqrt
from mpl_toolkits.mplot3d import Axes3D
from sklearn.datasets import make_circles
import matplotlib.pyplot as plt
import pylab as pl
def randrange(n, vmin, vmax):
return (vmax - vmin) * np.random.rand(n) + vmin
# 映射函数z=pow(x, 2)+pow(z, 2)
def fn_kernel(x1, x2):
return np.array([x1, x2, x1 ** 2.0 + x2 ** 2.0])
# 构建数据集
...
#画图
def plot_decision_boundary():
def main():
plot_decision_boundary()
-
多项式核函数:类似于上图中“圆”的处理,做了x,y的平方
-
高斯核函数,通过控制“σ”,来控制低维到高维度的映射。
-
核函数就是解决了非线性应用场景,核函数将非线性的样本映射到特征空间
什么问题使用怎样的核函数??
SVM-D-tree-Bayes-KNN四种算法比较。
- SVM使用:
- 保证样本变得线性河粉——选择核函数
- 在特征空间中使用SVM进行学习分类——SMO优化算法
之前的SVM的blog
- https://blog.csdn.net/djfjkj52/article/details/89002793
- https://blog.csdn.net/djfjkj52/article/details/89003914
- https://blog.csdn.net/djfjkj52/article/details/89024461
5.1 线性分类与回归
- 分类——》离散
- 回归针对的目标——》连续的数据
举例:
首先都是学习这些样本点,
然后来了一个新的样本点
- 回归:这个新的样本点的“y”值的估计
- 分类:这个新样本点属于上面,还是属于下面,希望个其一个label
- 但是逻辑回归是一种分类方法
回归性能
选定完“评分函数”(即选择完模型h(x)=wx+b)后,剩下的问题就是要优化问题,选择合适的w和b,来让损失函数最小化。
损失函数(新增)
参考:https://zhuanlan.zhihu.com/p/38471518
**如何找到好模型F来拟合训练数据集呢?从优化角度来看就是,就是在训练数据集上找到一个模型F来最小化损失函数L。**写成公式就是
常用的损失函数包括
名称 | 函数 | 适用情况 |
---|---|---|
平方损失squared loss: | (Y-F(X))^2 | 用于线性回归 |
对数损失logistic loss: | log(1+e^(-YF(X))) | 用于逻辑回归Yε {+1, -1} |
铰链损失hinge loss: | max(0, 1-Y∙F(X)) | 用于支持向量机,Y ε {+1, -1} |
使用闭形式求解线性回归的参数
#使用闭形式求解线性回归的参数
import numpy as np
import matplotlib.pyplot as plt
from sklearn import linear_model
# 在直线 y = 2 + 5x 附近生成随机点
X = np.arange(0, 5, 0.4)
Z = [2 + 5 * x for x in X]
Y = [np.random.normal(z, 0.8) for z in Z]
plt.plot(X, Y, 'y*')
plt.plot(X,Z,'ro')
plt.show()
m = len(X)
x0 = np.full(m, 1.0) #x0表示偏移b
print(x0)
input_data = np.vstack([x0, X]).T
print(input_data)
print(input_data.T)
print((np.mat(input_data.T) * np.mat(input_data)).I)
a = (np.mat(input_data.T) * np.mat(input_data)).I #X的转置*X,然后求逆
b = np.mat(input_data.T) #X的转置
print("闭形式求解系数:")
print(a*b*np.mat(Y).T)
#print(a*b*np.mat(Z).T)
model = linear_model.LinearRegression()
model.fit(input_data,Y)
print("sklearn线性回归求解系数:")
print(model.coef_)
print(model.intercept_)
上面的通解可以很容易求出α和β,但是需要求“(X的转置*X)的逆”,有时候不一定会有逆矩阵,这个时候就需要采用迭代法。迭代法就是一步一步尝试最终得到结果,梯度下降就是经典算法之一。
5.2 梯度下降
上图,初始之α与β是随机值,曲面是损失函数。绘制出损失函数平面,并打印出使得损失函数最小的参数值。沿着标准梯度下降的方向到达损失函数最小值。
标准梯度下降:
while count < loop_max:
count += 1
# 标准梯度下降
sum_m = np.zeros(2)
for i in range(m):
dif = (np.dot(theta, input_data[i]) - target_data[i]) * input_data[i]
sum_m = sum_m + dif
theta = theta - alpha * sum_m
# 判断是否停止迭代
if np.linalg.norm(theta - error) < epsilon:
finish = 1
break
else:
error = theta
print( 'loop count = %d' % count, '\tw:', theta)
print('loop count = %d' % count, '\tw:', theta)
plt.plot(x, target_data, 'g*')
plt.plot(x, theta[1] * x + theta[0], 'r')
5.3 正则化
什么是好的模型??
- 抓住样本特征,样本的规律
- 又能对没有出现在样本中的测试数据有很好的预测
6.1 逻辑回归
是一种分类方法
如果直接采用线性回归,碰到比较极端的值的时候,回归会出错,需要重新调整判断阈值。
缺点:
- 不同样本阈值不一样
- 对于拟合范围是无穷大的之后,阈值确定困难
逻辑回归,将线性回归的结果进行映射,阈值不变
引入sigmod函数:
可以看到sigmod函数:1、y轴取值0-1;2、x是无穷;3、有个交点(0,0.5),边界线。
sigmod函数是输出不是“回归线”上的值,而接近于这个label的概率
逻辑回归比线性回归多了,回归之后的映射判断,一般采用sigmod。
逻辑回归的代价函数也与线性回归的不同
特点之一就是对应两个参数来进行分类,而且是否有线性的边界。
然后继续使用梯度下降的方法求解代价函数进行优化问题
非线性的能不能用逻辑回归?
之前的逻辑回归输出的就是一个斜率+截距
非线性的,可以把高次变成一个新的数据集,例如x^2——>x
def map_features(f1, f2, order):
#从原有的数据中生成高阶数据,构造新的数据集,进行逻辑回归
assert order >= 1
def iter():
for i in range(1, order + 1):
for j in range(i + 1):
yield np.power(f1, i - j) * np.power(f2, j)
return np.vstack(iter())
out = map_features(X, Y,order)
X1 = out.transpose()
classifier = OneVsRestClassifier(LogisticRegression(penalty='l2', C=1)).fit(X1, Z)
print ('Coefficents: ', classifier.coef_)
print ('Intercept: ', classifier.intercept_)
print ('Accuracy: ', classifier.score(X1, Z))
这样就类似于SVM。