机器学习基础(十一)线性回归

首先可视化待训练数据

import numpy as np
import matplotlib.pyplot as plt

# 手写实现单自变量的线性回归问题,实现直线的拟合,f(x) = a * x + b
# 线性回归问题, 有监督学习模型
# 训练样本数据:1、线性模型  2、标签数据

xTrain = np.array([[6],
                  [8],
                  [10],
                   [14],
                   [18]])
yTrain = np.array([7, 8, 13, 17.5, 18])
plt.scatter(xTrain.flatten(), yTrain)
plt.show()

在这里插入图片描述

未开始训练的初始线

import numpy as np
import matplotlib.pyplot as plt

# 手写实现单自变量的线性回归问题,实现直线的拟合,f(x) = a * x + b
# 线性回归问题, 有监督学习模型
# 训练样本数据:1、线性模型  2、标签数据

xTrain = np.array([[6],
                  [8],
                  [10],
                   [14],
                   [18]])
yTrain = np.array([7, 8, 13, 17.5, 18])


# 使用梯度下降算法手写实现线性回归
# 损失函数(cost function)

# 定义模型函数原型
def predict(X, w, b):
    return X.dot(w) + b
    pass


# 定义损失函数,均方误差MSE mean square error
def loss(X, w, b, y):
    py = predict(X, w, b).flatten()
    return np.sum((py - y)**2)/2/len(X)
    pass

def gradient(X, w, b, y):
    py = predict(X, w, b).flatten()
    # g对w的导数
    g_w = X.T.dot(py - y)/len(X)  # np.sum(X[:, 0] + (py-y)/len(x))
    # g对b的导数
    g_b = np.sum(py - y) / len(X)
    return g_w, g_b
    pass

# 定义训练训练函数, 梯度下降算法
def train(X, w, b, y, alpha=0.01, tel = 0.0000000001, times = 1000):
    t = 0
    while t < times:
        loss0 = loss(X, w, b, y)  # 计算损失
        g_w, g_b = gradient(X, w, b, y)  # 求w和b的导数
        w = w - alpha*g_w   # 梯度更新
        b = b - alpha*g_b   # 梯度更新
        loss1 = loss(X, w, b, y)
        if np.absolute(loss0 -loss1) < tel:
            break
        t += 1
        pass
    pass


w = np.array([[2]])
b = 1
r = predict(xTrain, w, 1)
g_w, g_b = gradient(xTrain, w, b, yTrain)
print(r)
plt.plot(xTrain.flatten(), r.flatten())

# 画图显示
plt.scatter(xTrain.flatten(), yTrain)
plt.show()

在这里插入图片描述
加入训练函数后的代码:

import numpy as np
import matplotlib.pyplot as plt

# 手写实现单自变量的线性回归问题,实现直线的拟合,f(x) = a * x + b
# 线性回归问题, 有监督学习模型
# 训练样本数据:1、线性模型  2、标签数据

xTrain = np.array([[6],
                  [8],
                  [10],
                   [14],
                   [18]])
yTrain = np.array([7, 8, 13, 17.5, 18])


# 使用梯度下降算法手写实现线性回归
# 损失函数(cost function)

# 定义模型函数原型
def predict(X, w, b):
    return X.dot(w) + b
    pass


# 定义损失函数,均方误差MSE mean square error
def loss(X, w, b, y):
    py = predict(X, w, b).flatten()
    return np.sum((py - y)**2)/2/len(X)
    pass

def gradient(X, w, b, y):
    py = predict(X, w, b).flatten()
    # g对w的导数
    g_w = X.T.dot(py - y)/len(X)  # np.sum(X[:, 0] + (py-y)/len(x))
    # g对b的导数
    g_b = np.sum(py - y) / len(X)
    return g_w, g_b
    pass

# 定义训练训练函数, 梯度下降算法
def train(X, w, b, y, alpha=0.01, tel = 0.0000000001, times = 1000):
    t = 0
    while t < times:
        loss0 = loss(X, w, b, y)  # 计算损失
        g_w, g_b = gradient(X, w, b, y)  # 求w和b的导数
        w = w - alpha*g_w   # 梯度更新
        b = b - alpha*g_b   # 梯度更新
        loss1 = loss(X, w, b, y)
        if np.absolute(loss0 -loss1) < tel:
            break
        t += 1
        pass
    return w, b
    pass


w = np.array([[2]])
b = 1
r = predict(xTrain, w, 1)
g_w, g_b = gradient(xTrain, w, b, yTrain)
print(r)
plt.plot(xTrain.flatten(), r.flatten(), 'b--')

