社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  机器学习算法

机器学习必备技能之“数据预处理”

挖地兔 • 5 年前 • 597 次点击  


TUSHARE  金融与技术学习兴趣小组 


编译整理 | 一只小绿怪兽


译者简介:北京第二外国语学院国际商务专业研一在读,目前在学习Python编程和量化投资相关知识。


作者:Datacamp




Machine Learning 机器学习,是一门多领域交叉学科,涉及概率论、统计学、逼近论、凸分析、算法复杂度理论等多门学科。专门研究计算机怎样模拟或实现人类的学习行为,以获取新的知识或技能,重新组织已有的知识结构使之不断改善自身的性能。



它是人工智能的核心,是使计算机具有智能的根本途径,其应用遍及人工智能的各个领域,它主要使用归纳、综合而不是演绎。



上面的官方定义看起来很吓人,简单来说,机器学习的核心是,让机器通过算法从现有数据中学习,然后对新数据做出预测



在利用机器学习模型进行预测之前,非常重要的一步是对要输入的数据进行预处理,也就是本文要介绍的内容,主要包括对数据进行标准化、创建最有代表性的特征、并选择适合模型的最佳特征。



【工具】Python 3

【数据】tushare.pro 、Datacamp

【注意】本文注重的是方法的讲解,请大家灵活掌握。





01


数据清洗



在做任何分析之前,第一步,都是要对数据进行清洗。关于常见的数据清洗方法,在文章《这些方法解决了数据清洗80%的工作量》中已经介绍过了,这里就简单回顾一下。



① 删除某列有缺失值的行



print(volunteer.head())

   opportunity_id  content_id  vol_requests  event_time ... Census Tract  BIN BBL NTA
0            4996       37004            50           0  ...          NaN  NaN NaN NaN
1            5008       37036             2           0 ...          NaN  NaN NaN NaN
2            5016       37143            20           0 ...          NaN  NaN NaN NaN
3            5022       37237           500           0 ...          NaN  NaN NaN NaN
4            5055       37425            15           0 ...          NaN  NaN NaN NaN

[5 rows x 35 columns]


print(volunteer.shape)
(66535)

# 查看'category_desc'列有多少缺失值
print(volunteer['category_desc'].isnull().sum())
# 选中'category_desc'列不为空值的行
volunteer_subset = volunteer[volunteer['category_desc'].notnull()]
print(volunteer_subset.shape)

48
(61735)



② 用.astype()转换某列的数据类型。



print(volunteer.dtypes) 

opportunity_id          int64
content_id              int64
vol_requests            int64
event_time              int64
title                  object
hits                   object

# 查看hits列的前5
print(volunteer["hits"].head())

0    737
1     22
2     62
3     14
4     31
Name: hits, dtype: int64

# 把hits列的数据类型转换成整数int 
volunteer["hits"] = volunteer["hits"].astype('int')

# 查看数据类型
print(volunteer.dtypes)

opportunity_id          int64
content_id              int64
vol_requests            int64
event_time              int64
title                  object
hits                    int64



③ 划分训练集和测试集。



我们将数据分成两个部分,训练集用于建立模型,而测试集则用于评估模型的预测能力,这么做的目的是防止模型的过拟合。



sklearn是机器学习中一个常用的Python第三方模块,我们可以直接调用这个模块中的train_test_split【1】函数对数据集进行划分。默认是将数据集大小的75%设置为训练集,25%设置为测试集,如下示例。



from sklearn.model_selection import train_test_split
import numpy as np

X, y = np.arange(8).reshape((4 2)), range(4)
print(X)
print(list(y))

[[0 1]
 [2 3]
 [4 5]
 [6 7]]

[0123]

X_train, X_test, y_train, y_test = train_test_split(X, y)
print(X_train,  X_test, y_train, y_test)

[[4 5]
 [6 7]
 [2 3]]
 [[0 1]] [231] [0]



