机器学习-天池新人赛(离线赛)--初步数据分析

import numpy as np
import pandas as pd
import math
from sklearn.metrics import f1_score
idx = pd.IndexSlice

%matplotlib inline
# 2. 获取数据
actions = pd.read_csv("./fresh_comp_offline/tianchi_fresh_comp_train_user.csv")
items = pd.read_csv("./fresh_comp_offline/tianchi_fresh_comp_train_item.csv")
actions.head()
user_iditem_idbehavior_typeuser_geohashitem_categorytime
010001082285259775197lk14c40762014-12-08 18
11000108243689071NaN55032014-12-12 12
21000108243689071NaN55032014-12-12 12
310001082536167681NaN97622014-12-02 15
4100010821514669521NaN52322014-12-12 11
# 读取并且转换actions表, 用户的所有的行为
# TODO: 暂时忽略所有的geo信息

def prepare_data(actions, items):
    #convert time
    actions.time = pd.to_datetime(actions.time)

    #index user
    user_index = actions.user_id.drop_duplicates()
    user_index = user_index.reset_index(drop=True).reset_index().set_index("user_id")
    user_index.columns = ['user']
    actions = pd.merge(actions, user_index, left_on='user_id', right_index=True, how='left')

    #index item
    item_ids = actions.item_id.drop_duplicates()
    item_ids = item_ids.reset_index(drop=True).reset_index().set_index("item_id")
    item_ids.columns = ['item']
    actions = pd.merge(actions, item_ids, left_on='item_id', right_index=True, how='left')

    items = pd.merge(items, item_ids, left_on='item_id', right_index=True, how='left')

    # index category
    category = actions.item_category.drop_duplicates()
    category = category.reset_index(drop=True).reset_index().set_index("item_category")
    category.columns = ['category']
    actions = pd.merge(actions, category, left_on='item_category', right_index=True, how='left')

    #drop user_id, item_id
    actions = actions.drop(['user_id', 'item_id', 'item_category'], axis=1)
    items = items.drop(['item_id', 'item_category'], axis=1)
    
#     print(actions.head())

    #reoder columns
    actions = actions.loc[:,['user', 'item', 'behavior_type', 'category', 'time', 'user_geohash']]
    
    #add date and hour
    actions['date'] = actions.time.dt.date
    actions['hour'] = actions.time.dt.hour
    return actions, items, user_index, item_ids, category

# actions, items = prepare_data(actions, items)
actions, items, user_index, item_ids, _ = prepare_data(actions, items)
actions.head()
useritembehavior_typecategorytimeuser_geohashdatehour
000102014-12-08 18:00:0097lk14c2014-12-0818
101112014-12-12 12:00:00NaN2014-12-1212
201112014-12-12 12:00:00NaN2014-12-1212
302122014-12-02 15:00:00NaN2014-12-0215
403132014-12-12 11:00:00NaN2014-12-1211
items.head()
item_geohashitem
0NaN1185692
1NaN2222915
2NaN2623414
3NaN1772057
4NaN2634707
# 2 观察数据
geo = pd.concat([items.item_geohash, actions.user_geohash]).drop_duplicates()
item_geo = items.item_geohash.drop_duplicates().dropna()
print("商品的geo去重后总数的统计", item_geo.count())
action_geo = actions.user_geohash.drop_duplicates().dropna()
print("用户行为的geo去重后总数的统计",action_geo.count())
print("商品与用户行为的geo去重后总数的统计:\n", 
      "交集 / 用户行为geo:",
      len(action_geo[action_geo.isin(item_geo)]) / len(action_geo),
      "\n交集 / 商品geo:",
      len(item_geo[item_geo.isin(action_geo)]) / len(item_geo)
     )
del item_geo
del action_geo
#从结果可以看出, 大多数情况下用户和商品的地址存在匹配的情况, 少量不匹配
商品的geo去重后总数的统计 57358
用户行为的geo去重后总数的统计 1018981
商品与用户行为的geo去重后总数的统计:
 交集 / 用户行为geo: 0.025223237724746585 