# 训练模型
w,b = train(xTrain, w, b, yTrain)
py = predict(xTrain, w, 1)
plt.plot(xTrain.flatten(), py.flatten(), 'r--')

# 画图显示
plt.scatter(xTrain.flatten(), yTrain)
plt.show()

在这里插入图片描述
感觉效果有点差,调整参数alpha,继续看训练效果
在这里插入图片描述
可以使用sklearn简单实现线性回归

# 使用sklearn库实现线性回归模型
# 要想学会算法的原理和思想,必须从数学开始,从看懂数学原理入手,然后代码实现,才能真正理解

from sklearn.linear_model import LinearRegression
import numpy as np

xTrain = np.array([[6],
                  [8],
                  [10],
                   [14],
                   [18]])
yTrain = np.array([7, 8, 13, 17.5, 18])

mode1 = LinearRegression()
mode1.fit(xTrain, yTrain)

print(mode1.predict([[20]]))

print(mode1.intercept_)  # 截距
print(mode1.coef_)  # 斜率

二维平面拟合,注意这里使用3D可视化工具,如果matplotlib版本过高,无法绘制出图形,可以降低版本号(3.5.2)再绘制。

# 拟合平面
import numpy as np
import matplotlib.pyplot as plt
from  mpl_toolkits.mplot3d import Axes3D

# 手写实现多自变量的线性回归问题,实现直线的拟合,f(x) = a * x1 + b * x2 + c
# 线性回归问题, 有监督学习模型
# 训练样本数据:1、线性模型  2、标签数据

xTrain = np.array([[6, 2],
                  [8, 1],
                  [10, 0],
                   [14, 2],
                   [18, 0]])
yTrain = np.array([7, 8, 13, 17.5, 18])

# 通用算法
# 使用梯度下降算法手写实现线性回归
# 损失函数(cost function)

# 定义模型函数原型
def predict(X, w, b):
    return X.dot(w) + b
    pass

# 定义损失函数,均方误差MSE mean square error
def loss(X, w, b, y):
    py = predict(X, w, b).flatten()
    return np.sum((py - y)**2)/2/len(X)
    pass

def gradient(X, w, b, y):
    py = predict(X, w, b).flatten()
    # g对w的导数
    g_w = X.T.dot(py - y).reshape(-1, 1)  # np.sum(X[:, 0] + (py-y)/len(x))
    # g对b的导数
    g_b = np.sum(py - y) / len(X)
    return g_w, g_b
    pass

# 定义训练训练函数, 梯度下降算法
def train(X, w, b, y, alpha=0.0001, tel = 0.0000000001, times = 10000):
    t = 0
    while t < times:
        loss0 = loss(X, w, b, y)  # 计算损失
        print(loss0)
        g_w, g_b = gradient(X, w, b, y)  # 求w和b的导数
        w = w - alpha*g_w   # 梯度更新
        b = b - alpha*g_b   # 梯度更新
        loss1 = loss(X, w, b, y)
        if np.absolute(loss0 -loss1) < tel:
            break
        t += 1
        pass
    return w, b
    pass


w = np.array([[2],
              [1]])
b = 1
r = predict(xTrain, w, b)
g_w, g_b = gradient(xTrain, w, b, yTrain)
print(r)

# 训练模型
w,b = train(xTrain, w, b, yTrain)
py = predict(xTrain, w, b)

#  可视化算法的模型效果
#  观察模型效果
figure = plt.figure()
ax = Axes3D(figure)
ax.scatter3D(xTrain[:, 0], xTrain[:, 1], yTrain)
plt.show()

在这里插入图片描述

# 拟合平面
import numpy as np
import matplotlib.pyplot as plt
from  mpl_toolkits.mplot3d import Axes3D

# 手写实现多自变量的线性回归问题,实现直线的拟合,f(x) = a * x1 + b * x2 + c
# 线性回归问题, 有监督学习模型
# 训练样本数据:1、线性模型  2、标签数据

xTrain = np.array([[6, 2],
                  [8, 1],
                  [10, 0],
                   [14, 2],
                   [18, 0]])
yTrain = np.array([7, 8, 13, 17.5, 18])

# 通用算法
# 使用梯度下降算法手写实现线性回归
# 损失函数(cost function)

# 定义模型函数原型
def predict(X, w, b):
    return X.dot(w) + b
    pass

# 定义损失函数,均方误差MSE mean square error
def loss(X, w, b, y):
    py = predict(X, w, b).flatten()
    return np.sum((py - y)**2)/2/len(X)
    pass

