樣例參考自《從零開始學Python數(shù)據(jù)分析與挖掘》一書.
數(shù)據(jù)集
https://github.com/SnakeLiu/Python-Data-Aanalysis-and-Miner
第十章決策樹與隨機森林模型中 Titanic.csv
數(shù)據(jù)集表示在Titanic事件中乘客的幸存情況.Survived為因變量,為1表示該乘客幸存,為0表示該乘客不幸遇難,其他變量均為自變量.
數(shù)據(jù)清洗
先導入pandas模塊,調(diào)用read_csv()方法并讀取數(shù)據(jù),返回一個DataFrame.
import pandas as pd
Titanic=pd.read_csv('Titanic.csv')
通過Titanic.head()可以獲得這個DataFrame的前幾行數(shù)據(jù),不輸入?yún)?shù)默認返回前5行.
print(Titanic.head())

其中PassengerId,Ticket,Cabin三個自變量對因變量沒有直接的影響,因此將這三列去除.axis=1表示影響的是列,axis=0則表示影響的是行.inplace=True表示直接修改原DataFrame,inplace=False則表示不修改原DataFrame.
Titanic.drop(['PassengerId','Name','Ticket','Cabin'],axis=1,inplace=True)
檢查剩余變量中是否有缺失值.Titanic.isnull()將返回一個結(jié)構(gòu)和原先一致的DataFrame,內(nèi)容為True(空)或Fals(非空),再通過sum()方法進行累加,axis=0表示按行進行累加.
print(Titanic.isnull().sum(axis=0))

可以發(fā)現(xiàn)Age有177個缺失值,較多,我們用均值填充法進行填充.Embarked有2個缺失值,較少,我們用眾數(shù)填充法進行填充.
loc方法通過具體值來取DataFrame中符合的行,與此對應(yīng)的還有iloc方法,通過行號來取DataFrame中的數(shù)據(jù).
fillna()方法用來填充DataFrame中的缺失值.
這里先分別計算了男女的性別平均值,再將Titanic拆成temp1(男性),和temp2(女性)分別進行填充,最后調(diào)用concat()方法將temp1和temp2合成新的Titanic,并調(diào)用rest_index()方法對index進行重排.
對于Embarked,直接取其眾數(shù)進行填充.
fillna_Titanic=[]
maleAveAge=round(Titanic.Age[Titanic.Sex=='male'].mean())
femaleAveAge=round(Titanic.Age[Titanic.Sex=='female'].mean())
temp1=Titanic.loc[Titanic.Sex=='male'].fillna(value={'Age':maleAveAge})
temp2=Titanic.loc[Titanic.Sex=='female'].fillna(value={'Age':femaleAveAge})
temp=[]
temp.append(temp1)
temp.append(temp2)
Titanic=pd.concat(temp)
Titanic.reset_index(drop=True, inplace=True)
Titanic.fillna(value={'Embarked':Titanic.Embarked.mode()[0]},inplace=True)
Pclass當前為int型,然而Pclass直接的1,2,3并沒有數(shù)值上的倍數(shù)關(guān)系,因此需要對其進行類型轉(zhuǎn)換.astype()方法用于強制類型轉(zhuǎn)換,將Pclass轉(zhuǎn)換為object型,方便于之后的啞變量處理.
Titanic.Pclass=Titanic.Pclass.astype('object')
對Sex,Embarked,Pclass三個變量進行啞變量處理.get_dummies()方法返回一個包含啞變量的DataFrame,調(diào)用concat()方法將新的DataFrame與原先的DataFrame進行合并,并drop掉原始的Sex,Embarked,Pclass三列.
dummy=pd.get_dummies(Titanic[['Sex','Embarked','Pclass']])
Titanic=pd.concat([Titanic,dummy],axis=1)
Titanic.drop(['Sex','Embarked','Pclass'],inplace=True,axis=1)
至此,對數(shù)據(jù)集的清洗已經(jīng)完成,部分數(shù)據(jù)如下所示.

