特征工程(一)概念及python的实现手段

最近两天心情很忐忑,文章更新晚了点,想了想,继续努力吧。


  • 特征工程的定义

    我的理解:在我看来,特征工程涵盖几个方面的内容,
    1. 特征变量的选取

      这一步对我们的模型有深远的影响,就像给人讲故事,那么故事从何说起呢,就从特征变量开始说起。要想让故事说的令人信服,那么对特征的选取就会有要求,特征选取的越有逻辑性,故事越具有说服力和可信度。

      这里我深有体会,有一个观点可以在这里分享。我的观点是,“不要单一的去评价一个人或者事”。不是所有会机器学习算法的人就可以做好人工智能模型。特征工程就是第一个门槛,也叫做“经验”。说到这里肯定很多行业的人说,我有多年经验,你们做机器学习再牛逼的人还不是要向我请教为我服务。需要指正的是,这里的“经验”不是我们所说的行业经验,我很看不惯很多人说,我五年工作经验怎样怎样,倘若是单纯的上下班没有过多的思考,五年的行业经验在机器学习人工智能这里毫无意义。我所说的经验是对行业的思考,有的人思考半个小时就抓住了问题的关键,而有的人工作了五六年却依然不清楚问题的命脉在哪里,人和人是有差距的,所以不能局限的去看待一个人。所以,谁都别不看好谁,谁都别看低谁,需要具体人具体问题去分析。如果只会跑模型结果不好调参而逃离实际业务的人,这是一线工程师,如果只知道业务往来业务流程而不知道如何变现,这是一线业务员,如果了解算法了解模型了解业务coding能力强逻辑能力强,这是一线数据科学家。没有褒贬谁的意思,但实际上,人和人确实是不同的,脑力和脑量都会千差万别,所以,根据自身特点做自己擅长的事才是最聪明的做法。

      回到主题,在实际的应用中,我们会发现我们有大量特征可以供我们选择,在当今这个信息化数据化的时代,只要你留心记录,有大量的数据可以供我们选择,我们担心的不是有没有数据用,而是如何去用这些数据。现实中,很多人把希望寄托在模型身上,这也解释了为什么这几年深度学习越来越火热。深度学习的本质就是神经网络,他可以对任何复杂的情况进行逻辑上的预测,所以,这种算法减轻了特征的思考,但是大大加大了深度学习的计算量。计算结果呢有的可以解释,有的无法解释。实际上,这不是我们唯一的选择,特征的选取如果正确,那么我们可以用很简单的机器学习模型就能实现人工智能预测。这种做法在特征工程中增加了人脑的思考,在模型上减少了模型的复杂度和计算量。trade-off就是这个道理,但是第二种做法会让我们的人工智能模型在解释上变得有逻辑也更方便让人理解。

      1. 数据的预处理

        2.1 对缺失值的处理
        缺失值的处理分为几种情况:
        如果缺失值对应的数据列属于数值型数据,我们可以用前后数值的均值/中位数/众数来填充,具体问题具体分析。
        如果缺失值对应的数据列属于文本型数据,我们则需要用统计的方法,这里可以直接统计文本数据,也可以先将文本数据转为虚拟变量然后统计,最终根据需要可以用中位数/众数来填充。
        当然,如果数据样本足够大,缺失值所在的行并不多的情况下,我们可以直接对缺失值所在的整行进行删除。

        2.2 量纲的问题
        我对量纲的理解是这样的,如果单位不同,那么不同特征离散值的范围就不同,如果某个特征的范围过大,会导致模型参数差异大,最终导致模型评估效果不佳。
        因此,当我们把所有的特征变量都转化为无量纲,那么,每个特征的离散值都处于相同的值域内,这时候的模型效果会更好。
        实现无量纲的方法有很多,包括:
        0-1标准化(X-min)/(max-min)
        Z标准化(X-mean)/std
        log归一化log_{10}(x)/log_{10}(max)
        正则化Normalizer(d对每一个值除以范数,范数的求解如下表)

        2.3 特征值类型的问题

        特征值类型包含两大类,一类是文本型数据,一类是数值型数据。
        对于文本型数据来说,我们需要进行数据转化,将其转化为离散型数值,也就是我们常说的虚拟变量,也叫做哑变量(dummy variable)。
        如果是数值型数据,我们需要确定根据我们模型的特点而定。
        如果我们尝试用逻辑回归或者SVM做二分类或者多分类的问题,这些数值我们可以直接用。
        如果我们尝试用朴素贝叶斯来做二分类或者多分类,这时候,我们需要对离散的数值留意,是否可以代表一类,比如说,时间序列的数据,都是0.001的差别,但是其实我们的常识告诉我们,1.0002.000之间的所有值都是一种类别,那么我们需要将该特征的离散值泛化,用第三特征值表征这类数据。这里我们会用1来表示1.02.0之间的所有值,2表示2.0~3.0之间的所有值,以此类推。


