Predict Future Sales 预测未来销量, Kaggle 比赛,LB 0.89896 排名6%

Predict Future Sales

  • 数据分析
  • 1. 数据基本处理
    • 1.1 读入数据集
    • 1.2 基线模型预测
    • 1.3 节省存储空间
  • 2. 数据探索
    • 2.1 训练集分析 sales_train
      • 2.1.1 每件商品的销量
      • 2.1.2 每个商店的销量
      • 2.1.3 每类商品的销量
      • 2.1.4 销量和价格的离群值
    • 2.2 测试集分析
    • 2.3 商店特征
      • 2.3.1 商店信息清洗
      • 2.3.2 商店信息编码
    • 2.4 商品分类特征
  • 3 特征融合
    • 3.1 统计月销量
    • 3.2 相关信息融合
    • 3.2 历史信息
      • 3.2.1 lag operation产生延迟信息,可以选择延迟的月数。
      • 3.2.2 月销量(每个商品-商店)的历史信息
      • 3.2.3 月销量(所有商品-商店)均值的历史信息
      • 3.2.4 月销量(每件商品)均值和历史特征
      • 3.2.5 月销量(每个商店)均值和历史特征
      • 3.2.6 月销量(每个商品类别)均值和历史特征
      • 3.2.7 月销量(商品类别-商店)均值和历史特征
      • 3.2.8 月销量(商品类别_大类)均值和历史特征
      • 3.2.9 月销量(商品-商品类别_大类)均值和历史特征
      • 3.2.10 月销量(商店_城市)均值和历史特征
      • 3.2.11 月销量(商品-商店_城市)均值和历史特征
      • 3.2.12 趋势特征,半年来价格的变化
      • 3.2.13 每个月天数¶
      • 3.2.14 开始和结束的销量
  • 4. 数据建模
    • 4.1 lightgbm 模型
    • 4.2. 后处理
      • 4.2.1 过期商品
    • 4.3 重要性画图

预测未来销售该项目来源于kaggle中的一场比赛的赛题,数据是由日常销售数据组成的时间序列数据集,该数据集由俄罗斯最大的软件公司之一 - 1C公司提供。提供了包括商店,商品,价格,日销量等连续34个月内的数据,要求预测第35个月的各商店各商品的销量。评价指标为RMSE,Baseline是1.1677,我的成绩是0.89896,目前排名178/3200。

文件名文件说明
sales_train.csv训练集(date_block=0 到 33 的每日历史数据,包括各商品在各商店的销量,价格)
test.csv测试集(date_block=34 的商店和产品信息)
items.csv商品的详细信息(item_name、item_id、item_category_id)
item_categories.csv商品类别的详细信息(item_category_name、item_category_id)
shops.csv商店的详细信息(shop_name、shop_id)

数据分析

1. 数据基本处理

1.1 读入数据集

  • 训练集有六列,分别介绍日期,月份,商店,商品,价格和日销量
  • 测试集有三列,分别是ID,商店,和商品。
sales_train = pd.read_csv('input/sales_train.csv.gz')
test = pd.read_csv('input/test.csv.gz')
sales_train.head()
datedate_block_numshop_iditem_iditem_priceitem_cnt_day
002.01.201305922154999.001.0
103.01.20130252552899.001.0
205.01.20130252552899.00-1.0
306.01.201302525541709.051.0
415.01.201302525551099.001.0
test.head()
IDshop_iditem_id
0055037
1155320
2255233
3355232
4455268
  • 训练集,有21807种商品,60个商店。一共2935849 种商品-商店组合。
  • 测试集,有5100 种商品,42个商店。刚好就是5100 * 42 = 214200种 商品-商店组合。
print('how many lines in train set:', sales_train.shape)
print('unique items in train set:', sales_train['item_id'].nunique())
print('unique shops in train set:', sales_train['shop_id'].nunique())
print('how many lines in test set:', test.shape)
print('unique items in test set:', test['item_id'].nunique())
print('unique shops in test set:', test['shop_id'].nunique())
how many lines in train set: (2935849, 6)
unique items in train set: 21807
unique shops in train set: 60
how many lines in test set: (214200, 3)
unique items in test set: 5100
unique shops in test set: 42

查看数据的基本信息以及是否有数据缺失NAN
数据形状为(2935849, 6),sales_train中没有missing values,没有nan,

print('----------head---------')
print(sales_train.head(5))
print('------information------')
print(sales_train.info())
print('-----missing value-----')
print(sales_train.isnull().sum())
print('--------nan value------')
print(sales_train.isna().sum())
----------head---------date  date_block_num  shop_id  item_id  item_price  item_cnt_day
0  02.01.2013               0       59    22154      999.00           1.0
1  03.01.2013               0       25     2552      899.00           1.0
2  05.01.2013               0       25     2552      899.00          -1.0
3  06.01.2013               0       25     2554     1709.05           1.0
4  15.01.2013               0       25     2555     1099.00           1.0
------information------
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 2935849 entries, 0 to 2935848
Data columns (total 6 columns):
date              object
date_block_num    int64
shop_id           int64
item_id           int64
item_price        float64
item_cnt_day      float64
dtypes: float64(2), int64(3), object(1)
memory usage: 134.4+ MB
None
-----missing value-----
date              0
date_block_num    0
shop_id           0
item_id           0
item_price        0
item_cnt_day      0
dtype: int64
--------nan value------
date              0
date_block_num    0
shop_id           0
item_id           0
item_price        0
item_cnt_day      0
dtype: int64

1.2 基线模型预测

首先尝试复现基线模型。本次比赛中,基线模型就是用第34个月的销售当作第35个月的销售,即将2015年10月的结果当作2015年11月的预测。评估结果应该是1.16777.

  • 训练集中的数据是 商品-商店-每天的销售。而要求预测的是商品-商店-每月的销售,因此需要合理使用groupby()和agg()函数。
  • 训练集没有出现过的 商品-商店组合,一律填零,最终的结果需要限幅在 [0,20]区间。
sales_train_subset = sales_train[sales_train['date_block_num'] == 33]
sales_train_subset.head()grouped = sales_train_subset[['shop_id','item_id','item_cnt_day']].groupby(['shop_id','item_id']).agg({'item_cnt_day':'sum'}).reset_index()
grouped = grouped.rename(columns={'item_cnt_day' : 'item_cnt_month'})
grouped.head()
shop_iditem_iditem_cnt_month
02311.0
124863.0
227871.0
327941.0
429681.0
test = pd.read_csv('../readonly/final_project_data/test.csv.gz')
test = pd.merge(test,grouped, on = ['shop_id','item_id'], how = 'left')
print(test.head())
test['item_cnt_month'] = test['item_cnt_month'].fillna(0).clip(0,20)
print(test.head())
test = test[['ID','item_cnt_month']]
submission = test.set_index('ID')
submission.to_csv('submission_baseline.csv')
   ID  shop_id  item_id  item_cnt_month
