标签:默认 rate encoding 统一 最好 log 控制 哈哈 engine
interactions = data_raw["category"]+"_"+data_raw["country"] baseline_data = baseline_data.assign(category_country = label_encoder.fit_transform(interactions))
上面的第一句代码就是咱们interaction的部分,第二句是讲interaction过后的数据label encoding并且加入到咱们的数据集里面,简单明了。上面是将原始数据中的category 和 country连接在一起从而形成一个新的feature 2.2 numerical transforming。这是什么意思呢,对于有些numerical data的columns,他们的数据分布是很不均匀的,或者说他们的数值太大或者太小,有的时候不适合咱们的数据的训练,可能会出现vanishing gradient或者gradient explode的情况。具体啥叫vanishing gradient和gradient exploding,咱们在后面的内容在慢慢解释。暂时只需要知道这是个很麻烦的事情就好了,会导致咱们训练的模型不那么牛逼就行了。那么咱们通过什么方法解决呢?这里主要通过一些常见的数学的方式来解决,例如用log 或者 sqrt等等方式。咱们可以通过下面的代码来简单的展示一下
np.sqrt(baseline_data[‘goal‘]) np.log(baseline_data[‘goal‘])
从上面咱们可以看出,这里咱们主要还是通过numpy里面提供的API进行处理的,非常简单,简单跟1一样,好了这里就说到这了。 对了,忘记一个事儿,就是numerical transforming在tree-based模型中没有什么卵用的,因为tree-based的所有模型都是scale invariant的,就是tree-based模型都是不care数据的大小分布的。 2.3 rolling。这个就比较高级一点啦(相比前两种方式),首先咱们先要明白rolling的概念,其实rolling就是相当于在咱们的数据(series)上面卡上一个fixed-size的小window,然后对于这个window覆盖的数据进行一些简单的计算,例如:counting,mean,sum等等。如果大家还是觉得不懂,我把它的官方链接贴在这里,大家自己去看看,里面还有很多实例:https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Series.rolling.html#pandas.Series.rolling 。那么我先写一个简单的小例子给大家参考一下哈
launched = pd.Series(data_raw.index,data_raw.launched,name="count_7_days").sort_index() count_7_days = launched.rolling(‘7d‘).count() count_7_days.index = launched.values
count_7_days = count_7_days.reindex(data_raw.index)
我先简单解释一下上面代码的意思哈,第一句是让时间作为这个series的index,第二句rolling是计算最近7天的的数量,第三第四句是讲数据还原到之前的index的顺序,房间重新join到原来的数据集中。那么rolling这种方式一般在什么情况下用呢?一般在你的数据有datetime的时候,或者前面数据会影响到后面的结果的时候,大家可以考虑一下下,但是这个是不一定的,还是需要大家有一定的creativity的。例如上面的例子就是统计最近7天一共上传的APP的数量,来判断某一个APP是否被下载的应用场景。一般情况下,最近上传的APP数量太多,被下载的概率就越低,所以他们还是有一定关联关系的。所以我generate一个新的feature还是有一定道理的。 2.4 Time delta。从这个命名中咱们可以知道,这个跟time肯定有关系,这个大家猜的很对。time delta也是有一定随机性的,有时需要有时也不需要,也是要根据实际的数据的特性来决定的,甚至是根据工程师自己来决定的,跟上面的rolling有点相似。为了方便解释这其中的细节,我也是直接来一个例子然后慢慢解释
def time_since_last_project_same_category(series): return series.diff().dt.total_seconds()/3600 df = data_raw[[‘category‘,‘launched‘]].sort_values(‘launched‘) group_category = df.groupby(‘category‘) timedeltas = group_category.transform(time_since_last_project_same_category) timedeltas = timedeltas.fillna(timedeltas.mean()).reindex(baseline_data.index)
上面前两行是一个计算相邻datatime之间的相差多少个小时,第三行创建一个按照排序好的launched time为index的dataframe, 第四行是按照category的条件来group前面创建的df, 第五行是计算group里面相邻数据之间的time delta,并且返回一个series, 第六行是填充这些空数据,并且按照原始数据的方式index重新排序方便加入到原始数据。流程就这样结束了。上面的场景是计算同一个category相邻app上传的时间差,这个其实也是会影响到咱们的APP是否被下载的因素。所以这个也是咱们的一个creativity,实际情况中千变万化,一定要根据实际情况来定,不能为了装逼而装逼,一定要根据实际的业务需要,否则适得其反。 好了,其实关于feature generation还有很多种方式,例如有些事计算两个columns之间的差值,取模等等,这里没有统一的标准,唯一的捷径和key就是咱们一定得理解咱们每一个columns和dataset的实际业务的意思,否则再牛逼的generation也拯救不了你。下面咱们进入到这一章的最后一节feature selection吧。
from sklearn.feature_selection import SelectKBest, f_classif selector = SelectKBest(score_func = f_classif, k = 5) train,valid,test = get_data_splits(baseline_data, 0.1) feature_cols = train.columns.drop("outcome") X_new = selector.fit_transform(train[feature_cols],train["outcome"] )
#get back to the features we kept
features = pd.DataFrame(selector.inverse_transform(X_new), index = train.index, columns = feature_cols)
#drop the columns that the values are all 0s
feature_cols_final = features.columns[features.var()!=0]
features_final = features[feature_cols_final]
从上面的代码咱们可以看出来,首先得从sklearn.feature_selection这个模块中引进SelectKBest和f_classif两个子模块;第二步就是创建一个Selector实例对象,这个selector最终返回多少个features是通过咱们的参数K来控制的,selector的最终选择哪些features也是通过f_classif这个函数来控制的;最后就是这个selector的transform了,将features和target作为参数分别传递给他,他会自动搞定,并且返回K个features, 然后再将numpy array返回到dataframe的格式。这种方式的只能计算出每一个feature和target的linear dependency,并不能一次性包括所有的features进行关联性计算。 3.2 L1 Regression。L1 Regression可以直接包括所有的features一次性的计算这个columns和target的关联性。关联性越强,数值越大。它不需要制定最后返回多少个features,它是根据L1的结果自动帮助咱们features。但是它的运行速度要远远慢于上面k-classif的方法,可是好处就是一般情况下L1 Regression的运行结果要好于K-classif, 但也不一定澳,只能说大部分情况是这样的。
from sklearn.linear_model import LogisticRegression from sklearn.feature_selection import SelectFromModel train,valid,test = get_data_splits(baseline_data, 0.1) X, y = train[train.columns.drop("outcome")], train["outcome"] logistic_model = LogisticRegression(C=1, penalty="l1", random_state=7).fit(X,y) selector = SelectFromModel(logistic_model,prefit=True) X_new = selector.transform(X) features = pd.DataFrame(selector.inverse_transform(X_new),index = train.index, columns = feature_cols) feature_cols_final = features.columns[features.var()!=0]
总结:上面就是一般的的特征工程的feature selection和feature generation的一般方法,咱们上面讲了很多种的方式,实际情况中具体选择哪一种还是要根据实际情况,一定不要死读书。feature generation一般就是interaction,numerical generation,rolling和time delta四种方式。feature selection一般用到的技术手段就是就是f-classif和L1 regression几种方式。
机器学习-特征工程-Feature generation 和 Feature selection
标签:默认 rate encoding 统一 最好 log 控制 哈哈 engine
原文地址:https://www.cnblogs.com/tangxiaobo199181/p/12210734.html