%matplotlib inline
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from pandas.plotting import register_matplotlib_converters
register_matplotlib_converters()
from sklearn.preprocessing import LabelEncoder
ks = pd.read_csv('./ks-projects-201801.csv',
parse_dates=['deadline', 'launched'])
# Drop live projects
ks = ks.query('state != "live"')
# Add outcome column, "successful" == 1, others are 0
ks = ks.assign(outcome=(ks['state'] == 'successful').astype(int))
# Timestamp features
ks = ks.assign(hour=ks.launched.dt.hour,
day=ks.launched.dt.day,
month=ks.launched.dt.month,
year=ks.launched.dt.year)
# Label encoding
cat_features = ['category', 'currency', 'country']
encoder = LabelEncoder()
encoded = ks[cat_features].apply(encoder.fit_transform)
data_cols = ['goal', 'hour', 'day', 'month', 'year', 'outcome']
baseline_data = ks[data_cols].join(encoded)
可以组合不同的feature来产生新的feature
interactions = ks['category'] + "_" + ks['country']
print(interactions.head(5))
0 Poetry_GB
1 Narrative Film_US
2 Narrative Film_US
3 Music_US
4 Film & Video_US
dtype: object
将资料经过labelencoder处理,这样model才能够读取资料
label_enc = LabelEncoder()
data_interaction = baseline_data.assign(category_country=label_enc.fit_transform(interactions))
data_interaction.head()
若是想知道一个礼拜前的资料有几笔,该如何处理
可以使用.rolling
的方法
将资料中launched
的column当作是index,创造一个series,并且将index
资料设定成value
launched = pd.Series(ks.index, index=ks.launched, name="count_7_days").sort_index()
launched.head(20)
launched
1970-01-01 01:00:00 94579
1970-01-01 01:00:00 319002
1970-01-01 01:00:00 247913
1970-01-01 01:00:00 48147
1970-01-01 01:00:00 75397
1970-01-01 01:00:00 2842
1970-01-01 01:00:00 273779
2009-04-21 21:02:48 169268
2009-04-23 00:07:53 322000
2009-04-24 21:52:03 138572
2009-04-25 17:36:21 325391
2009-04-27 14:10:39 122662
2009-04-28 13:55:41 213711
2009-04-29 02:04:21 345606
2009-04-29 02:58:50 235255
2009-04-29 04:37:37 98954
2009-04-29 05:26:32 342226
2009-04-29 06:43:44 275091
2009-04-29 13:52:03 284115
2009-04-29 22:08:13 32898
Name: count_7_days, dtype: int64
当我们有一个timeseries的index,可以使用.rolling
去选取需要滑动的窗格
Example launched.rolling('7d')
可以创建一个滑动7天的窗格
为了不要计算到现在的时间,因此我们要将资料-1
count_7_days = launched.rolling('7d').count()-1
print(count_7_days.head(20))
# Ignore records with broken launch dates
plt.plot(count_7_days[7:]);
plt.title("Number of projects launched over periods of 7 days");
launched
1970-01-01 01:00:00 0.0
1970-01-01 01:00:00 1.0
1970-01-01 01:00:00 2.0
1970-01-01 01:00:00 3.0
1970-01-01 01:00:00 4.0
1970-01-01 01:00:00 5.0
1970-01-01 01:00:00 6.0
2009-04-21 21:02:48 0.0
2009-04-23 00:07:53 1.0
2009-04-24 21:52:03 2.0
2009-04-25 17:36:21 3.0
2009-04-27 14:10:39 4.0
2009-04-28 13:55:41 5.0
2009-04-29 02:04:21 5.0
2009-04-29 02:58:50 6.0
2009-04-29 04:37:37 7.0
2009-04-29 05:26:32 8.0
2009-04-29 06:43:44 9.0
2009-04-29 13:52:03 10.0
2009-04-29 22:08:13 11.0
Name: count_7_days, dtype: float64
现在我们有7天内有几笔资料的Series,现在我们要将这些资料加入training data
# 将时间资料改为index
count_7_days.index = launched.values
# 将时间资料fit原始资料的index
count_7_days = count_7_days.reindex(ks.index)
# 也可以用sort_index
# count_7_days = count_7_days.sort_index()
count_7_days.head(10)
0 1487.0
1 2020.0
2 279.0
3 984.0
4 752.0
5 522.0
6 708.0
7 1566.0
8 1048.0
9 975.0
Name: count_7_days, dtype: float64
baseline_data.join(count_7_days).head(10)
若是想投资一个游戏,但另一个相同类型的游戏才刚上市,就会赚不到钱
因此我们需要去抓出在同一个类型中,最後上市的时间
我们需要先将资料做.groupby
在用.transform
.
.transform
def time_since_last_project(series):
# Return the time in hours
return series.diff().dt.total_seconds() / 3600.
df = ks[['category', 'launched']].sort_values('launched')
df.head(20)
timedeltas = df.groupby('category').transform(time_since_last_project)
timedeltas.head(20)
将NaN利用timedeltas的median或是mean填入,再reindex,才能将资料加入其他data中
timedeltas = timedeltas.fillna(timedeltas.median()).reindex(baseline_data.index)
timedeltas.head(10)
"goal"
这一个column中显示很多比赛的奖金少於5000USD
但有些比赛的奖金却高达100,000USD
所以我们需要对数值资料做处理,去移除这些离群值(outliers)
一些比较常见的选择为square root和natual logarithm
plt.hist(ks.goal, range=(0, 100000), bins=50);
plt.title('Goal');
从上图中可以看出,接近0的数值非常多,但接近100,000的值却很少
plt.hist(np.sqrt(ks.goal), range=(0, 400), bins=50);
plt.title('Sqrt(Goal)');
将资料开根号之後可以让资料较为平缓
plt.hist(np.log(ks.goal), range=(0, 25), bins=50);
plt.title('Log(Goal)');
将资料做log处理後,资料会变得较为集中
这类型的转换对tree-based model的影响并不大
但却能帮助linear model或neural network
产生特徵的方法很多,但都要基於经验
另外一个方法就是我们可以产生很多特徵,并且利用特徵筛选的工具来选择较好的特徵
<<: Batch Processing (1) - Batch Processing with Unix Tools
0x1 前言 从 Day 0xA 开始撞墙,撞到今天总算解出来了 几个问题请让我娓娓道来 0x2 好...
HTTP 定义 网路通讯之间必须有共同的标准,而为了界定这些标准,於是产生协定(Protocol)。...
k3s 下载 安装 wget https://github.com/k3s-io/k3s/relea...
打开PGADMIN,新增表格 填入表单名,按下columns新增需要的栏位,Data type首先推...
在使用一段时间Cloudflare加速后,发现网站程序并不兼容IPV6,目前厂家未作升级处理,整了好...