交集 / 商品geo: 0.44809791136371563
ag = actions.loc[:, ['user', 'user_geohash']].dropna()
print("用户行为带有geohash的数量", len(ag))
ag = ag.drop_duplicates()
print("用户行为带有geohash的数量(去重后)", len(ag))
ag['c'] = 1
ag = ag.loc[:, ['user', 'c']].groupby('user').sum()
print(ag.describe())
del ag
#可以发现用户
#有geo hash地址的用户行为的中位数为68, 就是大多数用户所在的geohash是经常变化的
#用户在不同的时间, 处于多个不同的geo地址(也就是说这个geo的还是比较精确的, 可能离开商品的某个geo有一定的距离)
#那么可以考虑的是, 是否时间间隔越近的两个geohash地址, 意味着越近的距离
用户行为带有geohash的数量 7380017
用户行为带有geohash的数量(去重后) 1257674
                  c
count  16240.000000
mean      77.442980
std       53.782759
min        1.000000
25%       42.000000
50%       68.000000
75%      103.000000
max      709.000000
df = actions[actions.user_geohash.notna()]
print("购买的时候, 有geo信息的行为数量", len(df), "占全部行为的", len(df[df.user_geohash.isin(items.item_geohash)]) / len(df))
del df
购买的时候, 有geo信息的行为数量 7380017 占全部行为的 0.03044234179948366
# 3. 提取特征
# 首先要考虑要提取哪些特征, 这些特征需要考虑体现用户、商品、商品分类、地点等特性

# 用户: 总体行为次数,还有如何体现出用户的购买爱好, 比如针对某一类商品购买的喜好?
# 商品/分类: 总体有多少用户购买, 所有用户的总体行为计数
# 分类:总共有多少商品
# 上面特征的时间特性?
# 上面物品的地理特性
# 上面物品的交叉特性, 比如某个用户特别爱购买某个商品
# 与时间相关的特性, 用户某一天的购买行为计数, 用来计算第二天是否购买

# 3.0 保存特征
saved_actions = actions
print(len(actions))
actions.head()
23291027
useritembehavior_typecategorytimeuser_geohashdatehour
000102014-12-08 18:00:0097lk14c2014-12-0818
101112014-12-12 12:00:00NaN2014-12-1212
201112014-12-12 12:00:00NaN2014-12-1212
302122014-12-02 15:00:00NaN2014-12-0215
403132014-12-12 11:00:00NaN2014-12-1211
# actions = saved_actions;#恢复actions
print("共计: {}条交易记录".format(actions.user.max()))
共计: 19999条交易记录
# #从用户来限制提取特征对数据额占用, 是在太卡了, 后续删除
# actions = actions.set_index("user").loc[:10000, :]
# actions = actions.reset_index()
# print(actions.user.max())
# actions.head()
# 3.1 提取用户特征
#用户总计购买了多少商品
user = actions.groupby(['user', 'behavior_type'])[['item']].count().unstack().fillna(0).astype(np.int)
user.rename(columns={'item': 'c'}, level=0, inplace=True)
user.head()
c
behavior_type1234
user
0207004
14562615
2446168
38003114
4282020
# 统计购买商品的种类
c = actions.drop_duplicates(['user', 'behavior_type', 'item']) \
    .groupby(['user', 'behavior_type'])[['item']].count().unstack().fillna(0).astype(np.int)
user = user.merge(c, left_index=True, right_index=True, how='left')
user.head()
citem_xitem_y
behavior_type123412341234
user
02070048900489004
1456261514825151482515
2446168201158201158
3800311432130143213014
4282020151020151020
#统计购买商品类别的种类
c = actions.drop_duplicates(['user', 'behavior_type', 'category']) \
    .groupby(['user', 'behavior_type'])[['category']].count().unstack().fillna(0).astype(np.int)
