泰坦尼克號-數據挖掘項目實戰


一,典型課題研究

建立一個預測模型來回答以下問題:“什么樣的人更有可能生存?

二,數據

1,數據源:https://www.kaggle.com/c/titanic

 

 

 

 

 

 2,用到的庫:

  • Numpy-科學計算庫 主要用來做矩陣運算,什么?你不知道哪里會用到矩陣,那么這樣想吧,咱們的數據就是行(樣本)和列(特征)組成的,那么數據本身不就是一個矩陣嘛。
  • Pandas-數據分析處理庫 很多小伙伴都在說用python處理數據很容易,那么容易在哪呢?其實有了pandas很復雜的操作我們也可以一行代碼去解決掉!
  • Matplotlib-可視化庫 無論是分析還是建模,光靠好記性可不行,很有必要把結果和過程可視化的展示出來。
  • Seaborn-可視化庫 更簡單的可視化庫封裝上Matplot基礎之上。
  • Scikit-Learn-機器學習庫 非常實用的機器學習算法庫,這里面包含了基本你覺得你能用上所有機器學習算法啦。但還遠不止如此,還有很多預處理和評估的模塊等你來挖掘的!

3,導入庫,並查看數據

import numpy as np 
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
plt.style.use('fivethirtyeight') #制定畫圖風格
import warnings
warnings.filterwarnings('ignore') #將警告過濾掉
%matplotlib inline
data=pd.read_csv('train.csv')
data.head()

 

 

 4,字段解釋

PassengerId: 乘客ID
Survived: 是否生存,0代表遇難,1代表還活着
Pclass: 船艙等級:1Upper,2Middle,3Lower
Name: 姓名
Sex: 性別
Age: 年齡
SibSp: 兄弟姐妹及配偶個數
Parch:父母或子女個數
Ticket: 乘客的船票號
Fare: 乘客的船票價
Cabin: 乘客所在的倉位(位置)
Embarked:乘客登船口岸

 三,操作步驟

1,統計缺失值

data.isnull().sum() #統計缺失值

 2,查看整體數據

data.describe()

 3,不是要預測這大船的獲救情況嘛,先看看獲救比例咋樣

f,ax=plt.subplots(1,2,figsize=(18,8))
data['Survived'].value_counts().plot.pie(explode=[0,0.1],autopct='%1.1f%%',ax=ax[0],shadow=True)
ax[0].set_title('Survived')
ax[0].set_ylabel('')
sns.countplot('Survived',data=data,ax=ax[1])
ax[1].set_title('Survived')
plt.show()

 

顯然,這次事故中沒有多少乘客幸免於難。

在訓練集的891名乘客中,只有大約350人幸存下來,只有38.4%的機組人員在空難中幸存下來。我們需要從數據中挖掘出更多的信息,看看哪些類別的乘客幸存下來,哪些沒有。

我們將嘗試使用數據集的不同特性來檢查生存率。比如性別,年齡,登船地點等,但是首先我們得來理解下數據中的特征!

四,特征分析 & 缺失值填充

1性別比例和性別獲救情況

  • 離散值:性別(男,女) 登船地點(S,Q,C)

  • 連續值:年齡,船票價格

data.groupby(['Sex','Survived'])['Survived'].count()#對性別進行分組,並計數

 

 用圖形表示

f,ax=plt.subplots(1,2,figsize=(18,8))
data[['Sex','Survived']].groupby(['Sex']).mean().plot.bar(ax=ax[0])
ax[0].set_title('Survived vs Sex')
sns.countplot('Sex',hue='Survived',data=data,ax=ax[1])
ax[1].set_title('Sex:Survived vs Dead')
plt.show()

 這看起來很有趣。船上的男人比女人多得多。不過,挽救的女性人數幾乎是男性的兩倍。生存率為一個女人在船上是75%左右,而男性在18-19%左右。

這看起來是建模的一個非常重要的特性。一會我們會用上他的!

