机器学习基础算法四:逻辑回归算法实验

逻辑回归算法实验

一、逻辑回归介绍

  • 逻辑回归是一种分类模型
  • z = W T X = w 0 + w 1 x 1 + w 2 x 2 + . . . . . . + w n x n z =W^{T}X=w^{0}+w^{1}x^{1}+w^{2}x^{2}+......+w^{n}x^{n} z=WTX=w0+w1x1+w2x2+......+wnxn
  • 逻辑回归通过sigmoid函数将输入值映射到 [0,1] 的区间范围。
  • y = p = s i g m o i d ( z ) = 1 1 + e − z y=p=sigmoid(z)=\frac{1}{1+e^{-z}} y=p=sigmoid(z)=1+ez1
  • 逻辑回归的目标函数:
    J ( w ) = − ∑ 1 n y ( i ) l o g ( s ( z ( i ) ) ) + ( 1 − y ( i ) ) l o g ( 1 − s ( z ( i ) ) ) J(w)=-\sum^{n}_{1}y^{(i)}log(s(z^{(i)}))+(1-y^{(i)})log(1-s(z^{(i)})) J(w)=1ny(i)log(s(z(i)))+(1y(i))log(1s(z(i)))
    因此,当目标函数最小时,w的值,就是我们要求的最终权重值。

二、算法实现

1、鸢尾花的数据集

  • 通过sklearn的包导入鸢尾花的数据集:
    import numpy as np
    import pandas as pd
    from sklearn.datasets import load_iris
    
  • 用pd.DataFrage函数对数据集的显示进行整理:
    iris = load_iris()
    data = pd.DataFrame(iris.data, columns=iris.feature_names)  # 通过 pd.DataFrame 函数对数据集进行更清晰的展示
    data['Kind'] = iris['target']  # 插入列表 (kind表示花的种类)
    data = data[data["Kind"] != 2]  # 该实验只用到前两类的鸢尾花,故删除第三类。
    
  • 增加增加表格的列数行数和每行的宽度以此让数据集完整表示
    pd.set_option('display.max_rows', 1000)  # 行数
    pd.set_option('display.max_columns', 1000)  # 列数
    pd.set_option('display.width', 1000)  # 宽度
    
  • 数据集展示:
    print(data)
    
    在这里插入图片描述

2、具体的函数实现

class LogisticRegression:
    """使用python语言来实现逻辑回归算法。"""

    def __init__(self, alpha, times):
        """"初始化方法。
        :parameter
        alpha : float
            学习率。(用来在梯度下降的时候我们每次更新的步伐)
        times : int
            迭代次数。
        """

        self.alpha = alpha
        self.times = times
    def sigmoid(self, z):
        """"sigmoid函数的实现
        :parameter
        -----
        z: float
            自变量,值为z = w^T * x

        :returns
        -----
        p : float,值为[0,1]之间。
            返回样本属于类别1的概率值,用来作为结果的预测。
            当 s>=0.5(z>=0)时,判定为类别1,否则判定为类别0。
        """

        return 1.0/(1.0 + np.exp(-z))
    def fit(self, X, y):
        """根据提供的训练数据X,对模型进行训练。
        :parameter
        X:类数组类型。形状:[样本数量,特征数量]
            待训练的样本特征属性。

        y:类数组类型,形状:[样本数量]
            每个样本的目标值。(标签)
        """

        X = np.asarray(X)
        y = np.asarray(y)
        # 创建权重的向量,初始值为0,长度比特征数多1。(多出来的一个是截距)
        self.w_ = np.zeros(1 + X.shape[1])
        # 创建损失列表,用来保存每次迭代后的损失值。
        self.loss_ = []

        for i in range(self.times):
            z = np.dot(X, self.w_[1:]) + self.w_[0]
            # 计算概率值(结果判定为1的概率)
            p = self.sigmoid(z)
            # 根据逻辑回归的代价函数(目标函数),计算损失值。
            # 逻辑回归的代价函数(目标函数):
            cost = -np.sum(y * np.log(p) + (1-y) * np.log(1 - p))
            self.loss_.append(cost)

            # 调整权重值,根据公式:调整为:权重(j列) = 权重(j列)+ 学习率*sum((y-s(z))* x(j))
            self.w_[0] += self.alpha * np.sum(y-p)
            self.w_[1:] += self.alpha * np.dot(X.T, y-p)
    def predict_proba(self, X):
        """根据参数传递的样本,对样本数据进行预测。

        :parameter
        -----
        X: 类数组类型。形状为[样本数量,特征数量]
            待预测的样本特征(属性)

        :returns
        ---
        result:数组类型
            预测的结果(概率值)
        """

        X = np.asarray(X)
        z = np.dot(X, self.w_[1:]) + self.w_[0]
        p = self.sigmoid(z)
        # 将预测结果变成二维数组(结构)。便于后续拼接。
        p = p.reshape(-1, 1)
        # 将两个数组进行拼接。方向为横向拼接
        return np.concatenate([1-p, p], axis=1)
    def predict(self, X):
        """根据参数传递的样本,对样本数据进行预测。
        :parameter
        -----
        X : 类数组类型。[样本数量,特征数量]
            待测试的样本特征(属性)

        :returns
        -----
        result :数组类型。
            预测的结果(分类值)
        """

        return np.argmax(self.predict_proba(X), axis=1)
  • 对训练集和测试集进行划分:
t1 = data[data["Kind"]==0]
t2 = data[data["Kind"]==1]
t1 = t1.sample(len(t1), random_state=0)
t2 = t2.sample(len(t2), random_state=0)

train_X = pd.concat([t1.iloc[:40, :-1], t2.iloc[:40, :-1]], axis=0)
train_y = pd.concat([t1.iloc[:40, -1], t2.iloc[:40, -1]], axis=0)
test_X = pd.concat([t1.iloc[40:, :-1], t2.iloc[40:, :-1]], axis=0)
test_y = pd.concat([t1.iloc[40:, -1], t2.iloc[40:, -1]], axis=0)
  • 开始预测:
# 鸢尾花的特征列都在同一个数量级,我们这里不用进行标准化处理
lr = LogisticRegression(alpha=0.01, times=20)
lr.fit(train_X, train_y)
probability = lr.predict_proba(test_X)  # 预测的概率值
result = lr.predict(test_X)   # 预测的结果
accuracy = np.sum(result==test_y) / len(test_y)  # 预测结果的准确性
  • 打印预测结果:
print(probability)
print(result)
print(accuracy)

在这里插入图片描述

3、可视化

  • 调用画图库:
import matplotlib as mpl
import matplotlib.pyplot as plt
mpl.rcParams["font.family"] = "SimHei"  # 字体为黑体
mpl.rcParams["axes.unicode_minus"] = False  # 解决保存图像是负号'-'显示为方块的问问题
  • 绘制图:
# 绘制预测值
plt.plot(result, "ro", ms=15, label="预测值")
#绘制真实值
plt.plot(test_y.values, "go", label="真实值")
plt.title("逻辑回归")
plt.xlabel("样本序号")
plt.ylabel("类别")
plt.legend()
plt.show()

在这里插入图片描述

  • 绘制目标函数的损失值图像:
# 绘制目标函数的损失值图像
plt.plot(range(1, lr.times+1), lr.loss_, "go-")
plt.show()

在这里插入图片描述

  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值