如何处理包含离散和连续数据的数据集

Posted

技术标签:

【中文标题】如何处理包含离散和连续数据的数据集【英文标题】:How to deal with dataset that contains both discrete and continuous data 【发布时间】:2020-11-21 08:06:14 【问题描述】:

我正在训练一个模型,该模型包含 8 个特征,可以让我们预测房间被售出的概率。


Region:房间所属的区域(整数,取值在1到10之间)

Date:入住日期(1-365之间的整数,这里我们只考虑一天 请求)

Weekday:星期几(1-7 之间的整数)

Apartment:房间是整个公寓 (1) 还是只是一个房间 (0)

#beds:房间的床位数(1-4之间的整数)

评论:卖家的平均评论(1到5之间的连续变量)

图片质量:房间图片的质量(0到1之间的连续变量)

价格:房间的历史公布价格(连续变量)

Accept:这个帖子最终被接受(有人接受,1)还是不被接受(0)


列接受是“y”。因此,这是一个二元分类。

我们已经绘制了数据,并且一些数据存在偏差,因此我们应用了幂变换。 我们尝试了神经网络、ExtraTrees、XGBoost、梯度提升、随机森林。他们都给出了大约 0.77 AUC。然而,当我们在测试集上尝试它们时,AUC 下降到 0.55,精度为 27%。

我不确定什么时候出错了,但我的想法是原因可能是由于离散数据和连续数据的混合。尤其是其中一些是 0 或 1。 有人可以帮忙吗?

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.metrics import roc_auc_score
from sklearn.neural_network import MLPClassifier
from sklearn.preprocessing import MinMaxScaler
from sklearn.preprocessing import OneHotEncoder
import warnings
warnings.filterwarnings('ignore')

df_train = pd.read_csv('case2_training.csv')

X, y = df_train.iloc[:, 1:-1], df_train.iloc[:, -1]
y = y.astype(np.float32)


X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=123)

from sklearn.preprocessing import PowerTransformer

pt = PowerTransformer()

transform_list = ['Pic Quality', 'Review', 'Price']
X_train[transform_list] = pt.fit_transform(X_train[transform_list])
X_test[transform_list] = pt.transform(X_test[transform_list])

for i in transform_list:
    df = X_train[i]
    ax = df.plot.hist()
    ax.set_title(i)
    plt.show()
    
# Normalization
sc = MinMaxScaler()
X_train = sc.fit_transform(X_train)
X_test = sc.transform(X_test)

X_train = X_train.astype(np.float32)
X_test = X_test.astype(np.float32)


from sklearn.ensemble import RandomForestClassifier

clf =  RandomForestClassifier(random_state=123, n_estimators=50)
clf.fit(X_train,y_train)
yhat = clf.predict_proba(X_test)

# AUC metric
train_accuracy = roc_auc_score(y_test, yhat[:,-1])
print("AUC",train_accuracy)

from sklearn.ensemble import GradientBoostingClassifier

clf =  GradientBoostingClassifier(random_state=123, n_estimators=50)
clf.fit(X_train,y_train)
yhat = clf.predict_proba(X_test)

# AUC metric
train_accuracy = roc_auc_score(y_test, yhat[:,-1])
print("AUC",train_accuracy)


from torch import nn
from skorch import NeuralNetBinaryClassifier
import torch

model = nn.Sequential(
          nn.Linear(8,64),
          nn.BatchNorm1d(64),
          nn.GELU(),
          nn.Linear(64,32),
          nn.BatchNorm1d(32),
          nn.GELU(),
          nn.Linear(32,16),
          nn.BatchNorm1d(16),
          nn.GELU(),
          nn.Linear(16,1),
#           nn.Sigmoid()
        )
net = NeuralNetBinaryClassifier(
    model,
    max_epochs=100,
    lr=0.1,
    # Shuffle training data on each epoch
    optimizer=torch.optim.Adam,
    iterator_train__shuffle=True,
)
net.fit(X_train, y_train)
 

from xgboost.sklearn import XGBClassifier

clf = XGBClassifier(silent=0, 
                    learning_rate=0.01,  
                    min_child_weight=1,
                    max_depth=6,
                    objective='binary:logistic',
                    n_estimators=500,
                    seed=1000)

clf.fit(X_train,y_train)
yhat = clf.predict_proba(X_test)

# AUC metric
train_accuracy = roc_auc_score(y_test, yhat[:,-1])
print("AUC",train_accuracy)

这是数据截图的附件。 Sample data

【问题讨论】:

可能最好执行分层交叉验证,并检查 AUC 分数。从您对测试数据的 AUC 分数来看,您的模型似乎过度拟合。同样对于神经网络,您应该执行one-hot-encoding 而不是LabelEncoding,因为 NN 需要对数据进行标准化您还应该尝试对 one-hot-encoded 特征进行逻辑回归。请注意:对于所有线性分类器,归一化特征很重要。 【参考方案1】:

这是数据分析的基本第一步。你需要在这里做两件事:

数据理解 - 当前格式的数据字段是否有意义(数据类型、值范围等) 数据准备 - 在将这些数据字段传递给我们的模型之前,我应该如何更新它们?此外,您认为哪些输入对您的模型有用,哪些输入几乎没有什么好处?是否有我需要考虑/处理的异常值?

如果您是数据分析领域的入门者,一本好书是 Fundamentals of Machine Learning for Predictive Data Analytics (我与这本书无关)。

查看您的数据集,您可以尝试以下几件事来了解它如何影响您的预测结果:

除非区域顺序实际上是按重要性/价值排列的,否则我会将其更改为一个热编码特征,您可以在sklearn 中执行此操作。否则,您的模型可能会认为数字较大的区域(例如 10)比值较小的区域(例如 1)更重要。 如果某些类别比某些其他数据字段大得多,您可以尝试对其进行规范化Why Data Normalization is necessary for Machine Learning models

考虑查看 Kaggle 比赛House Prices: Advanced Regression Techniques。它所做的事情与您尝试做的事情类似,并且可能会为您在笔记本和讨论选项卡中如何解决问题提供一些指导。

【讨论】:

【参考方案2】:

您的模型过拟合。尝试先制作一个简单的模型,并使用较低的参数值。对于基于树的分类,缩放对模型没有任何影响。

【讨论】:

【参考方案3】:

如果不深入探索您使用的所有数据,就很难确定从训练集转移到测试集时导致准确度(或 AUC)下降的原因。 这不太可能是由混合的离散/连续数据引起的

下降只是表明您的模型过度拟合您的训练数据(因此不能很好地转移)。这可能是由于学习参数过多(考虑到您拥有的数据量)造成的 - 与您提到的其他一些方法相比,神经网络的问题更常见。或者,问题可能出在数据被分成训练/测试的方式上。如果数据的分布有显着差异(这可能并不明显),那么您就不会期望测试性能那么好。如果是我,我会仔细研究如何将数据拆分为训练/测试(假设您有相当大的数据集)。您可以尝试通过一些随机训练/测试拆分重复您的实验(如果您不熟悉,请搜索 k 折交叉验证)。

【讨论】:

以上是关于如何处理包含离散和连续数据的数据集的主要内容,如果未能解决你的问题,请参考以下文章

如何处理结构化的海量数据集? [关闭]

如何处理“rpart”中的连续和离散变量 - 使用 R 的决策树?

dask 如何处理大于内存的数据集

如何处理机器学习分类问题的小型和不平衡数据集

当 Relay 游标分页总是获取整个数据集时,它如何处理大数据集?

如何处理具有 35 个唯一值的分类数据?