一、单变量线性回归
机器学习是基于实验建模,通过采用归纳推理来解决问题;通过已知的一些数据来进行归纳总结出一个公式对该问题比较适合的,从而对未知的数据进行预测。
数据集描述:已知若干城市的人口和利润,用回归的方法计算去哪个 城市发展。针对于本案例:
第一步:提取特征;
(1)本案例只有人口这个特征
第二步:选择合适的模型。
(1)由于因变量利润为一个离散值,故为回归模型。
h ( θ ) = θ 0 + θ 1 x 1 + ⋯ + θ n x n h(\theta) = \theta_0+\theta_1x_1+\cdots + \theta_nx_n h(θ)=θ0+θ1x1+⋯+θnxn
第三步:选择合适的损失函数。
(1)选择mas(差的平方)作为损失函数
J ( θ ) = 1 2 m ∑ i = 0 n ( h θ ( x ( i ) − y ( i ) ) ) 2 J(\theta) = \cfrac{1}{2m}\sum_{i=0}^{n}(h_\theta(x^{(i)} - y^{(i)}))^2 J(θ)=2m1i=0∑n(hθ(x(i)−y(i)))2
第四步:选择合适的优化算法。
(1)采用梯度下降对参数进行更新,优化模型。
θ j : = θ j − α δ δ θ j J ( θ ) \theta_j := \theta_j - \alpha\cfrac{\delta}{\delta\theta_j}J(\theta) θj:=θj−αδθjδJ(θ)
θ j : = θ j − α 1 m ∑ i = 1 m ( h θ ( x ( i ) ) − y ( i ) ) x j ( i ) \theta_j := \theta_j - \alpha\cfrac{1}{m}\sum_{i=1}^m(h_\theta(x^{(i)})-y^{(i)})x_j^{(i)} θj:=θj−αm1i=1∑m(hθ(x(i))−y(i))xj(i)
第五步:进行迭代,选择迭代终止的条件。
(1)选择迭代的次数作为终止的条件。
代码解释:
#导入相应的包
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
path = 'ex1data1.txt'
data = pd.read_csv(path,header=None,names=['Populution','Profit'])
#预览数据集的前5行数据
data.head()
将数据进行可视化
data.plot(kind='scatter',x='Population',y='Profit',figsize=(12,8))
plt.show()
目的是为了找到一条直线去拟合平面中的离散点,使得距离直线的平均距离最小。 (数学的方法,采用最小二乘法去计算斜率和截距。)
#此为代价函数也称之为损失函数
def computeCost(X, y, theta):
# your code here (appro ~ 2 lines)
h = X * theta.T #根据参数θ计算输出y
cost = (h-y).T * (h-y) /(2*len(y)) #计算实际输出与期望输出之间的差距
return cost
在数据集中插入一列常数1,这一列是偏置项;
data.insert(0, 'Ones', 1)
对数据集进行拆分,分为特征X与标签,然后进行训练。
# 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 = np.matrix(X.values)
y = np.matrix(y.values)
# your code here (appro ~ 1 lines)
#初始化θ,记住这里要初始化为float,不能采用list进行初始化,那样会是整形,
#后面就会造成参数无法更新。 计算过程中,记住参数要一致。
#theta = np.matrix([0,0]) # 不能这样进行初始化。
theta = np.matrix(np.zeros((1,2)))
这里要注意进行参数更新时,是所有的参数同时进行更新的所以需要先计算梯度 t e m p [ i ] = α δ δ θ i J ( θ ) temp[i] = \alpha \cfrac{\delta}{\delta \theta_i} J(\theta) temp[i]=αδθiδJ(θ)
然后再分别对所有的参数进行更新。
# 在这里运行时,出现bug,就是数据的类型不一样,不能进行运算。
"""
temp -- 每一轮的梯度值
cost -- 统计迭代的所有轮为损失值.
"""
def gradientDescent(X, y, theta, alpha, iters):
temp = np.matrix(np.zeros(theta.shape))
parameters = int(theta.ravel().shape[1])
cost = np.zeros(iters)
print(theta)
for i in range(iters):
# your code here (appro ~ 1 lines)
#得到期望的值
h = X * theta.T
for j in range(parameters):
#这样要注意进行更新时,先计算梯度,在对参数进行更新。
#因为所有的参数是同时进行更新的,
temp[0,j] = alpha /len(y)* (h - y).T * X[:,j]
print("temp[0,j]",temp[0,j])
# your code here (appro ~ 2 lines)
theta[0,j] -= temp[0,j]
J = computeCost(X, y, theta)
cost[i] = J[0][0]
return theta, cost
设置学习率 α \alpha α以及迭代的次数iters。调用梯度下降函数即可得到回归模型的参数,以及100轮的损失值。
#设置学习率以及迭代的次数。
alpha = 0.01
iters = 100
g, cost = gradientDescent(X, y, theta, alpha, iters)
绘制回归模型,来观察对数据的拟合程度。
x = np.linspace(data.Population.min(), data.Population.max(), 100)
f = g[0, 0] + (g[0, 1] * x)
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()
二、多变量线性回归。
对于多变量线性回归,即特征的个数为n个(n>1),那么对应的参数 θ \theta θ的维度要设置为n+1维。
注意初始化为浮点型即可。
t h e t a 2 = n p . m a t r i x ( n p . z e r o s ( ( 1 , n ) ) ) theta2 = np.matrix(np.zeros((1,n))) theta2=np.matrix(np.zeros((1,n)))
# set X (training data) and y (target variable)
cols = data2.shape[1]
X2 = data2.iloc[:,0:cols-1]
y2 = data2.iloc[:,cols-1:cols]
# convert to matrices and initialize theta
X2 = np.matrix(X2.values)
y2 = np.matrix(y2.values)
theta2 = np.matrix(np.zeros((1,3)))
print(type(theta2[0,0]),theta2)
# perform linear regression on the data set
g2, cost2 = gradientDescent(X2, y2, theta2, alpha, iters)