手把手教会神经网络做数据分析(基于torch的分类问题)

作者简介:热编程的贝贝,致力于C/C++、Java、Python等多编程语言,热爱跑步健身,喜爱音乐的一位博主。
本文收录于贝贝的日常汇报系列,大家有兴趣的可以看一看
相关专栏深度学习、目标检测系列等,大家有兴趣的可以看一看
C++零基础入门系列,Web入门篇系列正在发展中,喜欢Python、C++的朋友们可以关注一下哦!
如有需要此项目工程,请评论区留言哦 

       文章目录

前言

一、数据集描述

二、实现思路

三、代码实现

四、完整代码

总结


前言

随着信息时代的来临,数据的产生和积累呈指数级增长。在这个海量数据的背景下,如何从数据中获取有价值的信息和洞见成为了各行各业的重要课题。数据分析作为一种关键的信息处理手段,在理解数据、发现规律、做出决策方面发挥着不可替代的作用。

神经网络作为一种人工智能的重要组成部分,由其在数据分析领域的成功应用引起了广泛的关注。神经网络模仿人类大脑的神经元网络结构,通过学习数据中的模式和特征,从而实现自主学习和预测能力。它能够处理非常复杂的数据关系,解决传统算法难以解决的问题,因此在数据分析领域表现出了强大的优势。

本文将探讨神经网络在数据分析中的应用。此文章中主要讨论数据分析中的分类的应用通过这些实际案例,我们将展示神经网络在数据分析中的潜力和优势。

完整代码见最后一个标题

一、数据集描述

 此数据集有109列,前108列均为特征,最后一列是标签,一共6各类别。训练集一共一万条数据,数据中有部分缺失值。

import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.impute import SimpleImputer

# 加载你的数据,这里假设数据以csv格式存储
# 请将"your_data.csv"替换为你的数据文件名
df = pd.read_csv("./训练集/train_10000.csv") 
df

手把手教会神经网络做数据分析(基于torch的分类问题)_第1张图片

二、实现思路

手把手教会神经网络做数据分析(基于torch的分类问题)_第2张图片

本文首先读取训练集和验证集,因为数据集中有大量的缺失值,进行中值填充会会对训练的数据造成干扰,使得准确率降低,实验中在查看各个特征的KDE图之后,

分析出以下特征会对模型最终识别精度造成负面影响,其中包括'feature0', 'feature8', 'feature11', 'feature17','feature18','feature24','feature26','feature28','feature40','feature43','feature50','feature57','feature62','feature63','feature69','feature70','feature73','feature74','feature77','feature90','feature93','feature98','feature99', 'feature100',  'feature103', 'feature104', 'feature106',

在删除上述特征之后,再对缺失值进行中位数填充,对数据进行标准化之后,搭建神经网络对数据进行训练后,准确度可以达到0.78

三、代码实现

        首先,读取数据集后,分出特征和标签,X为特征(除了最后一列的所有列),y为标签(最后一列)

# 导入需要的库
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.impute import SimpleImputer

# 加载你的数据,这里假设数据以csv格式存储
# 请将"your_data.csv"替换为你的数据文件名
df = pd.read_csv("./训练集/train_10000.csv") 

# 假设最后一列为标签,将其分离
X = df.iloc[:, 1:-1]  # 特征数据,取所有行,除了最后一列之外的所有列
y = df.iloc[:, -1]   # 标签数据,取所有行的最后一列
# 复制原始数据
df_filled = X.copy()

        接下来对数据的缺失值进行处理,此处使用中位数对Nan进行填充

# # 对每个特征,将NaN填充为中位数
for col in df_filled.columns:
    df_filled[col] = X[col].fillna(X[col].median())
df_filled= df_filled.dropna(axis=1)

        对数据进行归一化,并丢弃异常值

df_normalized = (df_filled - df_filled.min()) / (df_filled.max() - df_filled.min())
df_normalized = df_normalized.dropna(axis=1)

        删除冗余、表现效果差的特征列

