Loading

吴恩达机器学习笔记--ex1(Python实现)

单变量的线性回归(Linear Regression with one variable)

导入所需要的库

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'])
#print(data.head())

运行结果:

Population Profit
0 6.1101 17.5920
1 5.5277 9.1302
2 8.5186 13.6620
3 7.0032 11.8540
4 5.8598 6.8233

绘制散点图

data.plot(kind='scatter', x='Population', y='Profit', figsize=(12,8))
#plt.show()

运行结果:

image

计算损失函数

\[J(\theta)=\frac{1}{2m}\sum_{i=1}^m(h_\theta(x^{(i)})-y^{(i)})^2 \]

其中:\(h(\theta)=\theta^TX=\theta_0x_0+\theta_1x_1+...+\theta_nx_n\) (\(n=1,x_0=1\))

len = len(data)
c = 0
theta = np.zeros(2)

t = []#t为迭代轮数
cost = []#cost为每轮的损失值
theta0 = []
theta1 = []

for j in range(len):
    c += 1.0/(2*len) * pow(theta[0] * 1 + theta[1] * data.Population[j] - data.Profit[j],2)

#print(c)

运行结果:

32.072733877455676

实现梯度下降

批量梯度下降(batch gradient descent)算法的公式为:

\[\theta_j := \theta_j-\alpha\frac{\partial}{\partial\theta_j}J(\theta_0,\theta_1)\;\;\;\;\; (for\;i=0\;and\;i\;=1) \]

优化:

\[\theta_j:=\theta_j-\alpha\frac{1}{m}\sum_{i=1}^m(h_\theta(x^{(i)})-y^{(i)})x^{i}_j \]

Correct : Simultaneous update

\[temp0:=\theta_0-\alpha\frac{\partial}{\partial\theta_0}J(\theta_0,\theta_1) \\ temp1:=\theta_1-\alpha\frac{\partial}{\partial\theta_1}J(\theta_0,\theta_1) \\ \theta_0:=temp0 \\ \theta_1:=temp1 \]

alpha = 0.01        #学习率
iterations = 1500   #梯度下降的迭代轮数
for i in range(iterations):
    t.append(i)
    temp0 = theta[0]
    temp1 = theta[1]
    for j in range(len):
        temp0 -= (alpha/len) * (theta[0]+theta[1]*data.Population[j] - data.Profit[j])
        temp1 -= (alpha/len) * (theta[0]+theta[1]*data.Population[j] - data.Profit[j]) * data.Population[j]
    theta[0] = temp0
    theta[1] = temp1
    c = 0
    for j in range(len):
        c += 1.0/(2*len) * pow(theta[0] + theta[1] * data.Population[j] - data.Profit[j],2)
    cost.append(c)
    theta0.append(temp0)
    theta1.append(temp1)

拟合

x = [5.0, 22.5]
y = [5.0 * theta[1] + theta[0], 22.5 * theta[1] + theta[0]]
plt.plot(x, y, color="red")
plt.title("Linear Regression")
plt.xlabel("Population")
plt.ylabel("Profit")
plt.scatter(data.Population, data.Profit, marker='x')
#plt.show()

运行结果:

image

绘制损失值随梯度下降过程的变化曲线

plt.subplot(2, 2, 3)#???创建子图,subplot(nrows、ncols、index、**kwargs)
plt.title("Visualizing J(θ)")
plt.xlabel("iterations")
plt.ylabel("cost")
plt.plot(t, cost, color="red")
#plt.show()

运行结果:

image

完整代码

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

#step 1 读数据
path = 'ex1data1.txt'
data = pd.read_csv(path, header=None, names=['Population','Profit'])
#print(data.head())

#step 2 绘制散点图
data.plot(kind='scatter', x='Population', y='Profit', figsize=(12,8))
#plt.show()

#step 3 计算损失函数
len = len(data)
c = 0
theta = np.zeros(2)

t = []#t为迭代轮数
cost = []#cost为每轮的损失值
theta0 = []
theta1 = []

for j in range(len):
    c += 1.0/(2*len) * pow(theta[0] + theta[1] * data.Population[j] - data.Profit[j],2)

#print(c)

#step 4 实现梯度下降
alpha = 0.01        #学习率
iterations = 1500   #梯度下降的迭代轮数
for i in range(iterations):
    t.append(i)
    temp0 = theta[0]
    temp1 = theta[1]
    for j in range(len):
        temp0 -= (alpha/len) * (theta[0]+theta[1]*data.Population[j] - data.Profit[j])
        temp1 -= (alpha/len) * (theta[0]+theta[1]*data.Population[j] - data.Profit[j]) * data.Population[j]
    theta[0] = temp0
    theta[1] = temp1
    c = 0
    for j in range(len):
        c += 1.0/(2*len) * pow(theta[0] + theta[1] * data.Population[j] - data.Profit[j],2)
    cost.append(c)
    theta0.append(temp0)
    theta1.append(temp1)

#step 5 拟合
x = [5.0, 22.5]
y = [5.0 * theta[1] + theta[0], 22.5 * theta[1] + theta[0]]
plt.plot(x, y, color="red")
plt.title("Linear Regression")
plt.xlabel("Population")
plt.ylabel("Profit")
plt.scatter(data.Population, data.Profit, marker='x')
#plt.show()

