Python数据分析案例28——西雅图交通事故预测(不平衡样本处理)
本次案例適合機(jī)器學(xué)習(xí)數(shù)據(jù)科學(xué)方向的同學(xué)。
?引言(廢話(huà)集)
交通事故是一個(gè)嚴(yán)重的公共安全問(wèn)題,在全球范圍內(nèi)每年都有成千上萬(wàn)的人死于交通事故。隨著交通運(yùn)輸?shù)陌l(fā)展和城市化進(jìn)程的加速,交通事故已成為制約城市發(fā)展和人民幸福的主要因素之一。因此,通過(guò)分析交通事故的原因和嚴(yán)重程度,以及開(kāi)發(fā)有效的預(yù)測(cè)模型,可以有效預(yù)防交通事故的發(fā)生,并減少交通事故對(duì)人類(lèi)社會(huì)的危害。
本研究的目標(biāo)是通過(guò)機(jī)器學(xué)習(xí)模型預(yù)測(cè)交通事故的嚴(yán)重程度,以保護(hù)城市居民免受交通事故的嚴(yán)重傷害并防止交通碰撞。為了實(shí)現(xiàn)這一目標(biāo),我們將分析影響交通事故嚴(yán)重程度的各種因素,并建立一個(gè)準(zhǔn)確、可靠的預(yù)測(cè)模型。
目前,人們通常依靠經(jīng)驗(yàn)和統(tǒng)計(jì)數(shù)據(jù)來(lái)評(píng)估交通事故的嚴(yán)重程度。但是,這種方法的缺點(diǎn)是可能存在主觀性和局限性,無(wú)法準(zhǔn)確預(yù)測(cè)交通事故的發(fā)生和嚴(yán)重程度。相比之下,機(jī)器學(xué)習(xí)模型可以自動(dòng)學(xué)習(xí)和優(yōu)化模型,以最大程度地準(zhǔn)確預(yù)測(cè)交通事故的嚴(yán)重程度。本研究旨在比較當(dāng)前解決方案和我們提出的解決方案之間的優(yōu)缺點(diǎn),以證明機(jī)器學(xué)習(xí)模型在交通事故預(yù)測(cè)方面的優(yōu)勢(shì)。
最后,我們將通過(guò)分析西雅圖市10年內(nèi)的交通事故數(shù)據(jù)來(lái)提供支持我們研究的證據(jù),我們的響應(yīng)變量y是SEVERITYCODE(事故嚴(yán)重程度代碼)。因?yàn)樵谝粋€(gè)交通事故中,事故嚴(yán)重程度是我們最關(guān)心的問(wèn)題,也是我們希望能夠預(yù)測(cè)的目標(biāo)變量。其他列則可能作為預(yù)測(cè)變量x,幫助我們預(yù)測(cè)事故嚴(yán)重程度。本研究將為西雅圖交通政府制定更有效的交通事故預(yù)防措施和政策提供科學(xué)依據(jù)。
導(dǎo)入包
#導(dǎo)入數(shù)據(jù)分析常用包 import numpy as np import pandas as pd import matplotlib.pyplot as plt import seaborn as sns %matplotlib inline plt.rcParams['axes.unicode_minus'] = False #負(fù)號(hào)數(shù)據(jù)探索
# 讀取數(shù)據(jù) data=pd.read_csv('Collisions.csv',na_values='Unknown') #查看數(shù)據(jù)前三行 data.head(3) #自動(dòng)解析數(shù)據(jù)類(lèi)型 data=data.infer_objects() #查看數(shù)據(jù)信息 data.info()?
?#變量含義
'''OBJECTID:事故對(duì)象的標(biāo)識(shí)符
INCKEY:內(nèi)部事故唯一鍵
COLDETKEY:采集數(shù)據(jù)的標(biāo)識(shí)符
REPORTNO:事故報(bào)告號(hào)
STATUS:事故處理狀態(tài)
ADDRTYPE:地址類(lèi)型
INTKEY:十字路口標(biāo)識(shí)符
LOCATION:事故位置
EXCEPTRSNCODE:例外原因代碼
EXCEPTRSNDESC:例外原因描述
SEVERITYCODE:事故嚴(yán)重程度代碼
SEVERITYDESC:事故嚴(yán)重程度描述
COLLISIONTYPE:碰撞類(lèi)型
PERSONCOUNT:涉及的人數(shù)
PEDCOUNT:行人數(shù)量
PEDCYLCOUNT:自行車(chē)數(shù)量
VEHCOUNT:涉及的車(chē)輛數(shù)量
INJURIES:受傷人數(shù)
SERIOUSINJURIES:嚴(yán)重受傷人數(shù)
FATALITIES:死亡人數(shù)
INCDATE:事故發(fā)生日期
INCDTTM:事故發(fā)生日期和時(shí)間
JUNCTIONTYPE:交叉口類(lèi)型
SDOT_COLCODE:SDOT收集的事故代碼
SDOT_COLDESC:SDOT收集的事故描述
INATTENTIONIND:不注意標(biāo)記
UNDERINFL:受到駕駛員的影響
WEATHER:天氣狀況
ROADCOND:道路條件
LIGHTCOND:光線(xiàn)條件
PEDROWNOTGRNT:行人未被授予權(quán)利
SDOTCOLNUM:SDOT收集的事故編號(hào)
SPEEDING:超速行駛
ST_COLCODE:州事故代碼
ST_COLDESC:州事故描述
SEGLANEKEY:分段車(chē)道關(guān)鍵字
CROSSWALKKEY:人行橫道關(guān)鍵字
HITPARKEDCAR:是否碰撞停放的車(chē)輛'''
數(shù)據(jù)預(yù)處理?
特征預(yù)處理
'''OBJECTID,INCKEY,COLDETKEY,REPORTNO''' #這四個(gè)變量是取值唯一的編號(hào)型變量,對(duì)于模型沒(méi)有幫助,刪除 data.drop(columns=['OBJECTID','INCKEY','COLDETKEY','REPORTNO'],inplace=True)#若是有一行全為空值就刪除?
data.dropna(how='all',inplace=True)#取值唯一的變量刪除 ?(如果有一列的值全部一樣,也就是取值唯一的特征變量就可以刪除了,因?yàn)槊總€(gè)樣本沒(méi)啥區(qū)別,對(duì)模型就沒(méi)啥用)?
for col in data.columns:if len(data[col].value_counts())==1:print(col)data.drop(col,axis=1,inplace=True)?#缺失到一定比例就刪除,缺失量達(dá)到一定程度就給他刪了,缺失太多不如不要這個(gè)特征。我這里的比例是20%?
miss_ratio=0.2 for col in data.columns:if data[col].isnull().sum()>data.shape[0]*miss_ratio:print(col)data.drop(col,axis=1,inplace=True)總共38個(gè)變量,現(xiàn)在已經(jīng)刪除了11個(gè)了
然后需要對(duì)數(shù)據(jù)進(jìn)一步細(xì)化處理,要把數(shù)據(jù)分為數(shù)值型和其他類(lèi)型來(lái)看。
首先查看數(shù)值型數(shù)據(jù)
數(shù)值型變量預(yù)處理
#查看數(shù)值型數(shù)據(jù), pd.set_option('display.max_columns', 20) data.select_dtypes(exclude=['object']).head()?
做機(jī)器學(xué)習(xí)當(dāng)然需要特征越分散越好,因?yàn)檫@樣就可以在X上更加有區(qū)分度,從而更好的分類(lèi)。
所以那些數(shù)據(jù)分布很集中的變量可以扔掉。
可以用方差,但是由于數(shù)據(jù)的口徑大小不一致,方差不好對(duì)比,
這里我們采用異眾比例來(lái)衡量數(shù)據(jù)的分散程度,若異眾比例低于0.02就刪除
#計(jì)算異眾比例 variation_ratio_s=0.02 for col in data.select_dtypes(exclude=['object']).columns:df_count=data[col].value_counts()kind=df_count.index[0]variation_ratio=1-(df_count.iloc[0]/len(data[col]))if variation_ratio<variation_ratio_s:print(f'{col} 最多的取值為{kind},異眾比例為{round(variation_ratio,4)},太小了,沒(méi)區(qū)分度需要?jiǎng)h掉')#data.drop(col,axis=1,inplace=True)我們發(fā)現(xiàn)SERIOUSINJURIES,FATALITIES,SEGLANEKEY ,CROSSWALKKEY 四個(gè)變量的異眾比例是很小的,大部分取值都是0。
但是SERIOUSINJURIES 嚴(yán)重受傷程度 和FATALITIES 死亡數(shù)量都是對(duì)于交通嚴(yán)重程度很多有的變量,我們選擇保留他們。
而SEGLANEKEY和CROSSWALKKEY 是路段ID和人行橫道ID,對(duì)于預(yù)測(cè)作用應(yīng)該不大,選擇刪除。
##刪除 SEGLANEKEY和CROSSWALKKEY data.drop(columns=['SEGLANEKEY','CROSSWALKKEY'],inplace=True)object型變量預(yù)處理
查看非數(shù)值變量前三行?
data.select_dtypes(include=['object']).head(3) 'LOCATION','SDOT_COLDESC','ST_COLCODE','ST_COLDESC', #這四個(gè)變量都是針對(duì)這個(gè)事件的具體描述,有的是文本類(lèi)型,做不了特征變量,刪除 'SEVERITYDESC','STATUS','SDOT_COLCODE' #這幾個(gè)變量對(duì)于交通嚴(yán)重程度沒(méi)有解釋作用,也刪除 data.drop(columns=['LOCATION','SDOT_COLDESC','ST_COLCODE','ST_COLDESC','SEVERITYDESC','STATUS','SDOT_COLCODE'],inplace=True)填充缺失值
1.刪除缺失值:對(duì)于一些缺失值的行比較少的變量可以直接刪除缺失值的行樣本。
可以看出我們的響應(yīng)變量SEVERITYCODE存在缺失值,而且只有一個(gè)缺失值,刪掉這個(gè)缺失值不會(huì)對(duì)數(shù)據(jù)整體造成太大的影響,
而且缺失值可能會(huì)對(duì)后續(xù)的建模和分析產(chǎn)生干擾和誤差,因此在這種情況下,我們可以直接刪除存在缺失值的行。
2.其他變量填充缺失值:
(1)對(duì)于類(lèi)別變量(如ADDRTYPE, COLLISIONTYPE, JUNCTIONTYPE, UNDERINFL, WEATHER, ROADCOND, LIGHTCOND)可以使用眾數(shù)進(jìn)行填充。
# 刪除缺失值 data.dropna(subset=['SEVERITYCODE'], inplace=True)# 類(lèi)別變量填充眾數(shù) data['ADDRTYPE'].fillna(data['ADDRTYPE'].mode()[0], inplace=True) data['COLLISIONTYPE'].fillna(data['COLLISIONTYPE'].mode()[0], inplace=True) data['JUNCTIONTYPE'].fillna(data['JUNCTIONTYPE'].mode()[0], inplace=True) data['UNDERINFL'].fillna(data['UNDERINFL'].mode()[0], inplace=True) data['WEATHER'].fillna(data['WEATHER'].mode()[0], inplace=True) data['ROADCOND'].fillna(data['ROADCOND'].mode()[0], inplace=True) data['LIGHTCOND'].fillna(data['LIGHTCOND'].mode()[0], inplace=True)特征工程
兩個(gè)時(shí)間變量進(jìn)行轉(zhuǎn)化,變?yōu)闀r(shí)間的格式
data['INCDTTM'] = pd.to_datetime(data['INCDTTM']) data['INCDATE'] = pd.to_datetime(data['INCDATE'])?INCDTTM變量包含小時(shí),更為詳細(xì),對(duì)INCDTTM這個(gè)變量里面提取時(shí)間特征就行,我們提取這個(gè)事故發(fā)生的年,月,小時(shí)。因?yàn)槿湛赡軟](méi)有明顯的含義,而月份代表季節(jié)性,小時(shí)代表每天的交通事故發(fā)生的可能性最大的時(shí)刻,所以選擇年,月,小時(shí)三個(gè)作為新特征
data['year']=data['INCDTTM'].dt.year data['month']=data['INCDTTM'].dt.year data['hour']=data['INCDTTM'].dt.hour構(gòu)建了新特征后,原來(lái)的特征不要的就刪除
data.drop(columns=['INCDTTM','INCDATE'],inplace=True)UNDERINFL中有重復(fù)含義變量,需要進(jìn)行處理
#將0變?yōu)镹,1變?yōu)閅 data['UNDERINFL']=data['UNDERINFL'].map({'N':'N','0':'N','Y':'Y','1':'Y'})#查看處理完的數(shù)據(jù)信息
?
沒(méi)有缺失值了。
#首先對(duì)訓(xùn)練集取出y y=data['SEVERITYCODE'] data.drop(['SEVERITYCODE'],axis=1,inplace=True)?##查看分類(lèi)變量的每個(gè)變量分為幾類(lèi)
for col in data.select_dtypes(include=['object']).columns:print(f"{col}變量有{len(data[col].unique())}類(lèi)")數(shù)據(jù)探索?
?數(shù)值型變量畫(huà)圖
#查看特征變量的箱線(xiàn)圖分布 columns = data.select_dtypes(exclude=['object']).columns.tolist() # 列表頭 dis_cols = 4 #一行幾個(gè) dis_rows = len(columns) plt.figure(figsize=(4 * dis_cols, 4 * dis_rows),dpi=128) for i in range(len(columns)):plt.subplot(dis_rows,dis_cols,i+1)sns.boxplot(data=data[columns[i]], orient="v",width=0.5)plt.xlabel(columns[i],fontsize = 20) plt.tight_layout() #plt.savefig('特征變量箱線(xiàn)圖',formate='png',dpi=500) plt.show() #畫(huà)密度圖,訓(xùn)練集和測(cè)試集對(duì)比 dis_cols = 4 #一行幾個(gè) dis_rows = len(columns) plt.figure(figsize=(4 * dis_cols, 4 * dis_rows),dpi=128)for i in range(len(columns)):ax = plt.subplot(dis_rows, dis_cols, i+1)ax = sns.kdeplot(data[columns[i]], color="Red" ,fill=True)ax.set_xlabel(columns[i],fontsize = 20)ax.set_ylabel("Frequency",fontsize = 18) plt.tight_layout() #plt.savefig('訓(xùn)練測(cè)試特征變量核密度圖',formate='png',dpi=500) plt.show()?
分類(lèi)型變量畫(huà)圖
#查看特征變量的箱線(xiàn)圖分布 columns = data.select_dtypes(include=['object']).columns.tolist() # 列表頭 dis_cols = 3 #一行幾個(gè) dis_rows = len(columns) plt.figure(figsize=(5 * dis_cols, 5 * dis_rows),dpi=128) for i in range(len(columns)):plt.subplot(dis_rows,dis_cols,i+1)sns.barplot(x=data[columns[i]].value_counts().index, y=data[columns[i]].value_counts().values)#sns.barplot(data=data[columns[i]].value_counts(), orient="v",width=0.5)plt.xlabel(columns[i],fontsize = 15)plt.xticks(rotation=45) plt.tight_layout() #plt.savefig('特征變量箱線(xiàn)圖',formate='png',dpi=500) plt.show()相關(guān)性分析
#畫(huà)出數(shù)值型變量之間的相關(guān)性 corr = plt.subplots(figsize = (18,16),dpi=128) corr= sns.heatmap(data.corr(method='spearman'),annot=True,square=True)?
?分類(lèi)變量進(jìn)行獨(dú)立熱編碼
#很多x都是文本型分類(lèi)變量,所以要進(jìn)行的獨(dú)立熱編碼處理
data=pd.get_dummies(data) data.shape查看響應(yīng)變量的分布?
y.value_counts()可視化?
# 查看y的分布 #分類(lèi)問(wèn)題 plt.figure(figsize=(8,3),dpi=128) plt.subplot(1,2,1) y.value_counts().plot.bar(title='Response variable histogram graph') plt.subplot(1,2,2) y.value_counts().plot.pie(title='Response Variable Pie Chart') #plt.savefig('響應(yīng)變量.png') plt.tight_layout() plt.show()?
?##響應(yīng)變量數(shù)據(jù)分布存在極度的不平衡情況,我們將0,1,2,2b四組情況映射為0,? 3(表示交通事故很?chē)?yán)重)映射為1,表示是一個(gè)二分類(lèi)問(wèn)題
y=y.map({'0':0,'1':0,'2':0,'2b':0,'3':1}) y.value_counts()下面對(duì)y進(jìn)行類(lèi)別平衡處理
在處理極度不平衡的分類(lèi)樣本時(shí),可以考慮以下幾種方法: 欠采樣(Undersampling):從多數(shù)類(lèi)別中隨機(jī)選擇一部分樣本,使得多數(shù)類(lèi)別的樣本數(shù)量與少數(shù)類(lèi)別的樣本數(shù)量相近。這種方法的優(yōu)點(diǎn)是簡(jiǎn)單快捷,但可能會(huì)丟失一些有用信息。
過(guò)采樣(Oversampling):從少數(shù)類(lèi)別中隨機(jī)復(fù)制一些樣本,使得少數(shù)類(lèi)別的樣本數(shù)量與多數(shù)類(lèi)別的樣本數(shù)量相近。這種方法的優(yōu)點(diǎn)是可以充分利用數(shù)據(jù)集,但可能會(huì)導(dǎo)致過(guò)擬合。
SMOTE(Synthetic Minority Over-sampling Technique)算法:是一種常用的過(guò)采樣方法,它通過(guò)對(duì)少數(shù)類(lèi)別樣本進(jìn)行插值生成新的樣本來(lái)擴(kuò)充數(shù)據(jù)集。這種方法可以有效地避免過(guò)擬合問(wèn)題。
混合采樣(Mixed Sampling):結(jié)合欠采樣和過(guò)采樣的優(yōu)點(diǎn),既可以減少數(shù)據(jù)量,又可以充分利用數(shù)據(jù)集??梢韵冗M(jìn)行欠采樣,然后再對(duì)欠采樣后的數(shù)據(jù)進(jìn)行過(guò)采樣。
我們首先對(duì)樣本少的進(jìn)行上采樣
from imblearn.over_sampling import RandomOverSampler os=RandomOverSampler(sampling_strategy=0.0025) X_train_ns,y_train_ns=os.fit_resample(data,y) print("The number of classes before fit {}".format(y.value_counts().to_dict())) print("The number of classes after fit {}".format(y_train_ns.value_counts().to_dict()))?
將y為1的樣本增加到599個(gè)
再對(duì)樣本多的進(jìn)行下采樣,比例為0.2,即0類(lèi)數(shù)量8成,1類(lèi)數(shù)量2成。雖然也不平衡,但是比剛剛那個(gè)好多了。。也能訓(xùn)練了。
from imblearn.under_sampling import RandomUnderSampler rus = RandomUnderSampler(sampling_strategy=0.2) X_resampled, y_resampled = rus.fit_resample(X_train_ns, y_train_ns) X_train_ns2,y_train_ns2=rus.fit_resample(X_train_ns,y_train_ns) print("The number of classes before fit {}".format(y_train_ns.value_counts().to_dict())) print("The number of classes after fit {}".format(y_train_ns2.value_counts().to_dict()))?查看現(xiàn)在的數(shù)據(jù)形狀
print(X_train_ns2.shape,y_train_ns2.shape)一共3594個(gè)樣本,其中0類(lèi)有2995條,1類(lèi)有599條,x特征變量的個(gè)數(shù)有57個(gè)?
算法實(shí)現(xiàn)
#劃分訓(xùn)練集和測(cè)試集,查看他們的形狀 from sklearn.model_selection import train_test_split X_train,X_test,y_train,y_test=train_test_split(X_train_ns2,y_train_ns2,stratify=y_train_ns2,test_size=0.2,random_state=0) print(X_train.shape,X_test.shape,y_train.shape,y_test.shape)?
#數(shù)據(jù)標(biāo)準(zhǔn)化 from sklearn.preprocessing import StandardScaler scaler = StandardScaler() scaler.fit(X_train) X_train_s = scaler.transform(X_train) X_test_s = scaler.transform(X_test) print('訓(xùn)練數(shù)據(jù)形狀:') print(X_train_s.shape,y_train.shape) print('測(cè)試數(shù)據(jù)形狀:') print(X_test_s.shape,y_test.shape)上述代碼是先劃分訓(xùn)練集和測(cè)試集,測(cè)試集的比例為20%,隨機(jī)數(shù)種子為0。然后進(jìn)行數(shù)據(jù)的標(biāo)準(zhǔn)化, 打印查看訓(xùn)練集數(shù)據(jù),測(cè)試集數(shù)據(jù)的形狀。 可以看到我們有訓(xùn)練集4598,測(cè)試集1150,特征變量有74個(gè)。
#采用五種模型,對(duì)比驗(yàn)證集精度?
from sklearn.linear_model import LogisticRegression from sklearn.neighbors import KNeighborsClassifier from sklearn.tree import DecisionTreeClassifier from sklearn.ensemble import RandomForestClassifier from sklearn.svm import SVC #邏輯回歸 model1 = LogisticRegression(C=1e10,max_iter=10000)#K近鄰 model2 = KNeighborsClassifier(n_neighbors=10)#決策樹(shù) model3 = DecisionTreeClassifier(random_state=77)#隨機(jī)森林 model4= RandomForestClassifier(n_estimators=1000, max_features='sqrt',random_state=10)#支持向量機(jī) model5 = SVC(kernel="rbf", random_state=77)model_list=[model1,model2,model3,model4,model5] model_name=['Logistic Regression', 'K-Nearest Neighbors', 'Decision Tree', 'Random Forest','Support Vector Machine']評(píng)價(jià)標(biāo)準(zhǔn)
本文是一個(gè)分類(lèi)問(wèn)題,采用四個(gè)分類(lèi)問(wèn)題常用而且可靠的評(píng)價(jià)指標(biāo),準(zhǔn)確率、精確度、召回率和F1值對(duì)模型進(jìn)行全面的評(píng)價(jià)。四個(gè)指標(biāo)的計(jì)算公式如下
計(jì)算所有評(píng)價(jià)指標(biāo),定義評(píng)估函數(shù)
from sklearn.metrics import confusion_matrix from sklearn.metrics import classification_report from sklearn.metrics import cohen_kappa_score from sklearn.model_selection import KFold def evaluation(y_test, y_predict):accuracy=classification_report(y_test, y_predict,output_dict=True)['accuracy']s=classification_report(y_test, y_predict,output_dict=True)['weighted avg']precision=s['precision']recall=s['recall']f1_score=s['f1-score']#kappa=cohen_kappa_score(y_test, y_predict)return accuracy,precision,recall,f1_score #, kappa def evaluation2(lis):array=np.array(lis)return array.mean() , array.std() df_eval=pd.DataFrame(columns=['Accuracy','Precision','Recall','F1_score']) for i in range(5):model_C=model_list[i]name=model_name[i]print(f'{name}模型擬合完成')model_C.fit(X_train_s, y_train)pred=model_C.predict(X_test_s)s=classification_report(y_test, pred)s=evaluation(y_test,pred)df_eval.loc[name,:]=list(s) df_eval?
bar_width = 0.4 colors=['c', 'b', 'g', 'tomato', 'm', 'y', 'lime', 'k','orange','pink','grey','tan'] fig, ax = plt.subplots(2,2,figsize=(10,8),dpi=128) for i,col in enumerate(df_eval.columns):n=int(str('22')+str(i+1))plt.subplot(n)df_col=df_eval[col]m =np.arange(len(df_col))plt.bar(x=m,height=df_col.to_numpy(),width=bar_width,color=colors)#plt.xlabel('Methods',fontsize=12)names=df_col.indexplt.xticks(range(len(df_col)),names,fontsize=10)plt.xticks(rotation=40)plt.ylabel(col,fontsize=14)plt.tight_layout() #plt.savefig('柱狀圖.jpg',dpi=512) plt.show()?
?可以看到上面隨機(jī)森林模型效果最好
下面對(duì)隨機(jī)森林模型進(jìn)一步進(jìn)行超參數(shù)搜索
#利用K折交叉驗(yàn)證搜索最優(yōu)超參數(shù) from sklearn.model_selection import KFold, StratifiedKFold from sklearn.model_selection import GridSearchCV,RandomizedSearchCV管道流,網(wǎng)格化搜索?
from sklearn.pipeline import Pipeline steps = [('standardize', StandardScaler()), ('model',RandomForestClassifier(max_features='sqrt',random_state=10) ) ]RF_pipe = Pipeline( steps = steps )param_distributions = {'model__max_depth': range(2, 9),'model__n_estimators': [250,500,750,1000,1500,2000]}model= GridSearchCV( RF_pipe, param_distributions, n_jobs = 6, cv = KFold(n_splits=3, shuffle=True, random_state=0) )查看這個(gè)管道里面的參數(shù)
RF_pipe.get_params()['model'].get_params().keys()擬合模型?
model.fit(X_train,y_train)?
#查看模型最好的參數(shù)和準(zhǔn)確率 print(f" best param: {model.best_params_},accuary:{model.best_score_}" ) #將最好的參數(shù)賦值給模型 model = model.best_estimator_ pred=model.predict(X_test_s) s=evaluation(y_test,pred) print(f'Acc: {s[0]}, Prec: {s[1]}, Recall: {s[2]}, F1:{s[3]}')?
#準(zhǔn)確率、精確度、召回率和F1值
RF_s=evaluation(model.predict(data),y) RF_s?
?結(jié)論
模型的比較等等,在這個(gè)分類(lèi)問(wèn)題上,隨機(jī)森林效果最好,其次是支持向量機(jī)和邏輯回歸
本案例的局限性在于y取值為1的數(shù)據(jù)樣本量太少,上采樣多了可能會(huì)導(dǎo)致模型過(guò)擬合等等
?變量重要性
#使用所有數(shù)據(jù)訓(xùn)練 model=RandomForestClassifier(max_depth= 8,n_estimators=2000,max_features='sqrt',random_state=10) #使用前面的最優(yōu)參數(shù) model.fit(np.array(data),y) pred=model.predict(np.array(data)) s=evaluation(y,pred) print(f'Acc: {s[0]}, Prec: {s[1]}, Recall: {s[2]}, F1:{s[3]}') n=10 sorted_index = model.feature_importances_.argsort()[::-1][:n] mfs=model.feature_importances_[sorted_index][:n] plt.figure(figsize=(5,4),dpi=128) sns.barplot(y=np.array(range(len(mfs))),x=mfs,orient='h') plt.yticks(np.arange(data.shape[1])[:n], data.columns[sorted_index][:n]) plt.xlabel('Feature Importance') plt.ylabel('Feature') plt.title('LGBM') plt.show()?
可以看到,PEDCOUNT,COLLISIONTYPE_Pedesttain等變量對(duì)于響應(yīng)變量y的影響程度高,說(shuō)明這個(gè)幾個(gè)變量對(duì)交通事故有顯著性影響
應(yīng)該控制這幾個(gè)變量,來(lái)減少交通事故的嚴(yán)重程度
總結(jié)
以上是生活随笔為你收集整理的Python数据分析案例28——西雅图交通事故预测(不平衡样本处理)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 精益生产管理如何让全体员工养成消除浪费和
- 下一篇: English语法_7大句子成分