上一節對特徵進行了分析,這一節進行特徵處理,參考文獻:
特徵處理
處理分類數據
處理無序分類特徵
這裏使用獨熱編碼,對
- is_mix_service 是否固移融合套餐
- 連續超套 many_over_bill
- 合約類型 contract_type
- 是否承諾低消用戶 is_promise_low_consume
- 網絡口徑用戶 net_service
- gender 性別
進行one-hot編碼。
代碼如下:
is_mix_service_rank = pd.get_dummies(train_data['is_mix_service'],prefix='is_mix_service')
many_over_bill_rank = pd.get_dummies(train_data['many_over_bill'],prefix='many_over_bill')
contract_type_rank = pd.get_dummies(train_data['contract_type'],prefix='contract_type')
is_promise_low_consume_rank = pd.get_dummies(train_data.is_promise_low_consume,prefix = 'promise_low_consume')
net_service_rank = pd.get_dummies(train_data.net_service,prefix='net_service')
gender_rank = pd.get_dummies(train_data.gender,prefix='gender')
new = pd.concat([train_data,is_mix_service_rank,many_over_bill_rank,contract_type_rank,is_promise_low_consume_rank,net_service_rank,gender_rank],axis = 1)
new.drop(['is_mix_service','many_over_bill','contract_type'],axis=1,inplace=True)
new.drop(['is_promise_low_consume','net_service','gender'],axis=1,inplace=True)
處理有序分類特徵
有序分類特徵有:
- online_time 在網時長
- 交費次數 pay_times
- age 年齡
其實以上特徵都可以看作數值型特徵。
真正的有序分類特徵應該是這個:
- complaint_level 投訴重要性
一種處理方式是忽略特徵的有序性,直接進行獨熱編碼;另一種是使用遞進的向量表示。
這裏complaint_level共有{0,1,2,3}四個值。
設計一個如下的向量表示:
complaint_level | vector |
---|---|
0 | (0,0,0) |
1 | (0,0,1) |
2 | (0,1,1) |
3 | (1,1,1) |
我們兩種方法都嘗試一下,代碼如下:
complaint_level = train_data.complaint_level.values
cn = []
cn_dic = {0:[0,0,0],1:[0,0,1],2:[0,1,1],3:[1,1,1]}
for i in complaint_level:
temp = cn_dic[i]
cn.append(temp)
cn_df = pd.DataFrame(cn)
cn_df.columns = ['complaint_level_v1','complaint_level_v2','complaint_level_v3']
new = pd.concat([new,cn_df,complaint_level_rank],axis = 1)
new.drop(['complaint_level'],axis=1,inplace=True)
處理數值特徵
包括之前看作數值特徵的有序分類特徵:
- online_time 在網時長
- 交費次數 pay_times
- age 年齡
還有:
- 合約到期剩餘時長 contract time
- 交費金額 pay_num
- 月總出賬金額 * 4
- 當月累計流量 month_traffic
- 上月結轉流量
- 月累計-本地數據流量
- 本地語音主叫通話時長
- 套外主叫通話時長
- Service2_caller_time
- 交費金歷史投訴總量
- 歷史執行補救費用交費金額
這些數值型特徵。
我們使用決策樹離散化方法進行連續數值的處理:
pass 暫時沒找到現成的代碼。
連續特徵離散化方法還有:
基於熵的離散
基於卡方的離散
等距、等頻
這裏選擇一個更簡單的等距離離散的方法解決。
def discretization(arr,n=4):
# 等距離離散化連續特徵
# arr: list-like object
minn = min(arr)
maxn = max(arr)
diff = maxn - minn
lenn = diff / n
temp = []
for num in arr:
count = 0
while num >= minn + count*lenn:
count += 1
if count > n :
count = n
temp.append(count)
#index0 = temp.index(max(temp))
#temp[index0] -= 1
return temp
age_rank = pd.get_dummies(discretization(train_data.age.values),prefix='age')
contract_time_rank = pd.get_dummies(discretization(train_data.contract_time.values),prefix='contract_time')
online_time_rank = pd.get_dummies(discretization(train_data.online_time.values),prefix='online_time')
pay_times_rank = pd.get_dummies(discretization(train_data.pay_times.values),prefix='pay_times')
new = pd.concat([train_data,age_rank,contract_time_rank,online_time_rank,pay_times_rank],axis = 1)
new.drop(['age','contract_time','online_time','pay_times'],axis=1,inplace=True)
pay_num_rank = pd.get_dummies(discretization(train_data.pay_num.values),prefix='pay_num')
month_traffic_rank = pd.get_dummies(discretization(train_data.month_traffic.values),prefix='month_traffic')
l_total_fee_rank = pd.get_dummies(discretization(train_data['1_total_fee'].values),prefix='1_total_fee')
ll_total_fee_rank = pd.get_dummies(discretization(train_data['2_total_fee'].values),prefix='2_total_fee')
lll_total_fee_rank = pd.get_dummies(discretization(train_data['3_total_fee'].values),prefix='3_total_fee')
llll_total_fee_rank = pd.get_dummies(discretization(train_data['4_total_fee'].values),prefix='4_total_fee')
new = pd.concat([new,pay_num_rank,month_traffic_rank,l_total_fee_rank,ll_total_fee_rank,lll_total_fee_rank,llll_total_fee_rank],axis = 1)
new.drop(['pay_num','month_traffic','1_total_fee','2_total_fee','3_total_fee','4_total_fee'],axis=1,inplace=True)
last_month_traffic_rank = pd.get_dummies(discretization(train_data.last_month_traffic.values),prefix='last_month_traffic')
local_trafffic_month_rank = pd.get_dummies(discretization(train_data.local_trafffic_month.values),prefix='local_trafffic_month')
local_caller_time_rank = pd.get_dummies(discretization(train_data.local_caller_time.values),prefix='local_caller_time')
server1_caller_time_rank = pd.get_dummies(discretization(train_data.service1_caller_time.values),prefix='server1_caller_time')
server2_caller_time_rank = pd.get_dummies(discretization(train_data.service2_caller_time.values),prefix='server2_caller_time')
former_complaint_num_rank = pd.get_dummies(discretization(train_data.former_complaint_num.values),prefix='former_complaint_num')
former_complaint_fee_rank = pd.get_dummies(discretization(train_data.former_complaint_fee.values),prefix='former_complaint_fee')