在大多情况下,使用train_test_split函数中的默认参数设置不会有什么问题,但如果数据集不是均匀分布的,则划分的训练集和测试集中的数据可能就不具有代表性,会使模型的预测效果出现误差。



这时,分层抽样是一个更好的选择,可以通过设置参数stratify来实现。



下面的示例中,列class里面有100个样本,80个class1和20个class2,我们希望通过分层抽样,得到这样的划分:

【训练集】75个样本,60个class1,15个class2

【测试集】25个样本,20个class1,5个class2



print(df['class'].value_counts())

class1    80
class2    20
Name: classdtype: int64

X = df[['number']]
y = df[['class']]

# 设置参数stratify
X_train, X_test, y_train, y_test = train_test_split(X, y, stratify=y)
print(y_train['class'].value_counts())
print(y_test['class'].value_counts())

class1    60
class2    15
Name: classdtype: int64
class1    20
class2     5
Name: classdtype: int64

# 如果未设置stratify,效果如下
X_train, X_test, y_train, y_test = train_test_split(X, y)
print(y_train['class'].value_counts())
print(y_test['class'].value_counts())

class1    57
class2    18
Name: classdtype: int64
class1    23
class2     2
Name: classdtype: int64




02


数据标准化



当模型属于线性空间模型;数据集中的某个特征方差很大;数据集的特征是连续的且量纲不同;或者存在线性假定的时候,我们需要进行数据标准化处理。



本文主要介绍两种方法,一个是log函数标准化法,另一个是特征缩放法



① log函数标准化法


如果发现数据集中某一列特征的方差很大,可以用log函数进行处理,在Python中log()函数默认是以e为底的对数函数。



从下面的示例中可以观察到,在没有用log()函数进行处理之前,col2列数据的方差很大,但经过log()函数处理之后,两列数据方差的差距明显缩小。



   col1   col2
0  1.00    3.0
1  1.20   45.5
2  0.75   28.0
3  1.60  100.0

print(df.var())
col1       0.128958
col2    1691.729167
dtype: float64

import numpy as np
df['log_2'] = np.log(df['col2'])
print(df)

   col1   col2     log_2
0  1.00    3.0  1.098612
1  1.20   45.5  3.817712
2  0.75   28.0  3.332205
3  1.60  100.0  4.605170

print(np.var(df[['col1''log_2']]))
col1     0.096719
log_2    1.697165
dtype: float64



② 特征缩放法


当特征的量纲不同、使用线性模型时,可以用特征缩放的方法进行标准化,目的是把数据转化成标准正态分布,可以通过调用sklearn中的StandardScaler实现。



在如下示例中,可以观察到df中各列内部数据的差距不是很大,但是列与列之间的大小却有明显差距,需要进行标准化处理。



   col1  col2   col3
0  1.00  48.0  100.0
1  1.20  45.5  101.3
2  0.75  46.2  103.5
3  1.60  50.0  104.0

print (df.var())

col1    0.128958
col2    4.055833
col3    3.526667
dtype: float64


from sklearn.preprocessing import StandardScaler

ss = StandardScaler()
df_scaled = pd.DataFrame(ss.fit_transform(df), columns=df.columns)

print(df_scaled)

       col1      col2      col3
0 -0.442127  0.329683 -1.352726
1  0.200967 -1.103723 -0.553388
2 -1.245995 -0.702369  0.799338
3  1.487156  1.476409  1.106776

print(df.var())

col1    1.333333
col2    1.333333
col3    1.333333
dtype: float64




03 


特征工程



特征工程是根据原始特征创建新特征的过程,目的是让特征更准确地预测未知数据,这需要我们对数据集有很深入的理解和把握。



比如说,如果目标是想要评估一个班级整体的学习情况,那每个学生的考试成绩本身是没有太大参考价值的,而平均值是更好的一个选择。



