python实战(二)——房屋价格回归建模

一、任务背景

        本章将使用一个经典的Kaggle数据集——House Prices - Advanced Regression Techniques进行回归建模的讲解。这是一个房价数据集,与我们熟知的波士顿房价数据集类似,但是特征数量要更多,数据也要更为复杂一些。下面,我们将使用这个房价数据进行机器学习中的回归建模,依次分解机器学习建模的各个步骤并给出详细的注解。

二、机器学习建模

1、数据获取

        为了展示一个完整的机器学习建模流程,我们把数据集下载到了本地并使用python进行读取:

df = pd.read_csv('./data/housePrices.csv')
print('数据量:', len(df))
print(df.head())

        结果如下,数据总量是1460条,可以看到最后一列SalePrice就是我们要预测的标签了,此外除Id列之外还有80个特征列。

2、探索性数据分析

        通过常规的探索性分析,大概看一下这个数据集长什么样子,比如有多少行、有多少列、每一列中是否有空值、哪些列是数值类型的、哪些列是文本类型的,以及最重要的——我们要预测的标签是哪一列。

(1)查看空值

        由于特征列较多,所以全都打出来比较难阅读,这里通过筛选的方式,仅打印有空值的特征列:

for col in list(df.columns):sum_na = df[col].isna().sum()if sum_na > 0:print("{:<20} {}".format(col, sum_na))

        结果如下,有空值的列数为19列,其中一些列含有较多的空值,比如最后三列。

(2)查看特征取值类型

        我们可以通过筛选数据字段类型的方式分别统计出有多少是数值型特征,有多少是文本特征:

# 选择数值型的列
numeric_df = df.select_dtypes(include=['int64', 'float64'])
# 选择文本型的列
text_df = df.select_dtypes(include=['object'])  # 注意:这里可能包括了混合类型的列
# 打印结果
print("数值型列:")
print('数量:{}, 列名:{}'.format(len(numeric_df.columns), numeric_df.columns.tolist()))
print("文本型列:")
print('数量:{}, 列名:{}'.format(len(text_df.columns), text_df.columns.tolist()))

        结果如下:

        或者,还有个一步到位的方式:

print(df.info())

        结果如下,可以看到,使用.info()方法既可以打印出数据量,也能显示每一列非空值的数量以及字段类型等信息。

(3)查看标签分布

        通过可视化的方式把标签分布可视化出来

plt.figure(figsize=(9, 8))
sns.histplot(df['SalePrice'], color='b', bins=100)
plt.show()

        可以看到标签取值范围集中在100K到250K的区间内。

3、数据预处理

        在进行了初步的数据探索之后,我们可以开始数据的预处理了。首先,部分特征列存在大量的空值,虽然可以取当前列有效数据的平均值或者中值进行填充 ,但是由于空值列比例太大,笔者在这里直接去掉这些列。对于数据为文本类型的列,我们进行一个简单的转换,确保每一列的数据都是数值类型,以方面后续的相关性计算以及建模。由于文本列也可能存在空值,这里统一编码为“missing”。

# 去掉空值数量超过600的列,不同数据集相应空值数量临界值的界定视具体情况调整
df = df.drop(['Alley', 'MasVnrType', 'FireplaceQu', 'PoolQC', 'Fence', 'MiscFeature'], axis=1)
# 对于文本数据列首先填充空值,再进行数值化转换
label_encoder = LabelEncoder()
for col in text_df.columns:if col not in df:continuedf[col].fillna('missing', inplace=True)# 转换成数值类型的标号df[col] = label_encoder.fit_transform(df[col])

        其次,对于包含少量空值的数值类型列,我们使用中值进行填充。

# 计算每一列的中值
median_values = df.median()
# 使用中值填充空值
df = df.fillna(value=median_values)

4、特征工程

        由于总共有将近80列的特征,实际上我们可能不需要这么多特征,所以我们进行一个简单的相关性分析(这里使用Pearson相关系数,衡量线性相关度,也可以使用斯皮尔曼系数等来衡量非线性相关度),只保留跟标签列较相关的特征(相关性大于0.5)。在本文中,笔者只进行特征工程中的“特征选择方法”的展示,至于特征构造等内容,视建模结果而定,若建模结果不佳,则可能需要人工构造新特征了。

correlation_matrix = df.corr(method='pearson')
# 计算所有特征列与标签列之间的相关系数
correlations = df.drop('SalePrice', axis=1).corrwith(df['SalePrice'])
# 筛选出相关度大于0.5的特征列,实际取多少根据数据规律确定,例如这个数据集超过0.8的有0列,自然无法指定高于0.8的取值
highly_correlated_features = correlations[abs(correlations) > 0.5].index.tolist()
print("特征列与标签列相关度大于0.5的特征:", highly_correlated_features)

