机器学习系列(五) -- 逻辑回归(莺尾花数据集)

加载数据

import numpy as np
import pandas as pd

data = pd.read_csv('iris.csv')
# 去掉不需要的ID列
data.drop('ID',axis=1,inplace=True)
# 删除重复记录
data.drop_duplicates(inplace=True)
#

#  进行映射
de = data['Species'].drop_duplicates()

# print(de)
# setosa virginica  versicolor

data['Species'] = data['Species'].map({'setosa':0,'versicolor':1,'virginica':2})

# 只选取类别为0 1 的莺尾花数据  进行逻辑回归的二分类
data = data[data['Species'] != 2]
# print(len(data))

逻辑回归类

class LogisticRegression:
    # 实现逻辑回归
    def __init__(self,alpha,times):
        #  初始化方法
        #  参数: alpha :float 学习率
        #  times : int 迭代次数
        self.alpha = alpha
        self.times = times

    def sigmoid(self,z):
        # sigmoid函数的实现
        # 参数: x : float 自变量 值为x = w.T * x
        # return  p (概率0-1): 返回样本属于类别1的概率值,用来作为结果的预测
        # 当x>= 0.5 (Z>=0)时   判定为类别1  否则判定为类别0
        return 1.0 / (1.0 + np.exp(-z))

    def fit(self,X,y):
        # 根据提供的训练数据 对模型进行训练
        # 参数 : 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)
            # 根据逻辑回归的代价函数(目标函数)J(W)=-sum(yi * log(s(zi)) + (1-yi) * log(1-s(zi)))
            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):
        # 根据参数传递的样本,对样本数据进行预测
        # 参数 : X : 类数组类型 形状[样本数量,特征数量] 待训练的样本特征属性
        # return : 数组类型 预测结果(概率值)

        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):
        # 根据参数传递样本  对样本数据进行预测
        # 参数 X: 类数组类型 形状[样本数量,特征数量] 待训练的样本特征属性
#         # return : 数组类型 预测结果(分类值)
        return np.argmax(self.predict_proba(X),axis=1)

数据训练和测试

t1 = data[data['Species'] == 0]
t2 = data[data['Species'] == 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)
# 预测的概率值
# print(lr.predict_proba(test_X))
# 预测的分类值
# print()
# 计算准确性
result = lr.predict_proba(test_X)
# print(np.sum(result == test_y))
print(np.sum((result == test_y)/len(test_y)))

可视化

#    可视化
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',ms=5,label='真实值')

plt.title("逻辑回归")
plt.xlabel("样本序号")
plt.ylabel('类别')
plt.legend()
plt.show()

# 绘制目标函数损失值
plt.plot(range(1,lr.times+1),lr.loss_,'go-')
plt.show()
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

gm0012

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值