0   0        5     5037             NaN
1   1        5     5320             NaN
2   2        5     5233             1.0
3   3        5     5232             NaN
4   4        5     5268             NaNID  shop_id  item_id  item_cnt_month
0   0        5     5037             0.0
1   1        5     5320             0.0
2   2        5     5233             1.0
3   3        5     5232             0.0
4   4        5     5268             0.0

1.3 节省存储空间

因为后续会做大量的特征提取,对存储空间的消耗较大,而且较大的特征集对于模型训练来说也是个负担。在训练集中可以发现,很多数据的动态范围很小,比如date_block_num,shop_id,item_id,用int16存储就足够了。而Item_price, item_cnt_day 用float32 存储也是足够的。这样就可以在不损失信息的前提下,减少一般的存储空间消耗。结果来看从134.4+ MB,减少到了 61.6+ MB。

def downcast_dtypes(df):cols_float64 = [c for c in df if df[c].dtype == 'float64']cols_int64_32 = [c for c in df if df[c].dtype in ['int64', 'int32']]df[cols_float64] = df[cols_float64].astype(np.float32)df[cols_int64_32] = df[cols_int64_32].astype(np.int16)return df
sales_train = downcast_dtypes(sales_train)
test = downcast_dtypes(test)
sales_train.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 2935849 entries, 0 to 2935848
Data columns (total 6 columns):
date              object
date_block_num    int16
shop_id           int16
item_id           int16
item_price        float32
item_cnt_day      float32
dtypes: float32(2), int16(3), object(1)
memory usage: 61.6+ MB

2. 数据探索

2.1 训练集分析 sales_train

2.1.1 每件商品的销量

我们使用pivot_table来查看每件商品每个月的销量。pivot_table()和groupby()的用途类似,但更加灵活,可以对columns做更多处理。

sales_by_item_id = sales_train.pivot_table(index=['item_id'],values=['item_cnt_day'], columns='date_block_num', aggfunc=np.sum, fill_value=0).reset_index()
sales_by_item_id.columns = sales_by_item_id.columns.droplevel().map(str)
sales_by_item_id = sales_by_item_id.reset_index(drop=True).rename_axis(None, axis=1)
sales_by_item_id.columns.values[0] = 'item_id'
sales_by_item_id.tail()
item_id0123456789101112131415161718192021222324252627282930313233
21802221650000000100000000100000000000000000
218032216600000000023243225242113101512131312161178124810811511
21804221670000000056146968366574759415647473949494033464038313334292137
21805221682210000010000000000000000000000000
21806221690000000000000010000000000000000000

从上表中可以看出一共有21807件商品。使用sum()可以看到所有商品的总销量根据时间的变化关系。

sales_by_item_id.sum()[1:].plot(legend=True, label="Monthly sum")
<matplotlib.axes._subplots.AxesSubplot at 0x1e0806f0fd0>

在这里插入图片描述

分析有多少商品在最近的连续六个月内,没有销量。这些商品有多少出现在测试集中。

  • 训练集一共21807种商品,其中有12391种在最近的六个月没有销量。
  • 测试集一共5100种商品,其中有164种在训练中最近六个月没有销量,共出现了164 * 42 = 6888次。
  • Tips:在最终的预测结果中,我们可以将这些商品的销量大胆地设置为零。
outdated_items = sales_by_item_id[sales_by_item_id.loc[:,'27':].sum(axis=1)==0]
print('Outdated items:', len(outdated_items))
test = pd.read_csv('../readonly/final_project_data/test.csv.gz')
print('unique items in test set:', test['item_id'].nunique())
print('Outdated items in test set:', test[test['item_id'].isin(outdated_items['item_id'])]['item_id'].nunique())
Outdated items: 12391
unique items in test set: 5100
Outdated items in test set: 164

在训练集种有6行,是重复出现的,我们可以删除或者保留,这种数据对结果影响不大。

print("duplicated lines in sales_train is", len(sales_train[sales_train.duplicated()]))
duplicated lines in sales_train is 6

2.1.2 每个商店的销量

一共有 60 个商店,坐落在31个城市,城市的信息可以作为商店的一个特征。
这里先分析下哪些商店是最近才开的,哪些是已经关闭了的,同样分析最后六个月的数据。

  • shop_id = 36 是新商店
  • shop_id = [0 1 8 11 13 17 23 29 30 32 33 40 43 54] 可以认为是已经关闭了。
  • Tips:新商店,可以直接用第33个月来预测34个月的销量,因为它没有任何历史数据。而已经关闭的商店,销量可以直接置零
sales_by_shop_id = sales_train.pivot_table(index=['shop_id'],values=['item_cnt_day'], columns='date_block_num', aggfunc=np.sum, fill_value=0).reset_index()
sales_by_shop_id.columns = sales_by_shop_id.columns.droplevel().map(str)
sales_by_shop_id = sales_by_shop_id.reset_index(drop=True).rename_axis(None, axis=1)
sales_by_shop_id.columns.values[0] = 'shop_id'for i in range(27,34):print('Not exists in month',i,sales_by_shop_id['shop_id'][sales_by_shop_id.loc[:,'0':str(i)].sum(axis=1)==0].unique())for i in range(27,34):print('Shop is outdated for month',i,sales_by_shop_id['shop_id'][sales_by_shop_id.loc[:,str(i):].sum(axis=1)==0].unique())
Not exists in month 27 [36]
Not exists in month 28 [36]
Not exists in month 29 [36]
Not exists in month 30 [36]
Not exists in month 31 [36]
Not exists in month 32 [36]
Not exists in month 33 []
Shop is outdated for month 27 [ 0  1  8 11 13 17 23 30 32 40 43]
Shop is outdated for month 28 [ 0  1  8 11 13 17 23 30 32 33 40 43 54]
Shop is outdated for month 29 [ 0  1  8 11 13 17 23 29 30 32 33 40 43 54]
Shop is outdated for month 30 [ 0  1  8 11 13 17 23 29 30 32 33 40 43 54]
Shop is outdated for month 31 [ 0  1  8 11 13 17 23 29 30 32 33 40 43 54]
Shop is outdated for month 32 [ 0  1  8 11 13 17 23 29 30 32 33 40 43 54]
Shop is outdated for month 33 [ 0  1  8 11 13 17 23 27 29 30 32 33 40 43 51 54]