drop=[0,8,11,17,18,24,26,28,40,43,50,62,63,69,70,73,74,90,93,98,99,103,104,106]
drop_list=[]
for i in drop:
    name='feature'+str(i)
    drop_list.append(name)
# columns_to_remove = ['column1', 'column2', 'column3']
df_normalized = df_normalized.drop(columns=drop_list)

        将X和y转化为列表格式

X=[]
Y=[]
for i in range(len(df)):
    X.append(df_normalized.iloc[i,:].values)
    Y.append(y.iloc[i])

        导入神经网络工具包

import torch
import torch.nn as nn
from torch.autograd import Variable
import torch.utils.data as Data
import torch.nn.functional as F
import torch.optim as optim
from torch.utils.data import Dataset
from torch.utils.data import DataLoader

        构建数据集,重写dataset

X=torch.tensor(X,dtype=torch.float32)
Y=torch.tensor(Y,dtype=torch.int64)
X_val=torch.tensor(X_val,dtype=torch.float32)
Y_val=torch.tensor(Y_val,dtype=torch.int64)

class MyTrainDataset(Dataset):
    def __init__(self,data,label):
        self.data=data
        self.label=label
    def __len__(self):
        return len(self.label)
    
    def __getitem__(self, index):
        input=self.data[index]
        label=self.label[index]
        return input,label

dataset_train=MyTrainDataset(X,Y)
dataset_val=MyTrainDataset(X_val,Y_val)
dataset_train[0][0].size()
trainLoader=torch.utils.data.DataLoader(dataset=dataset_train,batch_size=8)
valLoader=torch.utils.data.DataLoader(dataset=dataset_val,batch_size=8)

        构建神经网络模型,此处没有用什么特殊的神经网络,只用较为简单的全连接神经网络,为了保证其收敛,数据集规模和参数量规模应基本一致,经调整后,为以下模型

        并设置损失函数,有乎其,学习策略

input_size=80
hidden_size=40
hidden_size2=256
output_size=6

model=torch.nn.Sequential(
    nn.Linear(input_size,hidden_size),
    nn.Sigmoid(),
    nn.Linear(hidden_size,output_size),
  
    # nn.Sigmoid(),
    # nn.Linear(hidden_size2,output_size),
)
model=model.cuda()
cost=nn.CrossEntropyLoss()
#lr=0.01
# 设定优化器
#optimizer = torch.optim.SGD(model.parameters(), momentum=0.9, weight_decay=0.0001, lr=lr)
# 以optimizer中设定的lr为基础,每隔10步,learning rate乘上0.3
optimizer=optim.Adam(model.parameters(),lr=0.001)
scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=100, gamma=0.3) 

       最终进行训练和验证

from tqdm import tqdm
import numpy as np

best_acc=0
for i in range(200):
    model.train()
    losses=[]
    correct=0
    scheduler.step()
    for data in tqdm(trainLoader):
        input,label=data
        input=input.cuda()
        label=label.cuda()
        optimizer.zero_grad()
        pred=model(input)
        #print(pred.size())
        
        loss=cost(pred,label)
        
        loss.backward(retain_graph=True)
        optimizer.step()
        losses.append(loss.item())

        max_value,max_index=torch.max(pred,1)
        pred_label=max_index.cpu().numpy()
        true_label=label.cpu().numpy()
        # print(pred_label,true_label)
        correct+=np.sum(pred_label==true_label)
        # print(correct)
    print("第{}此迭代".format(i))
    print("train:   loss:{},acc:{},learning_rate:{}".format(sum(losses)/len(losses),correct/len(dataset_train),scheduler.get_lr()[0]))

    val_losses=[]
    val_correct=0
    model.eval()
    for data in tqdm(valLoader):
        input,label=data
        input=input.cuda()
        label=label.cuda()
        pred=model(input)
        
        loss=cost(pred,label)
        #optimizer.zero_grad()
        #loss.backward(retain_graph=True)
        #optimizer.step()
        val_losses.append(loss.item())

        max_value,max_index=torch.max(pred,1)
        pred_label=max_index.cpu().numpy()
        true_label=label.cpu().numpy()
        val_correct+=np.sum(pred_label==true_label)
        # print(pred_label,true_label)
        # print(val_correct)
    #print("第{}此迭代".format(i))
    if(val_correct/len(dataset_val)>best_acc):
        best_acc=val_correct/len(dataset_val)
        torch.save(model,"./best_model_acc{}.pt".format(best_acc))
    print("val:    loss:{},acc:{}".format(sum(val_losses)/len(val_losses),val_correct/len(dataset_val)))

