智慧海洋建设TOP方案借鉴学习与整理
文章目錄
- 數據探索與預處理
- 漁船作業方式的定義
- 漁船作業過程中的三種狀態
- 預處理
- 特征工程
- 統計特征
- 表征漁船的軌跡
- POI信息
- 基于軌跡序列絕對和相對位置的復合向量編碼
- 表征漁船不同狀態下的信息
- Anchored-off狀態特征
- Turning狀態特征
- **Straight-sailing狀態特征**
- 動態信息特征
- 模型策略
本文主要是學習了天池的智慧海洋建設比賽的一些TOP方案,并對思路進行整理,本文以TOP1的方案為主,其他方案作為補充。
參考的文章如下:
非常感謝前排大佬開源的方案!
數據探索與預處理
漁船作業方式的定義
拖網:拖曳漁具在海底或海水中前進,對魚類進行捕撈的作業方式。
圍網:使用網具包圍魚群進行捕撈的作業方式
刺網:將長帶形的網列敷設于水域中,使魚刺入網目或被網衣纏絡后加以捕撈
漁船作業過程中的三種狀態
Anchored-off:船舶休息的點
Turning:船舶轉彎的點
Straight-sailing:船舶航行的點
預處理
軌跡數據預處理方面, 將平面坐標轉換為經緯度坐標。首先采用了經驗閾值均值濾波去除了每條軌跡速度的異常值、坐標的離群點, 并用多項式插值函數對離群點進行了插值,基于局部速度對異常坐標點進行插值。
特征工程
統計特征
1,分箱特征,距離海岸線的近似值。
對v求分箱特征,等分為200份,求每一份的統計值 對x求分箱特征,1000份和10000份,求每一份的次數統計值,和每一個分箱對應不同id數目 對y求分箱特征,1000份和10000份,求每一份的次數統計值,和每一個分箱對應不同id數目 求x,y分箱后的組合特征做為分組,求對應的次數統計值,和對應的id的不同數目 根據x分組,求y距離最小y的距離 # 可以理解為距離海岸線距離 根據y分組,求x距離最小x的距離 # 可以理解為距離海岸線距離2,對漁船的經緯度序列做均值、方差、分位數、眾數等統計,可以簡單地刻畫漁船的活動范圍
mode_df = data.groupby(['漁船ID', 'lat', 'lon'])['time'].agg({'mode_cnt':'count'}).reset_index() mode_df['rank'] = mode_df.groupby('漁船ID')['mode_cnt'].rank(method='first', ascending=False) for i in range(1, 4):tmp_df = mode_df[mode_df['rank']==i]del tmp_df['rank']tmp_df.columns = ['漁船ID', 'rank{}_mode_lat'.format(i), 'rank{}_mode_lon'.format(i), 'rank{}_mode_cnt'.format(i)]data_ = data_.merge(tmp_df, on=['漁船ID'], how='left')3,間隔空間位移特征
根據id分組,對x求,上一個x,下一個x,間隔2個x的距離 根據id分組,對y求,上一個y,下一個y,間隔2個y的距離 根據上述距離,求上一時刻,下一時刻,間隔2個時刻的面積,相對值4,行程特征
總行程距離 每一步行程的占比 將'dist_move_prev_bin_sen', 'v_bin_sen'轉化為onehot稀疏特征5,其他:
分別計算每個ship中速度大于0小于等于2、大于2小于等于6、大于6小于等于10的比例和平均值,三種區間代表三種運動狀態,
以每個區間中的平均速度代表該船在該運動狀態下的速度描述(根據速度的分布圖選擇的對速度的分箱方式)。以速度大于4的連續運動片段作為工作狀態,計算每個ship中的工作狀態片段并計算每個片段的位移作為作業間隔,統計每個ship中的作業間隔的中位數特征。
利用原數據’time’特征,提取其‘分鐘’特征,計算其最大值。
時間差的平均值。時間差的分位數。時間差的中位數。
計算每個ship中角度的平均值。設計了拐角特征,并統計每艘船的三種拐角形式的數量,均值作為特征。
數據處理:skew較大的特征使用log函數將其正態化;與速度相關的特征保留其兩位有效數字。
表征漁船的軌跡
POI信息
將每條軌跡投射到網格坐標系下,這樣軌跡序列變為了網格id的符號序列; 隨后我們基于被boat_id不同的漁船訪問次數, 不同boat_id的漁船在該網格停留的平均時長和網格總的被訪問的次數三個判據,篩選出了一系列的POI網格。
基于軌跡序列絕對和相對位置的復合向量編碼
經緯度常規的統計特征對漁船軌跡信息的表征能力其實是有限的,這里我們設計了一種軌跡序列的編碼方式(該方法可拓展至其他類型的軌跡序列數據),進一步刻畫了軌跡的動態信息和漁船經過的每個點之間的聯系
1,Geohash7編碼:Geohash其實是將地圖拆分成了一個個矩形網格,當經緯度落入到某個網格內時,則使用網格的編碼代替經緯度,這相當于是一種聚類方式。這里我們不直接使用經緯度(細粒度)的好處就是可以提高特征的泛化能力。除此之外,我們還采用了全集和下采樣兩種提取方式來提取Geohash7編碼后的軌跡序列。下采樣的好處是緩解漁船位置信息頻繁上報而產生的噪音。
2,梯度編碼:軌跡序列的梯度是指的后一個位置相對于前一個位置的變化,目的是為了獲取相對位置信息
3,基于Word2Vec和Node2Vec的DNN編碼:主要思想是將漁船的軌跡序列當成文本,每個地點(Geohash編碼)則是一個 “詞語”,使用Word2Vec進行向量表征;把漁船經過的地點構造成 “點”,而不同地點之間的關系構造成 “邊”,使用Node2Vec進行向量表征。
def w2v_feat(df, group_id, feat, length):print('start word2vec ...')data_frame = df.groupby(group_id)[feat].agg(list).reset_index()model = Word2Vec(data_frame[feat].values, size=length, window=5, min_count=1, sg=1, hs=1,workers=1, iter=10, seed=1, hashfxn=hashfxn)# data_frame[feat] 存放每個漁船的[xz5k92v, xz5k99f, ...,xz5kdjj]對應的【二維表】,維度:(n , 30)# n 是漁船的所有軌跡記錄[xz5k92v, xz5k99f, ...,xz5kdjj]的個數# 30是每個軌跡數據,如xz5k92v,通過Word2Vec得到是30維向量# 即每一行都存放了一個軌跡記錄的30維向量data_frame[feat] = data_frame[feat].apply(lambda x: pd.DataFrame([model[c] for c in x]))# 遍歷30維向量的每個分量for m in range(length):# 計算n行30維向量 的 每個分量 的均值,也就是計算第m列均值,作為該漁船的一個Word2Vec特征。data_frame['w2v_{}_mean'.format(m)] = data_frame[feat].apply(lambda x: x[m].mean())del data_frame[feat]return data_frame4,TFIDF&CountVec編碼:
此類編碼方式也是借鑒了文本的常用處理方法,提取漁船軌跡序列中Geohash的頻次信息。
def tfidf(input_values, output_num, output_prefix, seed=1024):tfidf_enc = TfidfVectorizer()tfidf_vec = tfidf_enc.fit_transform(input_values)svd_tmp = TruncatedSVD(n_components=output_num, n_iter=20, random_state=seed)svd_tmp = svd_tmp.fit_transform(tfidf_vec)svd_tmp = pd.DataFrame(svd_tmp)svd_tmp.columns = ['{}_tfidf_{}'.format(output_prefix, i) for i in range(output_num)]return svd_tmp表征漁船不同狀態下的信息
Anchored-off狀態特征
認為當漁船的速度為0時,漁船處于停靠或是收網的狀態。統計該狀態下漁船所處的位置,可以讓模型捕捉到不同作業方式下漁船停靠點或收網點的規律。
for col in ['lat', 'lon']:print(col)group_df = data[data['速度']==0].groupby(['漁船ID'])[col].agg({'錨點_'+col+'_mean': 'mean','錨點_'+col+'_max': 'max','錨點_'+col+'_min': 'min','錨點_'+col+'_nuniq': 'nunique','錨點_'+col+'_q1': lambda x: np.quantile(x, 0.10),'錨點_'+col+'_q2': lambda x: np.quantile(x, 0.20),'錨點_'+col+'_q3': lambda x: np.quantile(x, 0.30),'錨點_'+col+'_q4': lambda x: np.quantile(x, 0.40),'錨點_'+col+'_q5': lambda x: np.quantile(x, 0.50),'錨點_'+col+'_q6': lambda x: np.quantile(x, 0.60),'錨點_'+col+'_q7': lambda x: np.quantile(x, 0.70),'錨點_'+col+'_q8': lambda x: np.quantile(x, 0.80),'錨點_'+col+'_q9': lambda x: np.quantile(x, 0.90)}).reset_index()features = features.merge(group_df, on=['漁船ID'], how='left')Turning狀態特征
將數值型的方向特征進行離散化處理后,統計漁船作業過程中不同方向的頻次及比例。
data['方向'] = data['方向'].apply(lambda x:(int(round(x/30)))*30) degree_df = data.pivot_table(index='漁船ID',columns='方向',values='lat', dropna=False, aggfunc='count').fillna(0) degree_df.columns = [str(f)+'_方向_count' for f in degree_df.columns] degree_df.reset_index(inplace=True)Straight-sailing狀態特征
漁船的歷史數據中存在大量的速度為0的記錄,會對速度進行均值、方差等統計產生較大的影響。我們單獨取速度大于0時的樣本,再對速度構造統計特征,一方面去除速度為0的影響、另一方面刻畫了漁船航行時的狀態。
group_df = data[data['速度']>0].groupby(['漁船ID'])['速度'].agg({'速度_mean_new': 'mean','速度_q10_new': lambda x: np.quantile(x, 0.10),'速度_q20_new': lambda x: np.quantile(x, 0.20),'速度_q30_new': lambda x: np.quantile(x, 0.30),'速度_q40_new': lambda x: np.quantile(x, 0.40),'速度_q50_new': lambda x: np.quantile(x, 0.50),'速度_q60_new': lambda x: np.quantile(x, 0.60),'速度_q70_new': lambda x: np.quantile(x, 0.70),'速度_q80_new': lambda x: np.quantile(x, 0.80),'速度_q90_new': lambda x: np.quantile(x, 0.90), }).reset_index()動態信息特征
每個漁船id的速度、經緯度看做是一個序列信息
利用速度、經緯度的分位數統計量,將浮點特征分桶轉成一個類型特征
使用不同的ngram提取TF-IDF 特征(ngram=1, 2, 3)
最終,利用NLP的TF-IDF提取關鍵高維的ngram信息,有效獲取速度和經緯度動態變化的信息
模型策略
五折驗證,使用的lightgbm參數如下:
params = {'learning_rate': 0.05,'boosting_type': 'gbdt','objective': 'multiclass','metric': 'None','num_leaves': 63,'feature_fraction': 0.8,'bagging_fraction': 0.8,'bagging_freq': 5,'seed': 1,'bagging_seed': 1,'feature_fraction_seed': 7,'min_data_in_leaf': 20,'num_class': n_class,'nthread': 8,'verbose': -1,}再次感謝前排大佬開源的方案!
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的智慧海洋建设TOP方案借鉴学习与整理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 迪卡侬双 11 电商促销高于日常价被罚
- 下一篇: 魔兽世界怀旧服WLK卡拉赞黯血王子在哪里