数据和特征决定了机器学习的上限,而模型和算法只是逼近这个上限而已
好的数据和特征能够让机器学习事半功倍,甚至大大减轻算法的工作。想象一下极端情况,如果用全世界猫狗的照片来训练一个猫狗分类器,他将做到万无一失,反观如果只有几张猫狗照片来训练,甚至都不是猫狗的照片去训练猫狗分类器,那结果必定无法让人满意。手头的数据一般都是有限,但特征是需要我们去提取的,选出好的有意义的特征能够让数据的质量大大提高,达到以百抵千的效果。
实例
三位数的特征
股票的特征
电话号的特征
下面详解特征处理环节
从总数据中抽取符合要求的数据集,是一种数据归约的处理方式
将异常值丢弃或者修改,以方便后续的建模过程
给自己最终的目的属性进行标注,这个反应我们目的的属性就是我们的标记、标签、label
例子
要预测某个时间是否下雨,那么我们的数据集中是否下雨就是我们的标注
剔除掉与标注不相关或者冗余的特征。主要根据数据本身的特征和任务的需求进行选择,并且需要反复迭代,每次特征选择都要使用模型去验证,最后的目的就是为了选出最好的特征,其实就是一种数据归约的处理方式
三个切入思路
根据特征的特性进行一定方式的转换,使其更好的发挥自己的特点
对指化
离散化
离散化的原因
离散化的方法
#%% 等深分箱
lst = [6, 8, 10, 15, 16, 24, 25, 40, 67]
pd.qcut(lst, q=3, labels=["low", "medium", "high"])
#%% 等宽分箱
pd.cut(lst, bins=3, labels=["low", "medium", "high"])
归一化
标准化
#%% 归一化
from sklearn.preprocessing import MinMaxScaler, StandardScaler
MinMaxScaler().fit_transform(np.array([1, 4, 10, 15, 21]).reshape([-1, 1]))
#%% 标准化
StandardScaler().fit_transform(np.array([1, 0, 0, 0, 0, 0, 0, 0]).reshape([-1, 1]))
数值化
正规化
利用现有的特征进行某些组合生成新的具有含义的特征。直接采集到的特征不一定能提取出全部信息,需要通过特征衍生来发现新的含义
方法
import pandas as pd
import numpy as np
import scipy.stats as ss
import matplotlib.pyplot as plt
from sklearn.preprocessing import MinMaxScaler, StandardScaler
from sklearn.preprocessing import LabelEncoder, OneHotEncoder
from sklearn.preprocessing import Normalizer
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
from sklearn.decomposition import PCA
import seaborn as sns
sns.set_context(font_scale=2)
def hr_preprocessing(sl=False, le=False, npr=False, amh=False, tsc=False, wa=False, pl5=False, dp=False, slr=False, lower_d=True, ld_n=1):
'''
:param sl: satisfaction_level false:MinMax true:Standard
:param le: last_evaluation_level
:param npr: number_project
:param amh: average_monthly_hours
:param tsc: time_spend_company
:param wa: Work_accident
:param pl5: promotion_last_5years
:param dp: department false: Label true: OneHot
:param slr: salary false: Label true: OneHot
:param lower_d: 是否降维
:param ld_n: 保留的维度
:return:
'''
df = pd.read_csv("newHR.csv")
# 清洗数据
df = df.dropna(subset=["satisfaction_level", "last_evaluation"])
df = df[df['satisfaction_level'] <= 1][df["salary"] != "nme"]
# 得到标注
label = df['left']
df = df.drop("left", axis=1)
# 特征选择
# 特征处理
scaler_lst = [sl, le, npr, amh, tsc, wa, pl5]
column_lst = ['satisfaction_level', 'last_evaluation', 'number_project',\
'average_monthly_hours', 'time_spend_company', 'Work_accident',\
'promotion_last_5years']
for i in range(len(scaler_lst)):
if not scaler_lst[i]:
df[column_lst[i]] = MinMaxScaler().fit_transform(df[column_lst[i]].values.reshape(-1, 1)).reshape(-1, 1)
else:
df[column_lst[i]] = StandardScaler().fit_transform(df[column_lst[i]].values.reshape(-1, 1)).reshape(-1, 1)
scaler_lst = [slr, dp]
column_lst = ['salary', 'department']
for i in range(len(scaler_lst)):
if not scaler_lst[i]:
if column_lst[i] == 'salary':
df[column_lst[i]] = [map_salary(s) for s in df['salary'].values]
else:
df[column_lst[i]] = LabelEncoder().fit_transform(df[column_lst[i]])
df[column_lst[i]] = MinMaxScaler().fit_transform(df[column_lst[i]].values.reshape(-1, 1)).reshape(-1, 1)
else:
df = pd.get_dummies(df, columns=[column_lst[i]])
if lower_d:
return PCA(n_components=ld_n).fit_transform(df.values), label
return df, label
d = dict([("low", 0), ("medium", 1), ("high", 2)])
def map_salary(s):
return d.get(s, 0)
def main():
print(hr_preprocessing(lower_d=False, ld_n=3))
if __name__ == '__main__':
main()