user = user.merge(c, left_index=True, right_index=True, how='left')
user.head()
citem_xitem_ycategory
behavior_type1234123412341234
user
0207004890048900429004
1456261514825151482515451215
244616820115820115875157
3800311432130143213014581614
428202015102015102053020
user = pd.DataFrame(user.values, index=user.index, columns=["u{}".format(i) for i in range(0, 16, 1)])
user.head()
u0u1u2u3u4u5u6u7u8u9u10u11u12u13u14u15
user
0207004890048900429004
1456261514825151482515451215
244616820115820115875157
3800311432130143213014581614
428202015102015102053020
user = user / (user.mean() + user.std() * 3)
user.head()
u0u1u2u3u4u5u6u7u8u9u10u11u12u13u14u15
user
00.0395150.0000000.0000000.0666470.0421370.0000000.0000000.0820820.0421370.0000000.0000000.0820820.0968360.0000000.0000000.115024
10.0870480.1083950.0044840.0833080.0700700.1113530.0057540.1026030.0700700.1113530.0057540.1026030.1502630.1865120.0152550.143780
20.0851390.0041690.0269050.1332930.0951630.0044540.0287680.1641650.0951630.0044540.0287680.1641650.2504390.0155430.0762770.201293
30.1527160.1292410.0044840.0666470.1519760.1336230.0057540.0820820.1519760.1336230.0057540.0820820.1936730.2486820.0152550.115024
40.0538330.0000000.0089680.0000000.0714900.0000000.0115070.0000000.0714900.0000000.0115070.0000000.1769770.0000000.0305110.000000
# user.to_csv("user.csv")
# del user
# 3.2 统计商品属性
#统计商品被购买的次数
good = actions.groupby(['item', 'behavior_type'])[['user']].count().unstack().fillna(0).astype(np.int)
good.rename(columns={'user': 'c'}, level=0, inplace=True)
good.head()
c
behavior_type1234
item
078110
14000
287032
33000
47000
#统计商品被多少用户购买过
c = actions.drop_duplicates(['user', 'behavior_type', 'item']) \
    .groupby(['item', 'behavior_type'])[['user']].count().unstack().fillna(0).astype(np.int)
good = good.merge(c, left_index=True, right_index=True, how='left')
good.head()
cuser
behavior_type12341234
item
07811036110
140002000
28703222032
330001000
470003000
good = pd.DataFrame(good.values, index=good.index, columns=["g{}".format(i) for i in range(0, 8, 1)])
good.head()

g0g1g2g3g4g5g6g7
item
07811036110
140002000
28703222032
330001000
470003000
good = good / (good.mean() + good.std() * 3)
good.head()
g0g1g2g3g4g5g6g7
item
01.8761400.7629830.5330160.0000002.3897850.8252910.6881640.000000
10.0962120.0000000.0000000.0000000.1327660.0000000.0000000.000000
22.0926180.0000001.5990471.8323121.4604240.0000002.0644932.381005
30.0721590.0000000.0000000.0000000.0663830.0000000.0000000.000000
40.1683720.0000000.0000000.0000000.1991490.0000000.0000000.000000
# good.to_csv("good.csv")
# del good
# 3.3 统计商品类别特征
#统计商品类别被购买的次数
cat = actions.groupby(['category', 'behavior_type'])[['user']].count().unstack().fillna(0).astype(np.int)
cat.rename(columns={'user': 'c'}, level=0, inplace=True)
cat.head()
c
behavior_type1234
category
0816813012544
113471933993470690
2741911812874
3271839511788523049
4250652556772681678
#统计商品类别被多少用户购买过
c = actions.drop_duplicates(['user', 'behavior_type', 'category']) \
    .groupby(['category', 'behavior_type'])[['user']].count().unstack().fillna(0).astype(np.int)
cat = cat.merge(c, left_index=True, right_index=True, how='left')
cat.head()
cuser
behavior_type12341234
category
0816813012544923766342
113471933993470690644511901259506
2741911812874556517065
32718395117885230499766174828771873
42506525567726816788869171623251184
#统计商品类别有多少商品
c = actions.drop_duplicates(['item', 'behavior_type', 'category']) \
    .groupby(['category', 'behavior_type'])[['item']].count().unstack().fillna(0).astype(np.int)