def gradient(X, w, b, y):
    py = predict(X, w, b).flatten()
    # g对w的导数
    g_w = X.T.dot(py - y).reshape(-1, 1)  # np.sum(X[:, 0] + (py-y)/len(x))
    # g对b的导数
    g_b = np.sum(py - y) / len(X)
    return g_w, g_b
    pass

# 定义训练训练函数, 梯度下降算法
def train(X, w, b, y, alpha=0.0001, tel = 0.0000000001, times = 10000):
    t = 0
    while t < times:
        loss0 = loss(X, w, b, y)  # 计算损失
        print(loss0)
        g_w, g_b = gradient(X, w, b, y)  # 求w和b的导数
        w = w - alpha*g_w   # 梯度更新
        b = b - alpha*g_b   # 梯度更新
        loss1 = loss(X, w, b, y)
        if np.absolute(loss0 -loss1) < tel:
            break
        t += 1
        pass
    return w, b
    pass


w = np.array([[2],
              [1]])
b = 1
r = predict(xTrain, w, b)
g_w, g_b = gradient(xTrain, w, b, yTrain)
print(r)

# 训练模型
w,b = train(xTrain, w, b, yTrain)
py = predict(xTrain, w, b)

#  可视化算法的模型效果
#  观察模型效果
figure = plt.figure()
ax = Axes3D(figure)
ax.scatter3D(xTrain[:, 0], xTrain[:, 1], yTrain, c = 'r')

points = np.arange(0, 30, 0.5)
vx, vy = np.meshgrid(points, points)
xPoints = np.array([vx.flatten(), vy.flatten()]).T
py = predict(xPoints, w, b)
ax.plot_surface(vx, vy, py.reshape(vx.shape))
plt.show()

在这里插入图片描述
接下来实现高阶拟合,首先模拟出需要的实验数据,然后进行实验:

# 高阶拟合

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D


# 通用算法
# 使用梯度下降算法手写实现线性回归
# 损失函数(cost function)
# 定义模型函数原型
def predict(X, w, b):
    return X.dot(w) + b
    pass

# 定义损失函数,均方误差MSE mean square error
def loss(X, w, b, y):
    py = predict(X, w, b).flatten()
    return np.sum((py - y)**2)/2/len(X)
    pass

def gradient(X, w, b, y):
    py = predict(X, w, b).flatten()
    # g对w的导数
    g_w = X.T.dot(py - y).reshape(-1, 1)  # np.sum(X[:, 0] + (py-y)/len(x))
    # g对b的导数
    g_b = np.sum(py - y) / len(X)
    return g_w, g_b
    pass

# 定义训练训练函数, 梯度下降算法
def train(X, w, b, y, alpha=0.0001, tel = 0.0000000001, times = 10000):
    t = 0
    while t < times:
        loss0 = loss(X, w, b, y)  # 计算损失
        print(loss0)
        g_w, g_b = gradient(X, w, b, y)  # 求w和b的导数
        w = w - alpha*g_w   # 梯度更新
        b = b - alpha*g_b   # 梯度更新
        loss1 = loss(X, w, b, y)
        if np.absolute(loss0 -loss1) < tel:
            break
        t += 1
        pass
    return w, b
    pass

# 假设拟合 :f(x1, x2) = w1*x1^2 + w2*x2^2 + w0
# 数据需要符合特定的线性规律,才能使用线性拟合
# 实验1,假设拟合如下方程:f(x1, x2) = 2*x1^2 + 3*x2*x1 + x2^2 + 10

def makeY(xTrain):
    # 这里是为了得到实验的yTrain数据,注意还要在最后得到的数据上加一些偏移,以求更逼真的实验
    for row in xTrain:
        return np.array([2 * row[0]**2 + 3 * row[0] * row[1] + row[1] ** 2 + 10 + np.random.uniform(-1, 1) for row in xTrain])
        pass
    pass

xTrain = np.array([[1,  3],
                   [5,  7],
                   [2,  5],
                   [5,  10],
                   [1.5,  9]])
yTrain = makeY(xTrain)
print(yTrain)

# 绘出分布点
figure = plt.figure()
ax = Axes3D(figure)
figure.add_axes(ax)
ax.scatter3D(xTrain[:, 0], xTrain[:, 1], yTrain, c='r')
plt.show()

在这里插入图片描述
算法的效果与实验的数据数量也有关系,实验代码如下:

# 高阶拟合

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D


# 通用算法
# 使用梯度下降算法手写实现线性回归
# 损失函数(cost function)
# 定义模型函数原型
def predict(X, w, b):
    return X.dot(w) + b
    pass

# 定义损失函数,均方误差MSE mean square error
def loss(X, w, b, y):
    py = predict(X, w, b).flatten()
    return np.sum((py - y)**2)/2/len(X)
    pass