5、训练集/测试集划分

        在进行建模之前划分好训练集的测试集,训练集用于模型训练,测试集测试模型的效果。

# 选定训练特征和标签
X = df[highly_correlated_features].values.tolist()
y = df['SalePrice'].tolist()
# 数据划分
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=2024)
print('训练集数据量:', len(X_train))
print('测试集数据量:', len(X_test))

        这里讲一下几个比较重要的参数:

  • test_size:指定训练集和测试集划分过程中的比例,0-1开区间之间的小数。
  • random_state:指定随机数,以保证结果可复现。

6、模型训练

        这里我们使用一个GBDT回归器作为当前任务的模型。我们使用R2作为评价模型的指标,R2显示了一个回归模型的可解释方差占总方差的比例,R2得分越接近1代表模型效果越好。此外,MSE和MAE是两个常见的指标,不赘述了。

gbr = GradientBoostingRegressor(loss="squared_error", n_estimators=100, criterion="friedman_mse", random_state=2024)
gbr.fit(X_train, y_train)
y_pred = gbr.predict(X_test)
# 评估模型表现
print('r2:', r2_score(y_test, y_pred))
print('mae:', mean_absolute_error(y_test, y_pred))
print('mse:', mean_squared_error(y_test, y_pred))
print('rmse:', mean_squared_error(y_test, y_pred)**0.5)

        这里同样有几个需要注意的参数:

  • n_estimators:指定要构建的决策树的数量,默认值是100。更多的树可以提高模型的复杂度和拟合能力,但也会增加过拟合的风险及计算量。
  • max_depth:指定每个决策树的最大深度,树的深度太浅会欠拟合,树的深度太深则会过拟合,需要凭经验调整,默认值是3
  • loss:指定优化目标函数,可选squared_error(默认)、absolute_error、huber、quantile。squared _ error是回归的平方误差;absolute_error是回归的绝对误差;huber是两者的结合;quantile允许使用分位数回归(使用alpha指定分位数)。
  • criterion:指定衡量分裂质量的准则,可以选friedman_mse或mse。默认是friedman_mse,在某些情况下它可以得到更好的近似值。
  • random_state:随机数种子,用于控制树的抽样和特征选择的随机性,默认是None,即不指定。

        指标结果如下,由于我们并没有对标签进行归一化,所以MAE和MSE数值会非常大,但这是正常的,毕竟我们的标签房价基本都是10万元以上的:

        可视化模型预测结果和真实值的差异,可以见到预测效果还不错(这里我们的数据并不是时序性的,但是为了观察预测值和真实值的拟合情况,可以把数据看作是时序的并使用曲线进行可视化, 这时候的X轴是标签对应的序号,Y轴是房价):

plt.plot(y_test, label='real')
plt.plot(y_pred, label='pred')
plt.legend()
plt.show()

三、完整代码

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
from sklearn.preprocessing import LabelEncoder
from sklearn.model_selection import train_test_split
from sklearn.ensemble import GradientBoostingRegressor
from sklearn.metrics import r2_score, mean_absolute_error, mean_squared_errordf = pd.read_csv('./data/housePrices.csv')
print('数据量:', len(df))
print(df.head())# 查看包含空值的列
for col in list(df.columns):sum_na = df[col].isna().sum()if sum_na > 0:print("{:<20} {}".format(col, sum_na))# 选择数值型的列
numeric_df = df.select_dtypes(include=['int64', 'float64'])
# 选择文本型的列
text_df = df.select_dtypes(include=['object'])  # 注意:这里可能包括了混合类型的列
# 打印结果
print("数值型列:")
print('数量:{}, 列名:{}'.format(len(numeric_df.columns), numeric_df.columns.tolist()))
print("文本型列:")
print('数量:{}, 列名:{}'.format(len(text_df.columns), text_df.columns.tolist()))
print(df.info())# 可视化标签分布
print(df['SalePrice'].describe())
plt.figure(figsize=(9, 8))
sns.histplot(df['SalePrice'], color='b', bins=100)
plt.show()# 去掉空值数量超过600的列,不同数据集相应空值数量临界值的界定视具体情况调整
df = df.drop(['Alley', 'MasVnrType', 'FireplaceQu', 'PoolQC', 'Fence', 'MiscFeature'], axis=1)
# 对于文本数据列首先填充空值,再进行数值化转换
label_encoder = LabelEncoder()
for col in text_df.columns:if col not in df:continuedf[col].fillna('missing', inplace=True)# 转换成数值类型的标号df[col] = label_encoder.fit_transform(df[col])# 计算每一列的中值
median_values = df.median()
# 使用中值填充空值
df = df.fillna(value=median_values)correlation_matrix = df.corr(method='pearson')
# 计算所有特征列与标签列之间的相关系数
correlations = df.drop('SalePrice', axis=1).corrwith(df['SalePrice'])
# 筛选出相关度大于0.5的特征列,实际取多少根据数据规律确定,例如这个数据集超过0.8的有0列,自然无法指定高于0.8的取值
highly_correlated_features = correlations[abs(correlations) > 0.5].index.tolist()
print("特征列与标签列相关度大于0.5的特征:", highly_correlated_features)# 选定训练特征和标签
X = df[highly_correlated_features].values.tolist()
y = df['SalePrice'].tolist()
# 数据划分
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=2024)
print('训练集数据量:', len(X_train))
print('测试集数据量:', len(X_test))gbr = GradientBoostingRegressor(loss="squared_error", n_estimators=100, criterion="friedman_mse", random_state=2024)
gbr.fit(X_train, y_train)
y_pred = gbr.predict(X_test)
# 评估模型表现
print('r2:', r2_score(y_test, y_pred))
print('mae:', mean_absolute_error(y_test, y_pred))
print('mse:', mean_squared_error(y_test, y_pred))# 预测效果可视化
plt.plot(y_test, label='real')
plt.plot(y_pred, label='pred')
plt.legend()
plt.show()

