一、数据处理
- 初始化X、y
插入一列:
data.insert(0,'Ones',1)
#两种方法:
#法一:用loc,根据列名
X=data.loc[:,['Ones','Population']]
y=data.loc[:,['Profit']]
#法二:用iloc,根据列数
cols=data.shape[1]#列数,也为theta的个数
X = data.iloc[:,:-1]#X是data里的除最后列
y = data.iloc[:,cols-1:cols]#y是data最后一列
多特征可以进行先归一化处理:
#两种方法
#法一:标准差标准化,也叫z-score标准化
#x =(x - u)/σ u是均值 σ是标准差
# std 所有数减去平均值,它的平方和除以数的个数(或个数减一),再把所得值开根号,就是1/2次方,得到的数就是这组数的标准差。
data2 = (data2 - data2.mean()) / data2.std()
#法二:Min-Max标准化
#x = (x - min)/(max - min)
data2=(data2-data2.min())/(data2.max() - data2.min())
- 初始化其他参数
学习速率alpha = 0.01
迭代次数iters = 1500
二、代价函数
J ( θ ) = 1 2 m ∑ i = 1 m ( h θ ( x ( i ) ) − y ( i ) ) 2 J\left( \theta \right)=\frac{1}{2m}\sum\limits_{i=1}^{m}{{{\left( {{h}_{\theta }}\left( {{x}^{(i)}} \right)-{{y}^{(i)}} \right)}^{2}}} J(θ)=2m1i=1∑m(hθ(x(i))−y(i))2
def computeCost(X, y, theta):
inner=np.power((np.dot(X,theta.T) - y),2)#矩阵乘 X为72×2,theta.T为2×1
# 或者
# inner = np.power(((X * theta.T) - y), 2)
return np.sum(inner)/(2*len(X))
#这个部分计算J(Ѳ),X是矩阵
#theta.T为theta这个矩阵的转置
三、梯度下降算法
def gradientDescent(X, y, theta, alpha, iters):
temp = np.matrix(np.zeros(theta.shape))
parameters = int(theta.ravel().shape[1])#theta.ravel()将数据维度变为一维
#记录每一代中的代价函数值
cost = np.zeros(iters)
for i in range(iters):
error=(X * theta.T) - y
#遍历theta中每一个值并进行更新
for j in range(parameters):
term = np.multiply(error, X[:,j])#np.multiply()点乘,矩阵各个对应元素相乘
temp[0,j] = theta[0,j] - ((alpha / len(X)) * np.sum(term))
#更新theta和cost
theta = temp
cost[i] = computeCost(X, y, theta)
return theta, cost
#这个部分实现了Ѳ的更新
学习到了参数θ后,则可根据假设函数h(θ)进行预测:
y=θTx=θ0+θ1x
若用到了多项式如f1=x1,f2=x2,f3=x12,f4=x22,……:
y=θ0+θ1f1+θ2f2+θ3f3+θ4f4
四、正规方程
正规方程是通过求解下面的方程来找出使得代价函数最小的参数的:
∂
∂
θ
j
J
(
θ
j
)
=
0
\frac{\partial }{\partial {{\theta }_{j}}}J\left( {{\theta }_{j}} \right)=0
∂θj∂J(θj)=0 。
假设我们的训练集特征矩阵为 X(包含了
x
0
=
1
{{x}_{0}}=1
x0=1)并且我们的训练集结果为向量 y,则利用正规方程解出向量
θ
=
(
X
T
X
)
−
1
X
T
y
\theta ={{\left( {{X}^{T}}X \right)}^{-1}}{{X}^{T}}y
θ=(XTX)−1XTy 。
上标T代表矩阵转置,上标-1 代表矩阵的逆。设矩阵
A
=
X
T
X
A={{X}^{T}}X
A=XTX,则:
(
X
T
X
)
−
1
=
A
−
1
{{\left( {{X}^{T}}X \right)}^{-1}}={{A}^{-1}}
(XTX)−1=A−1
梯度下降与正规方程的比较:
梯度下降:需要选择学习率α,需要多次迭代,当特征数量n大时也能较好适用,适用于各种类型的模型
正规方程:不需要选择学习率α,一次计算得出,需要计算 ( X T X ) − 1 {{\left( {{X}^{T}}X \right)}^{-1}} (XTX)−1,如果特征数量n较大则运算代价大,因为矩阵逆的计算时间复杂度为 O ( n 3 ) O(n3) O(n3),通常来说当 n n n小于10000 时还是可以接受的,只适用于线性模型,不适合逻辑回归模型等其他模型
# 正规方程
def normalEqn(X, y):
theta = np.linalg.inv(X.T@X)@X.T@y#X.T@X等价于X.T.dot(X)
return theta