2.1.3 每类商品的销量

为了能使用商品的类别,需要先读取item_categories的信息,然后添加到sales_train里面

item_categories = pd.read_csv('../readonly/final_project_data/items.csv')
item_categories = item_categories[['item_id','item_category_id']]
item_categories.head()
item_iditem_category_id
0040
1176
2240
3340
4440
sales_train_merge_cat = pd.merge(sales_train,item_categories, on = 'item_id', how = 'left')
sales_train_merge_cat.head()
datedate_block_numshop_iditem_iditem_priceitem_cnt_dayitem_category_id
002.01.201305922154999.0000001.037
103.01.20130252552899.0000001.058
205.01.20130252552899.000000-1.058
306.01.201302525541709.0500491.058
415.01.201302525551099.0000001.056

2.1.4 销量和价格的离群值

从sales_train种找到销量和价格的离群值,然后删掉。

plt.figure(figsize=(10,4))
plt.xlim(-100,3000)
sns.boxplot(x = sales_train['item_cnt_day'])
print('Sale volume outliers:',sales_train['item_cnt_day'][sales_train['item_cnt_day']>1001].unique())
plt.figure(figsize=(10,4))
plt.xlim(-10000,320000)
sns.boxplot(x = sales_train['item_price'])
print('Sale price outliers:',sales_train['item_price'][sales_train['item_price']>300000].unique())
Sale volume outliers: [2169.]
Sale price outliers: [307980.]

在这里插入图片描述

在这里插入图片描述

sales_train = sales_train[sales_train['item_cnt_day'] <1001]
sales_train = sales_train[sales_train['item_price'] < 300000]
plt.figure(figsize=(10,4))
plt.xlim(-100,3000)
sns.boxplot(x = sales_train['item_cnt_day'])plt.figure(figsize=(10,4))
plt.xlim(-10000,320000)
sns.boxplot(x = sales_train['item_price'])
<matplotlib.axes._subplots.AxesSubplot at 0x1e080864a20>

在这里插入图片描述

在这里插入图片描述

有一个商品的价格是负值,将其填充为median。

sales_train[sales_train['item_price']<0]
datedate_block_numshop_iditem_iditem_priceitem_cnt_day
48468315.05.20134322973-1.01.0
median = sales_train[(sales_train['date_block_num'] == 4) & (sales_train['shop_id'] == 32)\& (sales_train['item_id'] == 2973) & (sales_train['item_price']>0)].item_price.median()
sales_train.loc[sales_train['item_price']<0,'item_price'] = median
print(median)
1874.0

2.2 测试集分析

测试集有5100 种商品,42个商店。刚好就是5100 * 42 = 214200种 商品-商店组合。可以分为三大类

  • 363种商品在训练集没有出现,363*42=15,246种商品-商店没有数据,约占7%。
  • 87550种商品-商店组合是只出现过商品,没出现过组合。约占42%。
  • 111404种商品-商店组合是在训练集中完整出现过的。约占51%。
test = pd.read_csv('../readonly/final_project_data/test.csv.gz')
good_sales = test.merge(sales_train, on=['item_id','shop_id'], how='left').dropna()
good_pairs = test[test['ID'].isin(good_sales['ID'])]
no_data_items = test[~(test['item_id'].isin(sales_train['item_id']))]print('1. Number of good pairs:', len(good_pairs))
print('2. No Data Items:', len(no_data_items))
print('3. Only Item_id Info:', len(test)-len(no_data_items)-len(good_pairs))
1. Number of good pairs: 111404
2. No Data Items: 15246
3. Only Item_id Info: 87550
no_data_items.head()
IDshop_iditem_id
1155320
4455268
454555826
646453538
656553571

2.3 商店特征

2.3.1 商店信息清洗

商店名里已经包含了很多特征,可以按以下结构分解。

城市 | 类型 | 名称

shops = pd.read_csv('../readonly/final_project_data/shops.csv')
shops.head()
shop_nameshop_id
0!Якутск Орджоникидзе, 56 фран0
1!Якутск ТЦ "Центральный" фран1
2Адыгея ТЦ "Мега"2
3Балашиха ТРК "Октябрь-Киномир"3
4Волжский ТЦ "Волга Молл"4

经过分析,发现以下商店名为同一个商店,可以合并shop_id.
* 11 => 10
* 1 => 58
* 0 => 57
* 40 => 39

查看测试集,发现 shop id [0,1,11,40] 都不存在。

  1. shop_id = 0, 1 仅仅存在了两个月,而 shop_id = 57,58 看起来就像是继任者。
  2. shop_id = 11 仅仅存在于 date_block = 25,而 shop_id = 10 只在那个月没有数据。
  3. shop_id = 40 仅仅存在于 date_block = [14,25] 而 shop_id = 39 在 date_block = 14 之后一直存在。
  4. shop_id = 46,商店名中间多了一个空格,会影响到编码,要去掉。 Сергиев Посад ТЦ “7Я”
  5. 通过商店命名,我发现shop 12 and 55都是网店,并且发现他们的销量的相关度很高,只是不知道怎么用这个信息。
sales12 = np.array(sales_by_shop_id.loc[sales_by_shop_id['shop_id'] == 12 ].values)
sales12 = sales12[:,1:].reshape(-1)
sales55 = np.array(sales_by_shop_id.loc[sales_by_shop_id['shop_id'] == 55 ].values)
sales55 = sales55[:,1:].reshape(-1)
months = np.array(sales_by_shop_id.loc[sales_by_shop_id['shop_id'] == 12 ].columns[1:])
np.corrcoef(sales12,sales55)
array([[1.        , 0.69647514],[0.69647514, 1.        ]])
test.shop_id.sort_values().unique()
array([ 2,  3,  4,  5,  6,  7, 10, 12, 14, 15, 16, 18, 19, 21, 22, 24, 25,26, 28, 31, 34, 35, 36, 37, 38, 39, 41, 42, 44, 45, 46, 47, 48, 49,50, 52, 53, 55, 56, 57, 58, 59], dtype=int64)
sales_train.loc[sales_train['shop_id'] == 0,'shop_id'] = 57
sales_train.loc[sales_train['shop_id'] == 1,'shop_id'] = 58
sales_train.loc[sales_train['shop_id'] == 11,'shop_id'] = 10
sales_train.loc[sales_train['shop_id'] == 40,'shop_id'] = 39

