逻辑回归-鸢尾花数据集

import numpy as np
import pandas as pd

data = pd.read_csv("iris.csv")
#去掉不需要的列
data.drop("id",axis=1,inplace=True)
data.drop_duplicates(inplace=True)
#实现映射操作
data['Species'] = data['Species'].map({'Iris-versicolor':0,'Iris-setosa':1,'Iris-virginica':2})
#对数据进行筛选,只选取类型为0,1的数据,进行逻辑回归二分类
data = data[data['Species'] != 2]
data
class LogisticRegression:
    """使用python实现逻辑回归算法"""
    def __init__(self,alpha,times):
        """初始化方法:
        Parameters:
        ----
        alpah:float
            学习率
        times : int
            迭代次数
        """
        self.alpha = alpha
        self.times = times
    
    def sigmoid(self,z):
        """sigmoid函数的实现
        Parameters:
        ----
        z: float
            自变量,值为:z = w.T * x
        Return:
        ----
        result:float,值为[0,1]之间
            返回样本属于类别一的概率值,用于结果的预测
            当s > 0.5(z>=0)时,判定为类别一,否则判定为类别0
        """
        return 1.0 / (1.0 + np.exp(-z))
    
    def fit(self, X, y):
        """根据训练数据,对模型进行训练
        Parameters:
        ----
        X : 类数组类型,形状[样本数量,特征数量]
            待训练的样本的特征属性
        y : 类数组类型。形状为[样本数量]
            每个样本的目标值(标签)
        """
        #将X,y转换成ndarray数组
        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]
            #计算概率值(判定结果一的概率值)
            p = self.sigmoid(z)
            #损失值,根据逻辑回归的目标函数,计算损失值。
            #目标函数:J(w) = - sum(yi * log(s(zi)) + (1-yi) * log(1-s(zi)))【i从1到n】
            cost = -np.sum((y * np.log(p)) + (1 - y) * np.log(1-p))
            self.loss_.append(cost)
            #更新权重,公式:权重(j) = 权重(j) + 学习率 * sum((y - s(zi))* xj)
            self.w_[0] += self.w_[0] + self.alpha * np.sum(y - p)
            self.w_[1:] += self.w_[1:] + self.alpha * np.dot(X.T,y-p)
    
    def predict_proba(self,X):
        """根据参数传递的样本,对样本数据进行预测
        Parameters
        -----
        X:类数组类型,形状为[样本数量,样本特征数量]
            待测试样本的属性特征
        Return
        ----
        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):
        """根据参数传递的样本,对样本数据进行预测
        Parameters:
        ----
        X:类数组类型,形状[样本数量,特征数量]
            待测试的样本特征(属性)
        Returns:
        -----
        result: 数组类型
            预测结果(分类值)
        """
        return np.argmax(self.predict_proba(X),axis = 1)
#构建测试集与训练街
t0 = data[data['Species'] == 0]
t1 = data[data['Species'] == 1]
t0 = t0.sample(len(t0),random_state = 0)
t1 = t1.sample(len(t1),random_state = 0)

train_X = pd.concat([t0.iloc[:40,:-1],t1.iloc[:40,:-1]],axis = 0)
train_y = pd.concat([t0.iloc[:40,-1],t1.iloc[:40,-1]],axis = 0)
test_X = pd.concat([t0.iloc[40:,:-1],t1.iloc[40:,:-1]],axis = 0)
test_y = pd.concat([t0.iloc[40:,-1],t1.iloc[40:,-1]],axis = 0)

#鸢尾花特征列都在同一个数量级,这里可以不用标准化处理
lr = LogisticRegression(alpha=0.01,times=20)
lr.fit(train_X,train_y)
#预测概率值
display(lr.predict_proba(test_X))
#类别预测
result = lr.predict(test_X)
display(result)
#计算准确性
np.sum(result == test_y) / len(test_X)
#对计算结果进行可视化展示
import matplotlib as mpl
import matplotlib.pyplot as plt
#设置matplotlib 支持中文显示
mpl.rcParams['font.family'] = 'SimHei' #设置字体为黑体
mpl.rcParams['axes.unicode_minus'] = False #设置在中文字体是能够正常显示负号(“-”)

#设置画布大小
plt.figure(figsize=(8,8))
#绘制预测值
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--')

逻辑回归-鸢尾花数据集