修改模型使模型不拟合

题目:基于回归算法房价预测与研究
问题:目前三个模型的r2趋近于1模型全部拟合帮助我调整参数使模型全部不拟合
在我的源代码上修改


#完成数据预处理,可视化
import pandas as pd
import numpy as np
from sklearn.model_selection import cross_val_score
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
from sklearn.metrics import mean_squared_error
from sklearn.linear_model import LinearRegression
from sklearn.tree import DecisionTreeRegressor
from sklearn.ensemble import RandomForestRegressor
import matplotlib.pyplot as plt
import seaborn as sns
# 读取数据
housing = pd.read_csv('F2.csv', encoding='gbk', dtype={'卧室数量': str, '客厅数量': str, '卫生间数': str})
housing['成交时间'] = housing['成交时间'].apply(lambda x: int(x.split('/')[0]))
#找出包含非数值数据的列
for column in housing.columns:
    if not pd.to_numeric(housing[column], errors='coerce').notnull().all():
        print(column)
        housing[column] = pd.to_numeric(housing[column], errors='coerce')


#然后使用中位数填充策略
housing = housing.apply(pd.to_numeric, errors='coerce')
imputer = SimpleImputer(strategy="median")
housing_imputed = imputer.fit_transform(housing)
housing = pd.DataFrame(housing_imputed, columns=housing.columns)
#箱型图
plt.rcParams['font.sans-serif'] = ['SimSun']
plt.rcParams['axes.unicode_minus'] = False
x=housing.describe()
groups = [['成交总价', '成交单价'], ['面积', '关注度'], ['卧室数量', '客厅数量']]

# 绘制分组箱型图
fig, axs = plt.subplots(len(groups), 1, figsize=(12, 8))
for i, group in enumerate(groups):
    housing[group].boxplot(ax=axs[i])
    axs[i].set_xlabel('特征')
    axs[i].set_ylabel('值')
    axs[i].set_title(f'Boxplot of Features {group[0]} to {group[-1]}')

plt.tight_layout()
plt.show()
#使用 IQR 方法(四分位数间距)去除数据中的异常值
def remove_outliers(df, column, multiplier=1.5):
    # 计算 IQR
    Q1 = df[column].quantile(0.25)
    Q3 = df[column].quantile(0.75)
    IQR = Q3 - Q1

    # 定义异常值范围
    lower_bound = Q1 - multiplier * IQR
    upper_bound = Q3 + multiplier * IQR

    # 过滤掉异常值
    no_outliers_df = df[(df[column] >= lower_bound) & (df[column] <= upper_bound)]

    return no_outliers_df
# 对您关心的列应用 remove_outliers 函数
columns_to_check = ['成交总价', '成交单价', '面积', '关注度', '卧室数量', '客厅数量']

for column in columns_to_check:
    housing = remove_outliers(housing, column)
# 计算相关性矩阵
corr_matrix = housing.corr()

# 查看与房屋价值相关性较高的特征
corr_matrix = housing.corr()
print("Correlation with price:")
print(corr_matrix["成交单价"].sort_values(ascending=False))



plt.rcParams['font.sans-serif'] = ['SimSun']
plt.rcParams['axes.unicode_minus'] = False
# 1. 总价在500万以下的
below_5m = housing[housing['成交总价'] <= 500]
below_5m['成交总价'].plot.hist(bins=50)
plt.xlabel('总价(10000元)')
plt.title('总价在500万以下的')
plt.show()

# 2. 每平米单价分布
housing['成交单价'].plot.hist(bins=50)
plt.xlabel('每平方米价格')
plt.title('每平方米分布价格')
plt.show()

# 3. 根据年份列出房价均值
avg_price_by_year = housing.groupby('成交时间')['成交单价'].mean()
avg_price_by_year.plot.bar()
plt.xlabel('Year')
plt.ylabel('每平方米平均价格')
plt.title('按年划分的每平方米平均价格')
plt.show()

# 4. 所有房子面积分布情况
housing['面积'].plot.hist(bins=50)
plt.xlabel('面积(平方米)')
plt.title('有房子面积分布情况')
plt.show()

# 5. 房子的客厅卧室数量情况
room_counts = housing['卧室数量'].value_counts().sort_index()
room_counts.plot.bar()
plt.xlabel('客厅数量')
plt.ylabel('属性数量')
plt.title('房子的客厅卧室数量情况')
plt.show()