不同的数据集和模型所采用的特征工程方法是不同的,本文只介绍其中的几个供大家参考。



情景一:分类变量型特征



分类变量一般是文本数据,需要先转化成数字,再输入到模型中,可以通过Pandassklearn两种方式实现。



① 调用sklearn中的LabelEncoder函数。



hiking[["Accessible"]].head()

  Accessible
0          Y
1          N
2          N
3          N
4          N

from sklearn.preprocessing import LabelEncoder

enc = LabelEncoder()
hiking["Accessible_enc"] = enc.fit_transform(hiking["Accessible"])

print(hiking[["Accessible_enc", "Accessible"]].head())

   Accessible_enc Accessible
0               1          Y
1               0          N
2               0          N
3               0          N
4               0          N



② 调用Pandas中的get_dummies()【2】函数。这里我们导入tushare.pro中的行业数据作为示例进行演示。



import tushare as ts

pro = ts.pro_api()

df = pro.stock_basic(exchange='', list_status='L', fields='ts_code, industry')
df = df.head()
print(df)

     ts_code industry
0  000001.SZ       银行
1  000002.SZ     全国地产
2  000004.SZ     生物制药
3  000005.SZ     环境保护
4   000006.SZ     区域地产

df_enc = pd.get_dummies(df['industry'])
df_enc.index = df['ts_code']
print(df_enc)

           全国地产  区域地产  环境保护  生物制药  银行
ts_code                              
000001.SZ     0     0     0     0   1
000002.SZ     1     0     0     0   0
000004.SZ     0     0     0     1   0
000005.SZ     0     0     1     0   0
000006.SZ     0     1     0     0   0



情景二:数字型特征



① 取平均值



print(running_times_5k)

      name  run1  run2  run3  run4  run5   
0      Sue  20.1  18.5  19.6  20.3  18.3  
1     Mark  16.5  17.1  16.9   17.6  17.3  
2     Sean  23.5  25.1  25.2  24.6  23.9 
3     Erin  21.7  21.1  20.9  22.1  22.2  
4    Jenny  25.8  27.1  26.1  26.7  26.9  
5  Russell  30.9  29.6  31.4  30.4  29.9  


run_columns = ["run1""run2""run3""run4""run5"]
running_times_5k["mean"] = running_times_5k.apply(lambda row: row[run_columns].mean(), axis=1)

print(running_times_5k)

      name  run1  run2  run3  run4  run5   mean
0      Sue  20.1  18.5  19.6  20.3  18.3  19.36
1     Mark  16.5  17.1  16.9  17.6  17.3  17.08
2     Sean  23.5  25.1  25.2  24.6  23.9   24.46
3     Erin  21.7  21.1  20.9  22.1  22.2  21.60
4    Jenny  25.8  27.1  26.1  26.7  26.9  26.52
5  Russell  30.9  29.6  31.4  30.4  29.9  30.44



② 提取日期中的月份



import tushare as ts

pro = ts.pro_api()

df = pro.daily(ts_code='000001.SZ', start_date='20180701', end_date='20180706')[['ts_code''trade_date''close']]
df.sort_values('trade_date', inplace=True)                              # 升序排列
df['trade_date'] = pd.to_datetime(df['trade_date'])                     # 将时间转化成日期类型
df["trade_date_month"] = df["trade_date"].apply(lambda row: row.month)  # 提取月份

print(df)

     ts_code trade_date  close  trade_date_month
4  000001.SZ 2018-07-02   8.61                  7
3  000001.SZ 2018-07-03   8.67                 7
2  000001.SZ 2018-07-04   8.61                 7
1  000001.SZ 2018-07-05   8.60                 7
0  000001.SZ 2018-07-06   8.66                 7



情景三:文本型特征



文本型数据相对会复杂一点,一般来说可以分成两步。第一步,先从文本中提取有效信息,可能是字符串的一部分,也可能是数字,第二步,把它们转化成特征。在下面的示例中,简单介绍了如何正则表达式re提取文本中的数字。