2.3.2 商店信息编码

shops['shop_name'] = shops['shop_name'].apply(lambda x: x.lower()).str.replace('[^\w\s]', '').str.replace('\d+','').str.strip()
shops['shop_city'] = shops['shop_name'].str.partition(' ')[0]
shops['shop_type'] = shops['shop_name'].apply(lambda x: 'мтрц' if 'мтрц' in x else 'трц' if 'трц' in x else 'трк' if 'трк' in x else 'тц' if 'тц' in x else 'тк' if 'тк' in x else 'NO_DATA')
shops.head()
shop_nameshop_idshop_cityshop_type
0якутск орджоникидзе фран0якутскNO_DATA
1якутск тц центральный фран1якутсктц
2адыгея тц мега2адыгеятц
3балашиха трк октябрькиномир3балашихатрк
4волжский тц волга молл4волжскийтц
shops['shop_city_code'] = LabelEncoder().fit_transform(shops['shop_city'])
shops['shop_type_code'] = LabelEncoder().fit_transform(shops['shop_type'])
shops.head()
shop_nameshop_idshop_cityshop_typeshop_city_codeshop_type_code
0якутск орджоникидзе фран0якутскNO_DATA290
1якутск тц центральный фран1якутсктц295
2адыгея тц мега2адыгеятц05
3балашиха трк октябрькиномир3балашихатрк13
4волжский тц волга молл4волжскийтц25

2.4 商品分类特征

商品类别之间的距离不好确定,使用one hot编码更加合适。

categories = pd.read_csv('../readonly/final_project_data/item_categories.csv')
lines1 = [26,27,28,29,30,31]
lines2 = [81,82]
for index in lines1:category_name = categories.loc[index,'item_category_name']
#    print(category_name)category_name = category_name.replace('Игры','Игры -')
#    print(category_name)categories.loc[index,'item_category_name'] = category_name
for index in lines2:category_name = categories.loc[index,'item_category_name']
#    print(category_name)category_name = category_name.replace('Чистые','Чистые -')
#    print(category_name)categories.loc[index,'item_category_name'] = category_name
category_name = categories.loc[32,'item_category_name']
#print(category_name)
category_name = category_name.replace('Карты оплаты','Карты оплаты -')
#print(category_name)
categories.loc[32,'item_category_name'] = category_name
categories.head()
item_category_nameitem_category_id
0PC - Гарнитуры/Наушники0
1Аксессуары - PS21
2Аксессуары - PS32
3Аксессуары - PS43
4Аксессуары - PSP4
categories['split'] = categories['item_category_name'].str.split('-')
categories['type'] = categories['split'].map(lambda x:x[0].strip())
categories['subtype'] = categories['split'].map(lambda x:x[1].strip() if len(x)>1 else x[0].strip())
categories = categories[['item_category_id','type','subtype']]
categories.head()
item_category_idtypesubtype
00PCГарнитуры/Наушники
11АксессуарыPS2
22АксессуарыPS3
33АксессуарыPS4
44АксессуарыPSP
categories['cat_type_code'] = LabelEncoder().fit_transform(categories['type'])
categories['cat_subtype_code'] = LabelEncoder().fit_transform(categories['subtype'])
categories.head()
item_category_idtypesubtypecat_type_codecat_subtype_code
00PCГарнитуры/Наушники033
11АксессуарыPS2113
22АксессуарыPS3114
33АксессуарыPS4115
44АксессуарыPSP117

3 特征融合

3.1 统计月销量

首先将训练集中的数据统计好月销量

ts = time.time()
matrix = []
cols = ['date_block_num','shop_id','item_id']
for i in range(34):sales = sales_train[sales_train.date_block_num==i]matrix.append(np.array(list(product([i], sales.shop_id.unique(), sales.item_id.unique())), dtype='int16'))matrix = pd.DataFrame(np.vstack(matrix), columns=cols)
matrix['date_block_num'] = matrix['date_block_num'].astype(np.int8)
matrix['shop_id'] = matrix['shop_id'].astype(np.int8)
matrix['item_id'] = matrix['item_id'].astype(np.int16)
matrix.sort_values(cols,inplace=True)
time.time() - tssales_train['revenue'] = sales_train['item_price'] *  sales_train['item_cnt_day']groupby = sales_train.groupby(['item_id','shop_id','date_block_num']).agg({'item_cnt_day':'sum'})
groupby.columns = ['item_cnt_month']
groupby.reset_index(inplace=True)
matrix = matrix.merge(groupby, on = ['item_id','shop_id','date_block_num'], how = 'left')
matrix['item_cnt_month'] = matrix['item_cnt_month'].fillna(0).clip(0,20).astype(np.float16)
matrix.head()test['date_block_num'] = 34
test['date_block_num'] = test['date_block_num'].astype(np.int8)
test['shop_id'] = test['shop_id'].astype(np.int8)
test['item_id'] = test['item_id'].astype(np.int16)
test.shapecols = ['date_block_num','shop_id','item_id']
matrix = pd.concat([matrix, test[['item_id','shop_id','date_block_num']]], ignore_index=True, sort=False, keys=cols)
matrix.fillna(0, inplace=True) # 34 month
print(matrix.head())
   date_block_num  shop_id  item_id  item_cnt_month
0               0        2       19             0.0
1               0        2       27             1.0
2               0        2       28             0.0
3               0        2       29             0.0
4               0        2       32             0.0

这里要确保矩阵里面没有 NA和NULL

print(matrix['item_cnt_month'].isna().sum())
print(matrix['item_cnt_month'].isnull().sum())
0
0

3.2 相关信息融合

将上面得到的商店,商品类别等信息与矩阵融合起来。