2,Pclass --> 船艙等級跟獲救情況的關系

pd.crosstab(data.Pclass,data.Survived,margins=True).style.background_gradient(cmap='summer_r')

 用圖形表示

f,ax=plt.subplots(1,2,figsize=(18,8))
data['Pclass'].value_counts().plot.bar(color=['#CD7F32','#FFDF00','#D3D3D3'],ax=ax[0])
ax[0].set_title('Number Of Passengers By Pclass')
ax[0].set_ylabel('Count')
sns.countplot('Pclass',hue='Survived',data=data,ax=ax[1])
ax[1].set_title('Pclass:Survived vs Dead')
plt.show()

人們說金錢不能買到一切。但我們可以清楚地看到,船艙等級為1的被給予很高的優先級而救援。盡管數量在pClass 3乘客高了很多,仍然存活數從他們是非常低的,大約25%。

對於pClass1來說存活是63%左右,而pclass2大約是48%。所以金錢和地位很重要。

3,船艙等級和性別對結果的影響

pd.crosstab([data.Sex,data.Survived],data.Pclass,margins=True).style.background_gradient(cmap='summer_r')

 用圖形表示

sns.factorplot('Pclass','Survived',hue='Sex',data=data)
plt.show()

我們用factorplot這個圖,看起來更直觀一些。

我們可以很容易地推斷,從pclass1女性生存是95-96%,如94人中只有3的女性從pclass1沒獲救。

顯而易見的是,不論pClass,女性優先考慮。

看來Pclass也是一個重要的特征。讓我們分析其他特征

4,Age--> 連續值特征對結果的影響

print('Oldest Passenger was of:',data['Age'].max(),'Years')
print('Youngest Passenger was of:',data['Age'].min(),'Years')
print('Average Age on the ship:',data['Age'].mean(),'Years')

 用圖形表示

f,ax=plt.subplots(1,2,figsize=(18,8))
sns.violinplot("Pclass","Age", hue="Survived", data=data,split=True,ax=ax[0])
ax[0].set_title('Pclass and Age vs Survived')
ax[0].set_yticks(range(0,110,10))
sns.violinplot("Sex","Age", hue="Survived", data=data,split=True,ax=ax[1])
ax[1].set_title('Sex and Age vs Survived')
ax[1].set_yticks(range(0,110,10))
plt.show()

結果:1)10歲以下兒童的存活率隨passenegers數量增加。

2)生存為20-50歲獲救幾率更高一些。

3)對男性來說,隨着年齡的增長,存活率降低。

5,缺失值填充

  • 平均值
  • 經驗值
  • 回歸模型預測
  • 剔除掉

年齡特征有177個空值。為了替換這些缺失值,我們可以給它們分配數據集的平均年齡。

但問題是,有許多不同年齡的人。最好的辦法是找到一個合適的年齡段!

我們可以檢查名字特征。根據這個特征,我們可以看到名字有像先生或夫人這樣的稱呼,這樣我們就可以把先生和夫人的平均值分配給各自的組。

data['Initial']=0
for i in data:
    data['Initial']=data.Name.str.extract('([A-Za-z]+)\.') 

這里我們使用正則表達式:[A-Za-z] +)來提取信息

pd.crosstab(data.Initial,data.Sex).T.style.background_gradient(cmap='summer_r') #用性別核對姓名首字母

 

data['Initial'].replace(['Mlle','Mme','Ms','Dr','Major','Lady','Countess','Jonkheer','Col','Rev','Capt','Sir','Don'],['Miss','Miss','Miss','Mr','Mr','Mrs','Mrs','Other','Other','Other','Mr','Mr','Mr'],inplace=True)
data.groupby('Initial')['Age'].mean()

 填充缺失值

