使用线性回归、LGBM对二手车价格进行预测

news2024/11/17 13:55:40

使用线性回归、LGBM对二手车价格进行预测

目录

  • 使用线性回归、LGBM对二手车价格进行预测
    • 说明
  • 数据导入、查看和清洗
    • 数据说明
    • 导入训练集
    • 导入测试集
    • 合并数据
    • 查看数据整体情况
    • 处理数据
      • 检查并处理缺失变量
  • EDA
    • 年份和价格
    • 地区和价格
    • 前任里程和价格
    • 燃料类型和价格
    • 传动装置类型
    • Mileage与价格
    • 发动机排量与价格
  • 特征编码
  • 数据切分
  • 模型建立
    • 线性回归
    • LGBM
  • 数据和代码
  • 专栏和往期项目

说明

本项目包含
1.数据处理
2.数据可视化
3.构建模型预测二手车价格

完整代码及数据见文末,可在线运行,也可下载

数据导入、查看和清洗

数据说明

column 列名
index 序号
Name 汽车的品牌和型号。
Location 该车正在销售或可购买的地点。
Year 车型的年份或版本。
Kilometers_Driven 前任车主驾驶该车的总公里数,单位为KM。
Fuel_Type 汽车使用的燃料类型(汽油/柴油/电动/CNG/LPG)。
Transmission 汽车使用的传动装置的类型。
Owner_Type 车主是否为第一手、第二手或其他。
Mileage 汽车公司提供的标准里程,单位是kmpl或km/kg。
Engine 发动机的排量,单位是cc。
Power 发动机的最大功率,单位是bhp。
Seats 汽车中的座位数。
New_Price 同一型号的新车的价格。
Price 二手车的价格,单位是印度卢比。( train.csv)

导入训练集

import pandas as pd
df_train = pd.read_csv('/home/mw/input/data6802/train-data.csv') 
df_train.drop('Unnamed: 0',axis=1,inplace=True)
df_train.head()

在这里插入图片描述

导入测试集

df_test = pd.read_csv('/home/mw/input/data6802/test-data.csv') 
df_test.drop('Unnamed: 0',axis=1,inplace=True)
df_test.head()

在这里插入图片描述

合并数据

先合并数据,方便清洗

df = df_train.append(df_test)
df.head()

查看数据整体情况

查看数据缺失请况,可以看出,新车价格大面积缺失,缺失了86%,其余特征缺失率都较低

df.info()

<class ‘pandas.core.frame.DataFrame’>
Int64Index: 7253 entries, 0 to 1233
Data columns (total 13 columns):
Engine 7207 non-null object
Fuel_Type 7253 non-null object
Kilometers_Driven 7253 non-null int64
Location 7253 non-null object
Mileage 7251 non-null object
Name 7253 non-null object
New_Price 1006 non-null object
Owner_Type 7253 non-null object
Power 7207 non-null object
Price 6019 non-null float64
Seats 7200 non-null float64
Transmission 7253 non-null object
Year 7253 non-null int64
dtypes: float64(2), int64(2), object(9)
memory usage: 793.3+ KB

all_data_na = (df.isnull().sum()/len(df))*100
all_data_na = all_data_na.drop(all_data_na[all_data_na == 0].index).sort_values(ascending=False)
missing_data = pd.DataFrame({'缺失率' : all_data_na})
missing_data
缺失率

New_Price 86.129877
Price 17.013650
Seats 0.730732
Power 0.634220
Engine 0.634220
Mileage 0.027575

发现有一个重复数据,我们后面需要剔除掉

df.duplicated().sum()

处理数据

#去除重复值
df.drop_duplicates(inplace=True)
#删去缺失价格列和Name列
df.drop("New_Price", axis=1, inplace=True)
df.drop("Name", axis=1, inplace=True)
df.head()

检查并处理缺失变量

Seats、Power、Engine、Mileage
含义为:
Mileage 汽车公司提供的标准里程,单位是kmpl或km/kg。
Engine 发动机的排量,单位是cc。
Power 发动机的最大功率,单位是bhp。
Seats 汽车中的座位数。
不着急做填充,先挨个检查变量,然后进行处理
首先是车座