調(diào)參獲取最佳參數(shù)
sklearn是封裝好的機器學習庫,導入相關(guān)的包.model_selection用于劃分數(shù)據(jù)集.GridSearchCV通過網(wǎng)格搜索法,用于自動調(diào)參.tree中包含了封裝好的決策樹.metrics用于對模型的性能進行評估.
Titanic.columns獲得所有列的名稱,取第1行至最后一行,這些是自變量,而第0行是因變量.
調(diào)用model_selection.train_test_split()方法可以對訓練集和測試集進行劃分,返回參數(shù)格式為固定寫法,方法參數(shù)中的第一個為特征數(shù)據(jù),第二個為標簽數(shù)據(jù),第三個為測試集/訓練集的大小,第四個為隨機種子.
from sklearn import model_selection
from sklearn.model_selection import GridSearchCV
from sklearn import tree
from sklearn import metrics
predictors=Titanic.columns[1:]
X_train,X_test,Y_train,Y_test=model_selection.train_test_split(Titanic[predictors],Titanic.Survived,test_size=0.25,random_state=1234)
通過網(wǎng)格搜索法進行調(diào)參,構(gòu)建決策樹模型.先預(yù)設(shè)模型參數(shù),等下將在這些候選參數(shù)中進行搜索.將預(yù)設(shè)好的各個參數(shù)封裝成一個字典,調(diào)用GridSeachCV()方法進行網(wǎng)格搜索,方法中的第一個參數(shù)為所使用的分類器,第二個參數(shù)為需要優(yōu)化的參數(shù)的候選取值,第三個參數(shù)為進行幾重交叉驗證,返回結(jié)果為一個決策樹模型.再調(diào)用模型的fit()方法對訓練集進行擬合,即可獲得的最佳參數(shù).輸出結(jié)果為一個字典,{'max_depth': 3, 'min_samples_leaf': 4, 'min_samples_split': 2}.
max_depth=[2,3,4,5,6]
min_samples_split=[2,4,6,8]
min_samples_leaf=[2,4,8,10,12]
parameters={'max_depth':max_depth,'min_samples_split':min_samples_split,'min_samples_leaf':min_samples_leaf}
grid_dtcateg=GridSearchCV(estimator=tree.DecisionTreeClassifier(),param_grid=parameters,cv=10)
grid_dtcateg.fit(X_train,Y_train)
print(grid_dtcateg.best_params_)
構(gòu)建決策樹
將調(diào)好的最佳參數(shù)放入模型中,并用訓練集進行擬合構(gòu)建決策樹,再對測試集進行預(yù)測.調(diào)用metrics.accuracy_score()方法計算模型在訓練集和測試集上的準確率.
CART_Class=tree.DecisionTreeClassifier(max_depth=3,min_samples_leaf=4,min_samples_split=2)
decision_tree=CART_Class.fit(X_train,Y_train)
predict=CART_Class.predict(X_test)
print("TrainSet accuracy:\n",metrics.accuracy_score(Y_train,CART_Class.predict(X_train)))
print("TestSet accuracy:\n",metrics.accuracy_score(Y_test,predict))
繪圖
最后導入matplotlib,繪制ROC曲線,x軸表示負例錯判率,y軸表示正例覆蓋率.
import matplotlib.pyplot as plt
Y_score=CART_Class.predict_proba(X_test)[:,1]
print(Y_score)
fpr,tpr,threshold=metrics.roc_curve(Y_test,Y_score)
roc_auc=metrics.auc(fpr,tpr)
plt.stackplot(fpr,tpr,color='steelblue',alpha=0.5,edgecolor='black')
plt.plot(fpr,tpr,color='black',lw=1)
plt.plot([0,1],[0,1],color='red',linestyle='--')
plt.text(0.5,0.3,'ROC curve (area = %0.2f)' % roc_auc)
plt.xlabel('1-Specificity')
plt.ylabel('Sensitivity')
plt.show()
