智慧海洋竞赛实践 专题三

文章目录

  • 智慧海洋竞赛实践 专题三
    • 1. 特征工程概述
      • 1.1 特征构建
      • 1.2 特征提取和特征选择
    • 2. 数据预处理
      • 2.1 读入数据
      • 2.2 基本处理
    • 3. 基础特征
      • 3.1 距离计算
      • 3.2 时间划分
      • 3.3 速度划分
      • 3.4 方位划分
      • 3.5 描述性统计
      • 3.6 坐标与角度偏移指标计算
      • 3.7 分箱
    • 4. embedding特征
      • 4.1 简介
      • 4.2 使用场景
      • 4.3 Word2Vec
      • 4.4 NMF提取文本的主题分布

1. 特征工程概述

特征工程大体可分为3部分,特征构建、特征提取和特征选择。

1.1 特征构建

把现有特征进行组合或互相计算,得到新的特征。

1.2 特征提取和特征选择

  • 特征提取

通过特征转换得到一组具有明显物理或统计意义的特征

  • 特征选择(属性选择/变量选择)

从这些特征集合中选出一个子集。

2. 数据预处理

2.1 读入数据

参考链接:https://blog.csdn.net/weixin_43496331/article/details/115769140?spm=1001.2014.3001.5501

2.2 基本处理

读入数据(df)预览:

# 将中文名改为英文
df.rename(columns = {'渔船ID': 'id', '速度': 'v', '方向': 'dir'},inplace = True)
# 把分类变量数值化
df.rename(columns ={'type': 'label'},inplace = True) #修改变量名
df['label'] = df['label'].map({'拖网': 0, '围网': 1, '刺网': 2})# 修改变量类型为float
cols = ['x','y','v']
for col in cols:df[col] = df[col].astype('float')
df['dir'] = df['dir'].astype('int')# 修改变量类型为时间类型,并增加年时间字段
df['time'] = pd.to_datetime(df['time'], format='%m%d %H:%M:%S')
df['date'] = df['time'].dt.date
df['hour'] = df['time'].dt.hour
df['month'] = df['time'].dt.month
df['weekday'] = df['time'].dt.weekday

3. 基础特征

3.1 距离计算

d=(x−x0)2+(y−y0)22d = \sqrt[2]{(x-x_0)^2+(y-y_0)^2} d=2(xx0)2+(yy0)2

3.2 时间划分

# 白天、黑天划分
df['day_nig'] = 0
df.loc[(df['hour'] > 5) & (df['hour'] < 20),'day_nig'] = 1# 季度划分
df['quarter'] = 0
df.loc[(df['month'].isin([1, 2, 3])), 'quarter'] = 1
df.loc[(df['month'].isin([4, 5, 6, ])), 'quarter'] = 2
df.loc[(df['month'].isin([7, 8, 9])), 'quarter'] = 3
df.loc[(df['month'].isin([10, 11, 12])), 'quarter'] = 4

3.3 速度划分

定义速度划分区间,生成新变量‘v_cut’

def v_cut(v):if v < 0.1:return 0elif v < 0.5:return 1elif v < 1:return 2elif v < 2.5:return 3elif v < 5:return 4elif v < 10:return 5elif v < 20:return 5else:return 6df['v_cut'] = df['v'].apply(lambda x:v_cut(x))

统计每个id的对应速度等级的个数,生成工具表c1

# 分组计算
tmp = df.groupby(['id', 'v_cut'], as_index=False)['v_cut'].agg({'v_cut_count': 'count'})
# 透视
c1 = tmp.pivot(index='id',columns='v_cut',values='v_cut_count')
# 修改列名
c1.columns = ['v_cut_' + str(col) for col in c1.columns.tolist()]
c1 = c1.reset_index()

3.4 方位划分

# 对方位进行16均分
df['d16'] = df['d'].apply(lambda x: int((x / 22.5) + 0.5) % 16 if not np.isnan(x) else np.nan)# 分组
tmp = df.groupby(['id', 'd16'], as_index=False)['d16'].agg({'d16_count': 'count'})
# 透视
c3 = c3.pivot(index='ship', columns='d16', values='d16_count')
# 修改列名
c3.columns = ['d16_' + str(col) for col in c3.columns.tolist()]
c3 = c3.reset_index()

3.5 描述性统计

方法一:groupby().agg()

详细请参考:http://joyfulpandas.datawhale.club/Content/ch4.html

对速度不为0的数据进行描述性统计