df['Seats'].value_counts()

5.0 6046
7.0 796
8.0 170
4.0 119
6.0 38
2.0 18
10.0 8
9.0 3
0.0 1
Name: Seats, dtype: int64

车座不可能为0,我们将其删除

df.drop(df[df['Seats']==0].index,axis=0,inplace=True)
df['Seats'].value_counts()

5.0 6046
7.0 796
8.0 170
4.0 119
6.0 38
2.0 18
10.0 8
9.0 3
Name: Seats, dtype: int64

剩余的缺失值我们用中位数填充

df['Seats'] = df['Seats'].fillna(df['Seats'].median())
df['Seats'].isnull().sum()

0

然后看看power,也就是发动机的最大功率
先把power的单位去除,再用中位数进行填补

df['Power'] = df['Power'].str.split(" ",expand=True)[0]
df['Power'] = pd.to_numeric(df['Power'],errors='coerce')
df['Power'].isnull().sum()

174

df['Power'] = df['Power'].fillna(df['Power'].median())
df['Power'].isnull().sum()

0
再来是Engine,发动机的排量,处理方式同上

df['Engine'] = df['Engine'].str.split(" ",expand=True)[0]
df['Engine'] = pd.to_numeric(df['Engine'],errors='coerce')
df['Engine'].isnull().sum()

46

df['Engine'] = df['Engine'].fillna(df['Engine'].median())
df['Engine'].isnull().sum()

0
Mileage 汽车公司提供的标准里程,单位是kmpl或km/kg。

df['Mileage'] = df['Mileage'].str.split(" ",expand=True)[0]
df['Mileage'] = pd.to_numeric(df['Mileage'],errors='coerce')
df['Mileage'].isnull().sum()

2

df['Mileage'] = df['Mileage'].fillna(df['Mileage'].median())
df['Mileage'].isnull().sum()

0

EDA

import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline

年份和价格

sns.catplot('Year', 'Price',height=6, aspect=2, data=df)
plt.xticks(rotation=60)

地区和价格

sns.catplot('Location', 'Price', kind="boxen",height=6, aspect=2, data=df)
plt.xticks(rotation=60)

在这里插入图片描述

前任里程和价格

Kilometers_Driven 前任车主驾驶该车的总公里数
我们发现有个异常点,行驶超过了600万公里,我们以100W公里为分界线,将超出部分剔除再看看

df = df[df['Kilometers_Driven'] > 0]
df = df[df['Kilometers_Driven'] < 1000000]
plt.figure(figsize=(9,6))
sns.scatterplot('Kilometers_Driven', 'Price', data=df)

在这里插入图片描述

燃料类型和价格

Fuel_Type 汽车使用的燃料类型(汽油/柴油/电动/CNG/LPG)。

df['Fuel_Type'].value_counts()

Diesel 3851
Petrol 3323
CNG 62
LPG 12
Electric 2
Name: Fuel_Type, dtype: int64
在这里插入图片描述

传动装置类型

Transmission 汽车使用的传动装置的类型。

df['Transmission'].value_counts()

Manual 5203
Automatic 2047
Name: Transmission, dtype: int64

在这里插入图片描述
几手车主
Owner_Type 车主是否为第一手、第二手或其他。

df['Owner_Type'].value_counts()

First 5949
Second 1152
Third 137
Fourth & Above 12
Name: Owner_Type, dtype: int64

在这里插入图片描述

Mileage与价格

Mileage 汽车公司提供的标准里程,单位是kmpl或km/kg。
在这里插入图片描述

发动机排量与价格

Engine 发动机的排量,单位是cc。

特征编码

from sklearn.preprocessing import LabelEncoder,OneHotEncoder
for feat in ['Fuel_Type', 'Location','Owner_Type', 'Transmission', 'Year']:
    lbl = LabelEncoder()
    lbl.fit(df[feat])
    df[feat] = lbl.transform(df[feat])
df.head()

在这里插入图片描述

数据切分

df_train = df[~df['Price'].isnull()]
df_train = df_train.reset_index(drop=True)
df_test = df[df['Price'].isnull()]
df_train.head()

在这里插入图片描述

