【机器学习】--二分类

开始迷信:

python 复制代码
"""
 *                        _oo0oo_
 *                       o8888888o
 *                       88" . "88
 *                       (| -_- |)
 *                       0\  =  /0
 *                     ___/`---'\___
 *                   .' \\|     |// '.
 *                  / \\|||  :  |||// \
 *                 / _||||| -:- |||||- \
 *                |   | \\\  - /// |   |
 *                | \_|  ''\---/''  |_/ |
 *                \  .-\__  '-'  ___/-. /
 *              ___'. .'  /--.--\  `. .'___
 *           ."" '<  `.___\_<|>_/___.' >' "".
 *          | | :  `- \`.;`\ _ /`;.`/ - ` : | |
 *          \  \ `_.   \_ __\ /__ _/   .-` /  /
 *      =====`-.____`.___ \_____/___.-`___.-'=====
 *                        `=---='
 *
 *
 *      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *
 *            佛祖保佑       永不宕机     永无BUG
 *
 * @Author       : gyp
 * @Date         : 2024-10-2 14.48.52
 * @LastEditTime : 2023-10-2 15:12:41
 * @LastEditors  : gyp
 * @Description  :
 * @FilePath     : \C\SString.c
 * 自学之用,欢迎讨论.13438784965
 */
"""

分类问题可以分为多类分类和二分类。本文将重点介绍二分类,解释其概念、应用场景、常用算法以及实际案例。

目录

1.二分类--定义

2.二分类--算法

3.二分类--评价指标

4.二分类--实验案例

