Kaggle比赛San Francisco Crime Classification分析

题目参见San Francisco Crime Classification

这里简要介绍下这个题目的注意事项:

  1. 多分类。为每个类输出相应类的概率
  2. 评估的时候使用的是multi-class log loss

特征工程

无疑,当前使用的是最原始的特征。我们并未对特征进行一定的调整,而是粗暴的直接拿来使用。

目前特征分成以下几类:

  • 时间类,包括月份、天、时、具体星期几
  • 地址类,包括经纬度以及所在辖区

Baseline Model

import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
from sklearn.model_selection import cross_val_score
from sklearn import linear_model
from sklearn import metrics
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import GridSearchCV



targets = ['ARSON', 'ASSAULT', 'BAD CHECKS', 'BRIBERY', 'BURGLARY',
     'DISORDERLY CONDUCT', 'DRIVING UNDER THE INFLUENCE', 'DRUG/NARCOTIC',
     'DRUNKENNESS', 'EMBEZZLEMENT', 'EXTORTION', 'FAMILY OFFENSES',
     'FORGERY/COUNTERFEITING', 'FRAUD', 'GAMBLING', 'KIDNAPPING',
     'LARCENY/THEFT', 'LIQUOR LAWS', 'LOITERING', 'MISSING PERSON',
     'NON-CRIMINAL', 'OTHER OFFENSES', 'PORNOGRAPHY/OBSCENE MAT',
     'PROSTITUTION', 'RECOVERED VEHICLE', 'ROBBERY', 'RUNAWAY',
     'SECONDARY CODES', 'SEX OFFENSES FORCIBLE', 'SEX OFFENSES NON FORCIBLE',
     'STOLEN PROPERTY', 'SUICIDE', 'SUSPICIOUS OCC', 'TREA', 'TRESPASS',
     'VANDALISM', 'VEHICLE THEFT', 'WARRANTS', 'WEAPON LAWS']

def feature_engineer(data):
  data["Month"] = data["Dates"].map(lambda x: int(x[5:7]))
  data["Day"] = data["Dates"].map(lambda x:int(x[8:10]))
  data["Hour"] = data["Dates"].map(lambda x:int(x[11:13]))
  data["District_No"] = data["PdDistrict"].map(lambda x:districts[x])
  data["Weekday"] = data["DayOfWeek"].map(lambda x:weekdays[x])
  return data



train = pd.read_csv("/Users/maodou/Desktop/crimeclass/train.csv")
test = pd.read_csv("/Users/maodou/Desktop/crimeclass/test.csv")
districts = {c:i for i,c in enumerate(train['PdDistrict'].unique())}
weekdays = {c:i for i,c in enumerate(train['DayOfWeek'].unique())}

train = feature_engineer(train)
train["targets"] = train["Category"].map(lambda x:targets.index(x))
test = feature_engineer(test)

X_all = ["Month", "Day", "Hour", "Weekday", "District_No", "X", "Y"]

forest = RandomForestClassifier(n_estimators=100).fit(train[X_all],train['targets'])
result = forest.predict_proba(test[X_all])

submission = pd.DataFrame({targets[p] : [result[i][p] for i in range(len(result))] for p in range(len(result[0]))})

submission['Id'] = [i for i in range(len(submission))]

submission.to_csv("submission_idx_baseline_tuning.csv.gz", index=False, compression='gzip')

这个模型结果3.8分。不够好。下面将优化。

Baseline代码中的几个Tricks

  1. 从最终predict出来的矩阵转到submission中的multi-class的DataFrame
submission = pd.DataFrame({targets[p] : [result[i][p] for i in range(len(result))] for p in range(len(result[0]))})

一句话初始化转换。
如果使用多重for循环,先默认初始化再复制的形式,会导致运行时间大大增长

  1. 单独定义feature_engineer函数,避免混乱的train和test同时变换
  2. 通过选择train中的指定列来定义训练数据,避免重新构造新的data frame。直接train[X_selected]即可只选择X_selected中选定的列数组

调参

RandomForest调参

RandomForest大部分参数使用默认的参数即可。涉及到调参的主要是以下几个:

  • n_estimators : 森林中树的个数, 一般来说树的个数越多越好。故该参数应该设置成能设置的最大值,不需要重新搜索
  • max_depth : 树的深度 一般设置为10到100之间
  • min_samples_split : 向下继续分支的最小样本数
  • max_features : 每颗树使用的特征数(log2, sqrt(auto), 等)

使用GridSearchCV来搜索最佳值

params = {"max_features":("log2", "sqrt")}

gsearch = GridSearchCV(estimator=RandomForestClassifier(n_estimators=100, max_depth=10, min_samples_split=100), param_grid = params, scoring = "neg_log_loss")
gsearch.fit(train[X_all], train["targets"])

print(gsearch.grid_scores_)

print("best params")

print(gsearch.best_params_)

print("best scores")

print(gsearch.best_score_)

这样逐个确认最佳参数。局部最优值不代表全局,可目前只能用这个方法啦。

最终使用参数如下:

  forest = RandomForestClassifier(n_estimators=100, max_depth=10, min_samples_split=100, max_features="log2", oob_score=True).fit(train[X_all],train['targets'])

得分2.4 , 大大提高了排名。

对比

优化点 Score
RF默认 3.84746
不使用街角特征 2.43471
不变换经度纬度&不使用街角特征 2.4061
不变换经度纬度&不使用街角特征&不变换Hour 2.40072

使用KNN进行预测

主体代码一样,关键代码如下:

knn = KNeighborsClassifier(n_neighbors = 4, weights = 'uniform').fit(train[X_all], train["targets"])
result = knn.predict_proba(test[X_all])

最终效果,得分21.48253。

简直不可接受啊!!!!

现在进行调参。

这个n_neighbors参数很多文章说使用3到5就行了。但经试验,发现这个值会对模型结果影响特别大。

params = {"n_neighbors": range(100 , 801, 100)}

gsearch = GridSearchCV(estimator=KNeighborsClassifier( weights = 'uniform'), param_grid = params , scoring = "neg_log_loss")

gsearch.fit(train[X_all], train["targets"])

print(gsearch.grid_scores_)

print("best params")

print(gsearch.best_params_)

print("best scores")

print(gsearch.best_score_)

在该实验中,发现n_neighbors取到800能达到更好的效果。public score能到2.77分。目前该值还是越大越好。因为本人电脑性能问题,暂不对n_neighbors的最优值进行探索

通过对KNN和RF的对比可以发现,使用不同的算法,很可能会大大影响到找到使模型快速收敛到最佳状态的参数

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,470评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,393评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,577评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,176评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,189评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,155评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,041评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,903评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,319评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,539评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,703评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,417评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,013评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,664评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,818评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,711评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,601评论 2 353

推荐阅读更多精彩内容