no_features = ['Price']
# 输入特征列
features = [col for col in df_train.columns if col not in no_features]

X = df_train[features] # 训练集输入
y = df_train['Price']# 训练集标签
X_test = df_test[features] # 测试集输入
from sklearn.model_selection import train_test_split
X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.20, random_state=2022)

模型建立

线性回归

from sklearn.linear_model import LinearRegression
lr = LinearRegression()
lr.fit(X_train, y_train)
y_pred= lr.predict(X_val)
print("Score on Traing set: ",lr.score(X_train,y_train))
print("Score on valid set: ",lr.score(X_val,y_val))

Score on Traing set: 0.702077663498507
Score on valid set: 0.6982662108270392

from sklearn import metrics
from sklearn.metrics import mean_squared_error, mean_absolute_error
import numpy as np
print("\t\tError Table")
print('Mean Absolute Error      : ', metrics.mean_absolute_error(y_pred,y_val))
print('Mean Squared  Error      : ', metrics.mean_squared_error(y_pred,y_val))
print('Root Mean Squared  Error : ', np.sqrt(metrics.mean_squared_error(y_pred,y_val)))
print('R Squared Error          : ', metrics.r2_score(y_pred,y_val))
	Error Table

Mean Absolute Error : 3.8191025211006466
Mean Squared Error : 35.51327770962762
Root Mean Squared Error : 5.959301780378942
R Squared Error : 0.6092807923897521

LGBM

params = {
    'learning_rate':0.1,
    'n_estimators':1000,
    'max_depth': 15,
    'metric': 'mse',
    'verbose': -1,
    'seed': 2022,
    'n_jobs': -1,
}
import lightgbm as lgb
model = lgb.LGBMRegressor(**params)
model.fit(X_train, y_train,
              eval_set=[(X_train, y_train), (X_val, y_val)],
              eval_metric='rmse',
              verbose=50, early_stopping_rounds=100)
y_pred = model.predict(X_val, num_iteration=model.best_iteration_)

Training until validation scores don’t improve for 100 rounds.
[50] training’s rmse: 2.74657 training’s l2: 7.54363 valid_1’s rmse:
3.51272 valid_1’s l2: 12.3392 [100] training’s rmse: 2.20497 training’s l2: 4.86191 valid_1’s rmse: 3.22494 valid_1’s l2: 10.4002 [150] training’s rmse: 1.91286 training’s l2: 3.65904 valid_1’s rmse: 3.14442 valid_1’s l2: 9.8874 [200] training’s rmse: 1.7006 training’s l2: 2.89204 valid_1’s rmse: 3.10488 valid_1’s
l2: 9.64028 [250] training’s rmse: 1.5359 training’s l2:
2.35898 valid_1’s rmse: 3.09994 valid_1’s l2: 9.6096 [300] training’s rmse: 1.40321 training’s l2: 1.969 valid_1’s rmse: 3.13444 valid_1’s
l2: 9.82473 [350] training’s rmse: 1.2895 training’s l2:
1.66282 valid_1’s rmse: 3.15344 valid_1’s l2: 9.9442 Early stopping, best iteration is: [253] training’s rmse: 1.52763 training’s l2:
2.33365 valid_1’s rmse: 3.09248 valid_1’s l2: 9.5634

print("Score on Traing set: ",model.score(X_train,y_train))
print("Score on valid set: ",model.score(X_val,y_val))

Score on Traing set: 0.9815388772454189
Score on valid set: 0.9187458418102552

print("\t\tError Table")
print('Mean Absolute Error      : ', metrics.mean_absolute_error(y_pred,y_val))
print('Mean Squared  Error      : ', metrics.mean_squared_error(y_pred,y_val))
print('Root Mean Squared  Error : ', np.sqrt(metrics.mean_squared_error(y_pred,y_val)))
print('R Squared Error          : ', metrics.r2_score(y_pred,y_val))

Error Table
Mean Absolute Error : 1.4166114668742893
Mean Squared Error : 9.563401874094804
Root Mean Squared Error : 3.092475040173292
R Squared Error : 0.9122361874546977

数据和代码

点击跳转代码,可在线运行
右上角Fork后可以获取全部代码
如果觉得还不错,可以点赞fork~

