相信每一个在机器学习感兴趣的小伙伴都对kaggle有所耳闻,甚至也自己上面打过一两场。kaggle上有很多经典的比赛可以让我们练手,最有名的当然要属泰坦尼克号的生存预测了。kaggle官网的泰坦尼克地址当然这么有名的题目解法一定很多,个人认为用logstic就可以解决(但是本身验证之后发现准确率不高)所以在这里给大家介绍一下另一个著名的解法——神经网络
一.介绍
1.编译器:Pycharm
2.dataset:训练数据集及测试数据集下载地址
二.数据处理
先附上一张预测结果图片(坐标大小没选好,但是可以看出来train_acc和test_acc都是在1.0附近的)
第一步:我们先引入需要用到的库
如果没有这些库的朋友可以在File->Setting->Interpreter中下载自己需要用到的库
data = pd.read_csv("train.csv") #利用pandas的read_csv函数将数据读入#我们可以看到数据中有好多是对我们没有帮助的#因此我们只需要提取出对我们有帮助的如下数据data = data[['Survived','Pclass','Sex','Age','SibSp','Parch','Fare','Cabin','Embarked']]#处理string类型和Nan类型的数据为数值型数据#由于有一些年龄的值为空,因此我们用一种比较保守的方法填充一下这些空值,取所有年龄的平均值即可data['Age'] = data['Age'].fillna(data['Age'].mean())#利用factorize方法进行数值化操作,返回一个元组,元祖的第一个值就是数值化的数值#Cabin指的是船的舱位,一般舱位会对能否顺利逃生造成影响data['Cabin'] = pd.factorize(data.Cabin)[0]data.fillna(0,inplace = True)#男人用数字1表示,女人用数字0表示,相信应该没有别的性别.....I guess so.data['Sex'] = [1 if x == 'male' else 0 for x in data.Sex]
如果这里大家对factorize这个函数不是很熟悉可以查看一下官方文档,也可以print(data['Cabin])来观察一下数据,相信就可以很清楚这个函数的功能。
这里向大家说明一下,为什么要选出这些数据,因为船舱等级,性别,年龄,是否有姐弟在船上,是否有父母在船上,登陆港口,以及船票价格等等因素,大家细想这些因素对我们是否可以生存都起着关键性的作用。
得嘞,咱继续
#这里要把Pclass改一下,因为如果单纯是Pclass=1,2,3的话,计算机会自动把它当成一种线性关系进行处理data['p1'] = np.array(data['Pclass'] == 1).astype(np.int32)data['p2'] = np.array(data['Pclass'] == 2).astype(np.int32)data['p3'] = np.array(data['Pclass'] == 3).astype(np.int32)del data['Pclass']
#与Pclass处理同理data['e1'] = np.array(data['Embarked'] == 'S').astype(np.int32)data['e2'] = np.array(data['Embarked'] == 'C').astype(np.int32)data['e3'] = np.array(data['Embarked'] == 'Q').astype(np.int32)del data['Embarked']
由于计算机会把1,2,3这种数据当做是一种线性关系来处理,同理我们对Embarked登陆港口也换成是比较明朗的表达方式
下面我们来取出要取出要寻来你的数据,并对测试数据做一些处理
#取出训练数据data_train = data[['Sex','Age','SibSp','Parch','Fare','Cabin','p1','p2','p3','e1','e2','e3']]#设置.values,是因为直接取出Survived的话,结果是一个Seriesdata_target = data['Survived'].values.reshape(len(data),1)
在介绍后面的代码之前,向大家介绍两个tensorflow的函数,placeholder()和Variable(),这个函数大家可以理解为声明变量的前序准备,但是这么定义变量之后需要global_variables_initializer()函数对这些变量进行初始化即可以完成这些变量的定义和赋值
#搭建训练模型x = tf.placeholder("float",shape = [None,12])y = tf.placeholder("float",shape = [None,1])#定义一个变量权重,每一个特征对应一个权重,因此有12个#randon_normal是随机生成符合正态分布的数据后面的参数提供了生成的数据维度weight = tf.Variable(tf.random_normal([12,1]))bias = tf.Variable(tf.random_normal([1]))#matmul表示矩阵相乘output = tf.matmul(x,weight) + bias#cast方法可以将一个bool类型的数值,转化为规定的类型,0.0或者1.0pred = tf.cast(tf.nn.sigmoid(output) > 0.5,tf.float32)
#定义损失函数,使用的参数一个是labels,表示正确值,logits表示在经过sigmod运算之前的数值#reduce_mean表示将一个向量值转变成一个标量值#sigmod_cross_entropy_with_logits是一个重要的计算loss function 的函数loss = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(labels = y,logits = output))#利用梯度下降来最小化losstrain_step = tf.train.GradientDescentOptimizer(0.003).minimize(loss)#求精度accuracy = tf.reduce_mean(tf.cast(tf.equal(pred,y),tf.float32))
一些tenforflow的函数已经在注释中作了介绍,如果觉得还有些晦涩的话,可以去tensorflow的官方文档做详细了解tensorflow官方文档
下面我们来对测试集做处理,这里的处理和训练集极其相似,不做详细介绍.
#对test数据集进行数据处理data_test = pd.read_csv("test.csv")data_test = data_test[['Pclass','Sex','Age','SibSp','Parch','Fare','Cabin','Embarked']]data_test['Age'] = data_test['Age'].fillna(data_test['Age'].mean())data_test['Cabin'] = pd.factorize(data_test.Cabin)[0]data_test.fillna(0,inplace = True)data_test['Sex'] = [1 if x == 'male' else 0 for x in data_test.Sex]data_test['p1'] = np.array(data_test['Pclass'] == 1).astype(np.int32)data_test['p2'] = np.array(data_test['Pclass'] == 2).astype(np.int32)data_test['p3'] = np.array(data_test['Pclass'] == 3).astype(np.int32)del data_test['Pclass']data_test['e1'] = np.array(data_test['Embarked'] == 'S').astype(np.int32)data_test['e2'] = np.array(data_test['Embarked'] == 'C').astype(np.int32)data_test['e3'] = np.array(data_test['Embarked'] == 'Q').astype(np.int32)del data_test['Embarked']
最后一步处理数据,就是与实际的数据集,也就是gender_submission.csv进行比较
#与实际数据集进行比较test_label = pd.read_csv("gender_submission.csv")#将数据进行reshape并且重新设置数据类型test_label = np.reshape(test_label.Survived.values.astype(np.float32),(418,1))
OK,下面到了一些比较次要的环节(因为个人认为,ML最重要的处理数据,数据处理明白了训练的过程就相当简单了)
三.模型训练
tensorflow开始训练模型的时候一定要先声明一个session,并将这个创建的session运行起来,一般的代码如下:
sess = tf.Session()sess.run()
但是这里我们之前已经说过了,我们定义了Variable和placeholder,所以这里的run没有那么简单,而应该是:
sess.run(tf.global_variables_initializer())
我们先来看一下训练的全部代码
#开始训练sess = tf.Session()#初始化参数sess.run(tf.global_variables_initializer())loss_train = []train_acc = []test_acc = []for i in range(25000):#为防止过拟合,对数据索引进行乱序#permutation函数的作用是用来乱序的,有返回值,不改变原数组,与shuffle不同index = np.random.permutation(len(data_target))data_train = data_train.loc[index]data_test = data_test.loc[index]#每次取出100个数据,因此要设置range(len(data_taregt) // 100 + 1)for n in range(len(data_target) // 100 + 1):batch_xs = data_train[n * 100:n * 100 + 100]batch_ys = data_target[n * 100:n * 100 + 100]#feed_dict表示的是用于训练的数据,是一个字典类型,通常要把x,y都传入进去sess.run(train_step,feed_dict = {x:batch_xs,y:batch_ys})if i % 1000 == 0:loss_temp = sess.run(loss,feed_dict = {x:batch_xs,y:batch_ys})loss_train.append(loss_temp)train_acc_temp = sess.run(accuracy,feed_dict = {x:batch_xs,y:batch_ys})train_acc.append(train_acc_temp)#求测试的精度,要传入的是测试集和真实标签#将data_test处理成与test_label相同维度test_acc_temp = sess.run(accuracy,feed_dict = {x:data_test[:418],y:test_label})test_acc.append(test_acc_temp)print(loss_temp,train_acc_temp,test_acc_temp)
这里面内部原理很简单,其实就是把这些数据分开处理,训练25000次,每次取出100个数据,每训练1000次就输出一下这1000次训练之后的损失程度,训练集的精确度,测试集的精确度。大家运行代码之后,可以发现准确率在不断上升,而损失会先上升再下降.
四.画图表示
最后一步啦!画图显示我们的结果
五.总结
OK,我们的泰坦尼克号的生存率预测项目就写完了。这段代码没有什么特殊的要求,大家只需要安装好需要使用到的库,将数据库下载到同名目录下就可以直接进行预测了。
另外kaggle上还有很多有意思的项目,如果大家对ML有兴趣可以自己尝试打一打比赛,觉得自己有一点基础了想提高一下可以试试鲸鱼尾巴的比赛鲸鱼尾巴的识别这是一个国外大佬的代码,大家可以看看作为参考,以后我也会再写一篇文章对我的算法和思路做出介绍。
包括一些tensorflow的用法,比较简单的利用CNN进行MNIST手写数据库识别,还有RNN的一些知识。
Machine learning个人认为还是很有意思的,虽然对一些理论要求很高(比如数学),不过在学数学,学理论算法的时候,也别忘了自己敲敲代码做一些实战练习。