思路:影响二手汽车售价的特征很多,比如汽车品牌,汽车性能,上牌年限等,同样的零部件参数,不一样的品牌,对应的售价是不一样的,而车的品牌众多,不在参数范围之内,所以本文将售价与新车价的比例作为目标进行分析预测。正文提供了三种求解方法:K近邻,线性回归,随机森林,以均方根误差为评判标准。

一:数据来源

瓜子二手车北京地区的二手车售卖信息。

本数据只包含了基本信息,其它参数未进行爬取。

import numpy as np

import pandas as pd

import matplotlib.pyplot as plt

%matplotlib inline

df = pd.read_excel("北京二手车.xlsx")

二:数据清洗

1.我们将上牌时间与2018年8月的时间差记为使用时间的长短,并将其他字段的字符中提取有用的信息

df['time'] = '2018-08'

df['使用时间'] = (pd.to_datetime(df.time)-pd.to_datetime(df.上牌时间)).map(lambda x :x.days)#单位是天

df['里程'] = df['里程数'].str[:-3]

df['排标'] = df.排放标准.str[:2]

df['过户次数'] = df.过户次数.str[0].astype(int)

df['售价'] = df.保价.str.strip('万').str[1:].astype(float)

df['原价'] = df.新车价.str.strip('新车指导价').str.strip('万(含税)').astype(float)

df.drop(['上牌时间','time','里程数','排放标准','保价','新车价','车名','时间急迫度'],axis=1,inplace = True)

得到初步清洗的数据

接下来将文字数字化

label_mapping = {"自动": 1, "手动": 0}

df['变速箱'] = df.变速箱.map(label_mapping)

label_mapping = {"国四": 4, "国五": 5,"国三": 3, "国二": 2}

df['排标'] = df.排标.map(label_mapping)

得到如下数据:

因为在日常中进行时间估计不会说我的车开了多少天,基本都是一年半,两年之类的大概说法,想将使用时间按年(365天)换算。一样的指标不一样的品牌也会导致原价不一样,售价不一样,故此我们以售价与原价的占比为目标进行估计。

注意到数据中含有空值,且“原价”字段中空值最多,但数量比较少,故删去。

df.dropna(inplace = True)

df['占比'] = round(df.售价/df.原价,2) #保留2位小数

df['时间'] = round(df.时间/365,1) #保留1一位小数

df.drop(['售价','原价'],axis=1,inplace = True)

得到最终清洗好的数据集干净的数据集

三:特征选取

虽然特征不多,但是也要进行特征工程,特征共线性对于一些模型(比如线性回归)影响很大,也去掉一些无用特征,使得模型的拟合能力更强。

先来看一下各个特征对于目标的分布:

mpl.rcParams['font.sans-serif'] = 'FangSong' # 中文字体设置-仿宋

mpl.rcParams['axes.unicode_minus'] = False

for i in df.columns[:-1]:

fig,ax = plt.subplots(1,1,figsize=(18,4))

df_1=df[['占比',i]].groupby([i],as_index=False).mean()

ax.set_xlabel(i,fontsize = 45)

ax.set_ylabel('占比',fontsize = 45)

sns.barplot(x=i,y='占比',data=df_1)

从上图图看汽车排量对于售价的影响不大,后续建模可以考虑将其删去

上图可知,虽不明显,但是随着过户次数增多,汽车售价降低

由上图发现,自动挡的车比手动挡车更值钱,平均售价更高

很明显,用车年限对于车的售价起着至关重要的作用

行驶的里程数越高,售价越低,对于目标的影响明显

汽车排放标准越高越值钱,排放标准对于售价影响很大

接着来看各个特诊之间是否具有线性关系:

Correlation = pd.DataFrame(df[['排量','过户次数','变速箱','使用时间','里程','排标']])

colormap = plt.cm.viridis

plt.figure(figsize=(14,12))

plt.title('Pearson Correaltion of Feature',y=1.05,size=15)

sns.heatmap(Correlation.astype(float).corr(),linewidths=0.1,vmax=1.0,square=True,cmap=colormap,linecolor='white',annot=True,xticklabels = True)

发现使用年限和里程数具有很大的相关性,后续建模可以考虑去掉里程数这一特征。

四:建模预测

1.KNN模型:

from sklearn.preprocessing import StandardScaler

from sklearn.neighbors import KNeighborsRegressor

from sklearn.metrics import mean_squared_error

features = ['排量','过户次数','变速箱','使用时间','里程','排标']

df1 = df.copy()

df1[features] = StandardScaler().fit_transform(df1[features])

df1_train = df1.iloc[:3000]

df1_test = df1.iloc[3000:]

def k():

knn = KNeighborsRegressor(5)

knn.fit(df1_train[features], df1_train['占比'])

predictions = pd.DataFrame(knn.predict(df1_test[features]))

predictions = round(predictions,2)

mse = mean_squared_error(df1_test['占比'], predictions)

rmse = mse ** (1/2)

score = knn.score(df1_test[features], df1_test['占比'])

print(features)

print("rmse",rmse)

print("score",score)

print("-"*40)

可以看到当特征为'过户次数','变速箱','使用时间','里程','排标'时,模型rmse最低

2.sklearn线性回归预测

#线性回归模型

from sklearn import linear_model

features = ['排量','过户次数','变速箱','使用时间','里程','排标']

df2=df.copy()

df2[features] = StandardScaler().fit_transform(df2[features])

df2_train = df2.iloc[:3000]

df2_test = df2.iloc[3000:]

def L():

model = linear_model.LinearRegression()

model.fit(df2_train[features], df2_train['占比'])

result = pd.DataFrame(model.predict(df2_test[features]))

result = round(result,2)

mse = mean_squared_error(df2_test['占比'], result)

rmse = mse ** (1/2)

score = model.score(df2_test[features], df2_test['占比'])

print(features)

print("rmse",rmse)

print("score",score)

print("theta",model.coef_ )

print("截距",model.intercept_)

print("-"*40)

theta值为负,意味着负相关,即过户次数、里程数、使用时间三特征与售价呈负相关,按照我们的常识,当然三手比二手便宜,开的时间和里程越久汽车的价值越低。

3.随机森林

from sklearn.ensemble import RandomForestRegressor

features = ['排量','过户次数','变速箱','使用时间','里程','排标']

df4 = df.copy()

df4[features] = StandardScaler().fit_transform(df4[features])

df4_train = df4.iloc[:3000]

df4_test = df4.iloc[3000:]

rfr = RandomForestRegressor(n_estimators = 20,max_features = 3)

rfr.fit(df4_train[features],df4_train['占比'])

result3 = pd.DataFrame(rfr.predict(df4_test[features]))

mse = mean_squared_error(df4_test['占比'], y_pred)

rmse = mse ** (1/2)

随机森林暂不做调参,本文仅供参考

3.融合以上三个模型:将三个模型的预测值求平均

比较两个模型的rmse值,以['过户次数', '变速箱', '使用时间', '里程', '排标']为特征比较好。

#融合两个模型,以['过户次数', '变速箱', '使用时间', '里程', '排标']为特征

features = ['过户次数','变速箱','使用时间','里程','排标']

df6=df.copy()

df6[features] = StandardScaler().fit_transform(df2[features])

df6_train = df6.iloc[:3000]

df6_test = df6.iloc[3000:]

model = linear_model.LinearRegression()

model.fit(df6_train[features], df6_train['占比'])

result1 = pd.DataFrame(model.predict(df6_test[features]))

knn = KNeighborsRegressor(5)

knn.fit(df6_train[features], df6_train['占比'])

result2 = pd.DataFrame(knn.predict(df6_test[features]))

result = (result1 + result2 + result3)/3

mse = mean_squared_error(df6_test['占比'], result)

rmse = mse ** (1/2)

print(rmse)

rmse 降低至

可见多个模型预测可降低标准差,模型得到优化。

四 总结:

二手车的售价与里程数、已使用年限、过户次数负相关。与排放标准、排量、变速箱正相关,即排量越大(印象里面豪车都是大排量)、自动、排放标准越大售价定的比例更高(排放标准越高代表废气排放越少)。多模型的融合可降低均方根误差。

当然线性方程也可采用梯度下降求解:(仅当做求解参考,可忽视。)

#建立目标函数模型

def model(X, theta):

return np.dot(X, theta.T)

#定义X,y(target)

df3 = df.copy()

df3.insert(0, 'Ones', 1)

df3_train = df3.iloc[:3000]