ts = time.time()
matrix = matrix.merge(items[['item_id','item_category_id']], on = ['item_id'], how = 'left')
matrix = matrix.merge(categories[['item_category_id','cat_type_code','cat_subtype_code']], on = ['item_category_id'], how = 'left')
matrix = matrix.merge(shops[['shop_id','shop_city_code','shop_type_code']], on = ['shop_id'], how = 'left')
matrix['shop_city_code'] = matrix['shop_city_code'].astype(np.int8)
matrix['shop_type_code'] = matrix['shop_type_code'].astype(np.int8)
matrix['item_category_id'] = matrix['item_category_id'].astype(np.int8)
matrix['cat_type_code'] = matrix['cat_type_code'].astype(np.int8)
matrix['cat_subtype_code'] = matrix['cat_subtype_code'].astype(np.int8)
time.time() - ts
4.71001935005188
matrix.head()
date_block_numshop_iditem_iditem_cnt_monthitem_category_idcat_type_codecat_subtype_codeshop_city_codeshop_type_code
002190.0407605
102271.01951405
202280.03051205
302290.02352005
402320.0407605
matrix.info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 11056140 entries, 0 to 11056139
Data columns (total 9 columns):
date_block_num      int8
shop_id             int8
item_id             int16
item_cnt_month      float16
item_category_id    int8
cat_type_code       int8
cat_subtype_code    int8
shop_city_code      int8
shop_type_code      int8
dtypes: float16(1), int16(1), int8(7)
memory usage: 200.3 MB

3.2 历史信息

将产生的信息做了融合。需要通过延迟操作来产生一些历史信息。比如可以将第0-33个月的销量作为第1-34个月的历史特征(延迟一个月)。按照以下说明,一共产生了15种特征。

  • 每个商品-商店组合每个月销量的历史信息,分别延迟[1,2,3,6,12]个月。这应该是最符合直觉的一种操作。
  • 所有商品-商店组合每个月销量均值的历史信息,分别延迟[1,2,3,6,12]个月。
  • 每件商品每个月销量均值的历史信息,分别延迟[1,2,3,6,12]个月。
  • 每个商店每个月销量均值的历史信息,分别延迟[1,2,3,6,12]个月。
  • 每个商品类别每个月销量均值的历史信息,分别延迟[1,2,3,6,12]个月。
  • 每个商品类别-商店每个月销量均值的历史信息,分别延迟[1,2,3,6,12]个月。

以上六种延迟都比较直观,直接针对商品,商店,商品类别。但是销量的变化趋势还可能与商品类别_大类,商店_城市,商品价格,每个月的天数有关,还需要做以下统计和延迟。可以根据模型输出的feature importance来选择和调整这些特征。

  • 每个商品类别_大类每个月销量均值的历史信息,分别延迟[1,2,3,6,12]个月。
  • 每个商店_城市每个月销量均值的历史信息,分别延迟[1,2,3,6,12]个月。
  • 每个商品-商店_城市组合每个月销量均值的历史信息,分别延迟[1,2,3,6,12]个月。

除了以上组合之外,还有以下特征可能有用

  • 每个商品第一次的销量
  • 每个商品最后一次的销量
  • 每个商品_商店组合第一次的销量
  • 每个商品_商店组合最后一次的销量
  • 每个商品的价格变化
  • 每个月的天数

3.2.1 lag operation产生延迟信息,可以选择延迟的月数。

def lag_feature(df, lags, col):tmp = df[['date_block_num','shop_id','item_id',col]]for i in lags:shifted = tmp.copy()shifted.columns = ['date_block_num','shop_id','item_id', col+'_lag_'+str(i)]shifted['date_block_num'] += idf = pd.merge(df, shifted, on=['date_block_num','shop_id','item_id'], how='left')return df

3.2.2 月销量(每个商品-商店)的历史信息

针对每个月的商品-商店组合的销量求一个历史信息,分别是1个月、2个月、3个月、6个月、12个月前的销量。这个值和我们要预测的值是同一个数量级,不需要求平均。而且会有很多值会是NAN,因为不存在这样的历史信息,具体原因前面已经分析过。

ts = time.time()
matrix = lag_feature(matrix, [1,2,3,6,12], 'item_cnt_month')
time.time() - ts
27.62108063697815

3.2.3 月销量(所有商品-商店)均值的历史信息

统计每个月的销量,这里的销量是包括了该月的所有商品-商店组合,所以需要求平均。同求历史信息。

ts = time.time()
group = matrix.groupby(['date_block_num']).agg({'item_cnt_month': ['mean']})
group.columns = [ 'date_avg_item_cnt' ]
group.reset_index(inplace=True)matrix = pd.merge(matrix, group, on=['date_block_num'], how='left')
matrix['date_avg_item_cnt'] = matrix['date_avg_item_cnt'].astype(np.float16)
matrix = lag_feature(matrix, [1,2,3,6,12], 'date_avg_item_cnt')
matrix.drop(['date_avg_item_cnt'], axis=1, inplace=True)
time.time() - ts
33.013164043426514

3.2.4 月销量(每件商品)均值和历史特征

统计每件商品在每个月的销量,这里的销量是包括了该月该商品在所有商店的销量,所以需要求平均。同求历史信息。

ts = time.time()
group = matrix.groupby(['date_block_num', 'item_id']).agg({'item_cnt_month': ['mean']})
group.columns = [ 'date_item_avg_item_cnt' ]
group.reset_index(inplace=True)matrix = pd.merge(matrix, group, on=['date_block_num','item_id'], how='left')
matrix['date_item_avg_item_cnt'] = matrix['date_item_avg_item_cnt'].astype(np.float16)
matrix = lag_feature(matrix, [1,2,3,6,12], 'date_item_avg_item_cnt')
matrix.drop(['date_item_avg_item_cnt'], axis=1, inplace=True)
time.time() - ts

3.2.5 月销量(每个商店)均值和历史特征

统计每个商店在每个月的销量,这里的销量是包括了该月该商店的所有商品的销量,所以需要求平均。同求历史信息。

ts = time.time()
group = matrix.groupby(['date_block_num', 'shop_id']).agg({'item_cnt_month': ['mean']})
group.columns = [ 'date_shop_avg_item_cnt' ]
group.reset_index(inplace=True)matrix = pd.merge(matrix, group, on=['date_block_num','shop_id'], how='left')
matrix['date_shop_avg_item_cnt'] = matrix['date_shop_avg_item_cnt'].astype(np.float16)
matrix = lag_feature(matrix, [1,2,3,6,12], 'date_shop_avg_item_cnt')
matrix.drop(['date_shop_avg_item_cnt'], axis=1, inplace=True)
time.time() - ts

3.2.6 月销量(每个商品类别)均值和历史特征

统计每个商品类别在每个月的销量,这里的销量是包括了该月该商品类别的所有销量,所以需要求平均。同求历史信息。