四、完整代码

# 导入需要的库
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.impute import SimpleImputer

# 加载你的数据,这里假设数据以csv格式存储
# 请将"your_data.csv"替换为你的数据文件名
df = pd.read_csv("./训练集/train_10000.csv") 

# 假设最后一列为标签,将其分离
X = df.iloc[:, 1:-1]  # 特征数据,取所有行,除了最后一列之外的所有列
y = df.iloc[:, -1]   # 标签数据,取所有行的最后一列
# 复制原始数据
df_filled = X.copy()

# # 对每个特征,将NaN填充为中位数
for col in df_filled.columns:
    df_filled[col] = X[col].fillna(X[col].median())
df_filled= df_filled.dropna(axis=1)


df_normalized = (df_filled - df_filled.min()) / (df_filled.max() - df_filled.min())
df_normalized = df_normalized.dropna(axis=1)
df_normalized.columns
drop=[0,8,11,17,18,24,26,28,40,43,50,62,63,69,70,73,74,90,93,98,99,103,104,106]
drop_list=[]
for i in drop:
    name='feature'+str(i)
    drop_list.append(name)
# columns_to_remove = ['column1', 'column2', 'column3']
df_normalized = df_normalized.drop(columns=drop_list)


X=[]
Y=[]
for i in range(len(df)):
    X.append(df_normalized.iloc[i,:].values)
    Y.append(y.iloc[i])


import pandas as pd
from sklearn.metrics import f1_score, classification_report
from sklearn.preprocessing import StandardScaler
import pickle

# 读取数据
data = pd.read_csv(r'./验证集/validate_1000.csv')


# 假设最后一列为标签,将其分离
X_valid = data.iloc[:, 1:-1]  # 特征数据,取所有行,除了最后一列之外的所有列
y_valid = data.iloc[:, -1]   # 标签数据,取所有行的最后一列


# 复制原始数据
X_valid_filled = X_valid.copy()

# # 对每个特征,将NaN填充为中位数
for col in X_valid.columns:
    X_valid_filled[col] = X_valid[col].fillna(X_valid[col].median())
X_valid_filled= X_valid_filled.dropna(axis=1)
#对数据进行归一化
# X_valid_normalized = sc.transform(X_valid_filled)

X_valid_normalized = (X_valid_filled - df_filled.min()) / (df_filled.max() - df_filled.min())
#X_valid_normalized = (X_valid_filled - X_valid_filled.min()) / (X_valid_filled.max() - X_valid_filled.min())
# X_valid_normalized = X_valid_normalized.fillna(X_valid_normalized.median())
X_valid_normalized = X_valid_normalized.dropna(axis=1)
#print(X_valid_normalized)
X_valid_normalized = X_valid_normalized.drop(columns=drop_list)

X_val=[]
Y_val=[]
for i in range(len(X_valid_normalized)):
    X_val.append(X_valid_normalized.iloc[i,:].values)
    Y_val.append(y_valid[i])




import torch
import torch.nn as nn
from torch.autograd import Variable
import torch.utils.data as Data
import torch.nn.functional as F
import torch.optim as optim
from torch.utils.data import Dataset
from torch.utils.data import DataLoader

