pyTorch框架:模型的子类写法--改进版二分类问题
目录
1.导包
2.加载数据
3.数据的特征工程
4.pytorch中最常用的一种创建模型的方式--子类写法
1.导包
import torch
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
2.加载数据
data = pd.read_csv('./dataset/HR.csv')
data.head() #查看数据的前5条
data.shape #共计14999个数据,10个特征
(14999, 10)
data.info() #查看数据信息
#data原数据没有缺失数据, 若有缺失数据,可以使用机器学习中的特征工程进行缺失值的处理
<class 'pandas.core.frame.DataFrame'> RangeIndex: 14999 entries, 0 to 14998 Data columns (total 10 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 satisfaction_level 14999 non-null float64 1 last_evaluation 14999 non-null float64 2 number_project 14999 non-null int64 3 average_montly_hours 14999 non-null int64 4 time_spend_company 14999 non-null int64 5 Work_accident 14999 non-null int64 6 left 14999 non-null int64 7 promotion_last_5years 14999 non-null int64 8 part 14999 non-null object 9 salary 14999 non-null object dtypes: float64(2), int64(6), object(2) memory usage: 1.1+ MB
data.part.unique() #查看数据part列数据中的去重之后的数据
array(['sales', 'accounting', 'hr', 'technical', 'support', 'management', 'IT', 'product_mng', 'marketing', 'RandD'], dtype=object)
3.数据的特征工程
#深度学习是机器学习的一部分,一个分支,不分家
#分类数据:即离散数据, 取值很有限
# 对于离散的字符串, 有两种处理方式, 1. 字典映射:转化成数字. 2. 进行one-hot编码.
#这里进行one-hot编码.的链式写法(同时编码多列数据)
#join() 是 在dataframe数据结构中 横向添加数据(即新增列数据)
#两次连续使用join(), 属于链式调用API方法
#不能多次运行
data = data.join(pd.get_dummies(data.part)).join(pd.get_dummies(data.salary))
# 把part和salary删掉.
data.drop(columns=['part', 'salary'], inplace = True)
data.left.value_counts() #left列数据是分类目标标记
0 11428 1 3571 Name: left, dtype: int64
#深度学习 受 数据分布不均衡的影响 没有机器学习 大
#对于不均衡的数据 , 在机器学习中需要使用 SMOTE算法 进行平衡性处理
11428 / (11428 + 3571) #数据标记分布不均衡,还在可接受的范围
0.7619174611640777
Y_data = data.left.values.reshape(-1, 1)
Y_data
array([[1], [1], [1], ..., [1], [1], [1]], dtype=int64)
Y = torch.from_numpy(Y_data).type(torch.FloatTensor)
Y
tensor([[1.], [1.], [1.], ..., [1.], [1.], [1.]])
#条件判断花式索引 获取X数据
data.columns != 'left'
array([ True, True, True, True, True, True, False, True, True, True, True, True, True, True, True, True, True, True, True, True, True])
#条件判断花式索引 获取X数据
[c for c in data.columns if c != 'left']
['satisfaction_level', 'last_evaluation', 'number_project', 'average_montly_hours', 'time_spend_company', 'Work_accident', 'promotion_last_5years', 'IT', 'RandD', 'accounting', 'hr', 'management', 'marketing', 'product_mng', 'sales', 'support', 'technical', 'high', 'low', 'medium']
X_data = data[[c for c in data.columns if c != 'left']].values #花式索引获取X数据
X = torch.from_numpy(X_data).type(torch.FloatTensor) #将X数据转化为 pyTorch中的Tensor数据
X.shape
torch.Size([14999, 20])
4.pytorch中最常用的一种创建模型的方式--子类写法
# pytorch中最常用的一种创建模型的方式
# 子类的写法.
from torch import nn #导入神经网络
#定义类对象
class HRModel(nn.Module): #继承子类nn.Module来创建类
def __init__(self):
#先调用父类的方法
super().__init__()
#定义自己写的网络中会用到的东西
self.lin_1 = nn.Linear(20, 64) #(输入特征维度20,输出特征维度64)
self.lin_2 = nn.Linear(64, 64)
self.lin_3 = nn.Linear(64, 1)
self.activate = nn.ReLU() #激活函数
self.sigmoid = nn.Sigmoid()
def forward(self, input):
#定义前向传播
x = self.lin_1(input) #输入
x = self.activate(x) #激活
x = self.lin_2(x) #输入
x = self.activate(x) #激活
x = self.lin_3(x) #输入
x = self.sigmoid(x) #激活
return x
#声明学习率
lr = 0.001
#定义获取模型的函数和优化器
def get_model():
model = HRModel() #声明模型对象
return model, torch.optim.SGD(model.parameters(),lr = lr) #定义优化器
#定义损失函数
loss_fn = nn.BCELoss() #交叉熵损失函数
model, opt = get_model() #获取模型和优化器
#声明参数
batch_size = 64 #一次取64个数据进行训练
steps = len(data) // batch_size #训练一次的过程中多少次能将训练数据取完
epochs = 100 #共训练100次
#定义训练过程
for epoch in range(epochs):
for step in range(steps):
#获取起始索引
start = step * batch_size
end = start + batch_size
#获取x,y数据
x = X[start: end]
y = Y[start: end]
#预测数据
y_pred = model(x)
#计算损失函数
loss = loss_fn(y_pred, y)
#梯度清零
opt.zero_grad()
#反向传播,即求导w,b
loss.backward()
#更新参数
opt.step()
print('epoch:', epoch, ' ', 'loss:', loss_fn(model(X), Y))
epoch: 99 loss: tensor(0.5977, grad_fn=<BinaryCrossEntropyBackward0>)
#设置概率阈值0.5来计算准确率
#分类预测的结果为概率
((model(X).data.numpy() > 0.5) == Y.data.numpy()).mean()
0.7619174611640777
((model(X).data.numpy() > 0.5) == Y.numpy()).mean()
0.7619174611640777