df3_test = df3.iloc[3000:]

train = df3_train.as_matrix()

test = df3_test.as_matrix()

cols = train.shape[1]

X = train[:,0:cols-1]

y = train[:,cols-1:cols]

#对于theta赋予初始值,这里赋值为0

theta = np.zeros([1, 7]) #一共7个参数

#定义损失函数

def cost(X, y, theta):

errors =(model(X, theta)-y)**2

return np.sum(errors)/len(X)

#计算梯度

def gradient(X, y, theta):

grad = np.zeros(theta.shape)#每一个参数对应一个下降梯度

error = (model(X, theta)- y).ravel()

for j in range(len(theta.ravel())): #for each parmeter

term = np.multiply(error, X[:,j])

grad[0, j] = np.sum(term) / len(X)

return grad

#梯度下降求解

#iters为梯度下降计算次数,以迭代次数为终止策略,当然也能以损失值小于多少为终止策略或以时间限度为终止策略

#alpha为学习率

import time

def descent(X,y,theta,iters,alpha):

i = 0 #迭代次数

init_time = time.time()

grad = np.zeros(theta.shape) # 计算的梯度

costs = [cost(X, y, theta)] # 损失值

while True:

grad = gradient(X, y, theta) #计算梯度

theta = theta - alpha*grad #更新参数theta

costs.append(cost(X, y, theta)) # 计算新的损失

i += 1

if i >iters: #迭代终止

break

return theta, costs, i-1,grad, time.time() - init_time

#梯度下降可视化(损失与迭代次数)

from matplotlib import pyplot as plt

iters = 5000

theta,costs,n,grad,times = descent(X,y,theta,iters,0.0001)

fig, ax = plt.subplots(figsize=(12,4))

ax.plot(np.arange(n+2), costs, 'r')

ax.set_xlabel('Iterations')

ax.set_ylabel('Cost')

ax.set_title( 'Error vs. Iteration (spent %.2f s)'%times)

可以看到学习率偏大,下降的很快,迭代五千次基本收敛于0.01左右。

将alpha 降为 0.00001,得到如下曲线

计算rsme:

#当学习率是0.00001时,theta=array([[0.00750955, 0.01538768, 0.00186182, 0.00707161, 0.0132343 ,0.01844291, 0.03455897]])

X_test = test[:,0:cols-1]

y_test = test[:,cols-1:cols]

mse = mean_squared_error(y_test, model(X_test,theta))

rmse = mse ** (1/2)

#rmse = 0.3092584574922207

对比rsme,梯度下降的值比前两者较大,说明梯度下降还有待优化,考虑到篇幅过长,但此处不再分析优化。

或者直接用线性方程求解:

直接给出theta的求解方程

from numpy.linalg import inv

X = train[:,0:cols-1]

y = train[:,cols-1:cols]

#计算rsme

theta = np.dot(np.dot(inv(np.dot(X.T, X)), X.T), y)

#theta = array([[ 0.56614127],[ 0.00770775],[-0.006578 ],[ 0.03765713],[-0.04862077],[-0.00399016],[ 0.02989723]]

X_test = test[:,0:cols-1]

y_test = test[:,cols-1:cols]

mse = mean_squared_error(y_test, model(X_test,theta.T))

rmse = mse ** (1/2)

#rmse = 0.0839764322871155

线性方程直接求出来的结果和sk-learn算出来的结果十分相似,当线性相关的时候直接用方程求解是十分便利的。但是有一个缺陷:有时候未必有解。

文章可转载,请注明出处!

