第一次试手阿里天池新人赛——快来一起挖掘幸福感,用xgb和lgb进行简单的特征处理后,训练线上结果最好只能到0.48,训练集交叉验证能到0.46。如果要进一步提升,不特征工程是不行了。下面是根据相关系数进行插值的处理,先记录下,待训练后看效果。
数据下载:https://tianchi.aliyun.com/competition/entrance/231702/information。
初步想法是:
1:前期训练发现几个class特征是比较重要的特征。
2:从找到class相关度较大的几个特征,以5个作为示例
3:对小于0和nan值进行填补。
具体代码和解释
train_file=r"D:\AI\tianchi\data\happiness\happiness_train_complete.csv"
test_file=r"D:\AI\tianchi\data\happiness\happiness_test_complete.csv"
import pandas as pd
import numpy as np
df_train_o=pd.read_csv(train_file,encoding="gbk")
df_test_o=pd.read_csv(test_file,encoding="gbk")
#连接训练集和测试集,特征一起处理
df_o=pd.concat([df_train_o,df_test_o],ignore_index=True)
#取class相关系数最大的前5个特征
class_corr_index=df_o.corr(method="pearson")["class"].sort_values().\
tail(5).dropna().index
#去掉happiness,因为它是要估计的
if "happiness" in class_corr_index:
class_corr_index=class_corr_index.drop(["happiness"])
#导入itertools,使用其进行特征组合
import itertools
#导入插值模块
import scipy.interpolate as si
#负值和缺失值都需要插值填补,都认为是缺失值
print("填补前空值统计:")
print(df_o[class_corr_index].isnull().sum())
print("填补前负值统计:")
print((df_o[class_corr_index] < 0).sum())
#第一层循环分别对只缺1、2、3、4个的值进行填补
#第二层循环组合1,2,3,4个特征,找出这些组合缺失,而剩下特征都未缺失的样本
#第三层循环分别对缺失的值进行填补
for i in range(1,5):
for j in itertools.combinations(class_corr_index,r=i):
#特征组合是否缺失矩阵
tmp1=((df_o.loc[:,j].isnull()) | (df_o.loc[:,j]<0)).sum(axis=1)==i
#剩下的特征组合
tmp_index=class_corr_index[~class_corr_index.isin(j)]
#剩下特征是否不缺失矩阵
tmp2=((df_o.loc[:,tmp_index].isnull()) | (df_o.loc[:,tmp_index]<0)).sum(axis=1)==0
#特征组合缺失,剩下不缺失的矩阵
index_for=tmp1&tmp2
#特征组合缺失,剩下不缺是的样本
x=df_o.loc[index_for,tmp_index]
if(0 == x.shape[0]):
continue
for k in j:
#k未特征组合中一个特征,与剩下特征组合形成新的组合,用于寻找拟合数据
index_points=tmp_index.insert(0,k)
#用于拟合的样本
tmp3=(((df_o.loc[:,index_points].isnull()) | (df_o.loc[:,index_points]<0)).sum(axis=1)==0)
#拟合数据样本
points_v=df_o.loc[tmp3,index_points]
#拟合数据坐标
points=points_v[tmp_index]
#拟合数据值
values=points_v[k]
#开始拟合
y=si.griddata(points.values,values.values,x.values)
#拟合结果填入到原数据
df_o.loc[index_for,k]=y
print("填补前空值统计:")
print(df_o[class_corr_index].isnull().sum())
print("填补后负值统计:")
print((df_o[class_corr_index] < 0).sum())
运行结果如下:
填补前空值统计:
family_status 0
class_14 0
class_10_after 0
class_10_before 0
class 0
dtype: int64
填补前负值统计:
family_status 64
class_14 191
class_10_after 638
class_10_before 148
class 106
dtype: int64
填补前空值统计:
family_status 0
class_14 1
class_10_after 3
class_10_before 0
class 0
dtype: int64
填补后负值统计:
family_status 9
class_14 9
class_10_after 9
class_10_before 9
class 9
dtype: int64
填补之后发现仍然由负值和缺失值。缺失值是由于拟合结果在拟合曲面之外。可以使用fill_value参数填充。griddata的fill_value参数解释如下:
fill_value : float, optional
Value used to fill in for requested points outside of the convex hull of the input points. If not provided, then the default is nan
. This option has no effect for the 'nearest' method.
负值出现是由于5个特征都是缺失或者负值,这种情况无法拟合。需要另外处理。