Обработка данных в этом блокноте проходит нормально, так же, как я делал то же самое в других блокнотах, и оценки в норме. Я внес изменения только в нескольких местах (обработка пропущенных значений и подгонка данных с помощью Torch), а сомнительные детали перечислю ниже.
Код: Выделить всё
for col in isna_cols:
train[col].fillna(train[col].mean(),inplace=True)
test[col].fillna(train[col].mean(),inplace=True)
Код: Выделить всё
pre=StandardScaler()
x_train=pre.fit_transform(x_train)
x_val=pre.transform(x_val)
x_test=pre.transform(x_test)
Код: Выделить всё
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import os
import warnings
warnings.filterwarnings("ignore")
dir="E:\Kaggle_data\Road_predict"
data_train=pd.read_csv(os.path.join(dir,"train.csv"))
data_test=pd.read_csv(os.path.join(dir,"test.csv"))
orig=[]
for s in ['2','10',"100"]:
orig.append(pd.read_csv(os.path.join(dir,f"synthetic_road_accidents_{s}k.csv")))
orig=pd.concat(orig,axis=0)
print("< train.shape >",data_train.shape)
display(data_train.head())
print("\n< test.shape >",data_test.shape)
display(data_test.head())
print("\n< orig.shape >",orig.shape)
display(orig.head())
data_test["accident_risk"]=0.5
orig["id"]=data_test.id.max()+1
orig=orig[data_train.columns]
print("< train.shape >",data_train.shape)
print("\n< test.shape >",data_test.shape)
print("\n< orig.shape >",orig.shape)
data=pd.concat([data_train,data_test,orig],axis=0,ignore_index=True)
print("< data.shape >",data.shape)
Features=orig.columns[1:-1].tolist()
Target="accident_risk"
import scipy
def f(X):
return \
0.3 * X["curvature"] + \
0.2 * (X["lighting"] == "night").astype(int) + \
0.1 * (X["weather"] != "clear").astype(int) + \
0.2 * (X["speed_limit"] >= 60).astype(int) + \
0.1 * (X["num_reported_accidents"] > 2).astype(int)
def clip(f):
def clip_f(X):
sigma = 0.05
mu = f(X)
a, b = -mu/sigma, (1-mu)/sigma
Phi_a, Phi_b = scipy.stats.norm.cdf(a), scipy.stats.norm.cdf(b)
phi_a, phi_b = scipy.stats.norm.pdf(a), scipy.stats.norm.pdf(b)
return mu*(Phi_b-Phi_a)+sigma*(phi_a-phi_b)+1-Phi_b
return clip_f
z = clip(f)(data)
data["y"] = z.values
Features.append("y")
cat_f,num_f,target=[],[],["accident_risk"]
for col in data.columns:
temp="CAT"
if data[col].dtype == "object":
cat_f.append(col)
else:
num_f.append(col)
temp="NUM"
nunique=data[col].nunique()
isna=data[col].isna().sum()
print(f"[{temp}] have {nunique:10} categories and have {isna:10} NA")
print("\nCAT Features",cat_f)
print("\nNUM Features",num_f)
train_size,test_size,orig_size=data_train.shape[0],data_test.shape[0],orig.shape[0]
train=data.iloc[:train_size]
test=data.iloc[train_size:train_size+test_size]
orig=data.iloc[-orig_size:]
print("< train.shape >",train.shape)
print("\n< test.shape >",test.shape)
print("\n< orig.shape >",orig.shape)
from sklearn.preprocessing import LabelEncoder
temp={}
for col in cat_f:
pre=LabelEncoder()
train[col]=pre.fit_transform(train[col])
test[col]=pre.transform(test[col])
orig[col]=pre.transform(orig[col])
temp[col]=data[col].unique()
TE=[]
for col in Features:
print(f"orig_{col}",end=" ")
temp=orig.groupby(col)[Target].mean()
temp.name=f"orig_{col}"
train=train.merge(temp,on=col,how="left")
test=test.merge(temp,on=col,how="left")
TE.append(f"orig_{col}")
Features.extend(TE)
isna_cols=["orig_y","orig_curvature"]
for col in isna_cols:
train[col].fillna(train[col].mean(),inplace=True)
test[col].fillna(train[col].mean(),inplace=True)
train.isna().sum().sum(),test.isna().sum().sum()
import torch
from torch import nn
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
x_train,x_val,y_train,y_val=train_test_split(train[Features],train["accident_risk"],test_size=0.2)
x_test=test[Features]
pre=StandardScaler()
x_train=pre.fit_transform(x_train)
x_val=pre.transform(x_val)
x_test=pre.transform(x_test)
x_train=torch.tensor(x_train,dtype=torch.float32)
x_val=torch.tensor(x_val,dtype=torch.float32)
x_test=torch.tensor(x_test,dtype=torch.float32)
y_train=torch.tensor(y_train.values,dtype=torch.float32)
y_val=torch.tensor(y_val.values,dtype=torch.float32)
# training
model=nn.Sequential(
nn.Linear(x_train.shape[1],32),
nn.ReLU(),
nn.Linear(32,64),
nn.ReLU(),
nn.Dropout(0.2),
nn.Linear(64,128),
nn.ReLU(),
nn.Dropout(0.4),
nn.Linear(128,32),
nn.ReLU(),
nn.Linear(32,1)
)
def init_weight(m):
if isinstance(m,nn.Linear):
nn.init.xavier_uniform_(m.weight)
nn.init.zeros_(m.bias)
model.apply(init_weight)
epochs=20
batch_size=128
from sklearn.metrics import root_mean_squared_error
def cal_loss(model,data_iter):
model.eval()
loss=0
num=0
with torch.no_grad():
for x,y in data_iter:
preds=model(x).detach()
loss+=criterion(preds,y).item()*len(x)
num+=len(x)
loss/=num
model.train()
return loss
from torch.utils.data import DataLoader,TensorDataset
optim=torch.optim.Adam(model.parameters(),lr=1e-3,weight_decay=1e-4)
criterion=nn.MSELoss()
schedule=torch.optim.lr_scheduler.ReduceLROnPlateau(optim,mode="min",factor=0.5,patience=3,threshold=1e-4,verbose=True)
train_iter=DataLoader(TensorDataset(x_train,y_train),batch_size=batch_size,shuffle=True)
val_iter=DataLoader(TensorDataset(x_val,y_val),batch_size=batch_size,shuffle=False)
test_iter=DataLoader(TensorDataset(x_test),batch_size=batch_size,shuffle=False)
# < training >
train_all_loss,val_all_loss=[],[]
for epoch in range(epochs):
print(f"< {epoch+1}/{epochs} > is training")
for x,y in train_iter:
optim.zero_grad()
temp=model(x)
loss=criterion(temp,y)
loss.backward()
optim.step()
train_loss=cal_loss(model,train_iter)
val_loss=cal_loss(model,val_iter)
train_all_loss.append(train_loss)
val_all_loss.append(val_loss)
schedule.step(val_loss)
print(f"train loss {train_loss}")
print(f"val loss {val_loss}")
< 1/20 > тренируется поезд loss0.02775017727133164 val
loss0.02776424903791882
< 2/20 > тренируется поезд loss0.02769827804194331 val
loss0.027714167244922257
< 3/20 > тренируется поезд loss0.027704472681621937 val
loss0.02772254535515173
< 4/20 > потеря тренировочного поезда0.027714180942946816 val
loss0.027732653668493566
< 5/20 > потеря тренировочного поезда0.027760836838309842 val
loss0.02778054339325232
< 6/20 > тренировочный поезд loss0.027765697200691598 val
loss0.027779511054893503
< 7/20 > тренировочный поезд loss0.027705941878791385 val
loss0.02772408291295153
< 8/20 > тренируется поезд loss0.027710020619716953 val
loss0.027725325872009314
< 9/20 > потеря тренировочного поезда0.027693071164615658 val
loss0.027710350072799844
< 10/20 > потеря тренировочного поезда0.027696465392543942 val
loss0.027712482124348445
< 11/20 > тренирует поезд loss0.027693810345137106 val
loss0.02771117624995427
......
Подробнее здесь: https://stackoverflow.com/questions/798 ... code-logic