以上就是我对特征工程的理解,接下来,说说具体python的实现手段。我会用两种方法实现,一种是自定义函数实现,一种调用python preprocessing包。

  • 对缺失值的处理

举例使用的数据是


  1. 缺失值剔除

python实现

data.dropna() #高级语言,高级实现

函数实现

def findinx(data):
    if len(data)==1:
        if  pd.isnull(data['豆瓣评分'][0]):
            data.drop([0])
    else:
        index=[]
        for i in range(len(data)):
            if pd.isnull(data['豆瓣评分'][i]) or pd.isnull(data['累计票房'][i]) or pd.isnull(data['电影名称'][i]):
                index.append(i)
    data.drop(index)
    return(data)  

处理结果


  1. 缺失值填充(填充可以填充均值/中位数/众数)

python实现

from sklearn.preprocessing import Imputer
imputer=Imputer(strategy='mean') #mean, median, most_frequent
data['累计票房']=imputer.fit_transform(data[['累计票房']])
data['豆瓣评分']=imputer.fit_transform(data[['豆瓣评分']])

函数实现

def findinx(data):
    if len(data)==1:
        if data['豆瓣评分'][0]==np.nan:
            data.drop([0])
    else:
        index=[]
        for i in range(len(data)):
            if pd.isnull(data['豆瓣评分'][i]):
                data['豆瓣评分'][i]=np.mean(data['豆瓣评分'])
            if pd.isnull(data['累计票房'][i]):
                data['累计票房'][i]==np.mean(data['累计票房'])
    return(data)    

处理结果


  • 量纲的转化

举例使用的数据


在上面的数据中我们发现,累计票房和豆瓣评分的数据跨度相差很大,如果我们不做量纲的转化,会导致我们模型很容易“扁长化”。


0-1标准化

python实现

from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()
data['标准累计票房'] = scaler.fit_transform(data[['累计票房']])
data['标准豆瓣评分']=scaler.fit_transform(data[['豆瓣评分']])

函数实现

def minmaxscaler1(data,columns):
    #columns=['累计票房','豆瓣评分']
    for column in columns:
        data['标准化'+column]=(data[column]-np.min(data[column]))/(np.max(data[column])-np.min(data[column]))
    return(data)

Z标准化

python实现

from sklearn.preprocessing import scale
data3['标准累计票房'] = scaler.fit_transform(data3[['累计票房']])
data3['标准豆瓣评分'] = scaler.fit_transform(data3[['豆瓣评分']])

函数实现

def zscale(data,columns):
    #columns=['累计票房','豆瓣评分']
    for column in columns:
        data['标准化'+ column]=(data[column]-np.mean(data[column]))/np.std(data[column])
    return(data)

Normalizer归一化

Normalizer一半用于TF-IDF的矩阵中

from sklearn.preprocessing import Normalizer
scaler=Normalizer(norm='l1') # l1, l2
data['标准累计票房']=scaler.fit_transform(data[['累计票房']].transpose()).transpose()
data['标准豆瓣评分']=scaler.fit_transform(data[['豆瓣评分']].transpose()).transpose()

函数实现

def pl1(data):
    sumvalue=0
    for i in data:
        sumvalue=sumvalue+np.abs(i)
    data=data/sumvalue
    return(data)

def pl2(data):
    sumvalue=0
    for i in data:
        sumvalue=sumvalue+i**2
    data=data/(np.sqrt(sumvalue))
    return(data)

def normalizer(data, columns, way):
    #way='l1' or 'l2'
    for column in columns:
        if way=='l1':
            data['归一化'+column]=pl1(data[column])
        elif way=='l2':
            data['归一化'+column]=pl2(data[column])    
    return(data)

可以看出我们函数计算的结果和调包计算的结果没有差别。

  • 文本变量转虚拟变量

转虚拟变量一半用dict就可以实现,当然python有现成包。
我们举例的数据如下。


python实现

dummiesData=pd.get_dummies(data4, columns=['症状'], prefix=['症状'], prefix_sep="_")
dummiesData = pd.get_dummies(
data4,columns=['职业','疾病','症状'],prefix=['职业','疾病','症状'],prefix_sep="_"
)

python这种虚拟变量的做法容易增加数据特征的维度。

函数实现

def dummyvariable(names):
    dummies=np.linspace(1,len(names),len(names))
    return(dummies)

def dummy(data):
    newdata=pd.DataFrame()
    columns=data.columns
    feature={}
    for column in columns:
        feature[column] = data[column].unique()
        dummy={}
        dummies=dummyvariable(feature[column])
        for i in range(len(feature[column])):
            dummy[feature[column][i]]=dummies[i]
        newdata[column]=data[column].map(dummy)
    return(newdata)

可以看出,我们已经将文本的数据转化成了数值型数据。


接下来,会写到,特征的分析以及降维的一些问题。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,980评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,178评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,868评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,498评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,492评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,521评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,910评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,569评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,793评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,559评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,639评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,342评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,931评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,904评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,144评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,833评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,350评论 2 342

推荐阅读更多精彩内容