iT邦幫忙

2021 iThome 鐵人賽

DAY 6
0
自我挑戰組

資料分析及AI深度學習-簡單基礎實作系列 第 6

DAY6:Kaggle-San Francisco Crime Classification(上)

大家好,今天來到第六天了~完成1/5了,必須說參加鐵人賽還都完賽的人,真的很棒很有毅力,花自己工作之餘的休息時間來分享自己的學習歷程,這邊我給自己一個肯定哈哈哈哈!!我會努力把30天寫完的!!

  • 資料來源和問題確認

今天這個題目呢,是我去年在資策會的時候想要自己練習做資料分析去Kaggle找到的一個題目,它是一堆犯罪紀錄,而我們要拿這些資料去預測它的test資料集是哪種犯罪類型,很好玩吧,是一個多分類的問題,不像前幾天做的都是二分類的問題。
kaggle傳送門

  • 導入資料及資料前處理

第一步一定是導入我們的資料啦~我們一樣用pandas套件的read_csv來導入資料。

import pandas as pd

train=pd.read_csv('./train.csv')
test=pd.read_csv('./test.csv')

再來我們看看資料型態長怎樣。

print(train.head(5))

我們來解釋一下它的各個資料欄位的意思,在train資料裡面總共有9個欄位,分別為:
 1. Dates:犯罪事件的時間戳。
 2. Category:犯罪事件的類型。(也就是我們要預測的Y)
 3. Descript:對於犯罪的描述。
 4. DayOfWeek:犯罪是在星期幾。
 5. PdDistrict:警察局管轄區域名稱。
 6. Resolution:犯罪是如何被解決的。
 7. Address:犯罪發生的大致街道地址。
 8. X:犯罪位置的經度。
 9. Y:犯罪位置的緯度。

接下來我們看看test資料裡面有哪些特徵欄位。

print(test.columns)

分別為:
 1. Id:編號ID。
 2. Dates:犯罪事件的時間戳。
 3. DayOfWeek:犯罪是在星期幾。
 4. PdDistrict:警察局管轄區域名稱。
 5. Address:犯罪發生的大致街道地址。
 6. X:犯罪位置的經度。
 7. Y:犯罪位置的緯度。

所以我們可以先做第一件事情就是把沒出現在test的特徵欄位刪除,所以我們將train裡面的"Descript"及"Resolution"這兩個特徵刪除。"Category"則是我們訓練時需要用到的應變數。

train.drop(['Descript','Resolution'],inplace=True,axis=1)

print(train.head(5))

查看有沒有缺失值,發現資料並無缺失值。

print(train.isnull().sum())
print(test.isnull().sum())

 train       test

接下來,在Dates的地方,我想把這個欄位再分的更細一點,年、月、時和分給區隔開來,日期我沒有分出來,我認為日期對我們要預測的應變數影響不大。還有Address的部分,若有含街道block的部分,我把它顯示為布林值。這裡DayOfWeek我們自己再做一次,怕原本資料寫錯,且原資料給的星期幾是類別變數,我們也直接將它轉成虛擬變數。

def build_datetime_and_block(df):
    df['Dates'] = pd.to_datetime(df['Dates'])
    df['Date'] = df['Dates'].dt.date
    df['Hour'] = df['Dates'].dt.hour
    df['Minute'] = df['Dates'].dt.minute
    df['DayOfWeek'] = df['Dates'].dt.weekday
    df['Month'] = df['Dates'].dt.month
    df['Year'] = df['Dates'].dt.year
    df['Block'] = df['Address'].str.contains('block', case=False)#case預設=True,表示區分大小寫。
    return df
train = build_datetime_and_block(train)
test = build_datetime_and_block(test)

我們已經把Dates和Address給分的更細了,那這些特徵就不需要了,將他們刪除。

train.drop(['Address','Dates','Date'],inplace=True,axis=1)
test.drop(['Address','Dates','Date'],inplace=True,axis=1)

print(train.head(5))
print(test.head(5))

train

test

處理完上面的特徵,我們來看看剩下"PdDistrict"和經緯度("X"、"Y")沒有動到,先來看看"PdDistrict"有沒有其他的問題,已經檢視過沒有缺失值了。

print(train.PdDistrict.unique())

看起來也沒有其他問題。

再來看看經緯度吧!

這裡我們會用到geopandas這個套件,我自己安裝的時候是有遇到一些問題,可以參考這裡去安裝。

from shapely.geometry import Point
import geopandas as gpd

def create_gdf(df):
    gdf = df.copy()
    gdf['Coordinates'] = list(zip(gdf.X, gdf.Y))
    gdf.Coordinates = gdf.Coordinates.apply(Point)
    gdf = gpd.GeoDataFrame(
        gdf, geometry='Coordinates', crs={'init': 'epsg:4326'})
    return gdf

train_gdf = create_gdf(train)

world = gpd.read_file(gpd.datasets.get_path('naturalearth_lowres'))
ax = world.plot(color='white', edgecolor='black')
train_gdf.plot(ax=ax, color='red')
plt.show()

可以發現最上面那個紅點明顯偏離了,代表有經緯度是給錯的。

我們將經緯度照順序列出來,看到X = -120.5和Y = 90.0這兩個變數屬於離群值。

print(sorted(list(train.X.unique()),reverse=True))
print(sorted(list(train.Y.unique()),reverse=True))

X            Y

先觀察筆數多寡,可以發現當X = -120.5時,Y = 90.0,train都是67筆,而test是76筆。

wrongxy = lambda df : len(df[(df['X'] == -120.5) & (df['Y'] == 90.0)])
print(wrongxy(train))
print(wrongxy(test))

wrongxy = lambda df : len(df[(df['X'] == -120.5)])
print(wrongxy(train))
print(wrongxy(test))

wrongxy = lambda df : len(df[(df['Y'] == 90.0)])
print(wrongxy(train))
print(wrongxy(test))

我們可選擇刪除或是改動值的方式,這邊我選擇依照PdDistrict的經緯度的中位數去改這些值。

def fix_gps(df):
    n = 0
    d = df[(df['X'] == -120.5) & (df['Y'] == 90.0)]
    for idx, row in d.iterrows():
        district = row['PdDistrict']
        xys = df[df['PdDistrict'] == district][['X', 'Y']]
        #print("PdDistrict:", district)
        df.loc[idx, ['X']] = xys['X'].median()
        df.loc[idx, ['Y']] = xys['Y'].median()
        #print(df.loc[idx, ['X']].values[0], df.loc[idx, ['Y']].values[0])
        n = n + 1
    print('更動幾筆資料:', n)
fix_gps(train)

fix_gps(test)


  • 今日小結

今天主要對資料做清洗,對於每個特徵,都較詳細的去處理他們,並且有搭配到用地圖去看經緯度資料是否有誤。資料前處理部分剩下一部分,主要是這次的資料很多為類別變數,我們需要幫它轉換成虛擬變數,文字變成數字,這樣才能丟進模型建模,那我們明天就來處理剩下的部分吧!!這次的模型,除了用之前的sklearn套件以外,還會嘗試用tensorflow去建立神經網路來建模,開始要接觸深度學習囉!!
那我們明天見~


上一篇
DAY5:Kaggle-Data Science London + Scikit-learn(二)
下一篇
DAY7:Kaggle-San Francisco Crime Classification(下)
系列文
資料分析及AI深度學習-簡單基礎實作30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言