用python预测车牌价格_利用python预测二手车售价相关推荐

  1. python多元线性回归实例_利用Python进行数据分析之多元线性回归案例

    线性回归模型属于经典的统计学模型,该模型的应用场景是根据已知的变量(自变量)来预测某个连续的数值变量(因变量).例如,餐厅根据每天的营业数据(包括菜谱价格.就餐人数.预定人数.特价菜折扣等)预测就餐规 ...

  2. python逐步回归筛选变量_利用python实现逐步回归

    逐步回归的基本思想是将变量逐个引入模型,每引入一个解释变量后都要进行F检验,并对已经选入的解释变量逐个进行t检验,当原来引入的解释变量由于后面解释变量的引入变得不再显著时,则将其删除.以确保每次引入新 ...

  3. python post请求 上传图片_利用python模拟实现POST请求提交图片的方法

    本文主要给大家介绍的是关于利用python模拟实现POST请求提交图片的方法,分享出来供大家参考学习,下面来一看看详细的介绍: 使用requests来模拟HTTP请求本来是一件非常轻松的事情,比如上传 ...

  4. 基于python的系统构建_利用python构建一个简单的推荐系统

    摘要: 快利用python构建一个属于你自己的推荐系统吧,手把手教学,够简单够酷炫. 本文将利用python构建一个简单的推荐系统,在此之前读者需要对pandas和numpy等数据分析包有所了解. 什 ...

  5. python ks值计算_利用Python计算KS的实例详解

    在金融领域中,我们的y值和预测得到的违约概率刚好是两个分布未知的两个分布.好的信用风控模型一般从准确性.稳定性和可解释性来评估模型.sOf免费资源网 一般来说.好人样本的分布同坏人样本的分布应该是有很 ...

  6. python实现邮件客户端_利用python实现简单的邮件发送客户端示例

    脚本过于简单,供学习和参考.主要了解一下smtplib库的使用和超时机制的实现.使用signal.alarm实现超时机制. #!/usr/bin/env python # -*- coding: ut ...

  7. python制作图片墙_利用python生成照片墙的示例代码

    PIL(Python Image Library)是python的第三方图像处理库,但是由于其强大的功能与众多的使用人数,几乎已经被认为是python官方图像处理库了.其官方主页为:PIL. PIL历 ...

  8. python金融量化风险_利用 Python 进行量化投资分析 - 利率及风险资产的超额收益...

    本文是 利用 Python 进行量化投资分析 系列的第一篇文章,这个系列主要以 Python 作为工具,结果国内金融市场情况,及使用真实历史数据来实践一些基础的金融投资概念. 这篇文章主要讲述了真实利 ...

  9. python处理nc数据_利用python如何处理nc数据详解

    利用python如何处理nc数据详解 来源:中文源码网    浏览: 次    日期:2018年9月2日 [下载文档:  利用python如何处理nc数据详解.txt ] (友情提示:右键点上行txt ...

最新文章

  1. B 站校招面试官“炫耀资产、贬低应试者”?当事人发长文回应,北邮学子要求向学校道歉
  2. MAC打开EXE文件的三大方法
  3. 汉字编码表(五笔编码表)
  4. lvs主从服务器转发风暴(广播风暴、大流量)
  5. 矩阵的二范数_【专题】GAN(二)—— 目标函数的优化
  6. json web token没有哪个成分_【分享项目】给你看看我们公司的登录认证是怎么做的?!(SpringBoot+Shiro+Token+Redis)...
  7. aws dynamodb_AWS Lambda将数据保存在DynamoDB中
  8. js判断对象为空_在 JavaScript 中如何检查对象为空
  9. 转帖:由C++转向C#的几种对策
  10. Ubuntu环境下NFS服务器搭建
  11. win10进不去计算机配置,Win10电脑系统设置打不开的解决方法
  12. 游戏感:虚拟感觉的游戏设计师指南——第十九章 游戏感的未来
  13. 手机号电子邮箱怎么填写?
  14. python3中expected an indented block(缩进问题)
  15. 解决-手机通过Charles连接代理无法上网,亲测可用
  16. QQ个性装扮气泡免费使用
  17. Android 上 Https 双向通信— 深入理解KeyManager 和 TrustManagers
  18. 图像大小调整_如何在Windows中调整图像和照片的大小
  19. 用c语言编写出的情话,c语言for情话
  20. BigDecimal 往左移动两位小数_移动信号灯

热门文章

  1. abb定位器与执行器和接线板之间的连接方式
  2. 实体店如何做社群裂变?社群裂变软件如何拉人进群?
  3. ios开发调用系统自带的分享
  4. Dubbo:搭建管理控制台(dubbo-admin)
  5. 前端的存储技术cookie、sessionStorage、localStorage
  6. 百密一疏——特殊的日子
  7. 放大器:A、B、AB、D、G、H
  8. 打造一个云计算业的江左梅郎
  9. Android Studio 代码提示不区分大小写
  10. ASP.NET core 搭建于 Deepin 2015.4 记录