import re

print(hiking[['Length']].head())

       Length
0   0.8 miles
1    1.0 mile
2  0.75 miles
3   0.5 miles
4   0.5 miles

# 定义函数:提取文本中的数字
def return_mileage(length):
    pattern = re.compile(r"\d+\.\d+")
    mile = re.match(pattern, length)

    if mile is not  None:
        return float(mile.group(0))

# 将该函数应用到Length列中
hiking["Length_num"] = hiking["Length"].apply(lambda row: return_mileage(row))
print(hiking[["Length""Length_num"]].head())

       Length  Length_num
0   0.8 miles        0.80
1    1.0 mile        1.00
2  0.75 miles        0.75
3   0.5 miles        0.50
4   0.5 miles        0.50




04 


特征选择



特征选择,是指从已有的特征库中,选出一些最有效特征以降低数据集维度的过程,从而最优化模型的预测效果,是提高学习算法性能的一个重要手段。



① 去除冗余特征。


比如,在线性回归模型中,由于假设特征之间是相互独立的,需要删除相关性强的特征。可以直接用.drop()函数删除。



print(df)

      A     B     C
0  3.06  3.92  1.04
1  2.76  3.40  1.05
2  3.24  3.17  1.03

print(df.corr())

          A         B         C
A  1.000000 -0.159921 -0.989743
B -0.159921  1.000000  0.299299
C -0.989743  0.299299  1.000000

# 创建列表:包含冗余数据列名
to_drop = ['C']

# 删掉这些列
df_subset = df.drop(to_drop, axis=1)

      A     B
0  3.06  3.92
1  2.76  3.40
2  3.24  3.17



② 主成分分析法降维。


Principal Component Analysis,即主成分分析PCA,是指把多指标合成为少数几个相互无关的综合指标的过程,其中每个主成分都能够反映原始变量的绝大部分信息,而且所含信息互不重复,可以起到降低维度的作用。



主成分分析法是一种数学变换的方法, 它把给定的一组相关变量通过线性变换转成另一组不相关的变量,这些新的变量按照方差依次递减的顺序排列。



同样,我们可以直接调用sklearn中的PCA类【3】。



print(X)

      A     B     C
0  3.06  3.92  1.04
1  2.76  3.40  1.05
2  3.24  3.17  1.03

from sklearn.decomposition import PCA

# 可以通过设置参数n_components降维,默认与原始数据的维度相同
pca = PCA()

transformed_X = pca.fit_transform(X)
print(transformed_X)

[[ 4.11310289e-01 -1.07865458e-01  7.28764779e-18]
 [-5.33422295e-02  2.72395027e-01  7.28764779e-18]
 [-3.57968060e-01 -1.64529570e-01  7.28764779e-18]]


# 查看不同特征的方差占比
print(pca.explained_variance_ratio_)

[7.26668849e-01 2.73331151e-01 3.85723283e-34]




05 


总结



本文主要介绍了在应用机器学习模型之前的准备工作——数据预处理,包括划分训练集和测试集、数据标准化、特征工程、特征选择这四个部分。



相关的官方文档和参考资料已附在下面,感兴趣的小伙伴可以自行查阅更多内容!



 

END


更多内容请关注“挖地兔”公众号。




【参考链接】

https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.train_test_split.html【1】

https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.get_dummies.html【2】

https://scikit-learn.org/stable/modules/generated/sklearn.decomposition.PCA.html【3】

https://www.datacamp.com/courses/preprocessing-for-machine-learning-in-python【Datacamp】


【扩展阅读】
数据科学必备基础之线性回归
最简洁的Python时间序列可视化实现
Pandas必备技能之“花式拼接表格”
Pandas必备技能之“时间序列数据处理”
Python+SQL无敌组合,值得你Pick!



Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/37154
 
597 次点击