专栏和往期项目

👉往期文章可以关注我的专栏
下巴同学的数据加油小站
会不定期分享数据挖掘、机器学习、风控模型、深度学习、NLP等方向的学习项目,关注不一定能学到你想学的东西,但是可以学到我想学和正在学的东西😀

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数据库 SQL 高级用法

目录 一、INSERT INTO SELECT 用法 二、逻辑控制语句 三、公式表表达式 四、存储程序 五、触发器 一、INSERT INTO SELECT 用法 INSERT INTO SELECT 语句从一个表复制数据&#xff0c;然后把数据插入到一个已存在的表中。 1、从一个表中复制所有的列插入到另一个已存在的表…

React(coderwhy)- 01

React的介绍&#xff08;技术角度&#xff09; React是什么&#xff1f;React&#xff1a;用于构建用户界面的 JavaScript 库React的官网文档&#xff1a;https://zh-hans.reactjs.org/React的特点&#xff1a; 声明式编程组件化开发多平台适配Hello React react需要3个依赖&am…

【数字图像处理】骨骼锐化

源码链接&#xff1a;skeleton.cpp 一、实验要求 附件是人体骨骼核扫描图像&#xff0c;我们的目的是通过图像锐化突出骨骼的更多细节来增强图像。图像灰度的动态范围很窄并且有很高的噪声内容。 二、实验内容 按照课本冈萨雷斯的《数字图像处理》上面的思路&#xff0c;整…

【代码题】五道链表面试题

目录 1.移除链表元素 2.反转链表 3.链表的中间结点 4.链表中倒数第k个结点 5.合并两个有序链表 1.移除链表元素 点击进入该题 给你一个链表的头节点 head 和一个整数 val &#xff0c;请你删除链表中所有满足 Node.val val 的节点&#xff0c;并返回新的头节点 。 思路&am…

CTF-AWD入门手册

引文 AWD赛制是一种网络安全竞赛的赛制。AWD赛制由安全竞赛专家及行业专家凭借十多年实战经验&#xff0c;将真实网络安全防护设备设施加入抽象的网络环境中&#xff0c;模拟政府、企业、院校等单位的典型网络结构和配置&#xff0c;开展的一种人人对抗的竞赛方式&#xff0c;…

语言和文法的形式定义---编译原理

文法的构建问题 * 参考已有的模型 最经典的即是算数表达式的模型&#xff0c;其有多个算术运算符号和优先级别。 文法与正则表达式与有穷自动机的转换 显然是3型文法&#xff0c;也就是正则文法才有相应的性质&#xff0c;因为只有3型文法才是右部至多仅有两个符 号&#xf…

【Vue路由】props配置、replace属性、编程式路由导航、缓存路由组件

文章目录props配置props值为对象props值为布尔值props值为函数总结\<router-link>的replace属性总结编程式路由导航案例实现总结缓存路由组件案例实现总结props配置 我们可以看看我们原来如何使用传递过来的参数的&#xff1a; 我们要写一大长串去从$route身上拿到我们…

传统目标跟踪——光流法

目录 一、光流法 二、LK光流法 2.1 实现原理 2.2 API 三、代码 四、总结 一、光流法 光流&#xff1a;空间运动物体在观察成像平面上像素运动的瞬时速度。 光流法利用图像序列中像素在时间域上的变化以及相邻帧之间的相关性来找到上一帧之间存在的对应关系&#xff0c;…

密码学_RSA

RSA是1977年由罗纳德李维斯特&#xff08;Ron Rivest&#xff09;、阿迪萨莫尔&#xff08;Adi Shamir&#xff09;和伦纳德阿德曼&#xff08;Leonard Adleman&#xff09;一起提出的。当时他们三人都在麻省理工学院工作。RSA就是他们三人姓氏开头字母拼在一起组成的。 RSA是非…

dom截图的几种实现方式

前端要实现dom截图的功能&#xff0c;现在比较常用的是使用以下两个库 dom-to-image 使用svg技术实现html2canvas 使用canvas技术实现 如果想自己写一个dom截图的可以参考 dom-pointer 代码比较简单&#xff0c;非常适合拿来研究rasterizeHTML.js 目前rasterizeHTML.js已经被…