cat = cat.merge(c, left_index=True, right_index=True, how='left')
cat.head()
cuseritem
behavior_type123412341234
category
08168130125449237663421354999235
1134719339934706906445119012595063451628032389571
27419118128745565170651386939559
3271839511788523049976617482877187342985369348111821
4250652556772681678886917162325118455323451247631319
cat = pd.DataFrame(cat.values, index=cat.index, columns=["c{}".format(i) for i in range(0, 12, 1)])
cat.head()
c0c1c2c3c4c5c6c7c8c9c10c11
category
08168130125449237663421354999235
1134719339934706906445119012595063451628032389571
27419118128745565170651386939559
3271839511788523049976617482877187342985369348111821
4250652556772681678886917162325118455323451247631319
cat = cat / (cat.mean() + cat.std() * 3)
cat.head()
c0c1c2c3c4c5c6c7c8c9c10c11
category
00.1331600.0949750.0848550.1084590.4377720.2279320.1447000.1665930.1119560.0932670.0939120.122399
12.1962752.4832372.3555631.7008303.0568153.5689342.8916982.0070542.8539742.6406822.4386511.996850
20.1209490.0862080.0868910.1824080.2637070.1529540.1607780.2578230.1146020.0876140.0969740.206329
34.4316933.7383726.0090607.5156984.6319415.2424346.6079567.4292713.5542383.4791434.9109886.368237
44.0862894.0671324.9337834.1362224.2065005.1464635.3401104.6963474.5744134.2507164.8619904.612688
# cat.to_csv('cat.csv')
# del cat
del c
# 3.4 时间特性
# 3.5 地理特性
# 3.6 交叉特性
# 3.7 24小时内的动作
def read_csv():
    return pd.read_csv("user.csv", index_col=0)
def read_good():
    return pd.read_csv("good.csv", index_col=0)
def read_cat():
    return pd.read_csv('cat.csv', index_col=0)
def read_label():
    return pd.read_csv("label.csv", index_col=0)
