2022李宏毅作业hw1—新冠阳性⼈员数量预测。
事前:
kaggle地址:
当然作为新⼿,我也是参考的其他⼤神的。参考的过多,我就不⼀⼀放地址了,在这⾥谢过各位⼤佬。如果和我⼀样的新⼿,调试代码看张量流动绝对是⼀个好⽤的⽅法。
作业介绍: 说的是啊 这个美国,好像是有40个州, 这四⼗个州呢 ,统计了连续三天的新冠阳性⼈数,和每天的⼀些社会特征,⽐如带⼝罩情况, 居家办公情况等等。现在有⼀群⼈⽐较坏,把第三天的数据遮住了,我们就要⽤前两天的情况以及第三天的特征,来预测第三天的阳性⼈数。但幸好的是,我们还是有⼀些数据可以作为参考的,就是我们的训练集。
⼀:数据读取。
(第⼀步引⽤的包:)
import numpy as np
from torch.utils.data import Datat,DataLoader
import csv
import torch
from sklearn.feature_lection import SelectKBest
from sklearn.feature_lection import chi2
先从kaggle上把数据下下来看看。点那个data就找到下载的地⽅了。下载好数据第⼀步先观察train的数据是什么样⼦的。如下图,可以看到有很多列,每⼀列都是⼀类特征,每⼀⾏都是⼀个样本。黄红蓝是第1,2,3天的测试阳性数据。蓝⾊的就是我们要预测的值啦。
我们再细看数据: 可以看到第⼀⾏是没有⽤的,他只是标签的名称。然后第⼀列也是没有⽤处的,因为他只是标注样本是第⼏个样本。等会处理数据时都要处理掉。 然后我们可以注意到前40列的数据和后⾯五⼗多列是不⼀样的,⼀般是⼀列全1 其他列全0 ,表⽰的是1所在的那个州,地点标识⽽已。
看清楚数据的结构,下⾯我们开始读⼊数据。csv数据和其他数据的读法差不多。⽐如你可以选择下⾯的⽂件式读法。
with open(ain.csv', 'r') as f:
train_data = f.readlines()
train_data = [line.split('\n') for line in train_data][1:] #分⾏之后不要第⼀⾏
train_data = [each[0].split(',') for each in train_data] #对于每⼀⾏去掉后⾯的空格
print(len(train_data[0]))
train_data = np.array(train_data) #转换成numpy的矩阵
train_x = train_data[:,1:-1] # x是数据,y是标签。第⼀个冒号表⽰所有⾏,第⼆个冒号表⽰
train_y = train_data[:,-1] #列。所以x就是第2列到倒数第⼆列。y就是倒数第⼀列。
也可以选择csv的专门读取excel表格的函数
气血不足怎样食补
with open(path,'r') as f:
csv_data = ader(f))
column = csv_data[0] #0⾏是标题
csv_data = np.array(csv_data[1:])[:,1:].astype(float) #连环操作先取⾏转numpy
#再取列转float
然后这⾥要介绍⼀个取最相关列的操作。 上⾯的数据我们知道有95列,可是,这90多列,每⼀列都与结果是相关的吗? 恐怕不⼀定,肯定有些特征卵⽤没有。所以我们这⾥可以找到那些相关的列,⽤这些特征来预测结果。找特征有很多⽅法,⼤家可以百度特征选择,有很多介绍。这⾥⽤的是SelectKBest 函数。顺便定义了⼀个挑特征的函数。column是第⼀⾏的特征名称,我传⼊是为了打印看看是哪些特征重要,要不然他挑了半天我也不知道啊 。k是挑多少个特征。
def get_feature_importance(feature_data, label_data, k =4,column = None):
"""
此处省略 feature_data, label_data 的⽣成代码。
如果是 CSV ⽂件,可通过 read_csv() 函数获得特征和标签。
"""
model = SelectKBest(chi2, k=k)#选择k个最佳特征
X_new = model.fit_transform(feature_data, label_data)
#feature_data是特征数据,label_data是标签数据,该函数可以选择出k个特征
print('x_new', X_new)
scores = model.scores_
# 按重要性排序,选出最重要的 k 个
indices = np.argsort(scores)[::-1] #找到重要K个的下标
if column:
k_best_features = [column[i+1] for i in indices[0:k].tolist()]
print('k best features are: ',k_best_features)
return X_new, indices[0:k]
找好特征后。我们还需要进⾏训练集和验证集的划分。 我们知道,kaggle下下来只有训练集和测试集,所以我们需要从训练集⾥分出来⼀个验证集来作为模型评价。 ⽅法可以是直接截⼀段,也可以是逢⼏个挑⼀个,也可以是随机的。我这⾥是逢5挑1
if mode == 'train':
indices = [i for i in range(len(csv_data)) if i % 5 != 0]
lf.y = torch.LongTensor(csv_data[indices,-1])
elif mode == 'val':
indices = [i for i in range(len(csv_data)) if i % 5 == 0]
# data = sor(csv_data[indices,col_indices])
lf.y = torch.LongTensor(csv_data[indices,-1])
el:
indices = [i for i in range(len(csv_data))]
#这是测试数据不需要标签也没有标签
取完数据后,⼀般还要有⼀个归⼀化的步骤,防⽌各个特征的数量级相差过于⼤。这⾥⽤的是Z-score标准化⽅法。减均值除以标准差
lf.data = (lf.data - an(dim=0,keepdim=True))
/lf.data.std(dim=0,keepdim=True) #这⾥将数据归⼀化。
综上所述,我们可以写出我们的datat函数了。基本上⼤部分神经⽹络都是需要读数据这部分的,过程就是把数据从本地⽂件,读⼊datat中去。datat中⼀般有三个函数,第⼀个是初始化__init__:
⼀般负责把数据从⽂件取出来。第⼆个获取数据__getitem__, 负责读第⼏个数据。第三个获取长度__len__: 负责返回数据集的长度。
⼀个完整的从csv到可以⽤的datat的 代码如下图所⽰。 这⼀部分被我放在model——utils的data模块⾥。
完整代码:
import numpy as np
from torch.utils.data import Datat,DataLoader
import csv
import torch
from sklearn.feature_lection import SelectKBest
from sklearn.feature_lection import chi2
def get_feature_importance(feature_data, label_data, k =4,column = None):
"""
此处省略 feature_data, label_data 的⽣成代码。
如果是 CSV ⽂件,可通过 read_csv() 函数获得特征和标签。
"""
model = SelectKBest(chi2, k=k)#选择k个最佳特征
X_new = model.fit_transform(feature_data, label_data)
#feature_data是特征数据,label_data是标签数据,该函数可以选择出k个特征
print('x_new', X_new)
scores = model.scores_
# 按重要性排序,选出最重要的 k 个
indices = np.argsort(scores)[::-1] #找到重要K个的下标
if column:
k_best_features = [column[i+1] for i in indices[0:k].tolist()]
print('k best features are: ',k_best_features)
过海关流程return X_new, indices[0:k]
class covidDatat(Datat):
def __init__(lf, path, mode, feature_dim):
with open(path,'r') as f:
csv_data = ader(f))亚瑟连招
column = csv_data[0]
train_x = np.array(csv_data)[1:][:,1:-1]
train_y = np.array(csv_data)[1:][:,-1]
_,col_indices = get_feature_importance(train_x,train_y,feature_dim,column)
col_indices = list() #得到重要列的下标
csv_data = np.array(csv_data[1:])[:,1:].astype(float)
if mode == 'train': #如果读的是训练数据就逢5取4 indices是数据下标
indices = [i for i in range(len(csv_data)) if i % 5 != 0]
lf.y = torch.LongTensor(csv_data[indices,-1])
elif mode == 'val': #如果读的是验证数据就逢5取1 indices是数据下标
indices = [i for i in range(len(csv_data)) if i % 5 == 0]
# data = sor(csv_data[indices,col_indices])
lf.y = torch.LongTensor(csv_data[indices,-1])
el: #如果读的是测试数据就全取了
indices = [i for i in range(len(csv_data))]
data = sor(csv_data[indices,:]) #取⾏
lf.data = data[:,col_indices] #取列
lf.data = (lf.data - an(dim=0,keepdim=True)) /lf.data.std(dim=0,keepdim=True) #这⾥将数据归⼀化。 asrt feature_dim == lf.data.shape[1]
print('Finished reading the {} t of COVID19 Datat ({} samples found, each dim = {})'
.format(mode, len(lf.data), feature_dim))
def __getitem__(lf, item):寺内正毅
de == 'test':
return lf.data[item].float()
el :
return lf.data[item].float(), lf.y[item]
疫情早点结束def __len__(lf):
彩纸手工灯笼return len(lf.data)
⼆模型设计。
数据都读完了,接下来肯定是模型了 。当然这⾥是⼀个简单的回归模型我⽤两个全连接实现的,中间加了⼀个relu。inDim是传⼊的参数 ,就是上⾯我们挑选的重要特征的数量啦。这部分⽐较简单,⼀般模型都是包括这两个部分 __init__和forward 也就是初始化和前向传播。初始化中会定义前向传播⾥需要的模型模块。前向传播⾥就是输⼊到输出的流动了 。x是输⼊的张量,最后输出模型计算结果。 模型也⾮常简单。
注意⽹络⼀般都是按batch⼤⼩计算的。我举个例⼦。 假如我挑了4个特征,那么模型输⼊长度就是4,输出长度就是1(回归值) 。假如我16个数据1批次, 输⼊⼤⼩就是(16,4) 输出就是(16,1) 这都是⾃动的 不⽤我们担⼼。这⼀部分被我放在model_utils的model模块⾥。
完整代码:
as nn
class myNet(nn.Module):阿里巴巴创始人
def __init__(lf,inDim):
super(myNet,lf).__init__()
lf.fc1 = nn.Linear(inDim, 64)
入团志愿书1000字lf.fc2 = nn.Linear(64,1)
def forward(lf, x):
x = lf.fc1(x)
x = lf.relu(x)
x = lf.fc2(x)
if len(x.size()) > 1:
return x.squeeze(1) #如果批量⼤⼩不为1 这⾥才需要展平。
el:
return x
三训练步骤。
训练函数推荐⼤家⾃⼰定义⼀个的,这样以后⾯对⼤部分问题都可以通⽤。
这个是训练的过程 都是很常规的步骤。