【精通特征工程】学习笔记(一)

2020-01-26  本文已影响0人  小小孩儿的碎碎念

【精通特征工程】学习笔记Day1&1.26&D1-2章&P1-32页

1、机器学习流程&基本概念

2、简单而又奇妙的数值

2.1 标量、向量、空间

2.2 处理计数

2.2.1 二值化
import pandas as pd
listen_count = pd.read_csv('millionsong/train_triplets.txt.zip',header=None, delimiter='\t')# 表中包含有形式为“用户-歌曲-收听次数”的三元组。只包含非零收听次数。 # 因此,要二值化收听次数,只需将整个收听次数列设为1。
listen_count[2] = 1
2.2.2 区间量化(分箱)

(1)固定宽度分箱

import numpy as np
small_counts = np.random.randint(0, 100, 20)# 生成20个随机整数,均匀分布在0~99之间
small_counts# 通过除法映射到间隔均匀的分箱中,每个分箱的取值范围都是0~9
1
np.floor_divide(small_counts, 10)#通过除法映射到间隔均匀的分箱中,每个分箱的取值范围都是0~9
2
large_counts = [296, 8286, 64011, 80, 3, 725, 867, 2215, 7689, 11495, 91897,44, 28, 7971, 926, 122, 22222]# 横跨若干数量级的计数值数组
np.floor(np.log10(large_counts))# 通过对数函数映射到指数宽度分箱
3

(2)分位数分箱

eg5:计算 Yelp 商家点评数量的十分位数

>>> deciles = biz_df['review_count'].quantile([.1, .2, .3, .4, .5, .6, .7, .8, .9])
>>> deciles
0.1 3.0
0.2 4.0
0.3 5.0
0.4 6.0
0.5 8.0
0.6 12.0
0.7 17.0
0.8 28.0
0.9 58.0

在直方图上画出十分位数


3.png
import pandas as pd # 继续使用例4中的large_couts
pd.qcut(large_counts, 4, labels=False)# 将计数值映射为分位数
0
# 计算实际的分位数值
large_counts_series = pd.Series(large_counts) 
large_counts_series.quantile([0.25, 0.5, 0.75])
1

2.3 对数变换

2-7.png
2.3.1 对数变换实战
# 使用Yelp点评数据框,计算Yelp点评数量的对数变换值
# 注意,我们为原始点评数量加1,以免当点评数量为0时,对数运算结果得到负无穷大。 
>>> biz_df['log_review_count'] = np.log10(biz_df['review_count'] + 1)
# 从UCI下载在线新闻流行度数据集,对n_tokens_content特征进行对数变换,这个特征表示的是一篇新闻文章中的单词 # (token)数量。
>>> df['log_n_tokens_content'] = np.log10(df['n_tokens_content'] + 1)

从下图可以看出,对数变换重组了 x 轴,对于那些目标变量值异常巨大(>200000 个分享)的文章,对数变换将它们更多地拉向了 x 轴的右侧,这就为线性模型在输入特征空间的低值端争取了更多的“呼吸空间”。 如果不进行对数变换(下面上方的图),模型就会面临更大的压力,要在输入变化很小的情况下去拟合变化非常大的目标值。


2-8.png
2.3.2 指数变换:对数变换的推广
2-11.png
>>> from scipy import stats
# 接上一个例子,假设biz_df包含Yelp商家点评数据。
# Box-Cox变换假定输入数据都是正的。
# 检查数据的最小值以确定满足假定。
>>> biz_df['review_count'].min()
3
# 设置输入参数λ为0,使用对数变换(没有固定长度的位移)。
>>> rc_log = stats.boxcox(biz_df['review_count'], lmbda=0)
# 默认情况下,SciPy在实现Box-Cox转换时,会找出使得输出最接近于正态分布的λ参数。 
>>> rc_bc, bc_params = stats.boxcox(biz_df['review_count'])
>>> bc_params
-0.4106510862321085

下面为Box-Cox 变换后的 Yelp 商家点评数量直方图(下),以及初始点评数量直方图(上)和对数变换后的点评数量直方图(中)


2-13.png 2-14.png

2.4 特征缩放/归一化

2.4.1 min-max缩放
2.4.2 特征标准化/方差缩放
2-16.png
2.4.3 l^2归一化
2-17.png
# 加载在线新闻流行度数据集
>>> df = pd.read_csv('OnlineNewsPopularity.csv', delimiter=', ')
# 查看原始数据——文章中的单词数量
>>> df['n_tokens_content'].as_matrix()
array([ 219., 255., 211., ..., 442., 682., 157.])
# min-max缩放
>>> df['minmax'] = preproc.minmax_scale(df[['n_tokens_content']]) >>> df['minmax'].as_matrix()
array([ 0.02584376, 0.03009205, 0.02489969, ..., 0.05215955,0.08048147,  0.01852726])
# 标准化——注意根据标准化的定义,有些结果会是负的
>>> df['standardized'] = preproc.StandardScaler().fit_transform(df[['n_tokens_ content']])
>>> df['standardized'].as_matrix()
array([-0.69521045, -0.61879381, -0.71219192, ..., -0.2218518 ,0.28759248, -0.82681689])
# L2-归一化
>>> df['l2_normalized'] = preproc.normalize(df[['n_tokens_content']], axis=0) 
>>> df['l2_normalized'].as_matrix()
array([ 0.00152439, 0.00177498, 0.00146871, ..., 0.00307663, 0.0047472 ,  0.00109283])