# 用户第二天是否会购买的标签
label = actions[actions.behavior_type == 4].copy()
label.date = (pd.to_datetime(label.date) - np.timedelta64(1, 'D'))
# label.date = label.date.dt.date
print(label.date.dtypes)
label['buy'] = 1
# label = label.loc[:, ['date', 'user','category','item','buy']].groupby(['date', 'user','category','item']).sum()
label = label.set_index(['date', 'user']).loc[:, ['item', 'category', 'buy']].drop_duplicates()
label.set_index(['category','item',], append=True, inplace=True)
label.head()
datetime64[ns]
buy
dateusercategoryitem
2014-12-010221
2014-12-1309131
2014-12-0108111
27591
2014-12-12130901
# label.to_csv("label.csv")
# del label
# read_label().head()
# 统计用户最后一天的行为
d_action = actions.copy()
d_action['d']  = 1
d_action.date = pd.to_datetime(d_action.date)
d_action = d_action.groupby([ 'date', 'user', 'category', 'item', 'behavior_type']).sum()[['d']]
d_action = d_action / (d_action.mean() + d_action.std() * 3)
d_action = d_action.unstack().fillna(0).astype(np.float32)
d_action.columns = d_action.columns.droplevel(0)
d_action.columns = ['d_t{}'.format(i) for i in range(1, 5, 1)]
d_action.head()
d_t1d_t2d_t3d_t4
dateusercategoryitem
2014-11-181461290.3423590.00.00.0
491630.3423590.00.00.0
581760.3423590.00.00.0
354780.3423590.00.00.0
1394450.5135390.00.00.0
# d_action.to_csv('d_action.csv')
# pd.read_csv('d_action.csv', index_col=0).dtypes
#某个用户3小时的行为
x_action = actions.copy()
x_action['c']  = 1
x_action.date = pd.to_datetime(x_action.date).dt.date
#数据量太大, 只考虑最后3个小时的数据
x_action = x_action.loc[x_action.hour.isin([23, 22, 21])]
x_action.date = pd.to_datetime(x_action.date)
x_action = x_action.groupby([ 'date', 'user', 'category', 'item', 'hour', 'behavior_type']).sum()
x_action = x_action.unstack()
x_action = x_action / (x_action.mean() + x_action.std() * 3)
x_action = x_action.stack().astype(np.float32)
x_action.head()
c
dateusercategoryitemhourbehavior_type
2014-11-1831394452110.559228
4872110.186409
6432110.186409
52010432210.372819
10702210.372819
x_action = x_action.unstack(['hour', 'behavior_type'], fill_value=0).sort_index(axis=1)
x_action.columns = x_action.columns.droplevel(0)
# print(x_action.describe())
#用如此方式来保证代码会被正确的展开成96列, 而不至于部分代码被
x_action = pd.DataFrame(x_action.values, index=x_action.index, columns=pd.MultiIndex.from_product([range(1, 5, 1), range(21, 24, 1)], names=['behavior_type','hour']))
x_action = x_action.fillna(0)
# x_action.info()
# x_action[:, :] = x_action[:, :].astype(np.int8)
# x_action.info()
# x_action = x_action.apply(lambda x: x.astype(np.int32))
x_action = pd.DataFrame(x_action.values, index=x_action.index, columns = ["h{}_{}".format(h, t) for h in range(21, 24, 1) for t in [1, 2, 3, 4]])
# print(x_action.describe())
x_action.head()
h21_1h21_2h21_3h21_4h22_1h22_2h22_3h22_4h23_1h23_2h23_3h23_4
dateusercategoryitem
2014-11-1831394450.5592280.00.00.00.0000000.00.00.00.00.00.00.0
4870.1864090.00.00.00.0000000.00.00.00.00.00.00.0
6430.1864090.00.00.00.0000000.00.00.00.00.00.00.0
52010430.0000000.00.00.00.3728190.00.00.00.00.00.00.0
10700.0000000.00.00.00.3728190.00.00.00.00.00.00.0
x_action = d_action.merge(x_action, left_index=True, right_index=True, how='left')
x_action.fillna(0, inplace=True)
x_action.head()
d_t1d_t2d_t3d_t4h21_1h21_2h21_3h21_4h22_1h22_2h22_3h22_4h23_1h23_2h23_3h23_4
dateusercategoryitem
2014-11-181461290.3423590.00.00.00.0000000.00.00.00.00.00.00.00.00.00.00.0
491630.3423590.00.00.00.0000000.00.00.00.00.00.00.00.00.00.00.0
581760.3423590.00.00.00.0000000.00.00.00.00.00.00.00.00.00.00.0
354780.3423590.00.00.00.0000000.00.00.00.00.00.00.00.00.00.00.0
1394450.5135390.00.00.00.5592280.00.00.00.00.00.00.00.00.00.00.0
# 合并x, y数据, 使用how='left'可以过滤掉之前没有行为, 但是却有购买动作的数据
# 当然, 这样我也过滤到了, 我看了n个便宜的, 结果买了这类里面的一个爆品
# TODO: 以后想法处理
x_action = x_action.merge(label, left_index=True, right_index=True, how='left')
x_action.fillna(0, inplace=True)
x_action.buy = x_action.buy.astype(np.int8)
x_action.head()
d_t1d_t2d_t3d_t4h21_1h21_2h21_3h21_4h22_1h22_2h22_3h22_4h23_1h23_2h23_3h23_4buy
dateusercategoryitem
2014-11-181461290.3423590.00.00.00.0000000.00.00.00.00.00.00.00.00.00.00.00
491630.3423590.00.00.00.0000000.00.00.00.00.00.00.00.00.00.00.00
581760.3423590.00.00.00.0000000.00.00.00.00.00.00.00.00.00.00.00
354780.3423590.00.00.00.0000000.00.00.00.00.00.00.00.00.00.00.00
1394450.5135390.00.00.00.5592280.00.00.00.00.00.00.00.00.00.00.00
#对应时间点行为对应的用户, 商品, 分类属性
x_action.reset_index(inplace=True)
x_action = user.merge(x_action, right_on='user', left_index=True, how='right')
x_action = good.merge(x_action, right_on='item', left_index=True, how='right')
x_action = cat.merge(x_action, right_on='category', left_index=True, how='right')
x_action.set_index(['date', 'user', 'category', 'item'], inplace=True)
x_action.head()
c0c1c2c3c4c5c6c7c8c9...h21_4h22_1h22_2h22_3h22_4h23_1h23_2h23_3h23_4buy
dateusercategoryitem
2014-11-181461290.2187160.1490380.1568110.3007271.2521320.4378690.3491170.4244160.1160910.110225...0.00.00.00.00.00.00.00.00.00
491632.2852062.0039782.3345193.0269853.5756913.0590863.1696143.9625422.3839902.098980...0.00.00.00.00.00.00.00.00.00
581760.1495770.0978980.1717460.3401660.4923160.2099370.2641340.4561490.0728460.092325...0.00.00.00.00.00.00.00.00.00
354789.4224359.3492179.1737965.4106124.9852897.7136967.3153775.9061329.1390689.315400...0.00.00.00.00.00.00.00.00.00
1394452.9030592.8434131.9631951.0993772.6882902.9451201.9522980.9955942.5032222.730181...0.00.00.00.00.00.00.00.00.00

