标题实验分析与设计思路

(1)读入数据
(2)分析数据格式和确定使用的模型
(3)数据预处理
(4)使用所选模型进行测试并改进
(5)应用不同算法(模型)对比效果
(6)使用集成学习算法提升回归效果
(7)网格搜索调参数

使用的函数库和初始化

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import warnings
import time# 模型预测
from sklearn.linear_model import LinearRegression
from sklearn.linear_model import Ridge
from sklearn.linear_model import Lasso
from sklearn.tree import DecisionTreeRegressor# 集成学习
from sklearn.ensemble import RandomForestRegressor
import xgboost as xgb# 参数搜索
from sklearn.model_selection import GridSearchCV,cross_val_score,StratifiedKFold
# 评价指标
from sklearn.metrics import make_scorer
from sklearn.metrics import mean_squared_error, mean_absolute_error,accuracy_score
from sklearn.model_selection import learning_curve, validation_curvewarnings.filterwarnings("ignore")# 消除警告
# 初始化图形参数
plt.rcParams['figure.figsize'] = (16,9)# 设置大小
# 图形美化
plt.style.use('ggplot')
# 图例无法显示中文的解决方法:设置参数
plt.rcParams['font.sans-serif']=['SimHei'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False # 用来正常显示负号

实验结果及分析

1、读取数据

这里使用在阿里巴巴天池下载的二手车交易数据https://tianchi.aliyun.com/?spm=5176.12281973.J_9711814210.8.3dd53eafkBCu9m

used_car.csv

  • 数据说明:
  • 读入数据
# 读取数据,以空格划分
used_car = pd.read_csv(r'C:\Desktop\数据挖掘实践\大作业\used_car.csv', sep=' ')
# 输出数据大小
print('数据大小:',used_car.shape)
'''可以看到数据一共有150000条,31个属性'''# 预览头10行数据
used_car.head(10)

查看数据大小:可以看到数据一共有150000条,31个属性

2、数据预处理

  • 查看数据信息
'''
可以看到:
model、bodyType、fuelType、gearbox这几个属性有缺失值
'''
# 查看对应数据列名和是否存在NAN缺失信息
used_car.info()


可以看到:model、bodyType、fuelType、gearbox这几个属性有缺失值

print('各列缺失值统计结果为:')
print(used_car.isnull().sum())

  • 统计描述
# 查看数值特征列的统计信息
used_car.describe()

  • 去除重复数据
# 默认根据所有属性去除,keep设置保留第一条一样的数据
used_car.drop_duplicates(keep='first')


可以看出无重复数据

  • 处理缺失值
    前面统计的时候知道,model、bodyType、fuelType、gearbox这几个属性有缺失值
    且这些属性都是标签类的数值型数据
    故填充缺失值使用众数
    对于大数据集也可以直接去掉有空值的样本
    使用函数dropna()
# 如果有多个众数的情况,用used_car.mode()[0]第一个众数填充
used_car['model'] = used_car['model'].fillna(used_car['model'].mode()[0])
used_car['bodyType'] = used_car['bodyType'].fillna(used_car['bodyType'].mode()[0])
used_car['fuelType'] = used_car['fuelType'].fillna(used_car['fuelType'].mode()[0])
used_car['gearbox'] = used_car['gearbox'].fillna(used_car['gearbox'].mode()[0])
  • 再次查看是否还有缺失值
used_car.info()

  • 提取不同类型的属性名
# 提取数值型属性名(exclude除去分类型)
numerical_cols = used_car.select_dtypes(exclude='object').columns
numerical_cols

# 提取分类型属性名(include包含分类型)
categorical_cols = used_car.select_dtypes(include='object').columns
categorical_cols

  • 划分特征和标签数据(手动降维)
    从数据说明中可以看出有些特征对于预测价格没有作用
    这里直接将其剔除
# 选择特征列名
feature_cols = [col for col in numerical_cols if col not in ['SaleID','name','regDate','creatDate','price','model','brand','regionCode','seller']]
feature_cols = [col for col in feature_cols if 'Type' not in col]X = used_car[feature_cols]
y = used_car['price']print('特征数据大小:',X.shape)
print('标签数据大小:',y.shape)

  • 查看标签数据(price)的分布
plt.hist(y)


可以看到标签主要分布再0-2000内
数据归一化在后面优化结果里

3、挖掘算法

预测二手车价格是一个回归任务,故使用回归模型。






4、模型训练+预测结果

  • 定义一个函数,进行k折交叉验证:
def modelKFold2MAE(X,y,model,k):# k折交叉验证train_scores = []  # 存放训练集精度test_scores = []  # 存放测试集精度# k折交叉验证(n_splits=k)sk = StratifiedKFold(n_splits=k,shuffle=True,random_state=0)for train_ind,test_ind in sk.split(X,y):# 训练数据X_train = X.iloc[train_ind].valuesy_train = y.iloc[train_ind]# 测试数据X_test = X.iloc[test_ind].valuesy_test = y.iloc[test_ind]# 训练模型model.fit(X_train,y_train)# 预测pred_train = model.predict(X_train)pred_test = model.predict(X_test)# 精度(使用平均错误率MAE)train_score = mean_absolute_error(y_train,pred_train)train_scores.append(train_score)test_score = mean_absolute_error(y_test,pred_test)test_scores.append(test_score)print('训练集的平均MAE:',np.mean(train_scores))print('测试集的平均MAE:',np.mean(test_scores))return train_scores,test_scores
  • 使用线性回归模型训练+预测结果
'''
可以看到计算出来的MAE很大
'''
lr = LinearRegression()
k = 5
train_scores,test_scores = modelKFold2MAE(X,y,lr,k)


可以看到计算出来的MAE(平均绝对误差)很大

  • 绘制特征v_2的值与标签的散点图
lr = LinearRegression()
lr.fit(X,y)
# 绘制特征v_2的值与标签的散点图
subsample_index = np.random.randint(low=0, high=len(y), size=50)plt.scatter(X['v_2'][subsample_index], y[subsample_index], color='black')
plt.scatter(X['v_2'][subsample_index], lr.predict(X.loc[subsample_index]), color='red')
plt.xlabel('v_2')
plt.ylabel('price')
plt.legend(['True Price','Predicted Price'],loc='best')
print('The predicted price is obvious different from true price')
plt.show()


发现模型的预测结果(红色点)与真实标签(黑色点)的分布差异较大
且出现了部分预测值小于0的情况
这说明该模型存在问题

  • 绘制标签数据的分布图:
print('It is clear to see the price shows a typical exponential distribution')
plt.figure(figsize=(15,5))
plt.subplot(1,2,1)
sns.distplot(y)
plt.subplot(1,2,2)
sns.distplot(y[y < np.quantile(y, 0.9)])


通过作图我们发现数据的标签(price)呈现长尾分布,不利于我们的建模预测
故对标签数据进行log(x+1)变换,使标签贴近于正态分布

# 对标签数据进行log(x+1)变换,使标签贴近于正态分布
y_ln = np.log(y+1)
  • 再次以v_2特征和标签为xy轴对预测值和真实值进行可视化
lr = LinearRegression()
lr.fit(X,y_ln)
# 绘制特征v_2的值与标签的散点图
subsample_index = np.random.randint(low=0, high=len(y_ln), size=50)plt.scatter(X['v_2'][subsample_index], y_ln[subsample_index], color='black')
plt.scatter(X['v_2'][subsample_index], lr.predict(X.loc[subsample_index]), color='red')
plt.xlabel('v_2')
plt.ylabel('price')
plt.legend(['True Price','Predicted Price'],loc='best')
print('The predicted price seems normal after np.log transforming')
plt.show()


发现预测结果与真实值较为接近,且未出现异常状况

  • 使用对数化之后的数据进行线性回归预测
# 使用对数化之后的数据进行线性回归预测
lr = LinearRegression().fit(X,y_ln)
# 这里直接调用cross_val_score函数进行交叉验证
scores = cross_val_score(lr,X=X,y=y_ln,verbose=1,cv=5,scoring=make_scorer(mean_absolute_error))
print('线性回归5折交叉验证的平均MAE:',np.mean(scores))


可以看到对数化之后的数据使用线性回归模型进行5折交叉验证之后的平均MAE明显比原始数据训练出来的模型的MAE小
说明对数据进行处理比没有处理的数据要更适合该模型

  • 展示5折交叉验证的5个MAE
scores = pd.DataFrame(scores.reshape(1,-1))
scores.columns = ['cv' + str(x) for x in range(1, 6)]
scores.index = ['MAE']
scores

5、结果可视化

  • 绘制学习率曲线和验证曲线
'''
定义一个绘制学习率曲线和验证曲线的函数
输入:estimator为传入的模型title为图像的标题cv为k折交叉验证的kn_jobs为learning_curve函数中的n_jobs参数'''
def plotLearningCurve(estimator,title,X,y,ylim=None,cv=None,n_jobs=1,train_size=np.linspace(.1, 1.0, 5 )):# 画布plt.figure()  plt.title(title)# 设置y轴区间if ylim is not None:  plt.ylim(*ylim) plt.xlabel('Training example')  plt.ylabel('score')# 调用learning_curve函数train_sizes, train_scores, test_scores = learning_curve(estimator,X,y,cv=cv,n_jobs=n_jobs,train_sizes=train_size,scoring = make_scorer(mean_absolute_error))  train_scores_mean = np.mean(train_scores, axis=1)  train_scores_std = np.std(train_scores, axis=1)  test_scores_mean = np.mean(test_scores, axis=1)  test_scores_std = np.std(test_scores, axis=1)  #区域  plt.grid()plt.fill_between(train_sizes, train_scores_mean - train_scores_std,  train_scores_mean + train_scores_std, alpha=0.1,  color="r")  plt.fill_between(train_sizes, test_scores_mean - test_scores_std,  test_scores_mean + test_scores_std, alpha=0.1,  color="g") # 绘制两条线plt.plot(train_sizes, train_scores_mean, 'o-', color='r',  label="Training score")  plt.plot(train_sizes, test_scores_mean,'o-',color="g",  label="Cross-validation score")plt.legend(loc="best")  return plt


训练曲线和验证曲线相聚距离较小,说明该模型是一个地方差且低偏差的
一个比较好的模型

6、多种模型算法对比

models = [LinearRegression(),Ridge(),Lasso(),DecisionTreeRegressor()]
result = dict()# 遍历所有模型
for model in models:model_name = str(model).split('(')[0]# 5折交叉验证scores = cross_val_score(model,X=X,y=y_ln,verbose=1,cv=5,scoring=make_scorer(mean_absolute_error))print('{0} 5折交叉验证的平均MAE:{1}'.format(model_name,np.mean(scores)))result[model_name] = scores


可以分别得到该模型的MAE以及训练时间(红色部分)

result = pd.DataFrame(result)
result.index = ['cv' + str(x) for x in range(1, 6)]
result
  • 将每次cv的MAE做成表格可视化


根据5折交叉验证的平均MAE可以分析出以下结果:
线性回归对于该数据效果最好
其次是回归树
Lasso的效果最差

7、集成

这里使用两种集成学习,一种是并行boosting迭代型的xgboost算法;一种是串行的随机森林算法

  • 随机森林
forest = RandomForestRegressor(n_estimators=120,random_state=0,max_depth=7)
forest_scores = cross_val_score(forest,X=X,y=y_ln,verbose=1,cv=5,scoring=make_scorer(mean_absolute_error))
print('随机森林5折交叉验证的平均MAE:',np.mean(forest_scores))

  • xgboost模型
# xgb回归模型
'''
n_estimators=120使用120个基学习器
learning_rate=0.1学习率
防止过拟合:设置subsample=0.8colsample_bytree=0.9列名筛选max_depth=7最大深度
'''
xgr = xgb.XGBRegressor(n_estimators=120, learning_rate=0.1, gamma=0, subsample=0.8,\colsample_bytree=0.9, max_depth=7) #,objective ='reg:squarederror'xgr_scores = cross_val_score(xgr,X=X,y=y_ln,verbose=1,cv=5,scoring=make_scorer(mean_absolute_error))
print('XGBRegressor折交叉验证的平均MAE:',np.mean(xgr_scores))

  • 对比结果可视化
fig = plt.figure(figsize=(20,10))
cv = [i for i in range(5)]
plt.plot(cv,forest_scores,'go-',label='随机森林')
plt.plot(cv,xgr_scores,'r>--',label='xgboost')
#设置x轴刻度
ticks = plt.xticks(cv)
#设置x轴和y轴的名称
xlabel = plt.xlabel('cv')
ylabel = plt.ylabel('MAE',rotation=0)
plt.legend(loc='best')


从上图可以看出
对于该数据,xgboost的效果要比随机森林好许多

  • 网格搜索调参
    从上图的分析可以看出xgboost的效果较好
    这里使用该算法进行网格调参选取最佳参数
    主要调整的参数有两个:
    基学习器数量和学习率;分别设置5个值进行调整
xgr = xgb.XGBRegressor(gamma=0, subsample=0.8,colsample_bytree=0.9, max_depth=7)
param_grid = {'learning_rate': [0.01,0.05,0.1,0.2,0.25],'n_estimators':[75,100,125,150,175]}
# 带交叉验证的网格搜索,5折交叉验证
xgb_gs = GridSearchCV(xgr, param_grid, cv=5)
xgb_gs.fit(X,y)


输出最佳的参数和最佳参数的精度:

print('最佳参数:',xgb_gs.best_params_)
print('最佳参数的训练精度:{:.2f}'.format(xgb_gs.best_score_))


最佳的参数是175个基学习器和0.1的学习率

  • 查看分析交叉验证的结果:
xgb_gs_result = pd.DataFrame(xgb_gs.cv_results_)
# 显示前5行
display(xgb_gs_result.head())


8、使用集成算法前后的结果比较分析

主要分析DecisionTreeRegressor、随机森林和xgboost的结果
因为随机森林和xgboost使用的基分类器都是决策树

# 去除DecisionTreeRegressor的结果
dtr_scores = []
for i in range(len(result['DecisionTreeRegressor'])):dtr_scores.append(result['DecisionTreeRegressor'].iloc[i])fig = plt.figure(figsize=(20,10))
cv = [i for i in range(5)]
plt.plot(cv,dtr_scores,'bo-',label='回归树')
plt.plot(cv,forest_scores,'g>--',label='随机森林')
plt.plot(cv,xgr_scores,'r>--',label='xgboost')
#设置x轴刻度
ticks = plt.xticks(cv)
#设置x轴和y轴的名称
xlabel = plt.xlabel('cv')
ylabel = plt.ylabel('MAE',rotation=0)
plt.legend(loc='best')


发现相比不使用集成学习的回归树,两种集成学习算法(随机森林和xgboost)的MAE更小,说明集成学习对于数据有较好的作用
其中以xgboost作用更为明显。

总结与思考

1、在整个的数据挖掘流程中,预处理是不是可有可无的一个步骤?主要解决哪些问题,有什么作用?
答:预处理是一个很重要且必不可少的步骤
主要解决:
(1)缺失数据填补或删除
(2)处理离群点或噪声点
(3)将数据成模型需要的格式(离散或是连续值)
(4)数据标准化
作用:
(1)可以处理缺失数据,否则模型无法运行
(2)确保模型不会因为数据格式等问题导致精度下降

2、不同算法之间有无优劣之分?有没有一种算法是最优的?
答:不同算法之间无法直观比较优劣,没有一种算法可以说是最优的。
对于不同的任务使用的算法不一样:分类任务使用分类算法、聚类任务使用聚类算法。
对于不同的数据适用的算法也不一样。存在对于数据A线性回归算法比回归树精度高,但是对于数据B回归树精度比线性回归算法精度高的情况。

【Python数据分析】二手车价格预测相关推荐

  1. Python【二手车价格预测案例】数据挖掘

    问题陈述 随着代步工具的普及,"买卖车"需求激增.但对于部分预算有限的个体或家庭而言,购置一辆二手车更为明智.二手车的巨大供给需求催生了近年来日益壮大的二手车市场,但二手车的售卖面 ...

  2. Python二手车价格预测(二)—— 模型训练及可视化

    系列文章目录 一.Python数据分析-二手车数据获取用于机器学习二手车价格预测 二.Python二手车价格预测(一)-- 数据处理 文章目录 系列文章目录 前言 一.明确任务 二.模型训练 1.引入 ...

  3. Python二手车价格预测(一)—— 数据处理

    文章目录 前言 一.数据 二.处理过程 1.引入库 2.读入数据 3.删除无效列与填充空值 4.数值型数据处理 5.日期型数据处理 6.二值型数据处理 7.One-Hot型数据处理 结语 前言 一年半 ...

  4. 【组队学习】【24期】河北邀请赛(二手车价格预测)

    河北邀请赛(二手车价格预测) 开源内容: https://github.com/datawhalechina/team-learning-data-mining/tree/master/SecondH ...

  5. 基于机器学习的二手车价格预测及应用实现(预测系统实现)

    1.摘要 随着中国汽车工业的迅速发展,国内的汽车数量也在迅速增长.新车销售市场已经逐渐饱和,而二手车交易市场正在兴起.但是,由于中国的二手车市场尚未成熟,与发达国家相比仍存在较大差距.其中一个重要原因 ...

  6. 基于二手车价格预测——特征工程

    特征工程 特征工程 分析: 第一步:异常值处理 箱型图法: 第二步:特征构造 第三步:数据分桶 数据分桶详解 删除不需要的数据 特征归一化 总结--特征 1.特征构造: 2.异常类型处理 3.构造新特 ...

  7. 二手车价格预测数据探索

    二手车价格预测数据探索 1.赛题理解 [类型]属于回归问题. [数据字段] 训练数据字段: 字段名字 含义 类型 name 汽车编码 int regDate 汽车注册时间 int model 车型编码 ...

  8. Datawhale task4打卡——二手车价格预测

    Datawhale task4打卡--二手车价格预测 1. 线性回归模型 1.1 *特征要求(易忽略) 1.2 *处理长尾分布(易忽略) 2. 模型性能验证 2.1 目标函数 2.2 交叉验证 2.2 ...

  9. 数据挖掘二手车价格预测 Task05:模型融合

    模型融合是kaggle等比赛中经常使用到的一个利器,它通常可以在各种不同的机器学习任务中使结果获得提升.顾名思义,模型融合就是综合考虑不同模型的情况,并将它们的结果融合到一起.模型融合主要通过几部分来 ...

  10. 数据挖掘-二手车价格预测 Task04:建模调参

    数据挖掘-二手车价格预测 Task04:建模调参 模型调参部分 利用xgb进行五折交叉验证查看模型的参数效果 ## xgb-Model xgr = xgb.XGBRegressor(n_estimat ...

最新文章

  1. 与《管理幸福》一书作者Jurgen Appelo的访谈
  2. arm linux中添加开机启动
  3. 算法--------设计哈希集合
  4. 有向图的拓扑排序的理解和简单实现(Java)
  5. Logistic回归的自己推导
  6. javascript 函数 add(1)(2)(3)(4)实现无限极累加 —— 一步一步原理解析
  7. beautifulsoup_BeautifulSoup爬虫了解一下
  8. 微软张宏江出任金山CEO 求伯君正式退休
  9. 三点估算 Sigma(σ)的值,期望值,标准差
  10. 手工扒网页模板简单流程
  11. 从玩具到工具,OPPO新一代智能眼镜Air Glass正式发布
  12. GCKontrol与嵌入式系统:STM32实现电机控制案例
  13. c语言程序有且只有一个什么函数,一个c程序有且仅有一个什么函数
  14. [ZJOI2014]力 题解
  15. 【上海交大oj】畅畅的牙签袋(改)(枚举+模拟)
  16. Coffee and Coursework
  17. python学习笔记05——字符串
  18. 张飞老师硬件第四部视频整理——模拟电路
  19. 北航微信打卡自动提醒程序
  20. 认购与申购的区别是什么

热门文章

  1. 数据分析——收入下降原因分析
  2. python 程序员待遇_python程序员待遇如何
  3. iOS(swift): Core ML的使用
  4. c语言写长方形体积公式是什么,长方体的体积公式 长方体的体积公式是什么
  5. 互联网+机器人”碰撞出啥样火花? 华数机器人以大数据云平台为智能制造连接“大脑”...
  6. oracle数据类型为文本类型,Oracle 字段类型
  7. 斗地主发牌游戏编程java,自己做的斗地主游戏发牌C#程序
  8. 青海干部网络学院 自动学习网站
  9. kasp技术原理_KASP 2x PCR Mix 说明书
  10. Pearson相关系数公式的四种形式及Python代码实现