拉勾网招聘数据的特征工程探索④

1.特征工程概述

什么是特征工程?
特征工程指的是最大程度上从原始数据中汲取特征和信息来使得模型和算法达到尽可能好的效果。

特征工程具体内容包括
1.数据预处理
2.特征选择
2.特征变换与提取
3.特征组合
4.数据降维

特征工程的两个基本面:
基于数理和模型的考虑
基于业务的考虑(需要了解数据所属业务领域的专业知识)

几个重要观点:
在实际的特征工程实践中,这两个基本面都要考虑,尤其是业务层面,直接关乎到模型的表现。
在数据维度特别大、特征数量极多的情况下,找到数据中的 magic feature 至关重要。

总之,数据和特征决定了机器学习效果的上限,模型和算法只是不断地逼近这个上限而已。
kaggle、天池等数据科学竞赛比模型吗?比算法吗?通通不是,比的是特征工程。

2.数据预处理

一些前期的数据清洗和预处理工作,是对原始数据的基本整理和重塑。参看课程第四讲。

3.特征选择

特征选择即选择与目标变量相关的自变量进行用于建模,也叫变量筛选。
特征选择基于两个基本面:
特征是否发散,即该特征对于模型是否有解释力,如果特征是一成不变的(0方差),这样的特征是无用的。
特征是否与目标变量有一定的相关性。这一点要充分基于业务层面去考虑。

特征选择柳叶三刀:
Filter (飞刀):特征过滤
Wrapper (弯刀):特征包装
Embedded (电刀):特征嵌入

除了基于pandas和numpy的手动特征选择外,sklearn也有一套特征选择模块。


招聘数据的特征工程探索

1.读取并观察数据

import warnings
warnings.filterwarnings('ignore')
import numpy as np
import pandas as pd
lagou_df = pd.read_csv('./lagou_data5.csv', encoding='gbk')
lagou_df.head()

在这里插入图片描述

2.分类变量one-hot处理

advantage和label这两个特征作用不大,可在最后剔除

2.1 city变量pandas one-hot方法
pd.get_dummies(lagou_df['city']).head()

在这里插入图片描述

2.2 sklearn onehot方法
2.2.1先要硬编码labelcoder
from sklearn.preprocessing import OneHotEncoder
from sklearn.preprocessing import LabelEncoder
lbl = LabelEncoder()
lbl.fit(list(lagou_df['city'].values))
lagou_df['city'] = lbl.transform(list(lagou_df['city'].values))
# 查看硬编码结果
lagou_df['city'].head()

在这里插入图片描述

2.2.2 再由硬编码转为one-hot编码
df_city = OneHotEncoder().fit_transform(lagou_df['city'].values.reshape((-1,1))).toarray()
df_city[:5]

在这里插入图片描述

2.3 分类特征统一one-hot处理
cat_features = ['city', 'industry', 'education', 'position_name', 'size', 'stage', 'work_year']
for col in cat_features:
    temp = pd.get_dummies(lagou_df[col])
    lagou_df = pd.concat([lagou_df, temp],axis=1)
    lagou_df = lagou_df.drop([col], axis=1)   
#lagou_df.shape

pd.options.display.max_columns = 999
lagou_df = lagou_df.drop(['advantage', 'label'], axis=1)
lagou_df.head()

在这里插入图片描述

3 特征信息提取

3.1 职位描述(position_detail)的特征信息提取
def position_detail():
    lagou_df2 = pd.read_csv('./lagou_data5.csv', encoding='gbk')
    lagou_df2 = lagou_df2[['position_detail', 'salary']]
    # 提取Python信息
    for i, j in enumerate(lagou_df2['position_detail']):
        if 'python' in j:
            lagou_df2['position_detail'][i] = j.replace('python', 'Python')

    lagou_df2['Python'] = pd.Series()
    for i, j in enumerate(lagou_df2['position_detail']):
        if 'Python' in j:
            lagou_df2['Python'][i] = 1
        else:
            lagou_df2['Python'][i] = 0
    print('Python\n', lagou_df2['Python'].value_counts())
    #print(lagou_df2['Python'][:20])
	
	# 提取SQL信息
    for i, j in enumerate(lagou_df2['position_detail']):
        if 'sql' in j:
            lagou_df2['position_detail'][i] = j.replace('sql', 'SQL')

    lagou_df2['SQL'] = pd.Series()
    for i, j in enumerate(lagou_df2['position_detail']):
        if 'SQL' in j:
            lagou_df2['SQL'][i] = 1
        else:
            lagou_df2['SQL'][i] = 0

    print('SQL\n',lagou_df2['SQL'].value_counts())

    lagou_df2['Excel'] = pd.Series()
    for i, j in enumerate(lagou_df2['position_detail']):
        if 'Excel' in j:
            lagou_df2['Excel'][i] = 1
        else:
            lagou_df2['Excel'][i] = 0

    print('Excel\n',lagou_df2['Excel'].value_counts())

    lagou_df2['Java'] = pd.Series()
    for i, j in enumerate(lagou_df2['position_detail']):
        if 'Java' in j:
            lagou_df2['Java'][i] = 1
        else:
            lagou_df2['Java'][i] = 0

    print('Java\n',lagou_df2['Java'].value_counts())

    for i, j in enumerate(lagou_df2['position_detail']):
        if 'linux' in j:
            lagou_df2['position_detail'][i] = j.replace('linux', 'Linux')

    lagou_df2['Linux'] = pd.Series()
    for i, j in enumerate(lagou_df2['position_detail']):
        if 'Linux' in j:
            lagou_df2['Linux'][i] = 1
        else:
            lagou_df2['Linux'][i] = 0

    print('Linux\n',lagou_df2['Linux'].value_counts())

    lagou_df2['C++'] = pd.Series()
    for i, j in enumerate(lagou_df2['position_detail']):
        if 'C++' in j:
            lagou_df2['C++'][i] = 1
        else:
            lagou_df2['C++'][i] = 0

    print('C++:\n',lagou_df2['C++'].value_counts())

    for i, j in enumerate(lagou_df2['position_detail']):
        if 'spark' in j:
            lagou_df2['position_detail'][i] = j.replace('spark', 'Spark')

    lagou_df2['Spark'] = pd.Series()
    for i, j in enumerate(lagou_df2['position_detail']):
        if 'Spark' in j:
            lagou_df2['Spark'][i] = 1
        else:
            lagou_df2['Spark'][i] = 0

    print('Spark\n',lagou_df2['Spark'].value_counts())

    for i, j in enumerate(lagou_df2['position_detail']):
        if 'tensorflow' in j:
            lagou_df2['position_detail'][i] = j.replace('tensorflow', 'Tensorflow')

        if 'TensorFlow' in j:
            lagou_df2['position_detail'][i] = j.replace('TensorFlow', 'Tensorflow')

    lagou_df2['Tensorflow'] = pd.Series()
    for i, j in enumerate(lagou_df2['position_detail']):
        if 'Tensorflow' in j:
            lagou_df2['Tensorflow'][i] = 1
        else:
            lagou_df2['Tensorflow'][i] = 0

    print('Tensorflow\n',lagou_df2['Tensorflow'].value_counts())

    lagou_df2 = lagou_df2.drop(['position_detail'], axis=1)
    print(lagou_df2.head())

    return lagou_df2