[判断其年收入是否高于 50,000 美元](#判断其年收入是否高于 50,000 美元)

数据集准备

1.导入数据

2.划分数据集

3.标准化

[4.Sigmoid Function函数](#4.Sigmoid Function函数)

[5.Mini_Batch Gradient Descent(最小批量梯度下降)](#5.Mini_Batch Gradient Descent(最小批量梯度下降))

6.测试


1.二分类--定义

二分类(Binary Classification)是指将数据分为两类的一种分类任务。换句话说,模型的输出只有两个类别。这两个类别通常被表示为 0 和 1,或者 -1 和 1,代表两个不同的类别或状态。

以下是一些常见的二分类问题:

垃圾邮件检测:将电子邮件分类为"垃圾邮件"或"正常邮件"。

疾病预测:根据医疗数据预测患者是否患有某种疾病(如癌症)。

客户流失预测:预测客户是否会取消订阅服务。

信用卡欺诈检测:判断一笔交易是否为欺诈行为。

2.二分类--算法

  1. 逻辑回归(Logistic Regression):逻辑回归是一种线性模型,适用于二分类问题。它通过学习输入特征和输出之间的关系,预测样本属于某个类别的概率。3. 机器学习--逻辑回归(分类)_逻辑回归而分类器-CSDN博客
  2. 支持向量机(Support Vector Machine, SVM)SVM 是一种强大的分类算法,通过寻找最佳分隔超平面来区分不同类别的样本。它在高维空间中表现良好,尤其适用于复杂的分类任务。9.机器学习--SVM支持向量机-CSDN博客
  3. 决策树(Decision Tree)决策树通过一系列的决策规则将数据划分为不同的类别。它简单易理解,但容易过拟合,可以结合集成方法(如随机森林和梯度提升)提高性能。8.机器学习--决策树_决策树 csdn-CSDN博客
  4. k 近邻算法(k-Nearest Neighbors, k-NN)k-NN 是一种基于实例的学习算法,通过测量样本之间的距离,将新样本归类到其 k 个最近邻样本中出现次数最多的类别。2.机器学习--KNN算法(分类)-CSDN博客
  5. 神经网络(Neural Networks)神经网络,尤其是深度学习模型,在处理复杂的二分类任务时表现出色。它们可以捕捉到数据中的非线性关系,适用于大规模数据集。1.3.浅层神经网络-CSDN博客

3.二分类--评价指标

在评估二分类模型时,有几种常用的指标:

  • 准确率(Accuracy):正确预测的样本数量占总样本数量的比例。
  • 精确率(Precision):正确预测的正样本数量占预测为正样本的数量的比例。
  • 召回率(Recall):正确预测的正样本数量占实际正样本数量的比例。
  • F1 分数(F1 Score):精确率和召回率的调和平均数,综合考虑了精确率和召回率。
python 复制代码
from sklearn.metrics import confusion_matrix, precision_score, recall_score, f1_score

# 计算混淆矩阵
cm = confusion_matrix(y_test, y_pred)
print(f"Confusion Matrix:\n{cm}")

# 计算精确率、召回率和 F1 分数
precision = precision_score(y_test, y_pred)
recall = recall_score(y_test, y_pred)
f1 = f1_score(y_test, y_pred)
print(f"Precision: {precision}")
print(f"Recall: {recall}")
print(f"F1 Score: {f1}")

4.二分类--实验案例

实验案例使用李宏毅老师的机器学习课程作业,

判断其年收入是否高于 50,000 美元

二元分类是机器学习中最基础的问题之一,在这份教学中,你将学会如何实作一个线性二元分类器,来根据人们的个人资料,判断其年收入是否高于 50,000 美元。我们将以两种方法: logistic regression 与 generative model,来达成以上目的,你可以尝试了解、分析两者的设计理念及差别。 实现二分类任务: 个人收入是否超过50000元?

数据集准备

李宏毅教授作业二-年收入预测数据集_数据集-飞桨AI Studio星河社区

这个资料集是由UCI Machine Learning Repository 的Census-Income (KDD) Data Set 经过一些处理而得来。为了方便训练,我们移除了一些不必要的资讯,并且稍微平衡了正负两种标记的比例。事实上在训练过程中,只有 X_train、Y_train 和 X_test 这三个经过处理的档案会被使用到,train.csv 和 test.csv 这两个原始资料档则可以提供你一些额外的资讯。

  • 已经去除不必要的属性。

  • 已经平衡正标和负标数据之间的比例。

特征格式

train.csv,test_no_label.csv。

  • 基于文本的原始数据

  • 去掉不必要的属性,平衡正负比例。

  • train.csv中的离散特征=>在X_train中onehot编码(学历、武功状态...)

  • train.csv中的连续特征 => 在X_train中保持不变(年龄、资本损失...)。

  • X_train, X_test : 每一行包含一个510-dim的特征,代表一个样本。

  • Y_train: label = 0 表示 "<=50K" 、 label = 1 表示 " >50K " 。

要求:

请动手编写 gradient descent 实现 logistic regression

请动手实现概率生成模型。

1.导入数据

python 复制代码
#1.读取数据

import numpy as np

X_train_path = 'data/X_train'
Y_train_path = 'data/Y_train'
X_test_path = 'data/X_test'
with open(X_train_path) as f:
    #跳过第一行
    next(f)
    #读取数据
    X_train = np.array([line.strip('\n').split(',')[1:] for line in f],dtype=float)
with open(Y_train_path) as f:
    next(f)
    Y_train = np.array([line.strip('\n').split(',')[1] for line in f], dtype=float)
with open(X_test_path) as f:
    next(f)
    X_test = np.array([line.strip('\n').split(',')[1:] for line in f], dtype=float)

print(X_train.shape)
print(Y_train.shape)
print(Y_train[0:3])

#先把X_train 和 Y_train 组合成一个矩阵,构成一个数据集data,最后一列是真实标签,

python 复制代码
#先把X_train 和 Y_train 组合成一个矩阵,构成一个数据集data,最后一列是真实标签,
Y_train=Y_train.reshape(-1,1)
data = np.concatenate((X_train,Y_train),axis=1)
print(data.shape)

2.划分数据集

python 复制代码
#2.划分数据集
#对数据集data进行随机打乱

#按行随机打乱训练数据集
def shuffle(x):
    return np.random.permutation(x)

data_shuffle = shuffle(data)
#进行训练集和验证集划分
train_len = int(len(data)*0.9)  #这里训练集占90%
train_set = data_shuffle[0:train_len,:]
vali_set = data_shuffle[train_len:,:]
print(train_set.shape)
print(vali_set.shape)

3.标准化

均值:

标准差:

z-score特征标准化;

python 复制代码
#4.下面对训练集和验证集分别进行标准化
train_set_mean = np.mean(train_set[:,0:-1] ,axis=0)
train_set_mean = train_set_mean.reshape(1,510)
print(train_set_mean.shape)
train_set_std  = np.std(train_set[:,0:-1], axis=0).reshape(1, -1)

train_set[:,0:-1]  = (train_set[:,0:-1]-train_set_mean)/(train_set_std+0.00000001)
#避免方差为0。当方差为零时,说明这一列的数值是一样的,那就把这一列都变为0

vali_set[:,0:-1] = (vali_set[:,0:-1] - train_set_mean)/(train_set_std+0.00000001)
#对验证集进行标准化时,使用训练集的均值和方差

print(train_set.shape)
print(vali_set.shape)
print(train_set[0,:])

4.Sigmoid Function函数

做logistic regression,需要Sigmoid Function,可以写一个Sigmoid Function函数。

然后需要一个损失函数,cross entropy

python 复制代码
#Sigmoid Function函数
def sigmoidFun(z):

    return 1/(1.0+np.exp(-np.clip(z,-10,10)))

#损失函数cross entropy
def crossEntropy(y_pre,y_true):
    ## y_pre 为预测值
    ## y_true 为真实值
    loss = -np.sum(y_true * np.log(y_pre) + (1 - y_true) * np.log(1 - y_pre))
    return loss

#计算预测准确率
def accuracy(Y_pred, Y_label):
    acc = 1 - np.mean(np.abs(Y_pred - Y_label))
    return acc

5.Mini_Batch Gradient Descent(最小批量梯度下降)

假如加入全部训练数据有1000条,因为同时放进去训练计算量太大,那就每次只选择10条数据用于训练

下面的训练代码里,使用了Adaptive Learning Rates

解释一下for t in range(iter_time):中的代码

iter_time是训练的总轮数,每次在新一轮训练开始之前,都随机打乱一下训练集,因为训练集比较大,就用Mini_Batch Gradient Descent, batch就是一次送去训练的训练集大小。

梯度下降:

学习率更新:

python 复制代码
#5.训练模型
batch = 1000

#初始化参数
batch_times = int(train_len/batch)#计算一共有多少个batch
lr = 0.1 #学习率
iter_time = 500  #训练的总轮数
epochs = 2
times = 1 #训练次数,学习率随着训练次数的增加而减小
dim = 510 + 1 # 510是train_set_x的列数,1是bias(b)的维数
w = np.zeros([dim, 1]) #初始化 这里面的w已经包括了b   也可以分开初始化,w=np.zeros([510, 1]) b = np.zeros([1, 1])

for t in range(iter_time):

    train_set = shuffle(train_set)  # 随机打乱训练数据
    train_set_x = train_set[:,0:-1] #获取特征数据
    train_set_x = np.concatenate((train_set_x,np.ones([train_len,1])),axis=1)
    train_set_y = train_set[:,-1]   #获取标签值

    vali_set = shuffle(vali_set)    #随机打乱验证数据
    vali_set_x = vali_set[:,0:-1]  #获取验证集的特征数据
    vali_set_x = np.concatenate((vali_set_x,np.ones([len(data)-train_len,1])),axis=1)
    vali_set_y = vali_set[:,-1]#获取验证集的标签数据
    vali_set_y = vali_set_y.reshape(-1,1)

    y = np.zeros([batch, 1]) #用于存储训练时的预测值
    y_hat = np.zeros([batch, 1]) #用于存储小批次的标签值

    for b in range(batch_times):
        x= train_set_x[batch*b:batch*(b+1),:]
        x = x.reshape(batch,-1)
        y_hat = train_set_y[b*batch:(b+1)*batch]
        y_hat = y_hat.reshape(batch,1)
        y = sigmoidFun(np.dot(x,w))  #用训练集train_set_x 预测的y
        err = y - y_hat
        gradient = np.dot(x.transpose(),err) #求梯度
        lr=lr/np.sqrt(times) * gradient
        w = w -  lr # 更新参数,Adaptive Learning Rates
        times = times+1

    if(t%100==0):  #每100轮打印一次
        y_predict = sigmoidFun(np.dot(vali_set_x,w))
        loss_vali  = crossEntropy(y_predict,vali_set_y)/(len(data)-train_len) #计算验证集交叉熵
        acc_vali = accuracy(np.round(y_predict),vali_set_y) #计算验证集准确率
        loos = crossEntropy(y,y_hat)/train_len #计算训练集交叉熵
        acc = accuracy(np.round(y),y_hat) #计算训练集准确率


        print(str(t)+"/" +str(iter_time) + " 训练集交叉熵:"+str(loos))
        print(str(t)+"/" +str(iter_time) + " 训练集准确率:"+str(acc))
        print(str(t)+"/" +str(iter_time) + " 验证集交叉熵:"+str(loss_vali))
        print(str(t)+"/" +str(iter_time) + " 验证集准确率:"+str(acc_vali))

6.测试

python 复制代码
#对测试集进行标准化

test_set  = (X_test-train_set_mean)/(train_set_std+0.00000001) #还是用训练集的均值和方差

#这里对测试集增加一列
test_set = np.concatenate((test_set,np.ones([len(test_set),1])),axis=1)

predict = np.round(sigmoidFun(np.dot(test_set,w)))

print(predict)
相关推荐
Pedantic1 小时前
SwiftUI 手势层级(Gesture Hierarchy)详解
前端
飘尘1 小时前
前端转型全栈(Java后端)的快速上手指引
前端·后端·全栈
一颗烂土豆1 小时前
Meshopt 压缩深度解析,为什么它比 Draco 更快
前端·javascript·webgl
浏览器工程师2 小时前
AI Agent 接浏览器任务,先别让它一路点到底
前端·后端
雨季mo浅忆2 小时前
VSCode自动格式化三要素
前端
爱勇宝3 小时前
深扒 Anthropic 1680 位工程师简历:应届生几乎没机会,AI 公司最缺的不是博士
前端·后端·程序员
kyriewen4 小时前
同事每天催我 Code Review,我写了个脚本让 AI 替我 review PR——现在他反过来催 AI 了
前端·javascript·ai编程
user20585561518136 小时前
Windows 项目安装时报 `node-sass` 错误,如何快速处理
前端
LiaCode6 小时前
Redis 在生产项目的使用
前端·后端