【机器学习】--二分类
开始迷信:
"""
* _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 美元
数据集准备
1.导入数据
2.划分数据集
3.标准化
4.Sigmoid Function函数
5.Mini_Batch Gradient Descent(最小批量梯度下降)
6.测试
1.二分类--定义
二分类(Binary Classification)是指将数据分为两类的一种分类任务。换句话说,模型的输出只有两个类别。这两个类别通常被表示为 0 和 1,或者 -1 和 1,代表两个不同的类别或状态。
以下是一些常见的二分类问题:
垃圾邮件检测:将电子邮件分类为“垃圾邮件”或“正常邮件”。
疾病预测:根据医疗数据预测患者是否患有某种疾病(如癌症)。
客户流失预测:预测客户是否会取消订阅服务。
信用卡欺诈检测:判断一笔交易是否为欺诈行为。
2.二分类--算法
- 逻辑回归(Logistic Regression):逻辑回归是一种线性模型,适用于二分类问题。它通过学习输入特征和输出之间的关系,预测样本属于某个类别的概率。3. 机器学习--逻辑回归(分类)_逻辑回归而分类器-CSDN博客
- 支持向量机(Support Vector Machine, SVM)SVM 是一种强大的分类算法,通过寻找最佳分隔超平面来区分不同类别的样本。它在高维空间中表现良好,尤其适用于复杂的分类任务。9.机器学习--SVM支持向量机-CSDN博客
- 决策树(Decision Tree)决策树通过一系列的决策规则将数据划分为不同的类别。它简单易理解,但容易过拟合,可以结合集成方法(如随机森林和梯度提升)提高性能。8.机器学习--决策树_决策树 csdn-CSDN博客
- k 近邻算法(k-Nearest Neighbors, k-NN)k-NN 是一种基于实例的学习算法,通过测量样本之间的距离,将新样本归类到其 k 个最近邻样本中出现次数最多的类别。2.机器学习--KNN算法(分类)-CSDN博客
- 神经网络(Neural Networks)神经网络,尤其是深度学习模型,在处理复杂的二分类任务时表现出色。它们可以捕捉到数据中的非线性关系,适用于大规模数据集。1.3.浅层神经网络-CSDN博客
3.二分类--评价指标
在评估二分类模型时,有几种常用的指标:
- 准确率(Accuracy):正确预测的样本数量占总样本数量的比例。
- 精确率(Precision):正确预测的正样本数量占预测为正样本的数量的比例。
- 召回率(Recall):正确预测的正样本数量占实际正样本数量的比例。
- F1 分数(F1 Score):精确率和召回率的调和平均数,综合考虑了精确率和召回率。
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.导入数据
#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,最后一列是真实标签,
#先把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.划分数据集
#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特征标准化;
#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
#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就是一次送去训练的训练集大小。
梯度下降:
学习率更新:
#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.测试
#对测试集进行标准化
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)