X=torch.tensor(X,dtype=torch.float32)
Y=torch.tensor(Y,dtype=torch.int64)
X_val=torch.tensor(X_val,dtype=torch.float32)
Y_val=torch.tensor(Y_val,dtype=torch.int64)

class MyTrainDataset(Dataset):
    def __init__(self,data,label):
        self.data=data
        self.label=label
    def __len__(self):
        return len(self.label)
    
    def __getitem__(self, index):
        input=self.data[index]
        label=self.label[index]
        return input,label

dataset_train=MyTrainDataset(X,Y)
dataset_val=MyTrainDataset(X_val,Y_val)
dataset_train[0][0].size()
trainLoader=torch.utils.data.DataLoader(dataset=dataset_train,batch_size=8)
valLoader=torch.utils.data.DataLoader(dataset=dataset_val,batch_size=8)
input_size=80
hidden_size=40
hidden_size2=256
output_size=6

model=torch.nn.Sequential(
    nn.Linear(input_size,hidden_size),
    nn.Sigmoid(),
    nn.Linear(hidden_size,output_size),
  
    # nn.Sigmoid(),
    # nn.Linear(hidden_size2,output_size),
)
model=model.cuda()
cost=nn.CrossEntropyLoss()
#lr=0.01
# 设定优化器
#optimizer = torch.optim.SGD(model.parameters(), momentum=0.9, weight_decay=0.0001, lr=lr)
# 以optimizer中设定的lr为基础,每隔10步,learning rate乘上0.3
optimizer=optim.Adam(model.parameters(),lr=0.001)
scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=100, gamma=0.3) 

from tqdm import tqdm
import numpy as np

best_acc=0
for i in range(200):
    model.train()
    losses=[]
    correct=0
    scheduler.step()
    for data in tqdm(trainLoader):
        input,label=data
        input=input.cuda()
        label=label.cuda()
        optimizer.zero_grad()
        pred=model(input)
        #print(pred.size())
        
        loss=cost(pred,label)
        
        loss.backward(retain_graph=True)
        optimizer.step()
        losses.append(loss.item())

        max_value,max_index=torch.max(pred,1)
        pred_label=max_index.cpu().numpy()
        true_label=label.cpu().numpy()
        # print(pred_label,true_label)
        correct+=np.sum(pred_label==true_label)
        # print(correct)
    print("第{}此迭代".format(i))
    print("train:   loss:{},acc:{},learning_rate:{}".format(sum(losses)/len(losses),correct/len(dataset_train),scheduler.get_lr()[0]))

    val_losses=[]
    val_correct=0
    model.eval()
    for data in tqdm(valLoader):
        input,label=data
        input=input.cuda()
        label=label.cuda()
        pred=model(input)
        
        loss=cost(pred,label)
        #optimizer.zero_grad()
        #loss.backward(retain_graph=True)
        #optimizer.step()
        val_losses.append(loss.item())

        max_value,max_index=torch.max(pred,1)
        pred_label=max_index.cpu().numpy()
        true_label=label.cpu().numpy()
        val_correct+=np.sum(pred_label==true_label)
        # print(pred_label,true_label)
        # print(val_correct)
    #print("第{}此迭代".format(i))
    if(val_correct/len(dataset_val)>best_acc):
        best_acc=val_correct/len(dataset_val)
        torch.save(model,"./best_model_acc{}.pt".format(best_acc))
    print("val:    loss:{},acc:{}".format(sum(val_losses)/len(val_losses),val_correct/len(dataset_val)))


总结

本文对神经网络进行数据分析的分类问题,进行了阐述、代码解释和处理流程,本教程作为读者的入门教程,更多的问题均可参考此模板迅速完成建模。

如果这份博客对大家有帮助,希望各位给恒川一个免费的点赞作为鼓励,并评论收藏一下⭐,谢谢大家!!!
制作不易,如果大家有什么疑问或给恒川的意见,欢迎评论区留言。

你可能感兴趣的:(深度学习,神经网络,数据分析,分类)