这是一篇很难写的文章,因为希望这篇文章能对大家有所帮助。我不会给大家介绍机器学习和数据挖掘的行业背景,也不会具体介绍逻辑回归、SVM、GBDT、神经网络等学习算法的理论基础和数学推导,这篇文章更多的是帮助大家您在流程方面对机器学习和数据建模的快速介绍。本文主要分为四个部分(限于时间关系,将分为两部分):第1部分:准备,主要涉及环境搭建和pandas基础知识。在应用部分,我会以kaggle上的Titanic为例,从数据源获取、数据清洗、特征处理、模型选择、模型输出到应用。下一篇:优化,介绍几种优化方法。思考文章,提出几个困扰我的问题,希望得到大家的帮助。1准备1环境搭建整个sklearn的实验环境为:python2.7+pycharm+Anaconda。2pandas基础知识这里只能介绍一下下面会用到的pandas知识,有兴趣的可以详细学习。给大家推荐一本参考书:《Python for Data Analysis》。有基础的可以直接跳到应用章节。Pandas主要使用两种数据结构,Series和DataFrame。Series就像是一维数组,而DataFrame更像是二维表结构。Series的构造方法:label=[1,0,1,0,1]data=pd.Series(data=label,index=['a','b','c','d','e'],dtype=int,name="label")printdataSeries取数据,通过index取数据data['a']data[['a','b']]DataFrame构造(1)构造frame的形式dictionary=pd.DataFrame({'name':['Time','Jack','Lily'],'Age':[20,30,12],"weight":[56.7,64.0,50.0]})(2)DataFrame是从DataFrame构造出来的。DataFrameframe1=pd.DataFrame(frame,columns=["name","Age"])从frame中读取两列,组成一个新的DataFrame。DataFrame的操作1添加列frame1["friends_num"]=[10,12,14]2删除列frame2=frame1.drop(["name","Age"],axis=1)3查找数据行frame1[frame1["friends_num"]>10]结果如下:DataFrame的统计方法1apply配合lambda处理列,比如对frame1的Age列进行切分。frame1["Age_group"]=frame1["Age"].apply(lambdax:0ifx<20else1)2描述输出统计,非常强大的frame1.describe()给出了8个统计,对我们的数据处理特别有用。有一个问题。直接使用describe方法只能对数值类的列进行统计,对字符类的变量没有统计。只需添加一个参数。frame1.describe(include=['O'])3缺失值处理#用0填充缺失值frame1.fillna(0)#丢弃所有包含NAN的行frame1.dropna()#删除所有为nanframe1的行。dropna(how="all")II应用1数据读取本例中以泰坦尼克号为数据源。您可以在附件中获取数据。data=pd.DataFrame(pd.read_csv(train_path))data_test=pd.DataFrame(pd.read_csv(test_path))data_test=data_test[["Pclass","Name","Sex","Age","SibSp""Parch","Ticket","Fare","Cabin","Embarked"]]x=data[["Pclass","Name","Sex","Age","SibSp","Parch""机票","票价","机舱","登船"]]y=数据[["幸存"]]printx.describe()printx.describe(include=['O'])printdata_test.describe()printdata_test.describe(include=['O'])数据的初始统计信息:2数据清洗1缺失值处理。Age和Embarked列有少量缺失值,分别处理。#用众数填充缺失值data_set["Embarked"]=data_set["Embarked"].fillna('S')#用均值填充Age缺失值data_set["Age"]=data_set["Age".fillna(data_set["Age"].mean())2删除缺失率高的列(初步处理时)Cabin列缺失率已经达到75%,删改列。data_set=data_set.drop(["Cabin"],axis=1)3特征处理特征处理是基于特定的数据,因此在进行特征处理之前需要充分了解数据。特征处理没有固定的方法。主要靠个人经验和观察,通过不断的尝试和改变,希望能挖掘出更好的特征变量。因此,特征处理是模型构建过程中最耗时耗脑的工作。1)单变量特征提取。#根据name的长度,抽象出name_len特征data_set["name_len"]=data_set["Name"].apply(len)观察name栏通过观察Name栏的数据,可以找到title信息以性别和婚姻为名。提取此信息(可能有用的功能)。data_set["name_class"]=data_set["Name"].apply(lambdax:x.split(",")[1]).apply(lambdax:x.split()[0])2)多个变量的组合sibsp表示兄弟姐妹和配偶的数量parch表示父母和子女的数量,所以可以将sibsp和parch合并得到家庭成员的数量data_set["family_num"]=data_set["Parch"]+data_set["SibSp"]+13)将名义变量转换为数值变量#Embarkeddata_set["Embarked"]=data_set["Embarked"].map({'S':1,'C':2,'Q':3}).astype(int)#Sexdata_set["Sex"]=data_set["Sex"].apply(lambdax:0ifx=='male'else1)4)数据切分是根据统计信息和经验切分#[7.91,14.45,31.0]是根据Fare的统计信息Segmentdata_set["Fare"]=data_set["Fare"].apply(lambdax:cutFeature([7.91,14.45,31.0],x))#[18,48,64]Segmentdata_set["Age"根据经验]=data_set["Age"].apply(lambdax:cutFeature([18,48,64],x))经过简单的数据处理,得到如下12维data:4模型选择和测试最初选择了5种类型测试模型RandomForestClassifierExtraTreesClassifierAdaBoostClassifierGradientBoostingClassifierSVC模型参数:#RandomForestrf_params={'n_jobs':-1,'n_estimators':500,'warm_start':True,#'max_features':0.2,'max_depth':6,'min_samples_leaf':2,'max_features':'sqrt','verbose':0}#ExtraTrees随机森林et_params={'n_jobs':-1,'n_estimators':500,#'max_features':0.5,'max_depth':8,'min_samples_leaf':2,'verbose':0}#AdaBoostada_params={'n_estimators':500,'learning_rate':0.75}#GBDTgb_params={'n_estimators':500,#'max_features':0.2,'max_depth':5,'min_samples_leaf':2,'verbose':0}#SVCsvc_params={'kernel':'linear','C':0.025}模型选择代码:classifiers=[("rf_model",RandomForestClassifier(**rf_params)),("et_model",ExtraTreesClassifier(**et_params)),("ada_model",AdaBoostClassifier(**ada_params)),("gb_model",GradientBoostingClassifier(**gb_params)),("svc_model",SVC(**svc_params)),]heldout=[0.95,0.90,0.75,0.50,0.01]rounds=20xx=1.-np.array(heldout)forname,clfinclassifiers:print("training%s"%name)rng=np.random.RandomState(42)yy=[]foriinheldout:yy_=[]forrinrange(rounds):X_train_turn,X_test_turn,y_train_turn,y_test_turn=\train_test_split(x_train,labels_train,test_size=i,random_state=rng)clf.fit(X_train_turn,y_train_turn)y_pred=clf.predict(X_test_turn)yy_.append(1-np.mean(y_pred==y_test_turn))yy.append(np.mean(yy_))plt.plot(xx,yy,label=name)plt.legend(loc="upperright")plt.xlabel("Proportiontrain")plt.ylabel("TestErrorRate")plt.show()选择结果如下:从上图可以看出,randomForest的总体性能优于其他算法,初步选择了randomforest算法。模型在训练集上的表现:defmodelScore(x_train,labels_train,x_test,y_test,model_name,et_params):print("--------%s------------")%(model_name)model=model_name(**et_params)model.fit(x_train,labels_train)if"feature_importances_"indir(model):printmodel.feature_importances_printclassification_report(labels_train,model.predict(x_train))printclassification_report(y_test,model.predict)(x_test))returnmodelmodelScore(x_train,labels_train,x_test,y_test,RandomForestClassifier,rf_params)训练集的混淆矩阵如下图:测试集的混淆矩阵如下图:至此初步学习模型建立,而测试集的准确度为83%。由于时间关系,优化和思考的文章会在下一篇文章中与大家分享,敬请期待。原文链接:https://cloud.tencent.com/community/article/229506作者:赵成龙【本文为专栏作者《腾讯云技术社区》原创稿件,转载请联系原作者获得授权】点此查看该作者更多好文