四、总结

        本文使用了开源数据集进行回归建模实践,遵循机器学习建模的几大流程注意展开讲解。分类和回归是机器学习的两大主要任务,也是业务过程中最常见的任务类型,因此有必要深入了解其中的建模流程及细节。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/458830.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux 命令行查看当前目录的总大小/总磁盘空间/磁盘清理

一、du 查看目录空间大小 &#xff08;一&#xff09; du 命令解析 在Linux命令行可以使用 du 命令来查看当前目录的总大小。du 是 disk usage 的缩写&#xff0c;表示磁盘使用情况。 命令解释&#xff1a;总结每个文件的磁盘使用情况&#xff0c;递归地用于目录。 使用格式…

以通俗易懂的仓库来讲解JVM内存模型

JVM内存模型可以想象成一个大型的仓库&#xff0c;这个仓库被分成了几个不同的区域&#xff0c;每个区域都有特定的用途和规则。下面我们用一个仓库的比喻来介绍JVM内存模型&#xff1a; 仓库大门&#xff08;JVM启动&#xff09;&#xff1a; 当JVM启动时&#xff0c;就像打开…

自动化抖音点赞取消脚本批量处理

&#x1f31f; 前言 欢迎来到我的技术小宇宙&#xff01;&#x1f30c; 这里不仅是我记录技术点滴的后花园&#xff0c;也是我分享学习心得和项目经验的乐园。&#x1f4da; 无论你是技术小白还是资深大牛&#xff0c;这里总有一些内容能触动你的好奇心。&#x1f50d; &#x…

多个立方体盒子组成

效果&#xff1a; 知识了解&#xff1a; 在同一水平上&#xff0c;盒子经纬度计算&#xff1a;经度有误差&#xff0c;纬度没有误差 纬度计算&#xff1a;lat50/111320 约等于0.000449 经度计算&#xff1a;lon50/111320*cos(纬度) 约等于0.000519 一个立方体&#xff1a; // 添…

CentOS进入单用户模式进行密码重置

一、单用户模式介绍 单用户模式是一种特殊的启动模式&#xff0c;主要用于系统维护和故障排除。在单用户模式下&#xff0c;系统以最小化的状态启动&#xff0c;只有最基本的系统服务会被加载&#xff0c;通常只有root用户可以登录。这种模式提供了对系统的完全控制&#xff0…

模型训练识别手写数字(一)

一、模型训练数据集 1. 导入所需库 import numpy as np from sklearn.datasets import fetch_openmlnumpy 是用于数值计算的库。 fetch_openml 是用于从 OpenML 下载数据集的函数。 2. 获取 MNIST 数据集 X, y fetch_openml(mnist_784, version1, return_X_yTrue)fetch_ope…

Spring Boot与Flyway实现自动化数据库版本控制

一、为什么使用Flyway 最简单的一个项目是一个软件连接到一个数据库&#xff0c;但是大多数项目中我们不仅要处理我们开发环境的副本&#xff0c;还需要处理其他很多副本。例如&#xff1a;开发环境、测试环境、生产环境。想到数据库管理&#xff0c;我们立刻就能想到一系列问…

Ovis原理解读: 多模态大语言模型的结构嵌入对齐

论文&#xff1a;https://arxiv.org/pdf/2405.20797 github:https://github.com/AIDC-AI/Ovis 在多模态大语言模型 (MLLM) 中&#xff0c;不同的嵌入策略有显著的区别。以下是使用基于连接器的方法与 Ovis 方法的比较&#xff1a; 基于连接器的方法-优缺点(connector-based …

斜杠往哪斜、路径绝对还是相对,终端目录切换不再迷茫