#step 6 绘出损失值随梯度下降过程的变化曲线,这个计算要插入到梯度下降过程中,计算和记录内容见step 4
plt.subplot(2, 2, 3)#???创建子图,subplot(nrows、ncols、index、**kwargs)
plt.title("Visualizing J(θ)")
plt.xlabel("iterations")
plt.ylabel("cost")
plt.plot(t, cost, color="red")
#plt.show()

多变量的线性回归(Linear Regression with multiple variables)

导入所需要的库

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

读取数据

path = 'ex1data2.txt'#路径
data = pd.read_csv(path , header=None , names=['house_size','bedroom_number','house_price'])
#print(data.head())

特征归一化

这里使用归一化方法的是min-max标准化,将数据映射到[-1,1]

\[x_{normalized}=\frac{x-mean}{ptp},mean=average,ptp=max−min \]

x1 = np.array(data.house_size).reshape(-1,1) #数组新的shape属性应该要与原来的一致,如果等于-1的话,那么Numpy会根据剩下的维度计算出数组的另外一个shape属性值。
x2 = np.array(data.bedroom_number).reshape(-1,1)
y = np.array(data.house_price).reshape(-1,1)
data = np.concatenate((x1,x2,y),axis=1) #放在一个np array中便于归一化处理
#print(data)

mean = np.mean(data,axis=0)#axis=0 按列
ptp = np.ptp(data,axis=0)
nor_data = (data-mean)/ptp
X = np.insert(nor_data[..., :2], 0, 1, axis=1)  #axis=1 按行添加x0=1 #nor_data[..., :2]????????
y = nor_data[...,-1]

定义损失函数

def cost(X,theta,y):
    m = X.shape[0]
    temp = X.dot(theta) - y
    return temp.T.dot(temp) / (2 * m)

定义梯度下降函数

def gradient_descent(X, theta, y, alpha, iterations):
    m = X.shape[0]
    c = []  # 存储计算损失值
    for i in range(iterations):
        theta -= (alpha / m) * X.T.dot(X.dot(theta) - y)
        c.append(cost(X, theta, y))
    return theta, c

梯度下降

theta = np.zeros((3,))
alpha = 0.1
iterations = 10000

theta, c = gradient_descent(X, theta, y, alpha=alpha, iterations=iterations)

正规方程求解

\[\theta=(X^TX)^{-1}X^Ty \]

推荐使用numpy.linalg.pinv()求矩阵的逆

def normal_equation(X,y):
    return np.linalg.pinv(X.T.dot(X)).dot(X.T).dot(y)

结果比较

print("use gradient descent:", theta)
print("use normal equation", normal_equation(X,y))

运行结果:

use gradient descent: [-2.37841661e-17  9.52411131e-01 -6.59473033e-02]
use normal equation [-2.08166817e-17  9.52411140e-01 -6.59473141e-02]

损失值变化曲线

plt.title("Visualizing J(θ)")
plt.xlabel("iterations")
plt.ylabel("cost")
plt.plot([i for i in range(iterations)], c, color="red")
#plt.show()

运行结果:

image

完整代码

from os import name
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

def cost(X,theta,y):
    m = X.shape[0]
    temp = X.dot(theta) - y
    return temp.T.dot(temp) / (2 * m)

def gradient_descent(X, theta, y, alpha, iterations):
    m = X.shape[0]
    c = []  # 存储计算损失值
    for i in range(iterations):
        theta -= (alpha / m) * X.T.dot(X.dot(theta) - y)
        c.append(cost(X, theta, y))
    return theta, c

#正规方程求解
def normal_equation(X,y):
    return np.linalg.pinv(X.T.dot(X)).dot(X.T).dot(y)

path = 'ex1data2.txt'
data = pd.read_csv(path,header=None,names=['house_size','bedroom_number','house_price'])
#print(data.head())

#特征归一化
x1 = np.array(data.house_size).reshape(-1,1)
x2 = np.array(data.bedroom_number).reshape(-1,1)
y = np.array(data.house_price).reshape(-1,1)
data = np.concatenate((x1,x2,y),axis=1) #放在一个np array中便于归一化处理
#print(data)

mean = np.mean(data,axis=0)#axis=0 按列
ptp = np.ptp(data,axis=0)
nor_data = (data-mean)/ptp
X = np.insert(nor_data[..., :2], 0, 1, axis=1)  #axis=1 按行添加x0=1 #nor_data[..., :2]????????
y = nor_data[...,-1]

#梯度下降
theta = np.zeros((3,))
alpha = 0.1
iterations = 10000

theta, c = gradient_descent(X, theta, y, alpha=alpha, iterations=iterations)

#使用梯度下降和正规方程所求结果有所差异
print("use gradient descent:", theta)
print("use normal equation", normal_equation(X,y))

# 损失值变化曲线
plt.title("Visualizing J(θ)")
plt.xlabel("iterations")
plt.ylabel("cost")
plt.plot([i for i in range(iterations)], c, color="red")
#plt.show()
posted @ 2021-11-18 17:04  Amsterdamnit  阅读(168)  评论(0)    收藏  举报