1231. 航班时间(恶心的输入处理 + 简单的数学)

题目如下&#xff1a; 题解 or 思路&#xff1a; 因为题目假设两次飞行时间是相同的&#xff0c;我们可以通过减法将时差消去。那么飞行时间就是: time1time22\frac{time_1 time2}{2}2time1​time2​ 题目的难点是处理输入&#xff0c;我们可以使用 sscanf 来进行处理&#x…

小程序开发经验分享(1)

账号搭建篇 1. 获取微信小程序的AppID 首先,我们需要拥有一个帐号,如果你能看到该文档,我们应当已经邀请并为你创建好一个帐号。注意不可直接使用服务号或订阅号的AppID。 利用提供的帐号,登录 https://mp.weixin.qq.com ,就可以在网站的“设置”-“开发者设置”中,查…

MySQL高级 SQL优化【插入数据主键优化】

目录 1&#xff1a;SQL优化 1.1&#xff1a;插入数据 1.1.1&#xff1a;insert 1). 优化方案一&#xff08;批量插入数据) 2). 优化方案二&#xff08;手动控制事务&#xff09; 3). 优化方案三 &#xff08;主键顺序插入&#xff0c;性能要高于乱序插入。&#xff09; …

java应用集成HanLP进行中文自然语言分词详细完整案例以及demo

本文可以作为上一篇《mysql/mariadb 实现全文检索》的补充&#xff0c;实现对字符串分词的逻辑 什么是自然语言&#xff0c;什么是自然语言分词及例子 什么是自然语言 狭义地讲&#xff0c;利用计算机进行语言分析的研究是一门语言学与计算机科学的交叉学科&#xff0c;学术界…

CTFSHOW新手杯MISC部分WriteUp

引文 之前复现了CTFSHOW新人杯的WEB方向部分题目&#xff0c;今天就复现一下MISC为主的题目&#xff0c;可能有些读者不太明白MISC方向是什么意思&#xff0c;简单来说就是"杂项",包括&#xff1a;隐写&#xff0c;压缩包处理&#xff0c;流量分析&#xff0c;攻击取…

电容基础知识

电解电容负极有标识标有耐压值&#xff08;400V 450WV&#xff09; 容量 &#xff08;68UF&#xff09; 温度&#xff08;105摄氏度&#xff09;等 电容容量判断方法&#xff1a;直标法&#xff1a;上图&#xff0c;容量68微法&#xff0c;耐压值400V。数字表示法&#xff1a;方…

如何在公司审计中保持安全

如何在公司审计中保持安全 如今&#xff0c;财务弹性是决定您的公司能否在不确定时期适应和发展的主要属性之一。这可能令人很惊讶&#xff0c;但您的年度业务审计可以成为您提高业务敏捷性的秘密武器。它通过确定内部控制和财务报告的效果以及哪些流程改进应该在您的优先级列…

蓝桥杯Python练习题15-区间k大数查询

资源限制   内存限制&#xff1a;256.0MB C/C时间限制&#xff1a;1.0s Java时间限制&#xff1a;3.0s Python时间限制&#xff1a;5.0s 问题描述   给定一个序列&#xff0c;每次询问序列中第l个数到第r个数中第K大的数是哪个。 输入格式   第一行包含一个数n&#xf…

黑马Hive+Spark离线数仓工业项目-任务流调度工具AirFlow(2)

Oracle与MySQL调度方法 目标&#xff1a;了解Oracle与MySQL的调度方法 实施 Oracle调度&#xff1a;参考《oracle任务调度详细操作文档.md》 - step1&#xff1a;本地安装Oracle客户端 - step2&#xff1a;安装AirFlow集成Oracle库 - step3&#xff1a;创建Oracle连接 - ste…

ODT在手,DDR5布线可以任性走?

作者&#xff1a;一博科技高速先生成员 姜杰 ODT是On Die Termination的缩写&#xff0c;又叫片内端接&#xff0c;顾名思义&#xff0c;就是把端接电阻放在了芯片内部。作为一种端接&#xff0c;ODT可以减小反射&#xff0c;对信号质量的改善显而易见&#xff0c;SI攻城狮很…