## 使用每組的均值來進行填充
data.loc[(data.Age.isnull())&(data.Initial=='Mr'),'Age']=33
data.loc[(data.Age.isnull())&(data.Initial=='Mrs'),'Age']=36
data.loc[(data.Age.isnull())&(data.Initial=='Master'),'Age']=5
data.loc[(data.Age.isnull())&(data.Initial=='Miss'),'Age']=22
data.loc[(data.Age.isnull())&(data.Initial=='Other'),'Age']=46
data.Age.isnull().any() #看看填充完了咋樣

False

用圖形表示

f,ax=plt.subplots(1,2,figsize=(20,10))
data[data['Survived']==0].Age.plot.hist(ax=ax[0],bins=20,edgecolor='black',color='red')
ax[0].set_title('Survived= 0')
x1=list(range(0,85,5))
ax[0].set_xticks(x1)
data[data['Survived']==1].Age.plot.hist(ax=ax[1],color='green',bins=20,edgecolor='black')
ax[1].set_title('Survived= 1')
x2=list(range(0,85,5))
ax[1].set_xticks(x2)
plt.show()

觀察:

1)幼兒(年齡在5歲以下)獲救的還是蠻多的(婦女和兒童優先政策)。

2)最老的乘客得救了(80年)。

3)死亡人數最高的是30-40歲年齡組。

sns.factorplot('Pclass','Survived',col='Initial',data=data)
plt.show()

6, Embarked--> 登船地點

pd.crosstab([data.Embarked,data.Pclass],[data.Sex,data.Survived],margins=True).style.background_gradient(cmap='summer_r')

sns.factorplot('Embarked','Survived',data=data)
fig=plt.gcf()
fig.set_size_inches(5,3)
plt.show()

 C港生存的可能性最高在0.55左右,而S的生存率最低。

用柱形圖表示

f,ax=plt.subplots(2,2,figsize=(20,15))
sns.countplot('Embarked',data=data,ax=ax[0,0])
ax[0,0].set_title('No. Of Passengers Boarded')
sns.countplot('Embarked',hue='Sex',data=data,ax=ax[0,1])
ax[0,1].set_title('Male-Female Split for Embarked')
sns.countplot('Embarked',hue='Survived',data=data,ax=ax[1,0])
ax[1,0].set_title('Embarked vs Survived')
sns.countplot('Embarked',hue='Pclass',data=data,ax=ax[1,1])
ax[1,1].set_title('Embarked vs Pclass')
plt.subplots_adjust(wspace=0.2,hspace=0.5)
plt.show()

觀察:

1)大部分人的船艙等級是3。

2)C的乘客看起來很幸運,他們中的一部分幸存下來。

3)S港口的富人蠻多的。仍然生存的機會很低。

4)港口Q幾乎有95%的乘客都是窮人。

sns.factorplot('Pclass','Survived',hue='Sex',col='Embarked',data=data)
plt.show()

觀察:

1)存活的幾率幾乎為1 在pclass1和pclass2中的女人。

2)pclass3 的乘客中男性和女性的生存率都是很偏低的。

3)端口Q很不幸,因為那里都是3等艙的乘客。

港口中也存在缺失值,在這里我用眾數來進行填充了,因為S登船人最多呀

data['Embarked'].fillna('S',inplace=True)
data.Embarked.isnull().any()

False

7,sibsip -->兄弟姐妹的數量

這個特征表示一個人是獨自一人還是與他的家人在一起。

pd.crosstab([data.SibSp],data.Survived).style.background_gradient(cmap='summer_r')

 

f,ax=plt.subplots(1,2,figsize=(20,8))
sns.barplot('SibSp','Survived',data=data,ax=ax[0])
ax[0].set_title('SibSp vs Survived')
sns.factorplot('SibSp','Survived',data=data,ax=ax[1])
ax[1].set_title('SibSp vs Survived')
plt.close(2)
plt.show()

pd.crosstab(data.SibSp,data.Pclass).style.background_gradient(cmap='summer_r')

觀察:

barplot和factorplot表明,如果乘客是孤獨的船上沒有兄弟姐妹,他有34.5%的存活率。如果兄弟姐妹的數量增加,該圖大致減少。這是有道理的。也就是說,如果我有一個家庭在船上,我會盡力拯救他們,而不是先救自己。但是令人驚訝的是,5-8名成員家庭的存活率為0%。原因可能是他們在pclass=3的船艙?

8,Parch --> 父母和孩子的數量

pd.crosstab(data.Parch,data.Pclass).style.background_gradient(cmap='summer_r')

 再次表明,大家庭都在pclass3。

f,ax=plt.subplots(1,2,figsize=(20,8))
sns.barplot('Parch','Survived',data=data,ax=ax[0])
ax[0].set_title('Parch vs Survived')
sns.factorplot('Parch','Survived',data=data,ax=ax[1])
ax[1].set_title('Parch vs Survived')
plt.close(2)
plt.show()

這里的結果也很相似。帶着父母的乘客有更大的生存機會。然而,它隨着數字的增加而減少。

在船上的家庭父母人數中有1-3個的人的生存機會是好的。獨自一人也證明是致命的,當船上有4個父母時,生存的機會就會減少。

9,Fare--> 船票的價格

print('Highest Fare was:',data['Fare'].max())
print('Lowest Fare was:',data['Fare'].min())
print('Average Fare was:',data['Fare'].mean())

 最低票價是0英鎊。這價格我也能去!

f,ax=plt.subplots(1,3,figsize=(20,8))
sns.distplot(data[data['Pclass']==1].Fare,ax=ax[0])
ax[0].set_title('Fares in Pclass 1')
sns.distplot(data[data['Pclass']==2].Fare,ax=ax[1])
ax[1].set_title('Fares in Pclass 2')
sns.distplot(data[data['Pclass']==3].Fare,ax=ax[2])
ax[2].set_title('Fares in Pclass 3')
plt.show()

概括地觀察所有的特征: 性別:與男性相比,女性的生存機會很高。

Pclass:有,第一類乘客給你更好的生存機會的一個明顯趨勢。對於pclass3成活率很低。對於女性來說,從pclass1生存的機會幾乎是。

年齡:小於5-10歲的兒童存活率高。年齡在15到35歲之間的乘客死亡很多。

港口:上來的倉位也有區別,死亡率也很大!

家庭:有1-2的兄弟姐妹、配偶或父母上1-3顯示而不是獨自一人或有一個大家庭旅行,你有更大的概率存活。

 

特征之間的相關性

sns.heatmap(data.corr(),annot=True,cmap='RdYlGn',linewidths=0.2) #data.corr()-->correlation matrix
fig=plt.gcf()
fig.set_size_inches(10,8)
plt.show()

 

特征相關性的熱度圖

首先要注意的是,只有數值特征進行比較

正相關:如果特征A的增加導致特征b的增加,那么它們呈正相關。值1表示完全正相關。

負相關:如果特征A的增加導致特征b的減少,則呈負相關。值-1表示完全負相關。

現在讓我們說兩個特性是高度或完全相關的,所以一個增加導致另一個增加。這意味着兩個特征都包含高度相似的信息,並且信息很少或沒有變化。這樣的特征對我們來說是沒有價值的!

那么你認為我們應該同時使用它們嗎?。在制作或訓練模型時,我們應該盡量減少冗余特性,因為它減少了訓練時間和許多優點。

現在,從上面的圖,我們可以看到,特征不顯著相關。

特征工程和數據清洗

當我們得到一個具有特征的數據集時,是不是所有的特性都很重要?

可能有許多冗余的特征應該被消除,我們還可以通過觀察或從其他特征中提取信息來獲得或添加新特性。

 

年齡特征:

正如我前面提到的,年齡是連續的特征,在機器學習模型中存在連續變量的問題。

如果我說通過性別來組織或安排體育運動,我們可以很容易地把他們分成男女分開。

如果我說按他們的年齡分組,你會怎么做?如果有30個人,可能有30個年齡值。

