目录
分析案例:
数据集
编辑
主函数代码
构建类feature_generation
类feature_generation的方法fit_generate
函数generate
函数auto_var
自定义的各类衍生函数们
计算最近p个月特征inv大于0的月份数。
where函数
计算最近p个月特征inv的均值
nanmean()函数
计算最近p个月,最近一次特征inv大于0到现在的月份数(可能有误)
计算最近p个月特征inv的变异系数。
计算最近p个月inv的极差。
计算最近p个月中,后一个月inv相比前一个月inv增长的月份数(原函数可能有误)
计算最近p个月inv的修剪均值(原函数可能有误)
分析案例:
Python手写了 35 种可解释的特征工程方法 - 腾讯云开发者社区-腾讯云
本节为读者介绍业内实用效果较好的35种基于时间序列进行特征聚合的方法
数据集
接下来我们将 ft 这个特征按照月份划分为12个特征 命名为ft1 ft2 ......ft12 代表每个用户每个月额度使用
主函数代码
#读取数据
data = pd.read_excel('textdata.xlsx')
#指定参与衍生的变量名
FEATURE_LIST = ['ft','gt']
#指定聚合月份
P_LIST = [3,6]
#调用变量衍生函数
gen = feature_generation(data, FEATURE_LIST, P_LIST)
df = gen.fit_generate()
#读取数据 data = pd.read_excel('textdata.xlsx') #指定参与衍生的变量名 FEATURE_LIST = ['ft','gt'] #指定聚合月份 P_LIST = [3,6] #调用变量衍生函数 gen = feature_generation(data, FEATURE_LIST, P_LIST) df = gen.fit_generate()
构建类feature_generation
这个类的构造函数:
data 即为我们传入的需要处理的数据
feature_list 即为我们需要处理的特征名 注意是前缀 例如我们需要传入的是ft 而不是ft1 ft2
p_list 即为需要聚合的月份
df 是我们最终得到的数据表格
func_list 是我们可以调用的函数的名字
类feature_generation的方法fit_generate
def fit_generate(self):
"""
通过循环变量名inv和月份p,
实现全部变量的衍生
"""
for self.inv in self.feature_list:
for self.p in self.p_list:
var_df = self.generate(self.inv, self.p)
self.df = pd.concat([self.df, var_df], axis=1)
return self.df
外层循环是遍历我们需要衍生的特征
内层循环是遍历具体的月份
for self.inv in self.feature_list: for self.p in self.p_list:
在循环里我们调用函数generate传入特征名和月份,然后将返回的结果存入var_df中 然后把var_df给拼接到df里 直到将所有处理好的特征都放到df中 结束循环 返回df
var_df = self.generate(self.inv, self.p) self.df = pd.concat([self.df, var_df], axis=1)
函数generate
python进程池:multiprocessing.pool - jihite - 博客园
def generate(self, inv, p): """ 多进程,衍生变量主函数 """ var_df = pd.DataFrame([]) pool = multiprocessing.Pool(self.core_num) results = [pool.apply_async(self.auto_var, [func]) for func in self.func_list] pool.close() pool.join() for i in range(len(results)): try: columns, value = results[i].get() var_df[columns] = value except: continue return var_df
调用函数auto_var 参数为我们定义的函数名
results = [pool.apply_async(self.auto_var, [func]) for func in self.func_list]
results的返回值 是每一列的列名+数据
然后我们就把每一个result结果放进var_df(DataFrame数据类型)中
for i in range(len(results)): try: columns, value = results[i].get() var_df[columns] = value except: continue
函数auto_var
def auto_var(self, func):
if func == 'Num':
try:
return self.Num(self.inv, self.p)
except:
print("Num PARSE ERROR", self.inv, self.p)
elif func == 'Nmz':
try:
return self.Nmz(self.inv, self.p)
except:
print("Nmz PARSE ERROR", self.inv, self.p)
依次调用我们需要的函数
自定义的各类衍生函数们
计算最近p个月特征inv大于0的月份数。
#计算最近p个月特征inv大于0的月份数。
def Num(self, inv, p):
df = self.data.loc[:, inv + '1':inv + str(p)].values
auto_value = np.where(df > 0, 1, 0).sum(axis=1)
return inv + '_num' + str(p), auto_value
where函数
np.where()的使用方法_YECHAOOO的博客-CSDN博客_np where
inv + '1':inv + str(p)
这个就是对应的特征名 例如inv=ft p=3时 提取ft1这一列到ft3这一列的数据
下面是对这个函数返回值做一个测试
df=pd.DataFrame({'X1':[1,2,3],'X2':[4,5,6],'X3':[7,8,9]}) print(df)
test = df.loc[:, 'X1':'X2'].values print(test) auto_value = np.where(test > 3, 1, 0).sum(axis=1) print(auto_value)
返回的就是每一个数据(一行)大于3的个数
计算最近p个月特征inv的均值
#计算最近p个月特征inv的均值。
def Avg(self, inv, p):
df = self.data.loc[:, inv + '1':inv + str(p)].values
auto_value = np.nanmean(df, axis=1)
return inv + '_avg' + str(p), auto_value
nanmean()函数
np.nansum()、np.nanmean() 函数用法_YL_python_C++_java的博客-CSDN博客_np.nanmean
忽略nan数值求平均值
计算最近p个月,最近一次特征inv大于0到现在的月份数(可能有误)
#计算最近p个月,最近一次特征inv大于0到现在的月份数。
def Msg(self, inv, p):
df = self.data.loc[:, inv + '1':inv + str(p)].values
df_value = np.where(df > 0, 1, 0)
auto_value = []
for i in range(len(df_value)):
row_value = df_value[i, :]
if row_value.max() <= 0:
indexs = '0'
auto_value.append(indexs)
else:
indexs = 1
for j in row_value:
if j > 0:
break
indexs += 1
auto_value.append(indexs)
return inv + '_msg' + str(p), auto_value
df_value = np.where(df > 0, 1, 0)
此时df_value是一个与df同型的矩阵
例:
df=pd.DataFrame({'X1':[1,2,3],'X2':[4,5,6],'X3':[7,8,9]}) print(df) test = df.loc[:, 'X1':'X2'].values print(test) auto_value = np.where(test == 3, 1, 0) print(auto_value)
计算最近p个月特征inv的变异系数。
均值除以方差
#计算最近p个月特征inv的变异系数。 def Cva(self, inv, p): df = self.data.loc[:, inv + '1':inv + str(p)] auto_value = np.nanmean(df, axis=1) / (np.nanvar(df, axis=1) + 1e-10) return inv + '_cva' + str(p), auto_value
计算最近p个月inv的极差。
最大值减去最小值
#计算最近p个月inv的极差。 def Ran(self, inv, p): df = self.data.loc[:, inv + '1':inv + str(p)].values auto_value = np.nanmax(df, axis=1) - np.nanmin(df, axis=1) return inv + '_ran' + str(p), auto_value
计算最近p个月中,后一个月inv相比前一个月inv增长的月份数(原函数可能有误)
#计算最近p个月中,后一个月inv相比前一个月inv增长的月份数。
def Nci(self, inv, p):
arr = self.data.loc[:, inv + '1':inv + str(p)].values
auto_value = []
for i in range(len(arr)):
df_value = arr[i, :]
value_lst = []
for k in range(len(df_value) - 1):
minus = df_value[k] - df_value[k + 1]
value_lst.append(minus)
value_ng = np.where(np.array(value_lst) > 0, 1, 0).sum()
auto_value.append(np.nanmax(value_ng))
return inv + '_nci' + str(p), auto_value
修改之后:
#计算最近p个月中,后一个月inv相比前一个月inv增长的月份数。 def Nci(self, inv, p): arr = self.data.loc[:, inv + '1':inv + str(p)].values auto_value = [] for i in range(len(arr)): df_value = arr[i, :] value_lst = [] for k in range(len(df_value) - 1): minus = df_value[k+1] - df_value[k] value_lst.append(minus) value_ng = np.where(np.array(value_lst) > 0, 1, 0).sum() auto_value.append(np.nanmax(value_ng)) return inv + '_nci' + str(p), auto_value
给修改的函数写了一个简单的案例
df=pd.DataFrame({'X1':[4,5,6],'X2':[6,5,3],'X3':[7,8,9]}) print(df) def Nci(data,n): arr = data.loc[:, 'X1':'X'+str(n)].values auto_value = [] for i in range(len(arr)): df_value = arr[i, :] value_lst = [] for k in range(len(df_value) - 1): minus = df_value[k+1] - df_value[k] value_lst.append(minus) value_ng = np.where(np.array(value_lst) > 0, 1, 0).sum() auto_value.append(np.nanmax(value_ng)) print(auto_value) Nci(df,3)
计算最近p个月inv的修剪均值(原函数可能有误)
修剪均值:去掉最大值最小值之后再求均值
#计算最近p个月inv的修剪均值。 def Trm(self, inv, p): df = self.data.loc[:, inv + '1':inv + str(p)] auto_value = [] for i in range(len(df)): trm_mean = list(df.loc[i, :]) trm_mean.remove(np.nanmax(trm_mean)) trm_mean.remove(np.nanmin(trm_mean)) temp = np.nanmean(trm_mean) auto_value.append(temp) return inv + '_trm' + str(p), auto_value
原函数可能有误
修改之后
#计算最近p个月inv的修剪均值。 def Trm(self, inv, p): df = self.data.loc[:, inv + '1':inv + str(p)] auto_value = [] for i in range(len(df)): trm_mean = list(df.loc[i, :]) trm_mean.remove(np.nanmax(trm_mean)) trm_mean.remove(np.nanmin(trm_mean)) temp = np.nanmean(trm_mean) auto_value.append(temp) return inv + '_trm' + str(p), auto_value