ts = time.time()
group = matrix.groupby(['date_block_num', 'item_category_id']).agg({'item_cnt_month': ['mean']})
group.columns = [ 'date_cat_avg_item_cnt' ]
group.reset_index(inplace=True)matrix = pd.merge(matrix, group, on=['date_block_num','item_category_id'], how='left')
matrix['date_cat_avg_item_cnt'] = matrix['date_cat_avg_item_cnt'].astype(np.float16)
matrix = lag_feature(matrix, [1,2,3,6,12], 'date_cat_avg_item_cnt')
matrix.drop(['date_cat_avg_item_cnt'], axis=1, inplace=True)
time.time() - ts

3.2.7 月销量(商品类别-商店)均值和历史特征

统计每个商品类别-商店在每个月的销量,这里的销量是包括了该月该商品商店_城市的所有销量,所以需要求平均。同求历史信息。

ts = time.time()
group = matrix.groupby(['date_block_num', 'item_category_id','shop_id']).agg({'item_cnt_month': ['mean']})
group.columns = [ 'date_cat_shop_avg_item_cnt' ]
group.reset_index(inplace=True)matrix = pd.merge(matrix, group, on=['date_block_num', 'item_category_id','shop_id'], how='left')
matrix['date_cat_shop_avg_item_cnt'] = matrix['date_cat_shop_avg_item_cnt'].astype(np.float16)
matrix = lag_feature(matrix, [1,2,3,6,12], 'date_cat_shop_avg_item_cnt')
matrix.drop(['date_cat_shop_avg_item_cnt'], axis=1, inplace=True)
time.time() - ts
15.178605556488037
matrix.info()

3.2.8 月销量(商品类别_大类)均值和历史特征

统计每个商品类别_大类在每个月的销量,这里的销量是包括了该月该商品类别_大类的所有销量,所以需要求平均。同求历史信息。

ts = time.time()
group = matrix.groupby(['date_block_num', 'cat_type_code']).agg({'item_cnt_month': ['mean']})
group.columns = [ 'date_type_avg_item_cnt' ]
group.reset_index(inplace=True)matrix = pd.merge(matrix, group, on=['date_block_num','cat_type_code'], how='left')
matrix['date_type_avg_item_cnt'] = matrix['date_type_avg_item_cnt'].astype(np.float16)
matrix = lag_feature(matrix, [1,2,3,6,12], 'date_type_avg_item_cnt')
matrix.drop(['date_type_avg_item_cnt'], axis=1, inplace=True)
time.time() - ts
14.34829592704773

3.2.9 月销量(商品-商品类别_大类)均值和历史特征

ts = time.time()
group = matrix.groupby(['date_block_num', 'item_id','cat_type_code']).agg({'item_cnt_month': ['mean']})
group.columns = [ 'date_item_type_avg_item_cnt' ]
group.reset_index(inplace=True)matrix = pd.merge(matrix, group, on=['date_block_num','item_id','cat_type_code'], how='left')
matrix['date_item_type_avg_item_cnt'] = matrix['date_item_type_avg_item_cnt'].astype(np.float16)
matrix = lag_feature(matrix, [1,2,3,6,12], 'date_item_type_avg_item_cnt')
matrix.drop(['date_item_type_avg_item_cnt'], axis=1, inplace=True)
time.time() - ts
14.34829592704773

3.2.10 月销量(商店_城市)均值和历史特征

统计每个商店_城市在每个月的销量,这里的销量是包括了该月该商店_城市的所有销量,所以需要求平均。同求历史信息。

ts = time.time()
group = matrix.groupby(['date_block_num', 'shop_city_code']).agg({'item_cnt_month': ['mean']})
group.columns = ['date_city_avg_item_cnt']
group.reset_index(inplace=True)matrix = pd.merge(matrix, group, on=['date_block_num',  'shop_city_code'], how='left')
matrix['date_city_avg_item_cnt'] = matrix['date_city_avg_item_cnt'].astype(np.float16)
matrix = lag_feature(matrix, [1,2,3,6,12], 'date_city_avg_item_cnt')
matrix.drop(['date_city_avg_item_cnt'], axis=1, inplace=True)
time.time() - ts
14.687093496322632

3.2.11 月销量(商品-商店_城市)均值和历史特征

统计每个商品-商店_城市在每个月的销量,这里的销量是包括了该月该商品-商店_城市的所有销量,所以需要求平均。同求历史信息。

ts = time.time()
group = matrix.groupby(['date_block_num','item_id', 'shop_city_code']).agg({'item_cnt_month': ['mean']})
group.columns = ['date_item_city_avg_item_cnt']
group.reset_index(inplace=True)matrix = pd.merge(matrix, group, on=['date_block_num', 'item_id', 'shop_city_code'], how='left')
matrix['date_item_city_avg_item_cnt'] = matrix['date_item_city_avg_item_cnt'].astype(np.float16)
matrix = lag_feature(matrix, [1,2,3,6,12], 'date_item_city_avg_item_cnt')
matrix.drop(['date_item_city_avg_item_cnt'], axis=1, inplace=True)
time.time() - ts
14.687093496322632

3.2.12 趋势特征,半年来价格的变化

ts = time.time()
group = sales_train.groupby(['item_id']).agg({'item_price': ['mean']})
group.columns = ['item_avg_item_price']
group.reset_index(inplace=True)matrix = pd.merge(matrix, group, on=['item_id'], how='left')
matrix['item_avg_item_price'] = matrix['item_avg_item_price'].astype(np.float16)group = sales_train.groupby(['date_block_num','item_id']).agg({'item_price': ['mean']})
group.columns = ['date_item_avg_item_price']
group.reset_index(inplace=True)matrix = pd.merge(matrix, group, on=['date_block_num','item_id'], how='left')
matrix['date_item_avg_item_price'] = matrix['date_item_avg_item_price'].astype(np.float16)lags = [1,2,3,4,5,6,12]
matrix = lag_feature(matrix, lags, 'date_item_avg_item_price')for i in lags:matrix['delta_price_lag_'+str(i)] = \(matrix['date_item_avg_item_price_lag_'+str(i)] - matrix['item_avg_item_price']) / matrix['item_avg_item_price']def select_trend(row):for i in lags:if row['delta_price_lag_'+str(i)]:return row['delta_price_lag_'+str(i)]return 0matrix['delta_price_lag'] = matrix.apply(select_trend, axis=1)
matrix['delta_price_lag'] = matrix['delta_price_lag'].astype(np.float16)
matrix['delta_price_lag'].fillna(0, inplace=True)# https://stackoverflow.com/questions/31828240/first-non-null-value-per-row-from-a-list-of-pandas-columns/31828559
# matrix['price_trend'] = matrix[['delta_price_lag_1','delta_price_lag_2','delta_price_lag_3']].bfill(axis=1).iloc[:, 0]
# Invalid dtype for backfill_2d [float16]fetures_to_drop = ['item_avg_item_price', 'date_item_avg_item_price']
for i in lags:fetures_to_drop += ['date_item_avg_item_price_lag_'+str(i)]fetures_to_drop += ['delta_price_lag_'+str(i)]matrix.drop(fetures_to_drop, axis=1, inplace=True)time.time() - ts
601.2605240345001

3.2.13 每个月天数¶

matrix['month'] = matrix['date_block_num'] % 12
days = pd.Series([31,28,31,30,31,30,31,31,30,31,30,31])
matrix['days'] = matrix['month'].map(days).astype(np.int8)

3.2.14 开始和结束的销量

Months since the last sale for each shop/item pair and for item only. I use programing approach.

Create HashTable with key equals to {shop_id,item_id} and value equals to date_block_num. Iterate data from the top. Foreach row if {row.shop_id,row.item_id} is not present in the table, then add it to the table and set its value to row.date_block_num. if HashTable contains key, then calculate the difference beteween cached value and row.date_block_num.

ts = time.time()
cache = {}
matrix['item_shop_last_sale'] = -1
matrix['item_shop_last_sale'] = matrix['item_shop_last_sale'].astype(np.int8)
for idx, row in matrix.iterrows():    key = str(row.item_id)+' '+str(row.shop_id)if key not in cache:if row.item_cnt_month!=0:cache[key] = row.date_block_numelse:last_date_block_num = cache[key]matrix.at[idx, 'item_shop_last_sale'] = row.date_block_num - last_date_block_numcache[key] = row.date_block_num         
time.time() - ts

Months since the first sale for each shop/item pair and for item only.

ts = time.time()
matrix['item_shop_first_sale'] = matrix['date_block_num'] - matrix.groupby(['item_id','shop_id'])['date_block_num'].transform('min')
matrix['item_first_sale'] = matrix['date_block_num'] - matrix.groupby('item_id')['date_block_num'].transform('min')
time.time() - ts
2.4333603382110596

因为使用了12个月作为延迟特征,必然由大量的数据是NA值,将最开始11个月的原始特征删除,并且对于NA值我们需要把它填充为0。

ts = time.time()
matrix = matrix[matrix.date_block_num > 11]
time.time() - ts
1.0133898258209229
ts = time.time()
def fill_na(df):for col in df.columns:if ('_lag_' in col) & (df[col].isnull().any()):if ('item_cnt' in col):df[col].fillna(0, inplace=True)         return dfmatrix = fill_na(matrix)
time.time() - ts

4. 数据建模

4.1 lightgbm 模型

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import time
import gc
import pickle
from itertools import product
from sklearn.preprocessing import LabelEncoderpd.set_option('display.max_rows', 500)
pd.set_option('display.max_columns', 100)#import sklearn.model_selection.KFold as KFold
def plot_features(booster, figsize):    fig, ax = plt.subplots(1,1,figsize=figsize)return plot_importance(booster=booster, ax=ax)
data = pd.read_pickle('data_simple.pkl')
X_train = data[data.date_block_num < 33].drop(['item_cnt_month'], axis=1)
Y_train = data[data.date_block_num < 33]['item_cnt_month']
X_valid = data[data.date_block_num == 33].drop(['item_cnt_month'], axis=1)
Y_valid = data[data.date_block_num == 33]['item_cnt_month']
X_test = data[data.date_block_num == 34].drop(['item_cnt_month'], axis=1)
del data
gc.collect();
import lightgbm as lgbts = time.time()
train_data = lgb.Dataset(data=X_train, label=Y_train)
valid_data = lgb.Dataset(data=X_valid, label=Y_valid)time.time() - tsparams = {"objective" : "regression", "metric" : "rmse", 'n_estimators':10000, 'early_stopping_rounds':50,"num_leaves" : 200, "learning_rate" : 0.01, "bagging_fraction" : 0.9,"feature_fraction" : 0.3, "bagging_seed" : 0}lgb_model = lgb.train(params, train_data, valid_sets=[train_data, valid_data], verbose_eval=1000) 
Y_test = lgb_model.predict(X_test).clip(0, 20)

I want to change some values to be zeros.

4.2. 后处理

4.2.1 过期商品

将最近12个月都没有销售的商品的销量置零。

4.3 重要性画图

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/33616.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

世界杯押注还得看技术流,这个预测AI把赔率也算上了

胡澎 发自 凹非寺 量子位 报道 | 公众号 QbitAI 世界杯小组赛将收官&#xff0c;你还依然信AI吗&#xff1f; 冷门频出&#xff0c;黑马击败豪强。不少AI模型始料未及。 到底还能不能愉快找到科学规律&#xff1f;或者说足球比赛乃至其他竞技体育赛事&#xff0c;数据科学家在A…

足球大数据预测实战之高胜率盈亏条件验证及优化算法

上周接到一位老用户&#xff0c;之前为他做过数据验证&#xff0c;给出了组合条件下的胜率回查&#xff0c;结果有些难看啊。这期主要介绍常用人工智能算法中在足球预测中的应用&#xff0c;以及数据验证后的实际效果。 由上图为用户依据条件查证后的比赛场次和概率统计。可以看…

苹果手机朝下无法唤醒Siri,这个解决方法你知道吗

Siri对于苹果手机的用户来说是一个非常大的吸引点&#xff0c;能够指挥苹果手机中的Siri去做很多事情&#xff0c;如&#xff1a;放一首歌曲、百度一些知识点、这句话用英语怎么说等等功能。但是&#xff0c;不知道你们有没有发现一般我们苹果手机朝下无法唤醒Siri。是不是觉得…

如何解决Siri无法正常运行的问题

Siri 是一位智能助理,能帮助你在 Apple 设备上更快速轻松地处理各种事务,甚至不用等你开口。 Mac 上的 Siri 可帮助您执行日常任务&#xff0c;如获取问题的快速***、播放音乐等。您可以询问 Siri 几乎任何内容&#xff0c;Siri 都可以为您执行或回答您的问题。如果在使用 Siri…

【推荐实践】多场景多任务学习在美团到店餐饮推荐的实践

省时查报告-专业、及时、全面的行研报告库 省时查方案-专业、及时、全面的营销策划方案库 【免费下载】2023年2月份热门报告合集 ChatGPT团队背景研究报告 ChatGPT的发展历程、原理、技术架构及未来方向 ChatGPT使用总结&#xff1a;150个ChatGPT提示此模板 ChatGPT数据集之谜 …

