纸上得来终觉浅,绝知此事要躬行
这两天在Q同学的安利下成(shi)功(bai)入坑机器学习,开始研究天池上面的数据挖掘入门比赛。第一个接触的便是二手车交易价格预测。本来觉得是一个比较简单的项目吧,套用一下keras解决波士顿房价回归预测的模型,写一个简单的神经网络把数据输入进去,就可以了。
因此我一直以为深度学习的基本步骤是:
(1)数据准备
(2)模型选择&模型开发
(3)模型评估(evaluate)
(4)模型预测
(5)模型调优(调参)
万万没想到啊,这个二手车交易价格预测,要想预测得准确,就要优化基本的机器学习方法。个人觉得和深度学习比起来,机器学习太难了,难在他底层全都是数学。整个过程包括:
(1)数据分析
(2)特征工程
(3)模型训练
(4)模型调参
特征工程涉及到很多的数据处理方法,其主要目的是,将数据以一种对模型更有用的形式表征出来,便于提高模型的表现效果。
翻看了keras之父弗朗索瓦·肖莱的《Python深度学习》一书,里面对特征工程的定义是:
“特征工程是指将数据输入模型之前,利用你自己关于数据和机器学习算法(包括神经网络)的知识对数据进行硬编码的变换(不是模型学到的),以改善模型的效果。”
多数情况下,一个机器学习模型无法从完全任意的数据中(指不经任何预处理)进行学习…例如你要预测一个时钟的图像,通过指针指向的内容来分析图像中的时间,那么可以将每个针尖对应的位置转换为(x,y)坐标,使得一个简单的机器学习算法就能预测时间,而不用编写复杂的图像识别程序。
最难的难点就在这个特征工程上面了。因为对一些数学统计学的概念,比如数据分桶、箱线图之类的不太了解,看天池给的代码也看不明白。感觉从接触科研到现在这是第一次遇到这么细化的数据处理问题。只好采用步步为营的方式,从头一行一行代码分析。
大家放心,我贴的代码放到一起绝对能运行。
第一步当然要导入必备的包。挨个解释一下:
(1)numpy
:numpy大家应该都很熟悉,是python封装好的矩阵运算库,能够完成矩阵之间的操作,各方面都很类似于matlab里的矩阵类型。
(2)pandas
:pandas是基于numpy的结构化数据工具,大家可以简单理解为它比numpy更加高层,一个最简单的例子就是,pandas的DataFrame类型比numpy的array矩阵更具有结构性。
(3)seaborn
和 matplotlib
:这两个都是Python绘图的工具库,其中seaborn是基于matplotlib的,绘图更加高级。seaborn之于matplotlib,恰似pandas之于numpy。
(4)missingno
:顾名思义,missing number。missingno是一个缺失值可视化分析模块,能够让无效的数据或者缺失的数据也可视化出来其缺失效果。怎么样,这个库是不是很强大?
(5)scipy
:scipy是一个科学计算库,它主要负责统计分析、线性代数计算、微积分计算。举个例子,我们代码里会用到的scipy.stats
,里面就包含了多种概率分布的随机变量,便于使用。
(6)time
:处理时间,因为源数据里面有时间,后续会对时间做处理。time会返回自计时以来的以秒为单位的当前时间作为浮点数。
(7)xgboost
:封装好的机器学习模型,训练的时候可以直接调用。说得官方一点的话,XGBoost是一个优化的分布式梯度增强库,目前大量的Kaggle选手选用XGBoost进行数据挖掘比赛。
(8)sklearn
:同理,也是Python事先封装好的一个机器学习工具库,建立在 NumPy, SciPy, Pandas 和 Matplotlib 之上,很多机器学习模型方法他都实现好了,调用即可,很适合我这种新手。
import numpy as np
import pandas as pd
import seaborn as sns
import missingno as msno
import matplotlib.pyplot as plt
from scipy import stats
import time
import xgboost as xgb
from sklearn.metrics import roc_auc_score,mean_absolute_error
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import cross_val_score,train_test_split
import sklearn.preprocessing as preprocessing
从上面的代码也可以看到,from sklearn import
的这几个包,都是一些机器学习要用到的工具/模型/组件,比如RandomForestClassifier
是随机森林,mean_absolute_error
是我们熟悉的mae(平均绝对误差,是一个常用的回归问题评估指标)。
接下来是数据加载。
用pandas加载天池给出的数据集,并把代表train训练集和test测试集矩阵data_train
和data_test
连接在一起,方便后续的处理。
data_train=pd.DataFrame(pd.read_csv(r'F:/kaggle天池/used_car_train_20200313.csv',sep=' '))
data_test=pd.DataFrame(pd.read_csv(r'F:/kaggle天池/used_car_testB_20200421.csv',sep=' '))
data_train['type']='train' #定义一个type属性便于区别训练集测试集
data_test['type']='test'
print(data_train.info(verbose=True,null_counts=True))
print(data_test.info(verbose=True,null_counts=True))
print(data_train.head())#打印表的前几行
print(data_test.head())
print(data_train.shape)#查看矩阵的尺寸形状
print(data_test.shape)
data_all=pd.concat([data_train,data_test],axis=0,ignore_index=True,sort=False)#按行连接训练集和测试集
这里有几个重要的方法:
head()
:当一个数据表比较大,但你又想看看它的大概情况,怎么办?这时候就可以用head(),head()默认打印出表格的前五行,方便我们对数据有大概的了解。如果你想打前十行,就写成head(10)就可以啦!
info()
:这个函数用于打印DataFrame的简要摘要,显示有关DataFrame的信息,包括索引的数据类型dtype和列的数据类型dtype,非空值的数量和内存使用情况。verbose
参数中文译为“冗长的”,它决定是否打印完整的摘要!
pd.concat()
:这个函数会把两个矩阵连接在一起。里面的axis值代表连接的维度,axis=0
代表把两个矩阵竖着连起来(按行往下拼接);axis=1
代表把两个矩阵横着连起来(按列向右拼接)。
pd.DataFrame()
:pandas自带的方法,能够将一个矩阵(array)转化为pandas特有的DataFrame
格式。DataFrame
和array
最大的不同就是,DataFrame是的矩阵是带有表头的,表头可以是字符串也可以是数字。具体可以参看下图:
图中,index表示的是行索引,column表示的是列索引,values表示的是数值。具体如何使用DataFrame
,我后面还会讲到。一个比较具象化的DataFrame
实例就是:
但如果你的矩阵是用的numpy的array
类型,矩阵就变成了:
所以说最直观的不同就是,DataFrame有表头。所以操作Excel或CSV很方便也很直观。