5 rows × 53 columns

#x_action.to_csv("x_action.csv") #数据量太大, 写入非常的慢, 如何破这个问题呢?
#pd.read_csv("x_action.csv").head()
# 3.8 优化方向
# 3.8.1 以后可能考虑加入噪音层, 不然, 某个用户可能存在只是查看了一次, 买了一次, 就被网络记忆成必买的用户

# 3.8.2 如何按组来训练, 毕竟用户一般是看一类商品, 然后选择其中一个商品来购买

# 3.8.3 目前采用的"正则化"是否合理, 是否有更好或者更加通用的数据处理方式, 或者直接用normal是否更好


大学生参加学科竞有着诸多好处,不仅有助于个人综合素质的提升,还能为未来职业发展奠定良好基础。以下是一些分析: 首先,学科竞是提高专业知识和技能水平的有效途径。通过参与竞,学生不仅能够深入学习相关专业知识,还能够接触到最新的科研成果和技术发展趋势。这有助于拓展学生的学科视野,使其对专业领域有更深刻的理解。在竞过程中,学生通常需要解决实际问题,这锻炼了他们独立思考和解决问题的能力。 其次,学科竞培养了学生的团队合作精神。许多竞项目需要团队协作来完成,这促使学生学会有效地与他人合作、协调分工。在团队合作中,学生们能够学到如何有效沟通、共同制定目标和分工合作,这对于日后进入职场具有重要意义。 此外,学科竞是提高学生综合能力的一种途径。竞项目通常会涉及到理论知识、实际操作和创新思维等多个方面,要求参者具备全面的素质。在竞过程中,学生不仅需要展现自己的专业知识,还需要具备创新意识和解决问题的能力。这种全面的综合能力培养对于未来从事各类职业都具有积极作用。 此外,学科竞可以为学生提供展示自我、树立信心的机会。通过比的舞台,学生有机会展现自己在专业领域的优势,得到他人的认可和赞誉。这对于培养学生的自信心和自我价值感非常重要,有助于他们更加积极主动地投入学习和未来的职业生涯。 最后,学科竞对于个人职业发展具有积极的助推作用。在竞中脱颖而出的学生通常能够引起企业、研究机构等用人单位的关注。获得竞奖项不仅可以作为个人履历的亮点,还可以为进入理想的工作岗位提供有力的支持。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值