下图为原始及缩放后的新闻文章单词数量。注意只有 x 轴的尺度发生了变化,特征缩放后的分布 形状保持不变

2-18.png

当一组输入特征的尺度相差很大时,就需要进行特征缩放。例如,一个人气很高的商业网 站的日访问量可能是几十万次,而实际购买行为可能只有几千次。如果这两个特征都被模 型所使用,那么模型就需要在确定如何使用它们时先平衡一下尺度。如果输入特征的尺度 差别非常大,就会对模型训练算法带来数值稳定性方面的问题。在这种情况下,就应该对 特征进行标准化。

2.5 交互特征

>>> from sklearn import linear_model
>>> from sklearn.model_selection import train_test_split
>>> import sklearn.preprocessing as preproc
# 假设df是一个Pandas数据框,其中包含了UCI在线新闻流行度数据集 >>> df.columns
Index(['url', 'timedelta', 'n_tokens_title', 'n_tokens_content',
            'n_unique_tokens', 'n_non_stop_words', 'n_non_stop_unique_tokens','num_hrefs', 'num_self_hrefs', 'num_imgs', 'num_videos',
            'average_token_length', 'num_keywords', 'data_channel_is_lifestyle',
            'data_channel_is_entertainment', 'data_channel_is_bus',
            'data_channel_is_socmed', 'data_channel_is_tech',
            'data_channel_is_world', 'kw_min_min', 'kw_max_min', 'kw_avg_min',
            'kw_min_max', 'kw_max_max', 'kw_avg_max', 'kw_min_avg', 'kw_max_avg',
            'kw_avg_avg', 'self_reference_min_shares', 'self_reference_max_shares',
            'self_reference_avg_sharess', 'weekday_is_monday', 'weekday_is_tuesday',
            'weekday_is_wednesday', 'weekday_is_thursday', 'weekday_is_friday',
            'weekday_is_saturday', 'weekday_is_sunday', 'is_weekend', 'LDA_00',
            'LDA_01', 'LDA_02', 'LDA_03', 'LDA_04', 'global_subjectivity',
            'global_sentiment_polarity', 'global_rate_positive_words',
            'global_rate_negative_words', 'rate_positive_words',
            'rate_negative_words', 'avg_positive_polarity', 'min_positive_polarity',
            'max_positive_polarity', 'avg_negative_polarity',
            'min_negative_polarity', 'max_negative_polarity', 'title_subjectivity',
            'title_sentiment_polarity', 'abs_title_subjectivity',
            'abs_title_sentiment_polarity', 'shares'],
           dtype='object')
# 选择与内容有关的特征作为模型的单一特征,忽略那些衍生特征 
>>> features = ['n_tokens_title','n_tokens_content','n_unique_tokens', 'n_non_stop_words', 'n_non_stop_unique_tokens','num_hrefs', 'num_self_hrefs', 'num_imgs', 'num_videos', 'average_token_length','num_keywords','data_channel_is_lifestyle','data_channel_is_entertainment', 'data_channel_is_bus', 'data_channel_is_socmed', 'data_channel_is_tech', 'data_channel_is_world']
>>> X = df[features]
>>> y = df[['shares']]
# 创建交互特征对,跳过固定偏移项
>>> X2 = preproc.PolynomialFeatures(include_bias=False).fit_transform(X) >>> X2.shape
(39644, 170)
# 为两个特征集创建训练集和测试集
>>> X1_train, X1_test, X2_train, X2_test, y_train, y_test = train_test_split(X, X2, y, test_size=0.3, random_state=123)
>>> def evaluate_feature(X_train, X_test, y_train, y_test):
     ...     """Fit a linear regression model on the training set and
     ...     score on the test set"""
     ...     model = linear_model.LinearRegression().fit(X_train, y_train)
     ...     r_score = model.score(X_test, y_test)
     ...     return (model, r_score)
# 在两个特征集上训练模型并比较R方分数
>>> (m1, r1) = evaluate_feature(X1_train, X1_test, y_train, y_test)
>>> (m2, r2) = evaluate_feature(X2_train, X2_test, y_train, y_test) 
>>> print("R-squared score with singleton features: %0.5f" % r1) 
>>> print("R-squared score with pairwise features: %0.10f" % r2) 
R-squared score with singleton features: 0.00924
R-squared score with pairwise features: 0.0113276523

注:

2.6 特征选择

参考:《精通特征工程》爱丽丝·郑·阿曼达·卡萨丽

上一篇 下一篇

猜你喜欢

热点阅读