def gradient(X, w, b, y):
    py = predict(X, w, b).flatten()
    # g对w的导数
    g_w = X.T.dot(py - y).reshape(-1, 1)  # np.sum(X[:, 0] + (py-y)/len(x))
    # g对b的导数
    g_b = np.sum(py - y) / len(X)
    return g_w, g_b
    pass

# 定义训练训练函数, 梯度下降算法
def train(X, w, b, y, alpha=0.001, tel = 0.00000000001, times = 200000):
    t = 0
    while t < times:
        loss0 = loss(X, w, b, y)  # 计算损失
        print(loss0)
        g_w, g_b = gradient(X, w, b, y)  # 求w和b的导数
        w = w - alpha*g_w   # 梯度更新
        b = b - alpha*g_b   # 梯度更新
        loss1 = loss(X, w, b, y)
        if np.absolute(loss0 -loss1) < tel:
            break
        t += 1
        pass
    return w, b
    pass

# 假设拟合 :f(x1, x2) = w1*x1^2 + w2*x2^2 + w0
# 数据需要符合特定的线性规律,才能使用线性拟合
# 实验1,假设拟合如下方程:f(x1, x2) = 2*x1^2 + 3*x2*x1 + x2^2 + 10

def makeY(xTrain):
    # 这里是为了得到实验的yTrain数据,注意还要在最后得到的数据上加一些偏移,以求更逼真的实验
    for row in xTrain:
        return np.array([2 * row[0]**2 + 3 * row[0] * row[1] + row[1] ** 2 + 4 * row[0] + 10 + np.random.uniform(-1, 1) for row in xTrain])
        pass
    pass

xTrain = np.array([[1.5,  3],
                   [0.5,  2],
                   [3,  5],
                   [5,  2],
                   [2.5,  1],
                   [1.5, 2],
                   [2, 1],
                   [1.1, 4],
                   [4, 1.1]])
yTrain = makeY(xTrain)
print(yTrain)

# 扩维降阶(属于工程方法),样本数量不够,也会影响算法的结果
xNewTrain = np.array([[2.25, 4.5, 9, 1.5],
                      [0.25, 1, 4, 0.5],
                      [9, 15, 25, 3],
                      [25, 10, 4, 5],
                      [6.25, 2.5, 1, 2.5],
                      [2.25, 3, 4, 1.5],
                      [4, 2, 1, 2],
                      [1.21, 4.4, 16, 1.1],
                      [16, 4.4, 1.21, 4]])
w = np.array([[0.5],
              [0.5],
              [0.2],
              [0.6]])
b = 0.1
w, b = train(xNewTrain, w, b, yTrain)
print(w)
print(b)

# 绘出分布点
figure = plt.figure()
ax = Axes3D(figure)
figure.add_axes(ax)
ax.scatter3D(xTrain[:, 0], xTrain[:, 1], yTrain, c='r')

# 绘制曲面(比较复杂)
xPoints = np.arange(-6, 6, 0.2)
vx, vy = np.meshgrid(xPoints, xPoints)
xxTrain = np.array([vx.flatten(), vy.flatten()]).T
xxNewTrain = np.array([xxTrain[:, 0]**2, xxTrain[:, 0] * xxTrain[:, 1], xxTrain[:, 1]**2, xxTrain[:, 0]]).T
py = predict(xxNewTrain, w, b)
ax.plot_surface(vx, vy, py.reshape(vx.shape))
plt.show()

在这里插入图片描述
可以看到最后的参数是比较接近2, 3, 1, 4, 10这几个参数的,训练效果比较理想。
在这里插入图片描述
逻辑回归
逻辑回归代码:

# 手写实现逻辑回归分类算法,并且实现二分类任务
# 逻辑回归属于监督学习模型

import numpy as np
# 激活函数
def sigmoid(x):
    return 1/(1+np.exp(-x))
    pass

# 模型函数, 与线性回归不同,在模型函数后加了一个激活函数
def predict(X, w, b):
    return sigmoid(X.dot(w) + b)
    pass

# 定义交叉熵损失函数
def loss(X, w, b, y):
    py = predict(X, w, b).flatten()
    return np.sum(-y * np.log(py) - (1-y) * np.log(1-py))/len(X)
    pass

def gradient(X, w, b, y):
    py = predict(X, w, b).flatten()
    # g对w的导数
    g_w = X.T.dot(py - y).reshape(-1, 1)  # np.sum(X[:, 0] + (py-y)/len(x))
    # g对b的导数
    g_b = np.sum(py - y) / len(X)
    return g_w, g_b
    pass