我們需要對連續值進行離散化來分組。

好的,乘客的最大年齡是80歲。所以我們將范圍從0-80成5箱。所以80/5=16。

data['Age_band']=0
data.loc[data['Age']<=16,'Age_band']=0
data.loc[(data['Age']>16)&(data['Age']<=32),'Age_band']=1
data.loc[(data['Age']>32)&(data['Age']<=48),'Age_band']=2
data.loc[(data['Age']>48)&(data['Age']<=64),'Age_band']=3
data.loc[data['Age']>64,'Age_band']=4
data.head(2)

 

data['Age_band'].value_counts().to_frame().style.background_gradient(cmap='summer')#檢查每個波段的密碼

sns.factorplot('Age_band','Survived',data=data,col='Pclass')
plt.show()

 

 生存率隨年齡的增加而減少,不論Pclass。

10,Family_size:家庭總人數

光看兄弟姐妹和老人孩子看不太直接,咱們直接看全家的人數

data['Family_Size']=0
data['Family_Size']=data['Parch']+data['SibSp']#family size
data['Alone']=0
data.loc[data.Family_Size==0,'Alone']=1#Alone

f,ax=plt.subplots(1,2,figsize=(18,6))
sns.factorplot('Family_Size','Survived',data=data,ax=ax[0])
ax[0].set_title('Family_Size vs Survived')
sns.factorplot('Alone','Survived',data=data,ax=ax[1])
ax[1].set_title('Alone vs Survived')
plt.close(2)
plt.close(3)
plt.show()

 

 family_size = 0意味着passeneger是孤獨的。顯然,如果你是單獨或family_size = 0,那么生存的機會很低。家庭規模4以上,機會也減少。這看起來也是模型的一個重要特性。讓我們進一步研究這個問題。

sns.factorplot('Alone','Survived',data=data,hue='Sex',col='Pclass')
plt.show()

 

 11,船票價格

因為票價也是連續的特性,所以我們需要將它轉換為數值。

pandas.qcut

data['Fare_Range']=pd.qcut(data['Fare'],4)
data.groupby(['Fare_Range'])['Survived'].mean().to_frame().style.background_gradient(cmap='summer_r')

 

 如上所述,我們可以清楚地看到,船票價格增加生存的機會增加。

data['Fare_cat']=0
data.loc[data['Fare']<=7.91,'Fare_cat']=0
data.loc[(data['Fare']>7.91)&(data['Fare']<=14.454),'Fare_cat']=1
data.loc[(data['Fare']>14.454)&(data['Fare']<=31),'Fare_cat']=2
data.loc[(data['Fare']>31)&(data['Fare']<=513),'Fare_cat']=3

顯然,隨着fare_cat增加,存活的幾率增加。隨着性別的變化,這一特性可能成為建模過程中的一個重要特征。

將字符串值轉換為數字 因為我們不能把字符串一個機器學習模型

data['Sex'].replace(['male','female'],[0,1],inplace=True)
data['Embarked'].replace(['S','C','Q'],[0,1,2],inplace=True)
data['Initial'].replace(['Mr','Mrs','Miss','Master','Other'],[0,1,2,3,4],inplace=True)

去掉不必要的特征

名稱>我們不需要name特性,因為它不能轉換成任何分類值

年齡——>我們有age_band特征,所以不需要這個

票號-->這是任意的字符串,不能被歸類

票價——>我們有fare_cat特征,所以不需要

船倉號——>這個也不要沒啥含義

passengerid -->不能被歸類

data.drop(['Name','Age','Ticket','Fare','Cabin','Fare_Range','PassengerId'],axis=1,inplace=True)
sns.heatmap(data.corr(),annot=True,cmap='RdYlGn',linewidths=0.2,annot_kws={'size':20})
fig=plt.gcf()
fig.set_size_inches(18,15)
plt.xticks(fontsize=14)
plt.yticks(fontsize=14)
plt.show()

 現在以上的相關圖,我們可以看到一些正相關的特征。他們中的一些人sibsp和family_size和干燥family_size和一些負面的孤獨和family_size。

