我正在尝试训练一个模型,以根据航空公司,每月的日期,目的地和出发地来预测出发延迟。我尝试了几种方法,但是准确性很低。 enter image description here 首先,我使用的延迟标签范围从-20到+20分钟不等,我尝试通过设置时间间隔来简化此操作,因此: 延迟[0 5 [=> 0 [5 10] => 1 ..etc
但是准确性仍然很差,我尝试了几种方法;
更改图层
不规范功能
删除和添加新功能
但是我仍然找不到有效的东西
###################加载数据集iCloud Documents
################掩码延迟值
df= dataset[['UniqueCarrier','DayofMonth','DepDelay','Dest','Origin']]
df.tail()
df = df.dropna()
df = df[(df['DepDelay'] <= 20) & (df['DepDelay'] <= 20)]
###############分割标签和特征
ask = (df.DepDelay > 0) & (df.DepDelay < 5)
column_name = 'DepDelay'
df.loc[mask, column_name] = 0
mask = (df.DepDelay >= 5) & (df.DepDelay < 10)
column_name = 'DepDelay'
df.loc[mask, column_name] = 1
mask = (df.DepDelay >= 10) & (df.DepDelay < 15)
column_name = 'DepDelay'
df.loc[mask, column_name] = 2
mask = (df.DepDelay >= 15) & (df.DepDelay <= 20)
column_name = 'DepDelay'
df.loc[mask, column_name] = 3
mask = (df.DepDelay >= -5) & (df.DepDelay < 0)
column_name = 'DepDelay'
df.loc[mask, column_name] = -1
mask = (df.DepDelay >= -10) & (df.DepDelay < -5)
column_name = 'DepDelay'
df.loc[mask, column_name] = -2
mask = (df.DepDelay >= -15) & (df.DepDelay < -10)
column_name = 'DepDelay'
df.loc[mask, column_name] = -3
mask = (df.DepDelay >= -20) & (df.DepDelay < -15)
column_name = 'DepDelay'
df.loc[mask, column_name] = -4
################替换字符值
y= df['DepDelay']
df.drop(columns = ['DepDelay'], inplace = True, axis = 1)
##########################规范化
from sklearn import preprocessing
le = preprocessing.LabelEncoder()
df['Dest'] = le.fit_transform(df.Dest.values)
df['Origin'] = le.fit_transform(df.Origin.values)
df['UniqueCarrier'] = le.fit_transform(df.UniqueCarrier.values
########################## 该模型
from sklearn.preprocessing import StandardScaler
from sklearn import preprocessing
# Normalize Training Data
std_scale = preprocessing.StandardScaler().fit(df)
df_norm = std_scale.transform(df)
training_norm_col1 = pd.DataFrame(df_norm, index=df.index,
columns=df.columns)
df.update(training_norm_col1)
print (df.head())
准确度约为:0.3524。 用于转换的数据帧大约有3M行
答案 0 :(得分:1)
在单节点最终层中使用loss = 'mean_squared_error'
且没有激活时(即默认的线性线性),如此处所示,您处于回归设置,其中(仅在分类问题中有意义)。
不幸的是,尽管事实证明Keras对您的问题毫无意义且不合适,但Keras不会在这种情况下“保护”您,而是坚持计算并向您报告“准确性”-请参阅What function defines accuracy in Keras when the loss is mean squared error (MSE)?中我的回答
如果您希望坚持使用回归设置,则只需从模型编译中删除metrics=['accuracy']
,而不必理会-在回归设置中,MSE本身也可以(并且通常确实)充当性能指标指标。但这意味着您将尝试直接预测数字值,而不是像您描述的那样预测来自合并的“标签”。
如果您要预测合并间隔,例如
[0 5] => 0
[5 10] => 1
等,即在分类设置中工作,您应该将损失更改为categorical_cross_entropy
,并保持准确性作为指标。请记住,您还应该将标签转换为一次热编码的标签(请参阅Keras to_categorical
),并用
model.add(Dense(num_classes, activation='softmax'))
其中num_classes
是分箱过程产生的类数。
答案 1 :(得分:0)
查看数据集,您确实遇到了分类和回归问题。您可能可以使用Keras进行建模,但是如果您的案例是回归的,那么分类将变得毫无意义。另一方面,我的建议是尝试使用决策树。
答案 2 :(得分:0)
根据我的经验(例如年龄估算),以合并损失(即回归+分类)训练网络永远会更好。
我认为您已经找到了解决问题的方法,即将目标输出量化为预定义的bin。结果,您的分类输出将预测样本属于分类的概率。
在不失一般性的前提下,假设您有N
个bin,第k
个bin的中心值为c[k]
。现在的问题是,您如何推断,即给定一个测试样本,如何估算确切航班延误。换句话说,除非您对bin估计感到满意,否则无论如何在测试期间都需要将分类问题转换回回归问题。
一种估算飞行延误(fd
)的简单方法是对您的bin分类结果进行加权平均,即
fd = np.sum(proba * centers)
其中proba
是来自clf.predict(sample)
的垃圾箱概率,而centers
是垃圾箱的中心值,即centers=[c[k] for k in range(N)]
。
当然,您可以在推理期间使用其他方式,但我们仅以此方式为例。现在的问题是如何将该推理功能集成到损失功能?
我希望您已经有了答案,这只是为了计算从使用上述公式得出的fd
与从地面真实情况得出的损失。
假设您有一个执行分类任务的keras model
,下面是使用回归损失对其进行训练的示例
from keras import backend as K
centers = K.variable(value=np.array([...]),dtype='float32') # shape of 1xN, fill in your center values
def regLoss(y_true, y_pred) :
# Note:
# a. your y_true will be the actual delay time, not bin membership
# b. y_pred is still the same as that for the classification task, i.e. the bin membership
# 1. convert your y_pred to flight delay
y_pred = K.sum( centers * y_pred, axis=-1)
# 2. compute loss between flight delay numbers
return keras.losses.mae(y_true, y_pred)
现在,您可以使用新的回归损失训练相同的模型。
正如我之前提到的,最好同时处理回归和分类损失。因为将它们一起使用将有助于您更好地优化网络。为什么?
因为只使用分类损失,所以给定
gt=[1,0,0,0,0,0]
p1=[0,1,0,0,0,0]
p2=[0,0,0,0,0,1]
您将拥有L(gt,p1) = L(gt,p2)
。但是,当您考虑自己的问题时,我们真正想要的是L(gt,p1) < L(gt,p2)
,而在介绍了回归损失之后,将覆盖这一部分。
同时,仅使用回归损失的问题是您真的不知道预测目标值的要素的物理含义是什么,但是您知道其中一个是否满足离群值,你搞砸了你的预测。对于分类损失,您知道用于回归的直接特征是bin成员身份。