# 统计速度为0的个数,以及速度不为0的统计量
df_zero_count = df.query("v==0")[['id', 'v']].groupby('id', as_index=False)['v'].agg({'num_zero_v': 'count'})
df_not_zero_agg = df.query("v!=0")[['ship', 'v']].groupby('id', as_index=False)['v'].agg({'v_max_drop_0': 'max','v_min_drop_0': 'min','v_mean_drop_0': 'mean','v_std_drop_0': 'std','v_median_drop_0': 'median','v_skew_drop_0': 'skew'})
c2 = df_zero_count.merge(df_not_zero_agg,on='id',how='left')

方法二:groupby().describe()

计算各种位数:[0.125, 0.25, 0.375, 0.5, 0.625, 0.75, 0.875]

df_raw.groupby('id')[key[i]].describe(percentiles=[0.05] + [ii / 1000 for ii in range(125, 1000, 125)] + [0.95])

3.6 坐标与角度偏移指标计算

方法:.shift()、.fillna(method=‘ffill’)

# 坐标
temp['ynext'] = temp.groupby('ship')['y'].shift(-1)
temp['ynext'] = temp['ynext'].fillna(method='ffill')temp['xnext'] = temp.groupby('ship')['x'].shift(-1)
temp['xnext'] = temp['xnext'].fillna(method='ffill')temp['angle_next'] = (temp['ynext'] - temp['y']) / (temp['xnext'] - temp['x'])
temp['angle_next'] = np.arctan(temp['angle_next']) / math.pi * 180
temp['angle_next_next'] = temp['angle_next'].shift(-1)# 时间
temp['timenext'] = temp.groupby('ship')['time'].shift(-1)
temp['timediff'] = np.abs(temp['timenext'] - temp['time'])
temp['timediff'] = temp['timediff'].fillna(method='ffill')
temp['hc_xy'] = abs(temp['angle_next_next'] - temp['angle_next'])

3.7 分箱

方法:pd.qcut()、zip()、map()、transform()

# 速度
df['v_bin'] = pd.qcut(df['v'], 200, duplicates='drop') # 速度进行 200分位数分箱
df['v_bin'] = df['v_bin'].map(dict(zip(df['v_bin'].unique(),range(df['v_bin'].nunique()))))# 分箱后# 坐标
for f in ['x', 'y']:df[f + '_bin1'] = pd.qcut(df[f], 1000, duplicates='drop') # x,y位置分箱1000df[f + '_bin1'] = df[f + '_bin1'].map(dict(zip(df[f + '_bin1'].unique(), range(df[f + '_bin1'].nunique()))))#编码df[f + '_bin2'] = df[f] // 10000 # 取整操作df[f + '_bin1_count'] = df[f + '_bin1'].map(df[f + '_bin1'].value_counts()) #x,y不同分箱的数量映射df[f + '_bin2_count'] = df[f + '_bin2'].map(df[f + '_bin2'].value_counts()) #数量映射df[f + '_bin1_id_nunique'] = df.groupby(f + '_bin1')['id'].transform('nunique')#基于分箱1 id数量映射df[f + '_bin2_id_nunique'] = df.groupby(f + '_bin2')['id'].transform('nunique')#基于分箱2 id数量映射

pre_cols = df.columns

一开始一直在想为什么要把这个放到最开始,执行到最后,才发现是为了过滤出新增列的数据。

new_cols = [i for i in df.columns if i not in pre_cols]
df[new_cols].head()

通过字典的形式来构建方法和重命名

agg_dict = {}
for ag in ['max','mean','median','std','skew']:agg_dict['{}_{}_{}'.format('speed',ag,"0")] = ag
print(agg_dict)

RUN:

{'speed_max_0': 'max', 'speed_mean_0': 'mean', 'speed_median_0': 'median', 'speed_std_0': 'std', 'speed_skew_0': 'skew'}

4. embedding特征

4.1 简介

word embedding就是把一个词用编码的方式表示以便于feed到网络中。Word Embedding有的时候也被称作为分布式语义模型或向量空间模型等,所以从名字和其转换的方式我们就可以明白, Word Embedding技术可以将相同类型的词归到一起,例如苹果,芒果香蕉等,在投影之后的向量空间距离就会更近,而书本,房子这些则会与苹果这些词的距离相对较远。

4.2 使用场景

Word Embedding可以用到特征生成,文件聚类,文本分类和自然语言处理等任务

如此次数据针对的航海问题中,对相同经纬度上不同的船进行Embedding,就可以得到每个船只的向量,就可以得到经常在某些区域工作的船只

4.3 Word2Vec

Word2vec在向量空间中对词进行表示, 或者说词以向量的形式表示,在词向量空间中:相似含义的单词一起出现,而不同的单词则位于很远的地方。这也被称为语义关系。神经网络不理解文本,而只理解数字。词嵌入提供了一种将文本转换为数字向量的方法。Word2vec就是在重建词的语言上下文。

