机器学习模型
线性回归的推广
非线性回归——表达数据中的非线性关系
- 多项式回归
y i = w 0 + w 1 x i + w 2 x i 2 + . . . + w d x i d + ϵ y_i = w_0 + w_1x_i + w_2x_i^2 + ...+w_dx_i^d + \epsilon yi=w0+w1xi+w2xi2+...+wdxid+ϵ
多项式的阶数d不能取过大,一般不大于3或者4
- 广义可加模型(GAM)
y i = w 0 + ∑ j = 1 p f j ( x i j ) + ϵ i y_i = w_0 + \sum\limits_{j=1}^{p}f_{j}(x_{ij}) + \epsilon_i yi=w0+j=1∑pfj(xij)+ϵi
sklearn.preprocessing.PolynomialFeatures
- 参数:
degree:特征转换的阶数。
interaction_onlyboolean:是否只包含交互项,默认False 。
include_bias:是否包含截距项,默认True。
order:str in {‘C’, ‘F’}, default ‘C’,输出数组的顺序。
回归树
依据分层和分割的方式将特征空间划分为一系列简单的区域
用所属区域中训练集的平均数或者众数对其进行预测
建立回归树的过程大致可以分为以下两步:
1. 将自变量的特征空间(即
x
(
1
)
,
x
(
2
)
,
x
(
3
)
,
.
.
.
,
x
(
p
)
x^{(1)},x^{(2)},x^{(3)},...,x^{(p)}
x(1),x(2),x(3),...,x(p))的可能取值构成的集合分割成J个互不重叠的区域
R
1
,
R
2
,
.
.
.
,
R
j
R_1,R_2,...,R_j
R1,R2,...,Rj。
2. 对落入区域
R
j
R_j
Rj的每个观测值作相同的预测,预测值等于
R
j
R_j
Rj上训练集的因变量的简单算术平均。
具体来说,就是:
a. 选择最优切分特征j以及该特征上的最优点s:
遍历特征j以及固定j后遍历切分点s,选择使得下式最小的(j,s)
m
i
n
j
,
s
[
m
i
n
c
1
∑
x
i
∈
R
1
(
j
,
s
)
(
y
i
−
c
1
)
2
+
m
i
n
c
2
∑
x
i
∈
R
2
(
j
,
s
)
(
y
i
−
c
2
)
2
]
min_{j,s}[min_{c_1}\sum\limits_{x_i\in R_1(j,s)}(y_i-c_1)^2 + min_{c_2}\sum\limits_{x_i\in R_2(j,s)}(y_i-c_2)^2 ]
minj,s[minc1xi∈R1(j,s)∑(yi−c1)2+minc2xi∈R2(j,s)∑(yi−c2)2]
b. 按照(j,s)分裂特征空间:
R
1
(
j
,
s
)
=
{
x
∣
x
j
≤
s
}
和
R
2
(
j
,
s
)
=
{
x
∣
x
j
>
s
}
,
c
^
m
=
1
N
m
∑
x
∈
R
m
(
j
,
s
)
y
i
,
m
=
1
,
2
R_1(j,s) = \{x|x^{j} \le s \}和R_2(j,s) = \{x|x^{j} > s \},\hat{c}_m = \frac{1}{N_m}\sum\limits_{x \in R_m(j,s)}y_i,\;m=1,2
R1(j,s)={x∣xj≤s}和R2(j,s)={x∣xj>s},c^m=Nm1x∈Rm(j,s)∑yi,m=1,2
c. 继续调用步骤1,2直到满足停止条件,就是每个区域的样本数小于等于5。
d. 将特征空间划分为J个不同的区域,生成回归树:
f
(
x
)
=
∑
m
=
1
J
c
^
m
I
(
x
∈
R
m
)
f(x) = \sum\limits_{m=1}^{J}\hat{c}_mI(x \in R_m)
f(x)=m=1∑Jc^mI(x∈Rm)
优点
- 能很好处理缺失值和异常值,对异常值不敏感,但是线性模型中异常值对模型结果的影响较大
- 可以直接做定性的特征而不需要像线性回归一样哑元化
sklearn.tree.DecisionTreeRegressor
-
参数:
criterion:{“ mse”,“ friedman_mse”,“ mae”},默认=“ mse”。衡量分割标准的函数 。
splitter:{“best”, “random”}, default=”best”。分割方式。
max_depth:树的最大深度。
min_samples_split:拆分内部节点所需的最少样本数,默认是2。
min_samples_leaf:在叶节点处需要的最小样本数。默认是1。
min_weight_fraction_leaf:在所有叶节点处(所有输入样本)的权重总和中的最小加权分数。如果未提供sample_weight,则样本的权重相等。默认是0。
支持向量机回归(SVR)
重点:KKT条件
KKT条件
假设
x
∗
x^*
x∗为最优化问题§的局部最优解,且
x
∗
x^*
x∗ 在某个适当的条件下 ,有:
∇
f
(
x
∗
)
+
∑
i
=
1
m
λ
i
∇
g
(
x
∗
)
+
∑
j
=
1
l
μ
j
∇
h
j
(
x
∗
)
=
0
(
对
偶
条
件
)
λ
i
≥
0
,
i
=
1
,
2
,
.
.
.
,
m
(
对
偶
条
件
)
g
i
(
x
∗
)
≤
0
(
原
问
题
条
件
)
h
j
(
x
∗
)
=
0
(
原
问
题
条
件
)
λ
i
g
(
x
∗
)
=
0
(
互
补
松
弛
定
理
)
\nabla f(x^*) + \sum\limits_{i=1}^{m}\lambda_i \nabla g(x^*) + \sum\limits_{j=1}^{l}\mu_j \nabla h_j(x^*) = 0(对偶条件)\\ \lambda_i \ge 0,\;i = 1,2,...,m(对偶条件)\\ g_i(x^*) \le 0(原问题条件)\\ h_j(x^*) = 0(原问题条件)\\ \lambda_i g(x^*) = 0(互补松弛定理)
∇f(x∗)+i=1∑mλi∇g(x∗)+j=1∑lμj∇hj(x∗)=0(对偶条件)λi≥0,i=1,2,...,m(对偶条件)gi(x∗)≤0(原问题条件)hj(x∗)=0(原问题条件)λig(x∗)=0(互补松弛定理)
对偶问题
任何一个原问题在变成对偶问题后都会变成一个凸优化的问题
强对偶问题和弱对偶问题(详情见南瓜书讲解课件——支持向量机)
sklearn.svm.SVR
- 参数:
kernel:核函数,{‘linear’, ‘poly’, ‘rbf’, ‘sigmoid’, ‘precomputed’}, 默认=’rbf’。(后面会详细介绍)
degree:多项式核函数的阶数。默认 = 3。
C:正则化参数,默认=1.0。(后面会详细介绍)
epsilon:SVR模型允许的不计算误差的邻域大小。默认0.1。
作业
1.线性回归的最小二乘法表示
E ( w , b ) = ∑ i = 1 m ( y i − ( w x i + b ) ) 2 E_{\left( w,b \right)}=\sum_{i=1}^m{\left( y_i-\left( wx_i+b \right) \right) ^2} E(w,b)=i=1∑m(yi−(wxi+b))2
2.极大似然估计与最小二乘估计的联系与区别
联系:线性回归的最小二乘估计等价于极大似然估计中噪声(误差)服从正态分布的极大似然估计
区别:最小二乘估计基于均方误差来进行模型的求解,极大似然估计基于随机误差的概率密度函数来进行求解
3.多项式回归在实际问题中的表现不是很好的原因
多项式回归通常会在训练集上有良好的表现,但这同时容易造成过拟合问题。
4.决策树模型与线性模型的联系与差别
联系:暂时没想到
差别:树模型拟合出来的函数其实是分区间的阶梯函数。线性模型拟合出来的函数则可以是任意曲线。
5.KKT条件
见上面笔记
6.为什么要引入对偶问题
任何一个原问题在变成对偶问题后都会变成一个凸优化的问题,便于求解
7.线性回归拟合模型
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
path = 'ex1data1.txt'
data = pd.read_csv(path, header=None, names=['Population', 'Profit'])
data.head() #预览数据
data.describe()
y = data["Profit"]
x = data["Population"]
fig, ax = plt.subplots(figsize = (10,8))
ax.scatter(x,y)
ax.set_xlabel("Population",fontsize = 10)
ax.set_ylabel("Profit",fontsize = 10)
plt.show()
def computeCost(X, y, w):
# your code here (appro ~ 2 lines)
#np.power(x,y)计算x的y次方
inner = np.power((np.dot(X,w.T)-y),2)#在numpy中w是一个行向量,要转换成列向量,然后使用矩阵相乘的np.dot方法
return np.sum(inner)/(2*len(X))
data["ones"] = 1
X = data.iloc[:,[0,2]]#Population和ones组成X
y = data.iloc[:,1]#Profit组成y
X = np.array(X)
y = np.array(y)
# your code here (appro ~ 1 lines)
w = np.array([0,0])
#w是参数向量
#eta是学习率
#iters是迭代次数
def gradientDescent(X, y, w, eta, iters):
temp = np.zeros(w.shape)#初始化w为全零向量
# parameters = int(theta.ravel().shape[1])
cost = np.zeros(iters)#构建iters个0的数组,用来存放每次迭代后的损失值
for i in range(iters):
# your code here (appro ~ 1 lines)
der_w = (np.matmul(X.T,np.matmul(X,w)-y))/len(y)#计算关于W的导数
# for j in range(parameters):
# your code here (appro ~ 2 lines)
w = w-eta*der_w#更新w的值
cost[i] = computeCost(X,y,w)#计算损失值
# your code here (appro ~ 2 lines)
return w, cost
eta = 0.01
iters = 1000
g, cost = gradientDescent(X, y, w, eta, iters)
computeCost(X, y, g)
x = np.linspace(data.Population.min(), data.Population.max(), 100)
f = (g[0] * x) + g[1] #得到y = wx+b的线性函数
fig, ax = plt.subplots(figsize=(12,8))
ax.plot(x, f, 'r', label='Prediction')
ax.scatter(data.Population, data.Profit, label='Traning Data')
ax.legend(loc=2)
ax.set_xlabel('Population')
ax.set_ylabel('Profit')
ax.set_title('Predicted Profit vs. Population Size')
plt.show()
fig, ax = plt.subplots(figsize=(12,8))
ax.plot(np.arange(iters), cost, 'r')
ax.set_xlabel('Iterations')
ax.set_ylabel('Cost')
ax.set_title('Error vs. Training Epoch')
plt.show()