2019移動廣告反欺詐算法挑戰賽之初始數據分析

前言:

最近參加的科大訊飛的2019移動廣告反欺詐算法挑戰賽,但是白天一直在忙着寫論文,所以一直是跑跑別人的公開的baseline,調調參數一類的,現在是94.43左右,有需要的可以和我說一下,免費奉獻。但是感覺成長不是很大,所以就學學kaggle上的一個大佬分析數據的方式很有意思,就拿過來學學。比貓畫虎而已,肯定有些不對的。程序是用jupyter寫的,但是CSDN不是很支持jupyter,所以每一段重要的程序前面,我會做個簡單的分析的。

 

重要通知:

catboost版本會對結果有影響,所以建議使用0.15.2的版本。

安裝方法:pip install catboost==0.15.2

查看版本的命令: pip2 list

 

第一: 數據的基本信息

設置最大顯示的列數,以及定義一些畫圖的包

# 移動廣告反欺詐算法挑戰賽 簡單的數據分析
# pandas中describe()函數自動計算的字段有count(非空值數)、unique(唯一值數)、top(頻數最高者)、freq(最高頻數)
import pandas as pd # 讀取數據集

import numpy as np  # 展示全部列的數據
pd.set_option('display.max_columns', 1000)

from datetime import timedelta, datetime # 處理時間戳數據
import time

import matplotlib.pyplot as plt  # 用於畫圖程序
import seaborn as sns
%matplotlib inline

sns.set(rc={'figure.figsize':(20,5)});
plt.figure(figsize=(20,5));

# 讀取數據集

# 讀取數據集
train = pd.read_table("data/traindata.txt")
test = pd.read_table("data/testdata.txt")

# 顯示一下數據的基本信息  我們可以看到數據集中含有缺失值的屬性有 city  lan  make  model  osv  ver 分別表示 城市 語言  廠商  機型  操作系統版本  app版本, 我看所給的baseline中並沒有對缺失值進行處理,所以我在baseline中對缺失值進行填充。
填充代碼爲: all_data['city'] = all_data['city'].fillna(method='pad')

# 顯示一下數據的信息
train.head(5)
train.info()
train.describe()

 

定義數據集中屬性列的相關變量

variables = ['pkgname', 'ver', 'adunitshowid', 'mediashowid', 'apptype', 'ip',
            'reqrealip', 'city', 'province', 'adidmd5', 'imeimd5', 'idfamd5',
            'openudidmd5', 'macmd5', 'dvctype', 'model', 'make', 'ntt',
            'carrier', 'os', 'osv', 'orientation', 'lan', 'h', 'w', 'ppi']

# 接下來我們統計一下數據集中,每個屬性的的唯一值是多少?其實我看的baseline統計了的特徵大多是每個屬性中唯一值的個數,以及對結果進行排序。其實我想如果是這樣的話,在訓練數據中也可以增加一個特徵,每一個屬性值佔總體的比例也可以試一下的。從結果中我們可以看到幾個比較顯著的特點:

第一: 有幾個屬性的唯一值比較的少,例如: 省  dvctype(設備類型)  廠商一類的

第二: 出現唯一值比較多的幾個屬性有,  IP地址  {(Adroid ID的MD5值)   mac的MD5值} 這兩個屬性可以表示是蘋果設備還是安安卓設備。  imei的MD5值 (這個屬性就不知道是啥意思了)

第三:如果統計os的唯一值出現的次數的話,那麼這一列的屬性值就會很大,應該10萬級別的,所以可不可以使用log以下結果。使得數據集中屬性列之間的值差距不是很大。

plt.figure(figsize=(10, 6))
plt.xticks(rotation=90,fontsize=12)
uniques = [len(train[col].unique()) for col in variables]
sns.set(font_scale=1.2)
ax = sns.barplot(variables, uniques, log=True)
ax.set(xlabel='feature', ylabel='unique count of each feature', title='Number of unique values for each feature')
for p, uniq in zip(ax.patches, uniques):
    height = p.get_height()
    ax.text(p.get_x()+p.get_width()/2.,
            height + 10,
            uniq,
            ha="center") 

 

# 接下來我們統計一下數據集中目標標籤出現的次數,看看是否出現正負樣本差距較大的情況,如果出現需要對數據進行重採樣。我們看到數據集中作弊的數量佔48%, 而負樣本佔52%。 所以不需要我們執行重採樣。


plt.figure(figsize=(6,6))
#sns.set(font_scale=1.2)  

mean = (train.label.values == 1).mean()
ax = sns.barplot(['Positive samples (1)', 'Negative Samples (0)'], [mean, 1-mean])
ax.set(ylabel='Proportion', title='Positive Samples vs Negative Samples')
for p, uniq in zip(ax.patches, [mean, 1-mean]):
    height = p.get_height()
    ax.text(p.get_x()+p.get_width()/2.,
            height+0.01,
            '{}%'.format(round(uniq * 100, 2)),
            ha="center")

 

 

# 根據我們收集的資料我們可以知道對於是否作弊而言,IP地址應該是一個強特徵,okay咱們開始分析一下IP地址和目標標籤之間的關係。首先咱們先統計一下數據集中ip地址出現的次數。然後畫圖展示一下IP地址出現次數的大致分佈。最後咱們分析一下IP地址和目標標籤之間的關係。

IP地址出現的次數

temp = train['ip'].value_counts().reset_index(name='counts')
temp.columns = ['ip', 'counts']

 

import matplotlib.pyplot as plt
import sys

print('數據集中前temp的值', type(temp))
name = list(temp['ip'].iloc[0:10])
num = list(temp['counts'].iloc[0:10])

plt.bar(name, num, color='rgby')
plt.xlabel('name of file')
plt.ylabel("num-of-file")
plt.title("num-of-each-file")
for a, b in zip(name, num):
 plt.text(a, b, '%.0f' % b, ha='center', va='bottom', fontsize=11)
 
plt.show()

 

IP地址出現的次數大多都是一次,最高的纔出現了200多次,這個可以作爲最後的新的特徵。上面我們可以看到向os這樣的屬性值中,每一個屬性可能出現上萬次,然後在我們ip地址纔出現200, 所以統計特徵的時候是否有必要所有的特徵都統計出現次數,我感覺是個問題。


IP地址出現的次數和是否下載之間的關係。藍色先表示的某個IP地址的出現的次數,黃色的線表示數據中出現的次數作弊率還是挺高的,所以我感覺IP地址應該是個相對不錯的特徵對於這個模型。但是還是有疑問的。

# 將原始數據中的標籤轉化成int型數據
train['label']=train['label'].astype(int)
proportion = train[['ip', 'label']].groupby('ip', as_index=False).mean().sort_values('label', ascending=False)
counts = train[['ip', 'label']].groupby('ip', as_index=False).count().sort_values('label', ascending=False)
merge = counts.merge(proportion, on='ip', how='left')
merge.columns = ['ip', 'click_count', 'prop_downloaded']

ax = merge[:100].plot(secondary_y='prop_downloaded')
plt.title('Conversion Rates over Counts of 100 Most Popular IPs')
ax.set(ylabel='Count of clicks')
plt.ylabel('Proportion Downloaded')
plt.show()

print('Counversion Rates over Counts of Most Popular IPs')
print(merge[:20])

 

 

同樣的方式還可以用到其他的屬性列的分析上。暫時不講了,下一節有時間的話,我談一下時間數據的應用。這個我看公開的源碼上都沒有做。早點睡覺了。ZZZZZZZZZZZZZZZZZZZ

 

 

 

 

 

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章