目录 路径表示绝对路径相对路径两者区别 路径中斜杠的用法正反斜杠对比表一个常见的问题 终端切换目录常用cd指令同一盘符内跨盘符 路径表示 在计算机文件系统中&#xff0c;路径是用来指定文件或目录位置的一种方式。路径可以是绝对路径或相对路径&#xff1a; 绝对路径 绝…

cmake 编译 vtk

1. 下载 VTK 源码 vtk 源码&#xff0c;点击&#xff1a;官网下载 在官网选择合适的版本下载&#xff0c;这里下载的是 vtk 8.2.0 版本 2. 下载 CMake CMake 工具&#xff0c;点击&#xff1a;镜像下载 下载版本比较新的 CMake 版本&#xff0c;这里使用的是 CMake 3.29.2 版…

在不支持AVX的linux上使用PaddleOCR

背景 公司的虚拟机CPU居然不支持avx, 默认的paddlepaddle的cpu版本又需要有支持avx才行,还想用PaddleOCR有啥办法呢? 是否支持avx lscpu | grep avx 支持avx的话,会显示相关信息 如果不支持的话,python运行时导入paddle会报错 怎么办呢 方案一 找公司it,看看虚拟机为什么…

C++基础:constexpr,类型转换和选择语句

constexpr 提到constexpr&#xff0c;我们会发现它和const类比 常和const类比constexpr符号常量必须给定一个在编译时已知的值&#xff0c; 若某个变量初始化时的值在编译时未知&#xff0c;但初始化后绝不变。 #include<iostream> #include<vector> #include&l…

【机器学习基础】激活函数

激活函数 1. Sigmoid函数2. Tanh&#xff08;双曲正切&#xff09;函数3. ReLU函数4. Leaky ReLU函数 1. Sigmoid函数 观察导数图像在我们深度学习里面&#xff0c;导数是为了求参数W和B&#xff0c;W和B是在我们模型model确定之后&#xff0c;找出一组最优的W和B&#xff0c;使…

Go使用exec.Command() 执行脚本时出现:file or directory not found

使用 Go 提供的 exec.Command() 执行脚本时出现了未找到脚本的 bug&#xff0c;三个排查思路 &#xff1a; exec.Command(execName, args…) 脚本名字不允许相对路径 exec.Command(execName, args…) execName 只能有脚本名&#xff0c;不允许出现参数 如果你是使用 Windows …

Python爬虫:商品详情的“八卦记者”

亲爱的代码侦探们&#xff0c;今天咱们不聊那些让人头秃的bug&#xff0c;也不谈那些让人眼花的架构图。咱们来聊聊那些在代码世界里挖掘商品秘密的“八卦记者”——Python爬虫。 Python爬虫&#xff1a;商品详情的“八卦记者” 想象一下&#xff0c;你在代码的世界里&#xf…

[笔记] ffmpeg docker编译环境搭建

文章目录 环境参考dockerfile 文件步骤常见问题docker 构建镜像出现 INTERNAL_ERROR 失败? 总结 环境 docker 环境 系统centos 7.9 (无所谓了 你用docker编译就无所谓系统了) ffmpeg3.3 参考 https://blog.csdn.net/jiedichina/article/details/71438112 dockerfile 文件 …

《等保测评新视角:安全与发展的双赢之道》

在数字化转型的浪潮中&#xff0c;企业面临的不仅是技术革新的挑战&#xff0c;更有信息安全的严峻考验。等保测评&#xff0c;作为国家网络安全等级保护的一项重要措施&#xff0c;不仅为企业的安全护航&#xff0c;更成为推动企业高质量发展的新引擎。本文将从全新的视角&…

如何将markdown文件转换为pdf

最近笔者在用vscode写markdown&#xff0c;但是提交时往往需要交pdf。所以就涉及到如何将markdown转化为pdf格式。 首先&#xff0c;需要在vscode上安装插件 markdown Preview Enhanced 之后在vscode的右上角即可看到下述图标&#xff0c;点击&#xff0c;vscode右半面就会显示…

【论文阅读】PGAN

1. WHY 问题 图像超分辨率一直是一个热门研究课题&#xff0c;具有重要的应用价值。基于生成对抗网络GAN的单幅图像超分辨率方法显示重建图像与人类视觉特征更一致。因此&#xff0c;基于 GAN 的网络优化已成为图像超分辨率的主流。然而&#xff0c;一些最新研究表明&#xf…

【JIT/极态云】技术文档--函数设计

一、简介 函数是计算机编程中非常重要的概念。它是一段代码&#xff0c;可以在程序中多次调用&#xff0c;用于完成特定的任务。 函数通常接受输入参数&#xff0c;执行特定的操作&#xff0c;并返回一个结果。这个结果可以被程序中的其他代码使用。 二、新建函数 在函数列表…