下载地址为:https://www.kaggle.com/c/sf-crime/data。
将train.csv放到和python文件的同级目录下,便于使用。
(1)导入需要的模块和包。
import pandas as pd
from sklearn import *
(2)读取文件。
train_df = pd.read_csv('train.csv')
(3)读取文件内容如下:
观察上图数据集,有日期、犯罪种类、描述、星期几、解决方案、地址及XY坐标等多列。我们将“犯罪类别”设置为类别,同时这里不将“罪行描述”、“X/Y坐标”、“结果”作为其特征。
sklearn提供了三种朴素贝叶斯模型,选择一个最适合的作为旧金山的犯罪预测。
模型名称 | 数据分布 | 特征特点 |
---|---|---|
GaussianNB(高斯朴素贝叶斯模型) | 连续式数据 | 特征的数据连续 |
BernoulliNB(伯努利朴素贝叶斯模型) | 离散式数据 | 所有特征必须0或1,表示出现或不出现 |
MultinomialNB(多项式朴素贝叶斯模型) | 离散式数据 | 适用于文本分类,计算某些词出现的频率 |
分析:
(1)高斯朴素贝叶斯模型适合连续数据,因为样本各特征都是离散特征所以不适合用此模型。
(2)伯努利朴素贝叶斯模型和多项式朴素贝叶斯模型都适合离散式数据,因为旧金山犯罪是个典型的伯努利分布,所以选择伯努利朴素贝叶斯模型。
le = preprocessing.LabelEncoder()
crime_type_encode = le.fit_transform(train_df['Category'])
哑变量:将不能定量处理的变量量化,构造只取“0”或“1”的人工变量,适合伯努利朴素贝叶斯模型。
例如将下图天气情况转换成哑变量:
hour = pd.to_datetime(train_df['Dates']).dt.hour # 从Dates列中抽取小时时间
# 将小时(0-24),星期(周一-周日) ,所属警区的特征使用pandas库的get_dummies()功能因子化,得到哑变量(dummy_variable)
hour = pd.get_dummies(hour)
day = pd.get_dummies(train_df['DayOfWeek'])
police_district = pd.get_dummies(train_df['PdDistrict'])
将三个特征功能因子化后如下:
(1)日期:
(2)警区:
(3)时间:
train_set = pd.concat([hour, day, police_district], axis = 1) # 将特征组合成一个DataFrame
合并完如下:
train_set['Crime type'] = crime_type_encode # 向特征组成的DataFrame添加新的一列类别
合并完如下:
from sklearn.model_selection import train_test_split
X = train_set.loc[:, train_set.columns != 'Crime type']
y = train_set['Crime type']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state=1)
数据集的划分如下:
from sklearn.naive_bayes import BernoulliNB
model = BernoulliNB()
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
print("model accuracy:", metrics.accuracy_score(y_test, y_pred))
model accuracy: 0.22405051181479002
最终预测值为22%左右。结果表明:在旧金山,任何一天,任何一小时,任何一片警区,我们知道它会发生39种犯罪类型的哪一种的准确率在22%左右。