五,機器學習建模

我們從EDA部分獲得了一些見解。但是,我們不能准確地預測或判斷一個乘客是否會幸存或死亡。現在我們將使用一些很好的分類算法來預測乘客是否能生存下來:

1)logistic回歸

2)支持向量機(線性和徑向)

3)隨機森林

4)k-近鄰

5)朴素貝葉斯

6)決策樹

7)神經網絡

1,導入機器學習庫

#importing all the required ML packages
from sklearn.linear_model import LogisticRegression #邏輯回歸
from sklearn import svm #支持向量機(線性和徑向)
from sklearn.ensemble import RandomForestClassifier #隨機森林
from sklearn.neighbors import KNeighborsClassifier #k-近鄰
from sklearn.naive_bayes import GaussianNB #朴素貝葉斯
from sklearn.tree import DecisionTreeClassifier #決策樹
from sklearn.model_selection import train_test_split #神經網絡
from sklearn import metrics #精度
from sklearn.metrics import confusion_matrix #for confusion matrix

2,切分訓練集與測試集

train,test=train_test_split(data,test_size=0.3,random_state=0,stratify=data['Survived'])
train_X=train[train.columns[1:]]
train_Y=train[train.columns[:1]]
test_X=test[test.columns[1:]]
test_Y=test[test.columns[:1]]
X=data[data.columns[1:]]
Y=data['Survived']

3,Radial Support Vector Machines(rbf-SVM)

model=svm.SVC(kernel='rbf',C=1,gamma=0.1)
model.fit(train_X,train_Y)
prediction1=model.predict(test_X)
print('Accuracy for rbf SVM is ',metrics.accuracy_score(prediction1,test_Y))
Accuracy for rbf SVM is  0.835820895522
4,線性支持向量機(Linear - svm)
model=svm.SVC(kernel='linear',C=0.1,gamma=0.1)
model.fit(train_X,train_Y)
prediction2=model.predict(test_X)
print('Accuracy for linear SVM is',metrics.accuracy_score(prediction2,test_Y))
Accuracy for linear SVM is 0.817164179104

5,邏輯回歸

model = LogisticRegression()
model.fit(train_X,train_Y)
prediction3=model.predict(test_X)
print('The accuracy of the Logistic Regression is',metrics.accuracy_score(prediction3,test_Y))
The accuracy of the Logistic Regression is 0.817164179104
6,決策樹
model=DecisionTreeClassifier()
model.fit(train_X,train_Y)
prediction4=model.predict(test_X)
print('The accuracy of the Decision Tree is',metrics.accuracy_score(prediction4,test_Y))
The accuracy of the Decision Tree is 0.805970149254

7,k-近鄰

model=KNeighborsClassifier() 
model.fit(train_X,train_Y)
prediction5=model.predict(test_X)
print('The accuracy of the KNN is',metrics.accuracy_score(prediction5,test_Y))
The accuracy of the KNN is 0.832089552239

現在的精度為KNN模型的變化,我們改變n_neighbours值屬性。默認值是5。讓我們檢查的精度在n_neighbours不同時的結果。

a_index=list(range(1,11))
a=pd.Series()
x=[0,1,2,3,4,5,6,7,8,9,10]
for i in list(range(1,11)):
    model=KNeighborsClassifier(n_neighbors=i) 
    model.fit(train_X,train_Y)
    prediction=model.predict(test_X)
    a=a.append(pd.Series(metrics.accuracy_score(prediction,test_Y)))
plt.plot(a_index, a)
plt.xticks(x)
fig=plt.gcf()
fig.set_size_inches(12,6)
plt.show()
print('Accuracies for different values of n are:',a.values,'with the max value as ',a.values.max())

