我试图建立一个线性回归模型来预测房屋价格,从机器学习开始,但在这段代码中使用交叉验证时遇到了负值:
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
x = df.drop(['MedHouseVal'], axis=1)
y = df['MedHouseVal']
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=0)
model = LinearRegression()
model.fit(x_train, y_train)
model.score(x_test, y_test)
from sklearn.model_selection import cross_val_score
scores = cross_val_score(model, x, y, cv=100)
plt.plot(scores)
我注意到,随着简历的增加,平均分数下降了。因此,我决定将其绘制出来,并意识到分数在某些点上呈现负值,但是真实的预测/样本大小如何为负值,它是用 (TP + TN - FP - FN)/样本大小计算的吗?提前致谢。 在此输入图片描述 抱歉英语不好(;))
Scikit 回归分数是使用 R2 计算的,如果您的拟合效果不佳,则该分数可能为负(请参阅详细信息此处)。
在您的代码中,您最初保留了 20% 的数据,当我运行它时,
model.score(x_test, y_test)
得出的分数约为 0.59
。
函数
cross_val_score
可以为您完成此操作。 例如,默认的 cv
使用 5 折交叉验证。交叉验证的思想是使用所有数据进行训练,同时也独立检查结果。 这会将数据随机分为 5 个部分,然后训练模型以保留这些分割之一(或 20% 的数据),检查那 20% 的模型,然后对每个部分重复。每一项的平均值应该给出合理的分数评估。事实上,它给出了 [0.54866323, 0.46820691, 0.55078434, 0.53698703, 0.66051406]
,其平均值/标准差为 0.553 +/- 0.062
。出于所有意图和目的,这两种方法的 R2 是相同的。
随着组数的增加
cv
,您可能会强制使用较小的样本量,无法代表整个数据集,而该数据集在该部分的得分中占主导地位(例如,一组有更多异常值)。这会导致结果出现更多差异。例如,对于 cv=100
,结果为 -0.095 +/- 0.918`(注意只有 20k 个数据点,因此每次折叠只有 200 个点)。这种噪音并不代表基础数据。
注意要重现此内容,我需要在代码顶部添加以下行:
from sklearn.datasets import fetch_california_housing
import pandas
import matplotlib.pyplot as plt
import numpy as np
california_housing = fetch_california_housing(as_frame=True)
df = california_housing.frame