Datawhale 零基础入门数据挖掘学习笔记-Task3 特征工程

Datawhale 零基础入门数据挖掘学习笔记-Task3 特征工程[¶]

  之前的应用中,把数据塞进模型前的部分统统简单粗暴地称之为“洗数据”。在这次的学习中,初步接触了“探索性学习”和“特征工程”两个概念。在我的理解中,探索性学习偏向数据本身,目的性较弱,主要是为了认识、了解数据本身的一些特性。而特征工程则和业务知识理解结合较为紧密,目的明确,一方面基于业务理解,尽可能可能找出对因变量有影响的所有自变量;另一方面基于前期对数据的探索,对原始数据进行加工,通过清洗、变换、组合、筛选,优化原始数据的特征,产生新的、相关性更高的特征,从而提高预测的准确性

  在开始本次学习之前,一直认为机器学习的重点在于选择、使用合适的模型,根据模型和训练反馈选用、调整参数。但是随着学习的深入,发现特别在比赛中,大家使用的模型都差不太多,调参水平也差不太多,再加上融合,基本上决定分数的关键就变成了特征工程。当然,在实际数据分析项目中,貌似机器学习方法一直被传统数学建模碾压,期待通过学习,能够更好地将机器学习与实际项目结合起来。

In [17]:

import numpy as np

import pandas as pd

np.set_printoptions(suppress=True)

pd.set_option(“max_columns”,1000,“display.max_colwidth”,20)

In [18]:

Train_data

path = “C:/Users/kk/Desktop/tianchi/”

Train_data = pd.read_csv(path+“used_car_train_20200313.csv”,sep = " ")

Test_data = pd.read_csv(path+“used_car_testA_20200313.csv”,sep = " ")

  Datawhale入门手册的优秀已无须多言,群上各路大佬们也基本上把前进路上的雷排了个干净。于是我一路行云流水地完成了删除异常值和构造“汽车使用时间”特征,来到了“提取城市信息”阶段。

In [19]:

#从邮编中提取城市信息,相当于加入了先验知识

Train_data[‘city’] = Train_data[‘regionCode’].apply(lambda x : str(x)[:-3])

print(Train_data[‘city’].value_counts())

36680
1 31886
2 26481
3 20545
4 14969
5 10047
6 6304
7 2986
8 102
Name: city, dtype: int64

  什么?这个“city”是个什么鬼?于是我又翻开了天池官方说明页,上面清楚地写着:“regionCode”,地区编码,已脱敏。既然不是原始的邮编,这样直接切片有业务知识依据么?我再次打开了天池官方说明。很遗憾,这次什么有用的信息都没有查找到。

  于是抱着探索的心态,我又掉转头来开始观察数据。

In [20]:

print(Train_data[‘regionCode’].value_counts().sort_index())

print(Train_data[‘regionCode’].value_counts().shape[0])

0 63
1 17
2 26
3 30
4 65
5 39
6 40
7 7
8 25
9 7
10 45
11 35
12 43
13 31
14 28
15 12
16 62
17 51
18 47
19 11
20 19

8072 1
8073 2
8077 1
8078 2
8081 1
8082 1
8084 1
8086 1
8087 1
8088 2
8090 1
8092 1
8093 1
8094 1
8097 1
8100 1
8102 1
8103 2
8104 1
8105 1
8106 1
8107 1
8109 1
8112 1
8113 1
8117 1
8120 1
Name: regionCode, dtype: int64
7905

  通过对“regionCode”字段的数据进行去重和排序,惊讶地发现它几乎是一列连续的整数!当然,通过行数的查看我们发现,并不是完全连续的,最大编号8120,但是只有7905行,中间缺了两百多个编号,占比2.5%,不知道这个比例对数据连续性影响大不大,暂且当作连续数据来考虑吧。

  根据我脑子里的陈年地理常识和生活常识,觉得邮编貌似不应该这么连续流畅,而应该是有一套映射规则的。面对这列如此连续的数据,我深深地怀疑那个取“city”的操作取出来的9个分类具体代表了什么意义。。。直接拿SaleID,不也能划出个分类吗?对我们的预测有意义吗?

  但是,这么稀疏的高维矩阵,直接拿来预测,似乎很难操作。接下来该怎么办呢?有人提出聚类。嗯,好像很有道理的样子。先来观察一下数据:

import matplotlib.pyplot as plt
plt.scatter(Train_data[‘regionCode’], Train_data[‘price’])
plt.show()
plt.close()

Datawhale 零基础入门数据挖掘学习笔记-Task3 特征工程

  Emmm,这么密实的一坨,貌似聚类的分类效果也不好啊。。。

  兜兜转转一圈,还是没有找到好的分类方式。。。好在小雨大佬终于睡醒了,指点我在先验知识不足的情况下,可以通过观察分布的方式来验证猜想。就是说,在不确定“regionCode”的前N位是否有确定的省市划分含义时,先直接从数据入手,观察数据是否有好的分布。如果分布好,赌它就是省市的划分!

In [22]:

plt.figure(figsize=(14,6),dpi=80)

#将city处理为int型,空格置0,方便坐标轴表示

Train_data[‘city’] = Train_data[‘regionCode’].apply(lambda x : int(str(x)[:-3]) if len(str(x)) > 3 else 0)

ax1 = plt.subplot(121)

plt.scatter(Train_data[‘city’], Train_data[‘price’])

#引入SaleID(交易流水号),同样切块,作为分布参照

Train_data[‘SB’] = Train_data[‘SaleID’].apply(lambda x : str(x)[1:2])

ax2 = plt.subplot(122)

plt.scatter(Train_data[‘SB’], Train_data[‘price’])

plt.show()

plt.close()

Datawhale 零基础入门数据挖掘学习笔记-Task3 特征工程

  可以看出按照city划分,明显比按照SaleID划分,分布的区分度要高。又学到了一手!

感谢Crazy、闫钟峰、小雨姑娘三位大佬对我的指点和帮助!