Accuracies for different values of n are: [ 0.75746269  0.79104478  0.80970149  0.80223881  0.83208955  0.81716418
  0.82835821  0.83208955  0.8358209   0.83208955] with the max value as  0.835820895522

8,朴素貝葉斯

model=GaussianNB()
model.fit(train_X,train_Y)
prediction6=model.predict(test_X)
print('The accuracy of the NaiveBayes is',metrics.accuracy_score(prediction6,test_Y))
The accuracy of the NaiveBayes is 0.813432835821

9,隨機森林

model=RandomForestClassifier(n_estimators=100)
model.fit(train_X,train_Y)
prediction7=model.predict(test_X)
print('The accuracy of the Random Forests is',metrics.accuracy_score(prediction7,test_Y))
The accuracy of the Random Forests is 0.820895522388

六,交叉驗證

  模型的精度並不是決定分類器效果的唯一因素。假設分類器在訓練數據上進行訓練,需要在測試集上進行測試才有效果

  現在這個分類器的精確度很高,但是我們可以確認所有的新測試集都是90%嗎?答案是否定的,因為我們不能確定分類器在不同數據源上的結果。當訓練和測試數據發生變化時,精確度也會改變。它可能會增加或減少。

為了克服這一點,得到一個廣義模型,我們使用交叉驗證。

一個測試集看起來不太夠呀,多輪求均值是一個好的策略!

1)的交叉驗證的工作原理是首先將數據集分成k-subsets。

2)假設我們將數據集划分為(k=5)部分。我們預留1個部分進行測試,並對這4個部分進行訓練。

3)我們通過在每次迭代中改變測試部分並在其他部分中訓練算法來繼續這個過程。然后對衡量結果求平均值,得到算法的平均精度。

這就是所謂的交叉驗證。

from sklearn.model_selection import KFold #for K-fold cross validation
from sklearn.model_selection import cross_val_score #score evaluation
from sklearn.model_selection import cross_val_predict #prediction
kfold = KFold(n_splits=10, random_state=22) # k=10, split the data into 10 equal parts
xyz=[]
accuracy=[]
std=[]
classifiers=['Linear Svm','Radial Svm','Logistic Regression','KNN','Decision Tree','Naive Bayes','Random Forest']
models=[svm.SVC(kernel='linear'),svm.SVC(kernel='rbf'),LogisticRegression(),KNeighborsClassifier(n_neighbors=9),DecisionTreeClassifier(),GaussianNB(),RandomForestClassifier(n_estimators=100)]
for i in models:
    model = i
    cv_result = cross_val_score(model,X,Y, cv = kfold,scoring = "accuracy")
    cv_result=cv_result
    xyz.append(cv_result.mean())
    std.append(cv_result.std())
    accuracy.append(cv_result)
new_models_dataframe2=pd.DataFrame({'CV Mean':xyz,'Std':std},index=classifiers)       
new_models_dataframe2

plt.subplots(figsize=(12,6))
box=pd.DataFrame(accuracy,index=[classifiers])
box.T.boxplot()

new_models_dataframe2['CV Mean'].plot.barh(width=0.8)
plt.title('Average CV Mean Accuracy')
fig=plt.gcf()
fig.set_size_inches(8,5)
plt.show()