**上下文:**在一般的生活情景中,当我们通过说话或写作来交流,其他人会试图找出句子的目的。例如,“印度的温度是多少”,这里的上下文是用户想知道“印度的温度”即上下文。

embedding_size=70
iters=70
min_count=3
window_size=25
num_runs=1
seed=9012sentences = []
for i in boat_id:traj = traj_data_corpus[traj_data_corpus['id']==i]sentences.append(traj['no_bin'].values.tolist())model = Word2Vec(sentences, size=embedding_size,min_count=min_count,workers=mp.cpu_count(),window=window_size,seed=seed, iter=iters, sg=0)embedding_vec = []
for ind, seq in enumerate(sentences):seq_vec, word_count = 0, 0for word in seq:if word not in model:continueelse:seq_vec += model[word]word_count += 1if word_count == 0:embedding_vec.append(embedding_size * [0])else:embedding_vec.append(seq_vec / word_count)

4.4 NMF提取文本的主题分布

class nmf_list(object):def __init__(self,data,by_name,to_list,nmf_n,top_n):self.data = dataself.by_name = by_nameself.to_list = to_listself.nmf_n = nmf_nself.top_n = top_ndef run(self,tf_n):df_all = self.data.groupby(self.by_name)[self.to_list].apply(lambda x :'|'.join(x)).reset_index()self.data =df_all.copy()print('bulid word_fre')# 词频的构建def word_fre(x):word_dict = []x = x.split('|')docs = []for doc in x:doc = doc.split()docs.append(doc)word_dict.extend(doc)word_dict = Counter(word_dict)new_word_dict = {}for key,value in word_dict.items():new_word_dict[key] = [value,0]del word_dict  del xfor doc in docs:doc = Counter(doc)for word in doc.keys():new_word_dict[word][1] += 1return new_word_dict self.data['word_fre'] = self.data[self.to_list].apply(word_fre)print('bulid top_' + str(self.top_n))# 设定100个高频词def top_100(word_dict):return sorted(word_dict.items(),key = lambda x:(x[1][1],x[1][0]),reverse = True)[:self.top_n]self.data['top_'+str(self.top_n)] = self.data['word_fre'].apply(top_100)def top_100_word(word_list):words = []for i in word_list:i = list(i)words.append(i[0])return words self.data['top_'+str(self.top_n)+'_word'] = self.data['top_' + str(self.top_n)].apply(top_100_word)# print('top_'+str(self.top_n)+'_word的shape')print(self.data.shape)word_list = []for i in self.data['top_'+str(self.top_n)+'_word'].values:word_list.extend(i)word_list = Counter(word_list)word_list = sorted(word_list.items(),key = lambda x:x[1],reverse = True)user_fre = []for i in word_list:i = list(i)user_fre.append(i[1]/self.data[self.by_name].nunique())stop_words = []for i,j in zip(word_list,user_fre):if j>0.5:i = list(i)stop_words.append(i[0])print('start title_feature')# 讲融合后的taglist当作一句话进行文本处理self.data['title_feature'] = self.data[self.to_list].apply(lambda x: x.split('|'))self.data['title_feature'] = self.data['title_feature'].apply(lambda line: [w for w in line if w not in stop_words])self.data['title_feature'] = self.data['title_feature'].apply(lambda x: ' '.join(x))print('start NMF')# 使用tfidf对元素进行处理tfidf_vectorizer = TfidfVectorizer(ngram_range=(tf_n,tf_n))tfidf = tfidf_vectorizer.fit_transform(self.data['title_feature'].values)#使用nmf算法,提取文本的主题分布text_nmf = NMF(n_components=self.nmf_n).fit_transform(tfidf)# 整理并输出文件name = [str(tf_n) + self.to_list + '_' +str(x) for x in range(1,self.nmf_n+1)]tag_list = pd.DataFrame(text_nmf)print(tag_list.shape)tag_list.columns = nametag_list[self.by_name] = self.data[self.by_name]column_name = [self.by_name] + nametag_list = tag_list[column_name]return tag_listdata = df.copy()
data.rename(columns={'v':'speed','id':'ship'},inplace=True)
for j in range(1):print('********* {} *******'.format(j))for i in ['speed','x','y']:data[i + '_str'] = data[i].astype(str)nmf = nmf_list(data,'ship',i + '_str',8,2)nmf_a = nmf.run(j)nmf_a.rename(columns={'ship':'id'},inplace=True)data_label = data_label.merge(nmf_a,on = 'id',how = 'left')

RUN:

Task3 特征工程相关推荐

  1. 【算法竞赛学习】数字中国创新大赛智慧海洋建设-Task3特征工程

    智慧海洋建设-Task3 特征工程 此部分为智慧海洋建设竞赛的特征工程模块,通过特征工程,可以最大限度地从原始数据中提取特征以供算法和模型使用.通俗而言,就是通过X,创造新的X'以获得更好的训练.预测 ...

  2. 【算法竞赛学习】二手车交易价格预测-Task3特征工程

    二手车交易价格预测-Task3 特征工程 三. 特征工程目标 Tip:此部分为零基础入门数据挖掘的 Task3 特征工程部分,带你来了解各种特征工程以及分析方法,欢迎大家后续多多交流. 赛题:零基础入 ...

  3. 零基础入门数据挖掘-Task3 特征工程

    Datawhale 零基础入门数据挖掘-Task3 特征工程 前言 内容介绍 数据清洗 缺失值 异常值 箱型图 3∂原则 Box-Cox 变换 特征缩放 特征编码 特征工程 特征提取 特征选择 特征构 ...

  4. Task3 特征工程(智慧海洋)

    Task3 特征工程(智慧海洋) 这里写目录标题 Task3 特征工程(智慧海洋) 目标: 内容: 1. 特征工程概述 1.1 特征构建 1.2 特征提取和特征选择 2. 赛题特征工程 分箱特征 v. ...

  5. Datawhale 智慧海洋建设-Task3 特征工程

    Datawhale 智慧海洋建设-Task3 特征工程 这里说声抱歉,这部分内容对于初学者的我来说难度有些大,内容有点多,只看了大约一半,还有一半会继续学习,待学完会及时补充笔记. DataWhale ...

  6. 二手车Task3 特征工程

    二手车Task3 特征工程 常见的特征工程包括: 异常处理: 通过箱线图(或 3-Sigma)分析删除异常值: BOX-COX 转换(处理有偏分布): 长尾截断: 特征归一化/标准化: 标准化(转换为 ...

  7. Datawhale 零基础入门数据挖掘-Task3 特征工程

    特征工程的主要目的还是在于将数据转换为能更好地表示潜在问题的特征,从而提高机器学习的性能.比如,异常值处理是为了去除噪声,填补缺失值可以加入先验知识等.特征构造也属于特征工程的一部分,其目的是为了增强 ...

  8. 智慧海洋建设-Task3 特征工程

    学习目标: 了解学习特征工程的基本概念 学习topline代码的特征工程构造方法,实现构建有意义的特征工程 了解构造特征的一些方法和步骤 学习内容: (对特征工程的个人理解:通过特征工程把一个X变成另 ...

  9. 二手车交易价格预测——Task3特征工程

    二手车交易价格预测--特征工程 一.目标 二.异常值处理 (一)删除异常值 三.特征构造 (一)构造时间特征 (二)构造地区特征 四.数据清洗 (一)数据分桶 (二)删除冗余数据 (三)处理数据集中的 ...

最新文章

  1. mysql set 子表,mysql update set 更新表数据
  2. VFS文件系统结构分析 与socket
  3. 线性布局 相对布局 参数
  4. APICS与AX的Master Planning(二)--Rescheduling Assumption 重排假设
  5. 【python】中的“.T”操作:转置
  6. maven静态资源导出(Ctrl+C+V)
  7. J2EE的经常使用十三规范——java菜鸟成长记
  8. Python基础知识-05-数据类型总结字典
  9. DevExpress破解和消除弹出框问题
  10. Linux文件管理常用命令
  11. nginx离线安装_做一个属于自己的离线下载服务器原来这么简单
  12. 杭电1003 java_杭电ACM 1003题
  13. 国内外接口文档工具哪家强?
  14. 图像处理-灰度图像转化为伪彩图像
  15. 嚯,这款AI建模工具实在太强大了,快来pick!
  16. TopCoder SRM 677 Div2
  17. Java实现屏幕截屏
  18. android音频编辑之音频裁剪的示例代码
  19. 数字IC面试总结(大厂面试经验分享)
  20. C#跑马灯抽签小程序

热门文章

  1. php show函数,PHP中的常用MYSQL函数 - msnshow的个人空间 - 51Testing软件测试网 51Testing软件测试网-软件测试人的精神家园...
  2. Cannot load configuration class: org.springframework.boot.autoconfigure报错 如何解决?注意核对版本
  3. 宏杉科技IPO终止审查,资本需对中国存储更多包容!
  4. MySQL8.0 存储过程和函数
  5. pgsql sql中获取当前时间_PostgreSQL 如何获取当前日期时间及注意事项
  6. java使用htmlunit+Jsoup爬虫,爬取ajax动态数据
  7. deepin 命令行卸载软件
  8. 使用for循环计算n的阶乘
  9. opencv 中无法打开文件“opencv_world401d.lib”
  10. FANUC系统5136报警维修