(一)读取数据:
(二)特征理解分析
(三)数据清洗与预处理
(四)建立模型
读取数据
#导入库
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#将图内置到浏览器中
#读取数据
train = pd.read_csv("E:Data/train.csv")
test = pd.read_csv("E:Data/test.csv")
train.head()
#判断是否有缺失值
train.isnull().sum()
年龄,仓位,登船口岸有缺失。
年龄缺失可以使用均值或中值替换,仓位缺失较多,可以考虑删除仓位属性或者将缺失作为一个单独的类,登船口岸只有两个缺失,可以直接删除这两个数据。
训练集一共有891条数据。
#查看获救比例
#1行两列的子图
f,ax=plt.subplots(1,2,figsize=(18,8))
#统计Survived属性
train['Survived'].value_counts().plot.pie(explode=[0,0.1],autopct='%1.1f%%',ax=ax[0],shadow=True)
#ax[0]表示第0个子图,ax[1]表示第一个子图
ax[0].set_title('Survived')
ax[0].set_ylabel('')
sns.countplot('Survived',data=train,ax=ax[1])
ax[1].set_title('Survived')
plt.show()
#查看获救比例
#1行两列的子图
f,ax=plt.subplots(1,2,figsize=(18,8))
#统计Survived属性
train['Survived'].value_counts().plot.pie(explode=[0,0.1],autopct='%1.1f%%',ax=ax[0],shadow=True)
#ax[0]表示第0个子图,ax[1]表示第一个子图
ax[0].set_title('Survived')
ax[0].set_ylabel('')
sns.countplot('Survived',data=train,ax=ax[1])
ax[1].set_title('Survived')
plt.show()
女性存活率高达74.2%,而男性存活率只有18.9%,因此性别对存活率有较大影响。
f,ax=plt.subplots(1,2,figsize=(18,8))
#统计Survived属性
train[['Sex','Survived']].groupby(['Sex']).mean().plot.bar(ax=ax[0])
#ax[0]表示第0个子图,ax[1]表示第一个子图
ax[0].set_title('Survived vs Sex')
sns.countplot('Sex',hue ='Survived',data=train,ax=ax[1])
ax[1].set_title('Sex:Survived vs Dead')
plt.show()
pd.crosstab(train.Pclass,train.Survived,margins=True).style.background_gradient(cmap='summer_r')
根据统计,不同等级的船舱获救比例不同,因此获救几率与船舱等级有关。
pd.crosstab([train.Sex,train.Survived],train.Pclass,margins=True).style.background_gradient(cmap='summer_r')
一等舱和二等舱女性几乎都获救,而在三等舱获救几率只有50%。 一等舱男性获救率36.9%,二等舱男性获救率 15.7%,三登船按下获救率13.5%,因此船舱等级不同影响存活率。
f,ax=plt.subplots(1,2,figsize=(18,8))
sns.violinplot("Pclass","Age", hue="Survived", data=train,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=train,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)对男性来说,随着年龄的增长,存活率降低。
常用方法:
平均值
经验值
回归模型预测
剔除掉
正如我们前面看到的,年龄特征有177个空值。为了替换这些缺失值,我们可以给它们分配数据集的平均年龄。但问题是,有许多不同年龄的人。最好的办法是找到一个合适的年龄段!我们可以检查名字特征。根据这个特征,我们可以看到名字有像先生或夫人这样的称呼这样我们就可以把先生和夫人的平均值分配给各自的组。
统计姓名的前缀
把相同意思不同前缀进行替换
再计算不同称呼的年龄的均值
对年龄缺失值进行填充
#填充年龄缺失值
## 使用每组的均值来进行填充
train.loc[(train.Age.isnull())&(train.Initial=='Mr'),'Age']=33
train.loc[(train.Age.isnull())&(train.Initial=='Mrs'),'Age']=36
train.loc[(train.Age.isnull())&(train.Initial=='Master'),'Age']=5
train.loc[(train.Age.isnull())&(train.Initial=='Miss'),'Age']=22
train.loc[(train.Age.isnull())&(train.Initial=='Other'),'Age']=46
pd.crosstab([train.Embarked,train.Pclass],[train.Sex,train.Survived],margins=True).style.background_gradient(cmap='summer_r')
pd.crosstab([train.Embarked,train.Pclass],[train.Sex,train.Survived],margins=True).style.background_gradient(cmap='summer_r')
港口中也存在缺失值,在这里我用众数来进行填充了,因为S登船人最多呀
train['Embarked'].fillna('S',inplace=True)
兄弟姐妹的数量与存活的关系
pd.crosstab([train.SibSp],train.Survived).style.background_gradient(cmap='summer_r')
f,ax=plt.subplots(1,2,figsize=(20,8))
#画柱状图
sns.barplot('SibSp','Survived',data=train,ax=ax[0])
ax[0].set_title('SibSp vs Survived')
#画散点图
sns.factorplot('SibSp','Survived',data=train,ax=ax[1])
ax[1].set_title('SibSp vs Survived')
plt.close(2)
plt.show()
根据观察,没有兄弟姐妹和只有一个兄弟姐妹的存活率最高,然后存活率随着兄弟姐妹个数的增多而降低。
父母和孩子的数量与存活的关系
f,ax=plt.subplots(1,2,figsize=(20,8))
#画柱状图
sns.barplot('Parch','Survived',data=train,ax=ax[0])
ax[0].set_title('Parch vs Survived')
#画散点图
sns.factorplot('Parch','Survived',data=train,ax=ax[1])
ax[1].set_title('Parch vs Survived')
plt.close(2)
plt.show()
带着父母的乘客有更大的生存机会。然而,它随着数字的增加而减少。
Fare 船票价格的影响
概括地观察所有的特征: 性别:与男性相比,女性的生存机会很高。
Pclass:有,第一类乘客给你更好的生存机会的一个明显趋势。对于pclass3成活率很低。对于女性来说,从pclass1生存的机会几乎是。
年龄:小于5-10岁的儿童存活率高。年龄在15到35岁之间的乘客死亡很多。
港口:上来的仓位也有区别,死亡率也很大!
家庭:有1-2的兄弟姐妹、配偶或父母上1-3显示而不是独自一人或有一个大家庭旅行,你有更大的概率存活。
#特征之间的相关性
sns.heatmap(train.corr(),annot=True,linewidths=0.2)
#data.corr()-->correlation matrix
#annot annotate的缩写 annot默认为False,当annot为True时,在heatmap中每个方格写入数据
fig=plt.gcf()
fig.set_size_inches(10,8)
plt.show()
从特征相关性热度图中可以看出,只有价格与船舱等级存在较强负相关,其他属性直接不存在显著相关性。
当我们得到一个具有特征的数据集时,是不是所有的特性都很重要?可能有许多冗余的特征应该被消除,我们还可以通过观察或从其他特征中提取信息来获得或添加新特性。
正如我前面提到的,年龄是连续的特征,在机器学习模型中存在连续变量的问题。
如果我说通过性别来组织或安排体育运动,我们可以很容易地把他们分成男女分开。
如果我说按他们的年龄分组,你会怎么做?如果有30个人,可能有30个年龄值。
我们需要对连续值进行离散化来分组。
好的,乘客的最大年龄是80岁。所以我们将范围从0-80成5组。所以80/5=16。
#添加一个新的属性,年龄类别
train['Age_band']=0
train.loc[train['Age']<=16,'Age_band']=0
train.loc[(train['Age']>16)&(train['Age']<=32),'Age_band']=1
train.loc[(train['Age']>32)&(train['Age']<=48),'Age_band']=2
train.loc[(train['Age']>48)&(train['Age']<=64),'Age_band']=3
train.loc[train['Age']>64,'Age_band']=4
train
光看兄弟姐妹和老人孩子看不太直接,咱们直接看全家的人数
#新建家庭人数属性
train['Family_Size'] = 0
train['Family_Size'] = train['Parch'] + train['SibSp']
#新建属性标记是否一个人
train['Alone']=0
train.loc[train['Family_Size'] == 0,'Alone'] = 1
因为票价也是连续的特性,所以我们需要将它转换为数值。
利用pd.qcut将船票价格分为四个
train['Fare_cat']=0
train.loc[train['Fare']<=7.91,'Fare_cat']=0
train.loc[(train['Fare']>7.91)&(train['Fare']<=14.454),'Fare_cat']=1
train.loc[(train['Fare']>14.454)&(train['Fare']<=31),'Fare_cat']=2
train.loc[(train['Fare']>31)&(train['Fare']<=513),'Fare_cat']=3
#将字符串值转换为数字 因为我们不能把字符串一个机器学习模型部分
#将字符串值转换为数字 因为我们不能把字符串一个机器学习模型
train['Sex'].replace(['male','female'],[0,1],inplace=True)
train['Embarked'].replace(['S','C','Q'],[0,1,2],inplace=True)
train['Initial'].replace(['Mr','Mrs','Miss','Master','Other'],[0,1,2,3,4],inplace=True)
名称>我们不需要name特性,因为它不能转换成任何分类值
年龄——>我们有age_band特征,所以不需要这个
票号-->这是任意的字符串,不能被归类
票价——>我们有fare_cat特征,所以不需要
船仓号——>这个也不要没啥含义
passengerid -->不能被归类
train.drop(['Name','Age','Ticket','Fare','Cabin','Fare_Range','PassengerId'],axis=1,inplace=True)
1)logistic回归
2)支持向量机(线性和径向)
3)随机森林
4)k-近邻
5)朴素贝叶斯
6)决策树
7)神经网络
导入各种模型
#importing all the required ML packages
from sklearn.linear_model import LogisticRegression #logistic regression
from sklearn import svm #support vector Machine
from sklearn.ensemble import RandomForestClassifier #Random Forest
from sklearn.neighbors import KNeighborsClassifier #KNN
from sklearn.naive_bayes import GaussianNB #Naive bayes
from sklearn.tree import DecisionTreeClassifier #Decision Tree
from sklearn.model_selection import train_test_split #training and testing data split
from sklearn import metrics #accuracy measure
from sklearn.metrics import confusion_matrix #for confusion matrix
将数据集拆分成训练集和测试集
train_data,test_data = train_test_split(train,test_size=0.3,random_state=0,stratify=train.Survived)
train_X = train_data[train_data.columns[1:]]
train_Y = train_data[train_data.columns[:1]]
test_X = test_data[test_data.columns[1:]]
test_Y = test_data[test_data.columns[:1]]
X = train[train.columns[1:]]
Y = train['Survived']
#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))
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))
#逻辑回归
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))
#决策树
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))
#KNN
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))
#贝叶斯
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))
#随机森林
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))
#交叉验证
from sklearn.model_selection import KFold
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import cross_val_predict
kfold = KFold(n_splits=10,random_state=22)#10折交叉验证
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")
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
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)
使用投票的方法集成
from sklearn.ensemble import VotingClassifier
ensemble_lin_rbf=VotingClassifier(estimators=[('KNN',KNeighborsClassifier(n_neighbors=10)),
('RBF',svm.SVC(probability=True,kernel='rbf',C=0.5,gamma=0.1)),
('RFor',RandomForestClassifier(n_estimators=500,random_state=0)),
('LR',LogisticRegression(C=0.05)),
('DT',DecisionTreeClassifier(random_state=0)),
('NB',GaussianNB()),
('svm',svm.SVC(kernel='linear',probability=True))
],
voting='soft').fit(train_X,train_Y)
print('The accuracy for ensembled model is:',ensemble_lin_rbf.score(test_X,test_Y))
cross=cross_val_score(ensemble_lin_rbf,X,Y, cv = 10,scoring = "accuracy")
print('The cross validated score is',cross.mean())
Bagging:
from sklearn.ensemble import BaggingClassifier
model=BaggingClassifier(base_estimator=KNeighborsClassifier(n_neighbors=3),random_state=0,n_estimators=700)
model.fit(train_X,train_Y)
prediction=model.predict(test_X)
print('The accuracy for bagged KNN is:',metrics.accuracy_score(prediction,test_Y))
result=cross_val_score(model,X,Y,cv=10,scoring='accuracy')
print('The cross validated score for bagged KNN is:',result.mean())
AdaBoost
from sklearn.ensemble import AdaBoostClassifier
ada=AdaBoostClassifier(n_estimators=200,random_state=0,learning_rate=0.1)
result=cross_val_score(ada,X,Y,cv=10,scoring='accuracy')
print('The cross validated score for AdaBoost is:',result.mean())