倒计时3天!2023新榜AIGC生态大会看点剧透

倒计时3天&#xff01;「AIGC赋能重塑内容生态」2023新榜AIGC生态大会将于7月14日在北京丽都皇冠假日酒店重磅登场。 内容行业正在步入AI时代。 AIGC&#xff08;AI Generated Content&#xff0c;即人工智能生成内容&#xff09;被认为是继OGC、PGC和UGC之后的新型内容生产方式…

携程平台增长部总经理王绩强:原生互联网企业正在经历一场数字升级丨数据猿专访...

‍数据智能产业创新服务媒体 ——聚焦数智 改变商业 以大数据和人工智能为核心&#xff0c;众多新兴技术开始赋能数字营销。于是&#xff0c;智能营销已然从工具化走向了业务化。 如今&#xff0c;数字化营销已经成为了企业数字化转型中的重要一环。相较于传统营销逻辑&#x…

技术总监亲自上阵,手撸了个推荐系统!

省时查报告-专业、及时、全面的行研报告库 省时查方案-专业、及时、全面的营销策划方案库 【免费下载】2023年2月份热门报告合集 从0到1详解推荐系统基础知识和框架 推荐技术在vivo互联网商业化业务中的实践.pdf 推荐系统基本问题及系统优化路径.pdf 大规模推荐类深度学习系统的…

融合GPT大模型产品,WakeData新一轮产品升级

近期&#xff0c;WakeData惟客数据&#xff08;以下简称 “ WakeData ” &#xff09;完成了新一轮的产品能力升级。就 ToB 企服公司如何融合GPT 大模型&#xff0c;WakeData 给出了自己的答案。 在2022年11月的产品发布会上&#xff0c;已传递出WakeData的“三个坚定”&#x…

借助chatGPT强大的源码理解能力,来快速学习elasticsearch 7.11.1整体源码结构(用chatGPT学源码太香了)

ES阅读学习源码的难处 es的源码非常之多。能够查阅的资料非常少。如果是我们一行一行的去扒着源码看&#xff0c;在我看来至少需要2年的时间&#xff0c;并且至少要耗费四分之一的头发。源码读起来很枯燥&#xff0c;特别是在我们一头雾水的时候。很容易产生放弃的念头。很少有…

大语言模型中的涌现现象是不是伪科学?

深度学习在理论上的孱弱一直被诟病&#xff0c;但科学史上存在大量先有应用再有理论的事例&#xff0c;而其中不能解释的重大实验现象往往预示着理论创新的契机。我们首先从现象出发&#xff0c;来看下LLM中最神秘的emergent ability&#xff0c;如图 上图中x、y轴分别表示模型…

自制开源的 Midjourney、Stable Diffusion “咒语”作图工具

本篇文章聊聊如何通过 Docker 和八十行左右的 Python 代码&#xff0c;实现一款类似 Midjourney 官方图片解析功能 Describe 的 Prompt 工具。 让你在玩 Midjourney、Stable Diffusion 这类模型时&#xff0c;不再为生成 Prompt 描述挠头。 写在前面 本文将提供两个版本的工…

【区块链技术社区】区块链微信群

磨链mochain社区-区块链技术讨论交流不定期进行线上的技术交流学习&#xff0c;技术分享。线下技术交流&#xff0c;成员主要在北京、上海、浙江、广东等地。欢迎&#xff1a;区块链技术大咖、区块链爱好者、区块链技术爱好者、想了解区块链技术的小白不欢迎&#xff1a;广告党…

区块链笔记:典型应用:数据资产、交易系统、即时通信、链上游戏、追踪溯源等

数据资产 1 &#xff09; 详解 这是区块链的一个比较核心的应用&#xff0c;对于软件系统或者说对于互联网系统来讲&#xff0c;对数据的处理、分析、计算&#xff0c;这些功能是属于比较基本的软件功能对于区块链来讲它的核心的功能是在于创新式的提供了一个原先各种软件都没…

靠谱的区块链应用到底是啥?通证啊!——第二次中关村-CSDN区块链开发技术沙龙【含PPT下载】

针对“通证”话题的多篇分析文章预热&#xff0c;本期沙龙在开始前就被区块链网友广泛关注。此次沙龙的参会者经过层层的严格筛选&#xff0c;才得以与众位大咖面对面沟通。 12月15日下午&#xff0c;中关村区块链产业联盟、CSDN、枫玉科技联合举办的区块链系列沙龙。来自中关村…

云图说丨不同区块链之间如何跨链交互?

本文分享自华为云社区《【云图说】第237期 不同区块链之间如何跨链交互&#xff1f;》&#xff0c;作者&#xff1a; 阅识风云。 可信跨链服务是基于一系列制定的可信区块链标准跨链协议&#xff0c;保证跨链交易全栈可追溯、可扩展性及可靠性等&#xff0c;助力不同区块链可…

知乎高赞 | 区块链是什么? (一)

首先不要把区块链想的过于高深&#xff0c;他是一个分布在全球各地、能够协同运转的数据库存储系统&#xff0c;区别于传统数据库运作——读写权限掌握在一个公司或者一个集权手上&#xff08;中心化的特征&#xff09;&#xff0c;区块链认为&#xff0c;任何有能力架设服务器…

XuperChain 百度区块链简易学习帖

百度XuperChain基于Ubuntu系统从零开始到部署简单合约 环境配置go语言安装git安装客户端安装 启动私链基本操作命令1. 创建普通用户2. 创建合约账号3. 查询余额4. 转账5. 查询交易信息6. 查询block信息 网络部署&#xff08;选择性阅读&#xff09;1. 创建网络部署环境2. 配置种…

建议收藏,轻松搞懂区块链

未来已来&#xff0c;只是不均衡地分布在当下 大家好&#xff0c;我是菜农&#xff0c;欢迎来到我的频道。 本文共 5844字&#xff0c;预计阅读 30 分钟 区块链是近些年来最热门的前沿技术&#xff0c;被认为是未来十几年对金融、物联网、医疗等诸多领域产生最大影响的"…

都说区块链可信,到底信了个啥?

‍‍ 题图摄于北京二环路 【前言】不时有朋友向我询问某某区块链项目怎么样。我通常只给他们讲一点&#xff1a;要考察项目中区块链的信任体系。不管项目方说得怎样天马行空&#xff0c;看懂其中的信任机制&#xff0c;就基本可判断其项目的价值。 最近热门词汇层出不穷&#x…