大数据、人工智能、机器学习等互联网技术是现在各行各业都绕不开的话题,市场对AI人才的需求也持续高涨。
学习机器学习技术一方面是要系统地学习专业知识,通过看书看视频(推荐南京大学周志华老师的西瓜书和吴恩达的视频课)来了解机器学习的基本原理。另一方面,就是要进行实操,在真实的数据集上实验所学,提升机器学习的应用效果。其中,Kaggle竞赛是实操练习的优秀平台,既能够实操锻炼,还能够将您的成绩与其他人进行比较,鼓励你改善算法、优化过程。
Kaggle
Titanic提升之路Titanic数据集非常适合新手入门的选择,笔者也是从这里开始的。经过一段时间的努力,幸存者的预测精度由0.69377提升到0.78947,排名由几万名开外提升到3363名,直观感受就是每一个小的进度都来自于自己对机器学习过程的理解加深和对优化技巧的掌握。
Public leaderboard
第一次提交,就是尝试基本的逻辑回归算法,贯通机器学习建模的过程,没有进行任何特征处理。
第二次提交尝试通过随机森林算法筛选特征,然后再以逻辑回归进行预测,效果较之前显著提升。
第三次提交是基于树模型进行预测,使用Bagging算法。
第四次提交一方面对特征工程工程进行了梳理,另一方面是采用了投票的集成算法,使得精度进一步提升。
越往后感觉精度每提升一点,排名都上升很快,这说明大多数人的预测精度都在0.78以下。目前,我只做到了第四次提交,后面继续优化,争取用可解释的方法将预测精度做到0.85以上,前路坎坷啊。
Titanic预测成绩
第四次提交完整代码我是会说科技,关注我,一起了解数据、科技、安全、金融那些琐事。
下面是第四次提交的完整代码,可以直接修改后在Kaggle中提交,主要包括库包引入、特征衍生、特征筛选、单算法、集成算法、预测应用等步骤,与各位一起交流、学习,如有可提升之处还望指导。
Titanic
#引入库包
import pandas as pd
import matplotlib.pyplot as plt
import sklearn
import numpy as np
import seaborn as sns
#读取训练集并进行特征工程处理
df = pd.read_csv("titanic/train.csv")
#添加新属性,姓名的长度
df['namelen'] = df.apply(lambda x:len(x.Name) if x.Name!="" else 0,axis=1)
#添加新属性,看看乘客是Mr、Miss还是Mrs
df['sexmore'] = df.apply(lambda x:'Mrs' if 'Mrs' in x.Name else ('Miss' if 'Miss' in x.Name else ('Mr' if 'Mr' in x.Name else ('Mr' if x.Sex=='male' else 'Mrs'))),axis=1)
#统计所有人员
df['withnum'] = df['SibSp'] df['Parch']
#区分Ticket
df['ticketclass'] = df.apply(lambda x:1 if x.Ticket.isdigit() else 0,axis=1)
#船舱的编号首字母
df['Cabin'] = df['Cabin'].astype('str') #把船舱编号类型置为str
df['cabinclass'] = df.apply(lambda x:x.Cabin[0:1],axis=1)
df['cabinlen'] = df.apply(lambda x:len(x.Cabin) if x.Cabin != 'n' else 0,axis=1)
#Age有空值,用中位数填充
df['Age'].fillna(df['Age'].median(),inplace=True) #年龄缺失值用中位数补缺
#Embarked有空值,用众数填充
df['Embarked'].fillna(df['Embarked'].mode()[0],inplace=True) #年龄缺失值用中位数补缺
#去除业务上无用的特征
df.drop(['PassengerId','Name','Ticket','Cabin'],axis=1,inplace=True)
df.head()
df['Pclass'] = df['Pclass'].astype('object') #把分类类型置为object
df['ticketclass'] = df['ticketclass'].astype('object')
df.info()
#分类型变量分析
#Pclass:等级越高存活率越高
#Sex:女士存活率高
#Sexmore:女士和夫人的存活率远高于先生,其中夫人的存活率高于女士
#Ticketclass:船票是否为全数字,无明显趋势
#cabinclass:船舱编号,为空的幸存率低于非空的
#cabinlen:船舱编号为三位的幸存率低,数量多
#Embarked:登船口C>Q>S的幸存率
df.groupby('Embarked')['Survived'].value_counts().unstack()
#连续型变量分析
#Age、SibSp、Parch、Fare、namelen、withnum、cabinlen
sns.distplot(df['Age'],kde=True,bins=40,rug=True)
sns.jointplot(x=df['Age'],y=df['Survived'])
#对连续性变量标准化
from sklearn.preprocessing import StandardScaler
ss = StandardScaler()
df['Age'] = ss.fit_transform(df[['Age']])
df['SibSp'] = ss.fit_transform(df[['SibSp']])
df['Parch'] = ss.fit_transform(df[['Parch']])
df['Fare'] = ss.fit_transform(df[['Fare']])
df['namelen'] = ss.fit_transform(df[['namelen']])
df['withnum'] = ss.fit_transform(df[['withnum']])
df['cabinlen'] = ss.fit_transform(df[['cabinlen']])
df.head()
#对连续性变量进行one-hot
df = pd.get_dummies(df)
df.head()
#查看变量相关性
abs(df.corr()['Survived'])<0.01
#根据相关性结果,去除与目标变量相关性较低的变量
df_y = df['Survived'].copy()
df_x = df.drop(['Survived','Embarked_Q','ticketclass_1','ticketclass_0','cabinclass_A','cabinclass_F','Embarked_Q','cabinclass_C','cabinclass_G','cabinclass_T'],axis=1).copy()
df_x.head()
#使用随机森林选择重要性较高的特征
from sklearn.ensemble import RandomForestClassifier
rf_clf = RandomForestClassifier(max_depth=3)
rf_clf.fit(X_train,y_train)
print(rf_clf.score(X_train,y_train))
print(rf_clf.score(X_test,y_test))
rf_clf.feature_importances_
#划分训练集和测试集
from sklearn.model_selection import train_test_split
X_train,X_test,y_train,y_test = train_test_split(df_x,df_y,test_size=0.3,random_state=12345)
print(X_train.shape)
print(y_train.shape)
print(X_test.shape)
print(y_test.shape)
features = pd.DataFrame(X_train.columns)
importances = pd.DataFrame(rf_clf.feature_importances_)
feature_importance = pd.concat([features,importances],keys=['feature','importance'],axis=1)
feature_importance.columns = ['feature','importance']
feature_importance.sort_values(by="importance",ascending=False)
feature_importance[feature_importance['importance']<=0.003].sort_values(by="importance",ascending=False)
#feature_importance[feature_importance['importance']>=0.003]['feature']
#切分自变量和因变量
df_y = df['Survived'].copy()
df_x = df.drop(['Survived','Embarked_Q','ticketclass_1','ticketclass_0','cabinclass_A','cabinclass_F','Embarked_Q','cabinclass_C','cabinclass_G','cabinclass_T'],axis=1).copy()
df_x.head()
from sklearn.svm import SVC
svc_clf = SVC(probability=True)
svc_clf.fit(X_train,y_train)
print(svc_clf.score(X_train,y_train))
print(svc_clf.score(X_test,y_test))
from sklearn.ensemble import VotingClassifier
vote_clf = VotingClassifier(estimators=[('lr',lr_clf),('tree',dt_clf),('svm',svc_clf),('rf',rf_clf)],voting='soft')
vote_clf.fit(X_train,y_train)
print(vote_clf.score(X_train,y_train))
print(vote_clf.score(X_test,y_test))
df_test = pd.read_csv("titanic/test.csv")
df_test.head()
df_test = pd.read_csv("titanic/test.csv")
df_test.head()
#添加新属性,姓名的长度
df_test['namelen'] = df_test.apply(lambda x:len(x.Name) if x.Name!="" else 0,axis=1)
#添加新属性,看看乘客是Mr、Miss还是Mrs
df_test['sexmore'] = df_test.apply(lambda x:'Mrs' if 'Mrs' in x.Name else ('Miss' if 'Miss' in x.Name else ('Mr' if 'Mr' in x.Name else ('Mr' if x.Sex=='male' else 'Mrs'))),axis=1)
#统计所有人员
df_test['withnum'] = df_test['SibSp'] df_test['Parch']
#区分Ticket
df_test['ticketclass'] = df_test.apply(lambda x:1 if x.Ticket.isdigit() else 0,axis=1)
#船舱的编号首字母
df_test['Cabin'] = df_test['Cabin'].astype('str') #把船舱编号类型置为str
df_test['cabinclass'] = df_test.apply(lambda x:x.Cabin[0:1],axis=1)
df_test['cabinlen'] = df_test.apply(lambda x:len(x.Cabin) if x.Cabin != 'n' else 0,axis=1)
#Age有空值,用中位数填充
df_test['Age'].fillna(df_test['Age'].median(),inplace=True) #年龄缺失值用中位数补缺
#Embarked有空值,用众数填充
df_test['Embarked'].fillna(df['Embarked'].mode()[0],inplace=True) #年龄缺失值用中位数补缺
#保留乘客ID
df_test_id = df_test['PassengerId'].copy()
#去除业务上无用的特征
df_test.drop(['PassengerId','Name','Ticket','Cabin'],axis=1,inplace=True)
df_test['Pclass'] = df_test['Pclass'].astype('object') #把分类类型置为object
df_test['ticketclass'] = df_test['ticketclass'].astype('object')
#对连续性变量标准化
from sklearn.preprocessing import StandardScaler
ss = StandardScaler()
df_test['Age'] = ss.fit_transform(df_test[['Age']])
df_test['SibSp'] = ss.fit_transform(df_test[['SibSp']])
df_test['Parch'] = ss.fit_transform(df_test[['Parch']])
df_test['Fare'] = ss.fit_transform(df_test[['Fare']])
df_test['namelen'] = ss.fit_transform(df_test[['namelen']])
df_test['withnum'] = ss.fit_transform(df_test[['withnum']])
df_test['cabinlen'] = ss.fit_transform(df_test[['cabinlen']])
#对连续性变量进行one-hot
df_test = pd.get_dummies(df_test)
#切分自变量和因变量
df_test_x = df_test.drop(['Embarked_Q','ticketclass_1','ticketclass_0','cabinclass_A','cabinclass_F','Embarked_Q','cabinclass_C','cabinclass_G'],axis=1).copy()
df_test_x.head()
#训练集中的字段在测试集中没有,则需要在测试集中补0
#求差值变量
delta1 = [x for x in df_x.columns if x not in df_test_x.columns]
delta1
#测试集中的字段在训练集中没有,去除
#求差值变量
delta1 = [x for x in df_test_x.columns if x not in df_x.columns]
delta1
print(len(df_x.columns))
print(len(df_test_x.columns))
#Fare有空值
#Age有空值,用中位数填充
df_test_x['Fare'].fillna(df_test_x['Fare'].median(),inplace=True) #年龄缺失值用中位数补缺
df_test_x.info()
result = vote_clf.predict(df_test_x)
result = pd.Series(result)
result = pd.concat([df_test_id,result],keys=['PassengerId','Survived'],axis=1)
result.to_csv('result20200730.csv',index=False)
#不同预测算法的应用及集成
#逻辑回归
from sklearn.linear_model import LogisticRegression
lr_clf = LogisticRegression()
lr_clf.fit(X_train,y_train)
print(lr_clf.score(X_train,y_train))
print(lr_clf.score(X_test,y_test))
#决策树
from sklearn.tree import DecisionTreeClassifier
dt_clf = DecisionTreeClassifier(max_depth=3)
dt_clf.fit(X_train,y_train)
print(dt_clf.score(X_train,y_train))
print(dt_clf.score(X_test,y_test))
#支持向量机
from sklearn.svm import SVC
svc_clf = SVC(probability=True) #支持软投票
svc_clf.fit(X_train,y_train)
print(svc_clf.score(X_train,y_train))
print(svc_clf.score(X_test,y_test))
#随机森林
rf_clf = RandomForestClassifier(max_depth=3,random_state=12345)
rf_clf.fit(X_train,y_train)
#投票算法
from sklearn.ensemble import VotingClassifier
vote_clf = VotingClassifier(estimators=[('lr',lr_clf),('tree',dt_clf),('svm',svc_clf),('rf',rf_clf)],voting='soft')
vote_clf.fit(X_train,y_train)
print(vote_clf.score(X_train,y_train))
print(vote_clf.score(X_test,y_test))
df_test_x = df_test.drop(['Embarked_Q','ticketclass_1','ticketclass_0','cabinclass_A','cabinclass_F','Embarked_Q','cabinclass_C','cabinclass_G'],axis=1).copy()
df_test_x.head()
#训练集中的字段在测试集中没有,则需要在测试集中补0
#求差值变量
delta1 = [x for x in df_x.columns if x not in df_test_x.columns]
delta1
#测试集中的字段在训练集中没有,去除
#求差值变量
delta1 = [x for x in df_test_x.columns if x not in df_x.columns]
delta1
print(len(df_x.columns))
print(len(df_test_x.columns))
#Fare有空值
#Age有空值,用中位数填充
df_test_x['Fare'].fillna(df_test_x['Fare'].median(),inplace=True) #年龄缺失值用中位数补缺
df_test_x.info()
result = vote_clf.predict(df_test_x)
result = pd.Series(result)
result = pd.concat([df_test_id,result],keys=['PassengerId','Survived'],axis=1)
result.to_csv('result20200730.csv',index=False)
#对测试集进行预测
df_test = pd.read_csv("titanic/test.csv")
df_test.head()
#添加新属性,姓名的长度
df_test['namelen'] = df_test.apply(lambda x:len(x.Name) if x.Name!="" else 0,axis=1)
#添加新属性,看看乘客是Mr、Miss还是Mrs
df_test['sexmore'] = df_test.apply(lambda x:'Mrs' if 'Mrs' in x.Name else ('Miss' if 'Miss' in x.Name else ('Mr' if 'Mr' in x.Name else ('Mr' if x.Sex=='male' else 'Mrs'))),axis=1)
#统计所有人员
df_test['withnum'] = df_test['SibSp'] df_test['Parch']
#区分Ticket
df_test['ticketclass'] = df_test.apply(lambda x:1 if x.Ticket.isdigit() else 0,axis=1)
#船舱的编号首字母
df_test['Cabin'] = df_test['Cabin'].astype('str') #把船舱编号类型置为str
df_test['cabinclass'] = df_test.apply(lambda x:x.Cabin[0:1],axis=1)
df_test['cabinlen'] = df_test.apply(lambda x:len(x.Cabin) if x.Cabin != 'n' else 0,axis=1)
#Age有空值,用中位数填充
df_test['Age'].fillna(df_test['Age'].median(),inplace=True) #年龄缺失值用中位数补缺
#Embarked有空值,用众数填充
df_test['Embarked'].fillna(df['Embarked'].mode()[0],inplace=True) #年龄缺失值用中位数补缺
#保留乘客ID
df_test_id = df_test['PassengerId'].copy()
#去除业务上无用的特征
df_test.drop(['PassengerId','Name','Ticket','Cabin'],axis=1,inplace=True)
df_test['Pclass'] = df_test['Pclass'].astype('object') #把分类类型置为object
df_test['ticketclass'] = df_test['ticketclass'].astype('object')
#对连续性变量标准化
from sklearn.preprocessing import StandardScaler
ss = StandardScaler()
df_test['Age'] = ss.fit_transform(df_test[['Age']])
df_test['SibSp'] = ss.fit_transform(df_test[['SibSp']])
df_test['Parch'] = ss.fit_transform(df_test[['Parch']])
df_test['Fare'] = ss.fit_transform(df_test[['Fare']])
df_test['namelen'] = ss.fit_transform(df_test[['namelen']])
df_test['withnum'] = ss.fit_transform(df_test[['withnum']])
df_test['cabinlen'] = ss.fit_transform(df_test[['cabinlen']])
#对连续性变量进行one-hot
df_test = pd.get_dummies(df_test)
#切分自变量和因变量
df_test_x = df_test.drop(['Embarked_Q','ticketclass_1','ticketclass_0','cabinclass_A','cabinclass_F','Embarked_Q','cabinclass_C','cabinclass_G'],axis=1).copy()
df_test_x.head()
#训练集中的字段在测试集中没有,则需要在测试集中补0
#求差值变量
delta1 = [x for x in df_x.columns if x not in df_test_x.columns]
delta1
#测试集中的字段在训练集中没有,去除
#求差值变量
delta1 = [x for x in df_test_x.columns if x not in df_x.columns]
delta1
print(len(df_x.columns))
print(len(df_test_x.columns))
#Fare有空值
#Age有空值,用中位数填充
df_test_x['Fare'].fillna(df_test_x['Fare'].median(),inplace=True) #年龄缺失值用中位数补缺
df_test_x.info()
#输出结果
result = vote_clf.predict(df_test_x)
result = pd.Series(result)
result = pd.concat([df_test_id,result],keys=['PassengerId','Survived'],axis=1)
result.to_csv('result20200730.csv',index=False)
Copyright © 2024 妖气游戏网 www.17u1u.com All Rights Reserved