旨在利用多种机器学习算法实现对房价的预测。并使用"R²", "RMSE", "MAE", "MAPE", "EV"

等指标进行评价。并使用雷达图、柱状图等进行展示。

结果如下图:

 

废话不多说,代码如下:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import warnings
from sklearn.ensemble import RandomForestRegressor, GradientBoostingRegressor, ExtraTreesRegressor
from sklearn.svm import SVR
from sklearn.neighbors import KNeighborsRegressor
from sklearn.neural_network import MLPRegressor
from sklearn.metrics import r2_score, mean_squared_error, mean_absolute_error, explained_variance_score

from sklearn.model_selection import train_test_split, KFold
warnings.filterwarnings("ignore")

plt.rcParams['font.family'] = 'Times New Roman'
plt.rcParams['axes.unicode_minus'] = False



df = pd.read_excel(r'C:\Users\lenovo\Desktop\blog\boston_housing_dataset.xlsx')
X = df.drop(['target'],axis=1)
y = df['target']

# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2,
                                                    random_state=42)


# 结果存储列表
results = []

# 定义函数用于计算指标
def evaluate_model(model_name, y_test, y_pred):
    r2 = r2_score(y_test, y_pred)
    rmse = mean_squared_error(y_test, y_pred, squared=False)
    mae = mean_absolute_error(y_test, y_pred)
    mape = np.mean(np.abs((y_test - y_pred) / y_test)) if np.all(y_test != 0) else np.nan
    ev = explained_variance_score(y_test, y_pred)
    results.append({
        "R²": r2,
        "RMSE": rmse,
        "MAE": mae,
        "MAPE": mape,
        "EV": ev,
        "Model": model_name
    })



# RandomForestRegressor
rfr = RandomForestRegressor(random_state=42)
rfr.fit(X_train, y_train)
y_pred_rfr = rfr.predict(X_test)
evaluate_model("RFR", y_test, y_pred_rfr)

# ExtraTreesRegressor
etr = ExtraTreesRegressor(random_state=42)
etr.fit(X_train, y_train)
y_pred_etr = etr.predict(X_test)
evaluate_model("ETR", y_test, y_pred_etr)

# GradientBoostingRegressor
gbr = GradientBoostingRegressor(random_state=42)
gbr.fit(X_train, y_train)
y_pred_gbr = gbr.predict(X_test)
evaluate_model("GBR", y_test, y_pred_gbr)

# SVR
svr = SVR(kernel='rbf')
svr.fit(X_train, y_train)
y_pred_svr = svr.predict(X_test)
evaluate_model("SVR", y_test, y_pred_svr)

# MLPRegressor
bpnn = MLPRegressor(random_state=42, max_iter=1000)
bpnn.fit(X_train, y_train)
y_pred_bpnn = bpnn.predict(X_test)
evaluate_model("BPNN", y_test, y_pred_bpnn)

# KNeighborsRegressor
knn = KNeighborsRegressor()
knn.fit(X_train, y_train)
y_pred_knn = knn.predict(X_test)
evaluate_model("KNN", y_test, y_pred_knn)



# 转为 DataFrame 并显示
results_df = pd.DataFrame(results)
results_df.to_excel('results.xlsx', index=False)
results_df






#=======归一化的柱状图========
# 获取模型名称和评价指标
models = results_df['Model']
metrics = results_df.iloc[:, :-1].columns

# 归一化数据(最小-最大归一化)
normalized_data = results_df.iloc[:, :-1].apply(lambda x: (x - x.min()) / (x.max() - x.min()))

# 绘图
fig, ax = plt.subplots(figsize=(16, 7))
width = 0.14  # 每个柱子的宽度
x = np.arange(len(metrics))  # 评价指标的位置

# 绘制每个模型的柱状图(竖直排列)
for i, model in enumerate(models):
    bars = ax.bar(x + (i - 2.5) * width, normalized_data.iloc[i], width=width, label=model)

    # 标注每个柱子的数值(使用原始数据)
    for j, bar in enumerate(bars):
        yval = bar.get_height()  # 获取归一化后的柱子高度
        original_value = results_df.iloc[i, j]  # 获取原始数据的值
        ax.text(bar.get_x() + bar.get_width() / 2, yval + 0.02,  # 设置文本位置(在柱子上方)
                f'{original_value:.3f}',  # 显示原始数值,保留三位小数
                ha='center', va='bottom', fontsize=8, color='black')  # 文本位置和格式

# 设置X轴标签和Y轴标签
ax.set_yticks([])  # 不显示y轴刻度
ax.set_xticks(x)
ax.set_xticklabels(metrics)
ax.set_ylabel('Normalized Performance Metric Values')
ax.set_title('Performance Metrics for Each Model')

# 图例位置
ax.legend(title='Models', loc='center right', bbox_to_anchor=(1.1, 0.5))  # 前面的1.1为偏移量(向右),0.5为上下居中

# 保存图像为PDF
plt.tight_layout()
plt.savefig("stylolitic_normalized.pdf", format='pdf', bbox_inches='tight', dpi=300)
plt.show()



#=======归一化的雷达图========

metrics = ["R²", "RMSE", "MAE", "MAPE", "EV"]
categories = results_df["Model"].tolist()
angles = np.linspace(0, 2 * np.pi, len(categories), endpoint=False).tolist()
angles += angles[:1]

# 调整figsize以减小雷达图的大小
fig, axs = plt.subplots(2, 3, figsize=(16, 10), subplot_kw=dict(polar=True))
axs = axs.flatten()

for i, metric in enumerate(metrics):
    max_value = results_df[metric].max()  # 取该指标的最大值
    values = results_df[metric].tolist()
    values += values[:1]  # Close the radar
    color = plt.cm.viridis(i / len(metrics))  # 使用 viridis 颜色映射
    axs[i].fill(angles, values, alpha=0.25, color=color)  # 使用 viridis 颜色
    axs[i].plot(angles, values, marker='o', color=color)  # 使用 viridis 颜色

   # axs[i].set_ylim(0, 1.001)#范围设置
    axs[i].set_ylim(0, max_value)
    axs[i].set_xticks(angles[:-1])
    # 增加字体大小
    axs[i].set_xticklabels(categories, fontsize=12)  # 原来是10,现在改为12
    axs[i].set_title(metric, pad=20)
    # 增加标题的字体大小
    axs[i].title.set_fontsize(14)  # 增加标题字体大小
    axs[i].set_yticklabels([])

# 删除最后一个子图
fig.delaxes(axs[-1])
plt.savefig("rader_plt.pdf", format='pdf', bbox_inches='tight', dpi=1200)
# 调整子图间距,确保字体变大后不会重叠
plt.subplots_adjust(hspace=1.4, wspace=1.6)
plt.tight_layout()
plt.show()





#======热图========
import seaborn as sns

# 创建一个包含所有指标数据的 DataFrame
heatmap_data = results_df[metrics].set_index(results_df["Model"])

# 设置绘图样式
plt.figure(figsize=(10, 6))

# 绘制热力图
sns.heatmap(heatmap_data, annot=True, cmap='coolwarm', fmt='.3f', linewidths=0.5)

# 添加标题
plt.title('Heatmap of Model Performance', fontsize=16)

plt.savefig("heatmap.pdf", format='pdf', bbox_inches='tight', dpi=1200)
# 显示图形
plt.tight_layout()
plt.show()



Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