混淆矩陣 它給出分類器的正確和不正確分類的數量。
f,ax=plt.subplots(3,3,figsize=(12,10))
y_pred = cross_val_predict(svm.SVC(kernel='rbf'),X,Y,cv=10)
sns.heatmap(confusion_matrix(Y,y_pred),ax=ax[0,0],annot=True,fmt='2.0f')
ax[0,0].set_title('Matrix for rbf-SVM')
y_pred = cross_val_predict(svm.SVC(kernel='linear'),X,Y,cv=10)
sns.heatmap(confusion_matrix(Y,y_pred),ax=ax[0,1],annot=True,fmt='2.0f')
ax[0,1].set_title('Matrix for Linear-SVM')
y_pred = cross_val_predict(KNeighborsClassifier(n_neighbors=9),X,Y,cv=10)
sns.heatmap(confusion_matrix(Y,y_pred),ax=ax[0,2],annot=True,fmt='2.0f')
ax[0,2].set_title('Matrix for KNN')
y_pred = cross_val_predict(RandomForestClassifier(n_estimators=100),X,Y,cv=10)
sns.heatmap(confusion_matrix(Y,y_pred),ax=ax[1,0],annot=True,fmt='2.0f')
ax[1,0].set_title('Matrix for Random-Forests')
y_pred = cross_val_predict(LogisticRegression(),X,Y,cv=10)
sns.heatmap(confusion_matrix(Y,y_pred),ax=ax[1,1],annot=True,fmt='2.0f')
ax[1,1].set_title('Matrix for Logistic Regression')
y_pred = cross_val_predict(DecisionTreeClassifier(),X,Y,cv=10)
sns.heatmap(confusion_matrix(Y,y_pred),ax=ax[1,2],annot=True,fmt='2.0f')
ax[1,2].set_title('Matrix for Decision Tree')
y_pred = cross_val_predict(GaussianNB(),X,Y,cv=10)
sns.heatmap(confusion_matrix(Y,y_pred),ax=ax[2,0],annot=True,fmt='2.0f')
ax[2,0].set_title('Matrix for Naive Bayes')
plt.subplots_adjust(hspace=0.2,wspace=0.2)
plt.show()

解釋混淆矩陣:來看第一個圖

1)預測的正確率為491(死亡)+ 247(存活),平均CV准確率為(491+247)/ 891=82.8%。

2)58和95都是咱們弄錯了的。

七,超參數整定

機器學習模型就像一個黑盒子。這個黑盒有一些默認參數值,我們可以調整或更改以獲得更好的模型。比如支持向量機模型中的C和γ,我們稱之為超參數,他們對結果可能產生非常大的影響。

from sklearn.model_selection import GridSearchCV
C=[0.05,0.1,0.2,0.3,0.25,0.4,0.5,0.6,0.7,0.8,0.9,1]
gamma=[0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1.0]
kernel=['rbf','linear']
hyper={'kernel':kernel,'C':C,'gamma':gamma}
gd=GridSearchCV(estimator=svm.SVC(),param_grid=hyper,verbose=True)
gd.fit(X,Y)
print(gd.best_score_)
print(gd.best_estimator_)
Fitting 3 folds for each of 240 candidates, totalling 720 fits
0.828282828283
SVC(C=0.5, cache_size=200, class_weight=None, coef0=0.0,
  decision_function_shape=None, degree=3, gamma=0.1, kernel='rbf',
  max_iter=-1, probability=False, random_state=None, shrinking=True,
  tol=0.001, verbose=False)
 
[Parallel(n_jobs=1)]: Done 720 out of 720 | elapsed:   16.2s finished

隨機森林
n_estimators=range(100,1000,100)
hyper={'n_estimators':n_estimators}
gd=GridSearchCV(estimator=RandomForestClassifier(random_state=0),param_grid=hyper,verbose=True)
gd.fit(X,Y)
print(gd.best_score_)
print(gd.best_estimator_)
Fitting 3 folds for each of 9 candidates, totalling 27 fits
 
[Parallel(n_jobs=1)]: Done  27 out of  27 | elapsed:   29.8s finished
 
0.817059483726
RandomForestClassifier(bootstrap=True, class_weight=None, criterion='gini',
            max_depth=None, max_features='auto', max_leaf_nodes=None,
            min_impurity_split=1e-07, min_samples_leaf=1,
            min_samples_split=2, min_weight_fraction_leaf=0.0,
            n_estimators=900, n_jobs=1, oob_score=False, random_state=0,
            verbose=0, warm_start=False)

RBF支持向量機的最佳得分為82.82%,C=0.5,γ=0.1。RandomForest,成績是81.8%
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM