San Francisco Crime Classification
1. 대회 설명
-
설명
1934년부터 1963년까지 샌프란시스코의 알카트라즈섬에 악명 높은 범죄자들을 수용 한 것으로 유명했습니다. 이 대회는 약 12년 동안 샌프란시스코의 모든 지역에서 발생한 범죄 보고서를 제공합니다. 시간과 장소가 주어지면 발생한 범죄의 유형(카테고리)을 예측하여 제출합니다.
-
키워드
#분류 # classification
-
평가방법
범죄 유형별 범죄 발생 가능성을 확률로 계산하여 제출하면, multi class logarithmic loss를 사용하여 정확도를 측정합니다.
2. 데이터
본 대회는 샌프란시스코 오픈 데이터 SF OpenData에서 제공하는 범죄관련 데이터를 사용합니다.
- 2003년 1월 1일 ~ 2015년 5월 13일 범죄데이터
- Training Set: 1,3,5,7 주
- Test Set: 2,4,6,8 주
-
Dates - 범죄 사건 발생 날짜 및 시간 정보
-
Category - 범죄 사건 카테고리(이 값이 예측할 목표변수)
-
Descript - 범죄 사건에 대한 자세한 설명
-
DayOfWeek - 요일
-
PdDistrict - 경찰서 구역 이름
-
Resolution - 범죄 사건이 해결 된 방법
-
Address - 범죄 사건의 대략적인 주소
-
X - 경도
-
Y - 위도
3. 데이터 전처리
데이터 훑어보기
-
데이터 로딩
(1) 데이터 압축 풀기
!unzip '/kaggle/input/sf-crime/test.csv' !unzip '/kaggle/input/sf-crime/train.csv' !unzip '/kaggle/input/sf-crime/sampleSubmission.csv'
최근들어 이전 대회에 데이터셋이 zip 형태의 파일이 제공되고 있습니다. 데이터셋을 불러오기 위해서는 압축을 해제하는 작업부터 시작해야합니다.
압축 해제를 한 결과물(csv파일)은 output 폴더에서 확인할 수 있습니다.
(2) csv 파일을 데이터프레임으로 읽기
train = pd.read_csv('./train.csv')
test = pd.read_csv('./test.csv')
submission = pd.read_csv('./sampleSubmission.csv')
읽어드릴 파일의 경로는 Copy file path를 사용하면 확인할 수 있습니다.
-
학습 데이터 셋의 상위 5개 항목 출력
train.head()
[결과]
Dates Category Descript DayOfWeek PdDistrict Resolution Address X Y 0 2015-05-13 23:53:00 WARRANTS WARRANT ARREST Wednesday NORTHERN ARREST, BOOKED OAK ST / LAGUNA ST -122.425892 37.774599 1 2015-05-13 23:53:00 OTHER OFFENSES TRAFFIC VIOLATION ARREST Wednesday NORTHERN ARREST, BOOKED OAK ST / LAGUNA ST -122.425892 37.774599 2 2015-05-13 23:33:00 OTHER OFFENSES TRAFFIC VIOLATION ARREST Wednesday NORTHERN ARREST, BOOKED VANNESS AV / GREENWICH ST -122.424363 37.800414 3 2015-05-13 23:30:00 LARCENY/THEFT GRAND THEFT FROM LOCKED AUTO Wednesday NORTHERN NONE 1500 Block of LOMBARD ST -122.426995 37.800873 4 2015-05-13 23:30:00 LARCENY/THEFT GRAND THEFT FROM LOCKED AUTO Wednesday PARK NONE 100 Block of BRODERICK ST -122.438738 37.771541
-
학습 데이터 셋의 각 필드 데이터 분포(평균, 최소값, 최대값 등)를 살펴보기
train.describe()
[결과]
X Y count 878049.000000 878049.000000 mean -122.422616 37.771020 std 0.030354 0.456893 min -122.513642 37.707879 25% -122.432952 37.752427 50% -122.416420 37.775421 75% -122.406959 37.784369 max -120.500000 90.000000 수치형 데이터를 포함한 컬럼에 대해서만 요약 값을 출력합니다. 총 878,049개의 학습데이터 셋이 있고, X좌표 Y좌표의 최소값, 최대값, 4분위수 등을 확인할 수 있습니다.
-
각 컬럼의 데이터 타입 확인하기
train.info()
[결과]
<class 'pandas.core.frame.DataFrame'> RangeIndex: 878049 entries, 0 to 878048 Data columns (total 9 columns): Dates 878049 non-null object Category 878049 non-null object Descript 878049 non-null object DayOfWeek 878049 non-null object PdDistrict 878049 non-null object Resolution 878049 non-null object Address 878049 non-null object X 878049 non-null float64 Y 878049 non-null float64 dtypes: float64(2), object(7) memory usage: 60.3+ MB
X,Y를 제외한 컬럼값이 모두 object 타입입니다. 기계학습을 위해서 사용이 필요한 변수들은 수치형데이터로 변환하는 작업이 필요하겠네요.
-
범죄의 범주 'Category'는 어떤 값이 있는지 확인하기
train['Category'].unique()
[결과]
array(['WARRANTS', 'OTHER OFFENSES', 'LARCENY/THEFT', 'VEHICLE THEFT', 'VANDALISM', 'NON-CRIMINAL', 'ROBBERY', 'ASSAULT', 'WEAPON LAWS', 'BURGLARY', 'SUSPICIOUS OCC', 'DRUNKENNESS', 'FORGERY/COUNTERFEITING', 'DRUG/NARCOTIC', 'STOLEN PROPERTY', 'SECONDARY CODES', 'TRESPASS', 'MISSING PERSON', 'FRAUD', 'KIDNAPPING', 'RUNAWAY', 'DRIVING UNDER THE INFLUENCE', 'SEX OFFENSES FORCIBLE', 'PROSTITUTION', 'DISORDERLY CONDUCT', 'ARSON', 'FAMILY OFFENSES', 'LIQUOR LAWS', 'BRIBERY', 'EMBEZZLEMENT', 'SUICIDE', 'LOITERING', 'SEX OFFENSES NON FORCIBLE', 'EXTORTION', 'GAMBLING', 'BAD CHECKS', 'TREA', 'RECOVERED VEHICLE', 'PORNOGRAPHY/OBSCENE MAT'], dtype=object)
데이터 할당/변경하기(create, update)
-
Dates 필드의 데이터타입을 'datetime64' 타입으로 변경하기
train['Dates'] = train['Dates'].astype('datetime64')
범죄 사건 발생 날짜 및 시간 정보를 포함한 'Dates'필드의 값을 연도별, 월별, 일별, 시간별로 분석하기 위해서 datetime64타입으로 변환합니다.
문자열 파싱을 해서 분석할 수도 있지만, datetime64 타입으로 변환하면 파이썬 내장함수를 사용해서 쉽게 연/월/일/시간별 값을 얻어올 수 있습니다.
-
연, 월, 일, 요일, 시, 분값을 새로운 컬럼(year, month, day, dayofweek, hour, minute)을 생성해서 할당하기
train['year'] = train['Dates'].dt.year train['month'] = train['Dates'].dt.month train['day'] = train['Dates'].dt.day train['dayofweek'] = train['Dates'].dt.dayofweek train['hour'] = train['Dates'].dt.hour train['minute'] = train['Dates'].dt.minute
[결과]
본 글에서는 train 데이터 셋 전처리에 대해서만 정리했습니다. 실제 캐글 데이터 전처리시, train데이터와 test데이터가 모두 동일한 형태로 변환할 수 있도록 함께 처리합니다.
-
범죄가 발생한 경도, 위도 값을 나타내는 X, Y 컬럼의 값을 더한 값을 담은 'X+Y' 컬럼, X, Y의 차이 값을 담은 'X-Y' 컬럼을 생성하기
train['X+Y'] = train['X'] + train['Y'] train['X-Y'] = train['X'] - train['Y']
[결과]
-
n_days라는 컬럼을 생성하고, 일별 d-day를 계산하여 입력하기
예: 범죄 첫발생일: 0, 다음 발생일: 1train['n_days'] = (train['Dates'].dt.date - train['Dates'].dt.date.min()).apply(lambda x: x.days) test['n_days'] = (test['Dates'].dt.date - test['Dates'].dt.date.min()).apply(lambda x: x.days)
-
변수 y를 선언해서 학습할 목표변수(=종속변수)인 Category 필드값을 담기
y = train['Category']
데이터 선택하기(select)
-
연도별(year) 범죄 발생 횟수를 알아보기
pd.value_counts(train['year']).sort_index()
.sort_index()는 연도순대로 출력하기 위해 호출하였습니다.
groupby()를 사용하는 방법은 아래, 월별 범죄횟수를 출력할 때 확인해보겠습니다.
-
월별(month) 범죄 발생 횟수를 알아보기
1) value_counts를 사용하는 방법
pd.value_counts(train['month']).sort_index()
[결과]
1 73536 2 70813 3 76320 4 78096 5 79644 6 70892 7 69971 8 68540 9 71982 10 80274 11 72975 12 65006 Name: month, dtype: int64
2) groupby를 사용하는 방법
train.groupby('month').size()
[결과]
1 73536
2 70813
3 76320
4 78096
5 79644
6 70892
7 69971
8 68540
9 71982
10 80274
11 72975
12 65006
dtype: int64
train 데이터필드를 'month' 필드를 기준으로 그룹핑하고, 그룹별 개수를 출력하기 위해 .size()를 호출합니다.
-
요일별(DayOfWeek) 범죄 발생 횟수를 알아보기
pd.value_counts(train['DayOfWeek'])
-
카테고리별(Category) 범죄 발생 횟수를 알아보기
pd.value_counts(train['Category'])
-
null값이 포함된 데이터 필드가 있는지 확인하기
df.isnull().any().sum()
데이터 시각화
-
라이브러리 import
import seaborn as sns import matplotlib.pylab as plt
- 월별 범죄율 시각화하기
sns.barplot(x=train.groupby('month').size().index, y=train.groupby('month').size().values -62500)
sns.barplot(x=train.groupby('year').size().index, y=train.groupby('year').size().values - 40000)
sns.barplot(x=train.groupby('day').size().index, y=train.groupby('day').size().values)
sns.barplot(x=train.groupby('dayofweek').size().index, y=train.groupby('dayofweek').size().values - 110000)
plt.subplots(figsize = (20,12))
sns.barplot(x=train.groupby('Category').size().index, y=train.groupby('Category').size().values)
plt.xticks(rotation=70)
데이터 삭제하기(delete)
-
'Dates','Category','Descript','DayOfWeek','Resolution' 컬럼 삭제하기
train = train.drop(['Dates','Category','Descript','DayOfWeek','Resolution'], axis=1)
학습용, 테스트용 데이터 셋 분리하기
1.
from sklearn.model_selection import train_test_split
x_train, x_valid, y_train, y_valid = train_test_split(train, y, test_size=0.2, random_state = 5, stratify = y)
'Kaggle·데이터분석예제' 카테고리의 다른 글
[Kaggle][문제]강아지 품종 분류(dog-breed-identification) (0) | 2020.07.20 |
---|---|
[파시데]파이썬 기본 연습문제 (4) | 2020.07.20 |
[Kaggle][문제]타이타닉(titanic) (0) | 2020.07.20 |
[Kaggle][답]타이타닉(titanic) (0) | 2020.07.20 |
[Kaggle][문제]샌프란시스코 범죄 예측(sf-crime) (0) | 2020.07.19 |