单变量线性回归
1、单变量线性回归代价函数
代价函数
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
假设函数
h
θ
(
x
)
=
θ
T
X
=
θ
0
x
0
+
θ
1
x
1
+
θ
2
x
2
+
.
.
.
+
θ
n
x
n
{{h}_{\theta }}\left( x \right)={{\theta }^{T}}X={{\theta }_{0}}{{x}_{0}}+{{\theta }_{1}}{{x}_{1}}+{{\theta }_{2}}{{x}_{2}}+...+{{\theta }_{n}}{{x}_{n}}
hθ(x)=θTX=θ0x0+θ1x1+θ2x2+...+θnxn
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import random
path = 'ex1data1.txt'
data = pd.read_csv(path, header=None, names=['Population', 'Profit'])
data.head() #预览数据
#看数据的趋势,散点图
data.plot(kind='scatter', x='Population', y='Profit', figsize=(12,8))
plt.show()
'''
𝐽(𝜃)=1/2𝑚∑𝑖=1𝑚(ℎ𝜃(𝑥(𝑖))−𝑦(𝑖))^2
其中:
ℎ𝜃(𝑥)=𝜃^𝑇*𝑋=𝜃0𝑥0+𝜃1𝑥1+𝜃2𝑥2+...+𝜃𝑛𝑥𝑛
'''
#计算代价函数
def computeCost(X, y, theta):
# 其实就是J(theta)的矩阵表达形式,即变量X*特征向量theta-已知标注y的差求平方和
tmp = np.power((X*theta -y),2)
return np.sum(tmp)/(2*len(X))
#其中np.sum是对矩阵中所有元素求和,len则是求该矩阵中有多少行,而不是总个数,详见下例
tmp1 = np.random.rand(10)
print(tmp1)
tmp2 = np.matrix(tmp1).reshape(5,-1)
lens = len(tmp2)
print(tmp2)
print(lens)
#这里前后文无关
#突然想起来如何批量生成随机数,在不用np.random.rand的条件下
import random
def random_list(start,stop,length):
if length>=0:
length=int(length)
start, stop = (int(start), int(stop)) if start <= stop else (int(stop), int(start))
random_list = []
for i in range(length):
random_list.append(random.randint(start, stop))
return random_list
#继续说如何做线性回归,上文中做完了cost函数
data.insert(0, 'Ones', 1) #变量初始化
# set X (training data) and y (target variable)
cols = data.shape[1]
X = data.iloc[:,0:cols-1]#X是所有行,去掉最后一列
y = data.iloc[:,cols-1:cols]#X是所有行,最后一列
X.head()#head()是观察前5行
y.head()
#代价函数是应该是numpy矩阵,所以我们需要转换X和Y,然后才能使用它们。 我们还需要初始化theta,即把theta所有元素都设置为0.
X = np.matrix(X.values)
y = np.matrix(y.values)
# 这里初始化theta,随便写啥都行
theta = np.mat(np.array([0,0]))
theta = np.mat([0,0]) #这么写似乎也行
#看看结果
theta
X.shape, theta.shape, y.shape
computeCost(X, y, theta)
2、梯度下降算法(用以选出与实际值偏差最小的theta作为模拟算法的参数代入)
#𝜃𝑗:=𝜃𝑗−𝛼∂∂𝜃𝑗𝐽(𝜃)
def gradientDescent(X, y, theta, alpha, iters):
temp = np.matrix(np.zeros(theta.shape))
parameters = int(theta.ravel().shape[1])#ravel函数是降维函数,默认降成按行排序,如果是一行输进去的话,则和theta.shape[1]没啥区别,取列数
cost = np.zeros(iters)
for i in range(iters):
'''
求出delta J(theta)/delta(theta j)这一部分的值,后面再对其进行减法算最新迭代的theta。
因为把假设函数写成了h(theta) = theta0*x1+theta1*x2, 其中x1 = 1。
因此分部求导发现,对theta0求导有1/N*error*xi1,对theta1求导有1/N*error*xi2
其中xi1(也就是X的第一列全部行数据)全部为1
'''
error = (X*theta.T-y)
for j in range(parameters):
'''
这里的multiply用于点乘,即除了矩阵乘法的另外一种乘法
比如a = np.mat(np.random.rand(3,3))
b= np.mat([1,2,3]),乘出来的东西是a的每一行都乘以1、2、3
'''
term = np.multiply(error,X[:,j])
temp[0,j] = theta[0,j] -(alpha/len(X)*np.sum(term))
#把temp的两个值其实也就是theta0、theta1传给theta,再计算第i次迭代出来的代价函数的值
theta = temp
cost[i] = computeCost(X, y, theta)
return theta, cost