让我所有的预测都倾向于二进制分类的一侧

Posted

技术标签:

【中文标题】让我所有的预测都倾向于二进制分类的一侧【英文标题】:Having all my predictions inclined to one side for binary classification 【发布时间】:2020-12-08 06:08:36 【问题描述】:

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

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

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

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

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

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

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

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

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

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

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


    我已经为分类数据完成了OneHotEncoder。 我已对数据应用标准化。 我修改了以下RandomRofrest参数:
Max_depth: 16点高峰 n_estimators: 峰值 300 min_samples_leaf: 2点达到峰值 max_features:对 AUC 没有影响。

AUC 达到峰值 0.7889。我还能做些什么来增加它?


这是我的代码

import pandas as pd
import numpy as np
from sklearn.model_selection import cross_val_score
from sklearn.preprocessing import OneHotEncoder
from sklearn.pipeline import make_pipeline
from sklearn.compose import make_column_transformer
from sklearn.model_selection import train_test_split
df_train = pd.read_csv('case2_training.csv')

# Exclude ID since it is not a feature
X, y = df_train.iloc[:, 1:-1], df_train.iloc[:, -1]
y = y.astype(np.float32)

# Split the data
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.05,shuffle=False)

ohe = OneHotEncoder(sparse = False)
column_trans = make_column_transformer(
(OneHotEncoder(),['Region','Weekday','Apartment']),remainder='passthrough')
X_train = column_trans.fit_transform(X_train)
X_test = column_trans.fit_transform(X_test)

# Normalization
from sklearn.preprocessing import MaxAbsScaler
mabsc = MaxAbsScaler()

X_train = mabsc.fit_transform(X_train)
X_test = mabsc.transform(X_test)

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

from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import roc_auc_score

RF =  RandomForestClassifier(min_samples_leaf=2,random_state=0, n_estimators=300,max_depth = 16,n_jobs=-1,oob_score=True,max_features=i)
cross_val_score(RF,X_train,y_train,cv=5,scoring = 'roc_auc').mean()
RF.fit(X_train, y_train)
yhat = RF.predict_proba(X_test)

print("AUC:",roc_auc_score(y_test, yhat[:,-1]))

# Run the prediction on the given test set.
testset = pd.read_csv('case2_testing.csv')
testset = testset.iloc[:, 1:] # exclude the 'ID' column
testset = column_trans.fit_transform(testset)
testset = mabsc.transform(testset)


yhat_2 = RF.predict_proba(testset)
final_prediction = yhat[:,-1]

但是,'final_prediction' 的所有概率都低于 0.45,基本上,模型认为所有样本都是 0。 有人可以帮忙吗?

【问题讨论】:

你最后一行的意思是yhat_2[:,-1] @StevenRouk Predict_proba 将给出两个类的概率,在这种情况下是 0 和 1。我的目标是找到 1 的可能性,所以我选择了第二列。 【参考方案1】:

您在测试集上使用column_trans.fit_transform,这完全覆盖了训练期间拟合的特征。基本上数据现在是您训练的模型无法理解的格式。

在训练集上进行训练后,只需使用 column_trans.transform

【讨论】:

感谢您的回答,但没有解决问题。 testset = column_trans.transform(testset) 没有对结果做任何改变,所有答案仍然倾向于'0' 请注意,您在代码中这样做了两次,而不仅仅是在 testset 上。你也应该写testset = testset.iloc[:,1:1] 来排除最后一列。之后您使用fit_transform,然后再次使用transform?这甚至意味着什么? 1.专门加载的testset 没有最后一列,因此我不需要操作该部分。 2. 我对fit_transform 背后的直觉testset 是OneHotEncoder 的特征,因为该模型是基于OneHotEncoder 特征训练的。紧随其后的是mabsc.transform(testset),用于标准化输入值。 3. 请注意X_test 是第一个 CSV 文件的一部分,testset 来自另一个 CSV 文件。

以上是关于让我所有的预测都倾向于二进制分类的一侧的主要内容,如果未能解决你的问题,请参考以下文章

使用 CNN 进行癌症预测的分类

分类:类中的数据偏斜

二进制输出的文本分类

Spark二进制分类预测准确性

分类:类内的倾斜数据

当预测变量不是二进制时,Sklearn 朴素贝叶斯伯努利分类器如何工作?