# 定义训练训练函数, 梯度下降算法
def train(X, w, b, y, alpha=0.1, tol = 1e-10, times = 200000):
    t = 0
    while t < times:
        loss0 = loss(X, w, b, y)  # 计算损失
        print(loss0)
        g_w, g_b = gradient(X, w, b, y)  # 求w和b的导数
        w = w - alpha*g_w   # 梯度更新
        b = b - alpha*g_b   # 梯度更新
        loss1 = loss(X, w, b, y)
        if np.absolute(loss0 -loss1) < tol:
            break
        t += 1
        pass
    return w, b
    pass

w = np.array([[2],
              [2]])
b = 0
xTrain = np.array([[30, 50],
                   [70, 80],
                   [60, 40],
                   [70, 90],
                   [90, 70],
                   [50, 40],
                   [40, 60],
                   [30, 90],
                   [90, 80],
                   [70, 90],
                   [10, 20],
                   [50, 50],
                   [61, 62]])
xTrain = xTrain/100
yTrain = np.array([0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1])
w, b = train(xTrain, w, b, yTrain)
result = predict(xTrain, w, b)
print(result)
result = np.where(result > 0.5, 1, 0)
print(result.flatten())

在这里插入图片描述
使用测试集验证后:

# 手写实现逻辑回归分类算法,并且实现二分类任务
# 逻辑回归属于监督学习模型

import numpy as np
# 激活函数
def sigmoid(x):
    return 1/(1+np.exp(-x))
    pass

# 模型函数, 与线性回归不同,在模型函数后加了一个激活函数
def predict(X, w, b):
    return sigmoid(X.dot(w) + b)
    pass

# 定义交叉熵损失函数
def loss(X, w, b, y):
    py = predict(X, w, b).flatten()
    return np.sum(-y * np.log(py) - (1-y) * np.log(1-py))/len(X)
    pass

def gradient(X, w, b, y):
    py = predict(X, w, b).flatten()
    # g对w的导数
    g_w = X.T.dot(py - y).reshape(-1, 1)  # np.sum(X[:, 0] + (py-y)/len(x))
    # g对b的导数
    g_b = np.sum(py - y) / len(X)
    return g_w, g_b
    pass

# 定义训练训练函数, 梯度下降算法
def train(X, w, b, y, alpha=0.1, tol = 1e-10, times = 200000):
    t = 0
    while t < times:
        loss0 = loss(X, w, b, y)  # 计算损失
        print(loss0)
        g_w, g_b = gradient(X, w, b, y)  # 求w和b的导数
        w = w - alpha*g_w   # 梯度更新
        b = b - alpha*g_b   # 梯度更新
        loss1 = loss(X, w, b, y)
        if np.absolute(loss0 -loss1) < tol:
            break
        t += 1
        pass
    return w, b
    pass

w = np.array([[2],
              [2]])
b = 0
xTrain = np.array([[30, 50],
                   [70, 80],
                   [60, 40],
                   [70, 90],
                   [90, 70],
                   [50, 40],
                   [40, 60],
                   [30, 90],
                   [90, 80],
                   [70, 90],
                   [10, 20],
                   [50, 50],
                   [61, 62]])
xTrain = xTrain/100
yTrain = np.array([0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1])
w, b = train(xTrain, w, b, yTrain)
result = predict(xTrain, w, b)
print(result)
result = np.where(result > 0.5, 1, 0)
print(result.flatten())

# 预测
xTest = np.array([[30, 30],
                  [100, 100],
                  [40, 60]])
xTest = xTest/100
yTest = ([0, 1, 0])
result = predict(xTest, w, b)
result = np.where(result > 0.5, 1, 0).flatten()
print(result)

# 使用测试集验证,计算准确率
acc = 1-np.count_nonzero(yTest - result) / len(yTest)
print("准确率: %.2f%%" % (acc * 100))

在这里插入图片描述
调用sklearn库的算法:

from sklearn.linear_model import  LogisticRegression
import numpy as np

# 训练样本
xTrain = np.array([[30, 50],
                   [70, 80],
                   [60, 40],
                   [70, 90],
                   [90, 70],
                   [50, 40],
                   [40, 60],
                   [30, 90],
                   [90, 80],
                   [70, 90],
                   [10, 20],
                   [50, 50],
                   [61, 62]])
yTrain = np.array([0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1])

model = LogisticRegression()
model.fit(xTrain, yTrain)

result = model.predict(xTrain)
print(result)

# 预测
xTest = np.array([[30, 30],
                  [100, 100],
                  [40, 60]])
yTest = np.array([0, 1, 0])
print(model.predict(xTest))
print(model.score(xTest, yTest))  # 准确率
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值