# 6. 所有特征值的相关性图
#分析与目标值相关度最高的十个变量
corrs=housing.corr()
cols_10 = corrs.nlargest(10, '成交总价')['成交总价'].index
corrs_10 = housing[cols_10].corr()
plt.figure(figsize=(6, 6))
sns.heatmap(corrs_10, annot=True)

#7.绘制房价分布的地理图,市中心房价极高,从天安门向外递减飞快
plt.figure(figsize=(5,5))
sns.scatterplot(x = housing['经度'], y = housing['纬度'], hue = housing['成交单价'])
#绘制房价分布的地理图,市中心房价极高,从天安门向外递减飞快

num_attribs = list(housing.columns)

num_pipeline = Pipeline([
    ('std_scaler', StandardScaler()),
])

housing_prepared = num_pipeline.fit_transform(housing)

# 更新标签数据
from sklearn.model_selection import train_test_split
housing = housing.rename(columns={'成交总价': '房屋价值'})
y = housing["房屋价值"].copy()
X = housing.drop(labels=["房屋价值","所在行政区",'是否满五年','户梯比例','卫生间数','客厅数量','厨房数量','经度','纬度'], axis=1)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 线性回归
from sklearn.metrics import r2_score
lin_reg = LinearRegression()
lin_reg.fit(X_train, y_train)
coefficients = pd.DataFrame({'feature': X.columns, 'coefficient': lin_reg.coef_,'intercept':lin_reg.intercept_})
print(coefficients)
# 使用模型进行预测
y_pred = lin_reg.predict(X_train)
# 计算R²
r2 = r2_score(y_train, y_pred)

print("R² =", r2)
# 决策树
tree_reg = DecisionTreeRegressor(max_depth=18,criterion='mse',random_state=42)
tree_reg.fit(X_train,y_train)
y_pred = tree_reg.predict(X_train)
r2 = r2_score(y_train, y_pred)

print("R² =", r2)
#随机森林
forest_reg = RandomForestRegressor(max_depth=18,random_state=42)
forest_reg.fit(X_train,y_train)
y_pred = forest_reg.predict(X_train)
r2 = r2_score(y_train, y_pred)

print("R² =", r2)
# 评估函数
def evaluate(model, X, y):
    y_pred = model.predict(X)
    mse = mean_squared_error(y, y_pred)
    rmse = np.sqrt(mse)
    r2 = r2_score(y_train, y_pred)

    print("R² =", r2)
    print("RMSE: {:.2f}".format(rmse))

    scores = cross_val_score(model, X, y,
                             scoring="neg_mean_squared_error", cv=5)
    rmse_scores = np.sqrt(-scores)
    print("Scores:", rmse_scores)
    print("Mean:", rmse_scores.mean())
    print("Standard deviation:", rmse_scores.std())

# 使用训练集进行评估
print("Linear Regression Model:")
evaluate(lin_reg, X_train,y_train)

print("Decision Tree Model:")
evaluate(tree_reg, X_train,y_train)

print("Random Forest Model:")
evaluate(forest_reg, X_train,y_train)
x=[[2020,100,31000,90,1,0,0,40000]]
y_pred = forest_reg.predict(x)

过度拟合是机器学习建模经常遇到的问题,也是棘手问题,甚至数据科学岗位面试时候经常会遇到这类难题。大家不要怕,接下来我会详细讲述python xgboost如何降低过度拟合方法和其它更好方法。

xgboost建模中,如果变量数量太多,模型容易过度拟合,英文术语为overfitting,如下图右。

如果变量太少,容易欠拟合,英文术语为underfitting,如下图左。

如果变量刚好合适,模型拟合就会比较好,如下图中。

我们用xgboost建模时应当如何避免过度拟合呢?

1.我们应首先观察模型变量是否太多,是否包含大量无效变量(噪音变量)?如果模型噪音变量太多,就先变量筛选,踢除无效变量,或用降维手段测试效果。这一条是至关重要的前提,如果做不好变量筛选和降维,后续方法效果会大打折扣。

2.我们可以设置xgboost中eval_set,eval_metric,early_stopping_rounds参数,来减轻过度拟合。如果因数据原因,完全消除过度拟合是不可能的。

3.采用其他集成树算法进一步减轻过度拟合,例如对称树算法catboost。对称树算法catboost有天然对抗过度拟合优点,之后我会安排时间讲解catboost算法。