lagou_df2=position_detail()

在这里插入图片描述

3.2 删除position_detail信息
lagou_df2 = lagou_df2.drop(['position_detail'], axis=1)
lagou_df2.head()

在这里插入图片描述

lagou_df = lagou_df.drop(['position_detail', 'salary'], axis=1)
lagou_df.head()

在这里插入图片描述

3.3 合并特征信息
lagou = pd.concat((lagou_df2, lagou_df), axis=1).reset_index(drop=True)
lagou.head()
lagou.to_csv('lagou_featured.csv', encoding='gbk')

在这里插入图片描述

4.建立模型

4.1准备训练集,测试集
X = lagou_df.drop(['salary'], axis=1)
y = np.log(lagou_df['salary'].values.reshape((-1, 1)))
print(X.shape, y.shape)

在这里插入图片描述

4.2 划分训练集,测试集
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
print(X_train.shape, y_train.shape, X_test.shape, y_test.shape)

在这里插入图片描述

4.3 建立模型
from sklearn.model_selection import KFold
from sklearn.ensemble import GradientBoostingRegressor
model = GradientBoostingRegressor(n_estimators = 40, max_depth = 2)
model.fit(X_train, y_train)
4.4 测试集预测的均方误差
from sklearn.metrics import mean_squared_error
y_pred = model.predict(X_test)
print('\nmean_squared_error:',np.sqrt(mean_squared_error(y_test, y_pred)))

在这里插入图片描述

4.5 交叉验证

在实际训练中,模型通常对训练数据表现好,对非训练数据拟合程度较差,通过将训练集本身随机分成K份,相当于有了多对训练集和测试集,同一个模型可以产生多个准确率,比较多个可能的模型进行交叉验证的结果的准确率方差后,可以比较各个模型的泛化能力。

K折验证

from sklearn import model_selection
from sklearn.ensemble import GradientBoostingRegressor
# 将训练集分成5份,4份用来训练模型,1份用来预测,这样就可以用不同的训练集在一个模型中训练
clf = GradientBoostingRegressor()
# 定义特征集和结果集
print(model_selection.cross_val_score(clf, X, y, cv=5))

在这里插入图片描述

4.6 查看前十个预测值与测试值
print('\ny_pred:',np.exp(y_pred[:10]))
print('\ny_test',np.exp(y_test[:10]))

在这里插入图片描述

4.7 优化

过拟合
通过不断的进行特征工程,产生的特征越来越多,用这些特征去训练模型,会对我们的训练集拟合的越来越好,同时也可能在丧失泛化能力,从而在待预测的数据上,表现不佳,也就是发生过拟合现象。
欠拟合
从另一个角度上说,如果模型在待预测的数据上表现不佳,除掉上面说的过拟合问题,
也有可能是欠拟合,也就是说,即使在训练集上也表现得不那么好。

优化
在机器学习问题上,对于过拟合和欠拟合两种情形,我们优化的方式是不同的。
对于过拟合而言,通常以下策略对结果优化是有用的:
A 做一下特征选择,挑出较好的特征的子集来做训练
B 提供更多的数据,从而弥补原始数据的偏差问题,学习到的模型也会更准确。
而对于欠拟合,我们通常需要更多的特征,更复杂的模型来提高准确度。
著名的学习曲线(learning curve)可以帮助我们判定我们的模型现在所处的状态

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值