接下来我将描述如何在 Python 中使用提前停止来限制 XGBoost 的过度拟合。

通过这篇文章,你会了解:

关于提前停止作为减少训练数据过度拟合的一种方法。如何在训练期间监控 XGBoost 模型的性能并绘制学习曲线。如何使用提前停止在最佳时期提前停止 XGBoost 模型的训练。提前停止以避免过度拟合

提前停止是一种训练复杂机器学习模型以避免过度拟合的方法。

它的工作原理是监控在单独的测试数据集上训练的模型的性能,并在经过固定次数的训练迭代后测试数据集的性能没有提高时停止训练过程。

它通过尝试自动选择测试数据集性能开始下降的拐点来避免过度拟合,而随着模型开始过度拟合,训练数据集的性能继续提高。

性能度量可能是正在优化以训练模型的损失函数(例如对数损失),或通常对问题感兴趣的外部度量(例如分类准确度)。

以下答案由GPT-3.5大模型与博主波罗歌共同编写:
为使模型不拟合,可以采取以下方法:

  1. 减少特征数量:从相关性分析中可以看到,与房屋价值相关性最高的是面积和关注度,因此可以只使用这两个特征进行建模。
  2. 增加正则化:通过增加L1或L2正则化项,可以使模型更加简单,减少过拟合。例如在LinearRegression中设置参数alpha来控制正则化项的强度。
  3. 减少模型复杂度:减少决策树的最大深度和随机森林的树的数量,可以降低模型的复杂度,避免过度拟合。

修改后的代码如下:

新建特征矩阵,只使用面积和关注度

X = housing[['面积', '关注度']]
y = housing['成交单价']

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

使用线性回归,增加L2正则化项

lin_reg = LinearRegression(alpha=0.1)
lin_reg.fit(X_train, y_train)

使用模型进行预测

y_pred = lin_reg.predict(X_train)

计算R²

r2 = r2_score(y_train, y_pred)
print("Linear Regression R² =", r2)

决策树,最大深度为2

tree_reg = DecisionTreeRegressor(max_depth=2, random_state=42)
tree_reg.fit(X_train, y_train)
y_pred = tree_reg.predict(X_train)
r2 = r2_score(y_train, y_pred)
print("Decision Tree R² =", r2)

随机森林,树的数量为2

forest_reg = RandomForestRegressor(n_estimators=2, random_state=42)
forest_reg.fit(X_train, y_train)
y_pred = forest_reg.predict(X_train)
r2 = r2_score(y_train, y_pred)
print("Random Forest R² =", r2)

使用训练集进行评估

print("Linear Regression Model:")
evaluate(lin_reg, X_train, y_train)

print("Decision Tree Model:")
evaluate(tree_reg, X_train, y_train)

print("Random Forest Model:")
evaluate(forest_reg, X_train, y_train)
如果我的回答解决了您的问题,请采纳!

引用chatGPT作答,要让模型不过度拟合,可以通过以下几种方式进行调整:

1.正则化:加入正则项限制模型的复杂度,从而避免过拟合。可以尝试在线性回归模型中使用Lasso或Ridge正则化,或者在决策树和随机森林模型中使用max_depth等参数限制树的深度。
2.特征选择:删除一些不必要或不相关的特征,以减少模型的复杂度。可以通过观察特征的相关性和重要性来进行选择,或者使用正则化等方法自动选择特征。
3.数据扩增:通过一些方法增加训练集的样本数量,使模型更好地泛化。例如,可以使用数据增强方法对图像数据进行增强,或者使用生成对抗网络生成更多的数据样本。
4.交叉验证:使用交叉验证方法评估模型的泛化能力,并选择最优的超参数和模型。
5.集成学习:通过将多个不同的模型进行集成来提高预测的准确性和稳定性。例如,可以使用Bagging方法对决策树进行集成,或者使用Boosting方法对多个弱分类器进行集成。
在您的代码中,可以尝试使用以上方法之一来避免过拟合。例如,在决策树或随机森林模型中使用max_depth等参数限制树的深度,或者在线性回归模型中使用Lasso或Ridge正则化。另外,还可以使用交叉验证方法来选择最优的超参数和模型,并评估模型的泛化能力。

不知道你这个问题是否已经解决, 如果还没有解决的话:

如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^