kaggle入門題Titanic

集成開發環境:Pycharmhtml

python版本:2.7(anaconda庫)python

用到的庫:科學計算庫numpy,數據分析包pandas,畫圖包matplotlib,機器學習庫sklearn數組

大致步驟分爲三步:機器學習

1.數據分析函數

2.交叉驗證學習

3.預測並輸出結果測試

 

導入庫函數spa

import numpy as np
import pandas as pa
import matplotlib.pyplot as pl
from sklearn.linear_model import LogisticRegression
from sklearn import model_selection
# 最後一個庫是原來cross_validation的替代,原來那個過期了,再用會有警告,其實裏邊的函數都沒變

 

第一步:數據分析code

1.1經過畫圖分析出數據中對預測影響很小的特徵值,忽略這些特徵能夠減少工做量htm

 

 1 # pandas庫裏的read_csv能夠把csv文件讀取爲dataFrame對象,這個對象就是不少列(數組)共享一個index,這個index 是真的存在的且能夠指定,每一列都有name
 2 # 其形狀大小是真實數據的形狀,不包括index和name
 3 # 路徑能夠是絕對路徑和相對路徑,注意路徑中的反斜線是兩根,或者一根/
 4 train_obj = pa.read_csv('train.csv')
 5 test_obj = pa.read_csv('test.csv')
 6 
 7 # 首先把一看就知道對結果沒有影響的數據去掉
 8 # DataFrame對象的drop方法:刪除行或者列,能夠多行,drop('行名或者列名',axis=0/1(0是行,1是列)),多個行名或者列名:['','']
 9 trainData = train_obj.drop(['Name', 'Ticket', 'Cabin'], axis=1)
10 testData = test_obj.drop(['Name', 'Ticket', 'Cabin'], axis=1)
11 
12 # 下面用畫圖的形式對其餘變量對最後結果的影響做出判斷:
13 # 首先考察船艙和性別,用groupby函數對的數據進行分類,groupby('列名'),根據給出的列,把具備相同數值的合爲一組,組數爲列值的種數
14 # 若是groupby(['列名1','列名2']),則列1爲分大類,大類中再根據列2進行分類
15 train_group1 = trainData.groupby(['Sex', 'Pclass'])  # 返回類型是Groupby類型,裏邊有key1*key2組
16 # sum()是將各組內每一個特徵的全部數據相加,返回也是key1*key2組,只不過每組裏只有一行數據,是全部數據之和
17 # count()是統計各組每一個特徵的數據量(因爲有缺失數據,因此各個特徵間是不必定同樣的)
18 rate = (train_group1.sum() / train_group1.count())['Survived']  # 有6組,每組都只有一個值,生存率
19 
20 # 下面開始畫圖,柱狀圖
21 x = np.array([1, 2, 3])
22 wi = 0.15
23 # bar(left,height,width,color)用來化柱狀圖,參數分別是每一個柱子的中心位置座標,高度(通常就是數據),寬度,顏色,前三個通常都是集合
24 pl.bar(x-wi, rate.female, wi*2, color='r')
25 pl.bar(x+wi, rate.male, wi*2, color='b')
26 pl.title("survived rate")
27 # 座標軸名稱
28 pl.xlabel("Pclass")
29 pl.ylabel("rate")
30 # 指定網格線格式
31 pl.grid(True, linestyle='-', color='0.7')
32 # 軸的刻度
33 pl.xticks([1, 2, 3])
34 # arange(起點,終點,間隔),建立一個等差序列
35 pl.yticks(np.arange(0.0, 1.1, 0.1))
36 # 對不一樣的柱作標記
37 pl.legend(['female', 'male'])
38 pl.show()
39 # 接下來的過程和上邊差很少,分別是判斷了年齡、上船地點、船上親屬人數

 

分析性別和上船地點的結果,結果顯示兩個特徵的影響都須要保留

 

 

1.2數據預處理,將特徵中比較類似的直接相加做爲一個,非數值類型轉爲數值類型,對缺失值進行處理

 1 # 船上的親屬人數就是把兩個表明家眷的變量相加
 2 trainData['family'] = trainData['SibSp'] + trainData['Parch']
 3 # pandas中的map()函數通常是用來進行數據轉換的,參數是函數或者字典,一個series調用map(),會對照字典用的key,將series中的key所有改爲相應的value,map()函數返回一個新的,對源對象不操做
 4 trainData['Sex'] = trainData['Sex'].map({'female': 0, 'male': 1})
 5 trainData['Embarked'] = trainData['Embarked'].map({'C': 0, 'Q': 1, 'S': 2})
 6 # numpy.isnan()函數的做用是返回一個Boolean數組,對應input的下標,若當前位置是nan那麼就是true,不然false
 7 # 對一個數組挑選時能夠用array[True,False,True...]True就是選擇
 8 # 挑選出age爲nan的,這個集合不用age這個特徵,作四特徵預測
 9 train_age_nan = trainData[np.isnan(trainData['Age'])]
10 # 挑選出age不爲空的數據,直接調用dropna(),這個方法會去掉輸入數組中有nan特徵的數據,挑選後的具有全部特徵,因此能夠用全部特徵
11 train_all = trainData.dropna()
12 # 對於以上兩個數據集分別挑選出須要的特徵組成訓練集,由於以前已經確認了有的是對結果沒有影響的,因此能夠只挑選有用的
13 # dataframe選取列的格式是兩個方括號,[['列名','列名']]
14 train_five = train_all[['Sex', 'Embarked', 'family', 'Age', 'Pclass']]
15 train_four = train_age_nan[['Sex', 'Embarked', 'family', 'Pclass']]
16 
17 # 兩個數據集的標記數組
18 train_five_label = train_all['Survived']
19 train_four_label = train_age_nan['Survived']
20 
21 # 至此處理數據工做所有完成,接下來就是訓練模型

2.交叉驗證

 

 1 # 使用分類器類
 2 classifier = LogisticRegression(C=10000)  # 這個做爲5特徵分類器,這裏的c是正則化係數,防止系統因爲過於複雜而產生過擬合
 3 # 調用cross_validation.cross_val_score(分類器,data,target,cv),這個函數返回每次交叉驗證的準確率,方法是StratifiedKFold,具體看http://blog.sina.com.cn/s/blog_6a90ae320101a5rc.html
 4 # 函數返回一個數組
 5 score = model_selection.cross_val_score(classifier, train_five, train_five_label, cv=5)  # 交叉驗證
 6 classifier2 = LogisticRegression()  # 這個做爲4特徵分類器
 7 score2 = model_selection.cross_val_score(classifier2, train_four, train_four_label, cv=5)  # 交叉驗證
 8 # 查看平均值
 9 print "五特徵分類器交叉驗證結果:"
10 print score.mean()
11 print "四特徵分類器交叉驗證結果:"
12 print score2.mean()

 

 

 

3.輸出結果

 

 1 # 下面開始輸出結果
 2 
 3 # 首先處理測試集
 4 testData['Sex'] = testData['Sex'].map({'female': 0, 'male': 1})
 5 testData['Embarked'] = testData['Embarked'].map({'C': -1, 'Q': 0, 'S': 1})
 6 testData['family'] = testData['SibSp'] + testData['Parch']
 7 # 這裏不能用兩個數據集,由於若是將數據分開分別判斷,那麼沒法和乘客號對應
 8 # 讀取官方結果
 9 answer = pa.read_csv('gender_submission.csv')
10 
11 # 訓練分類器
12 classifier.fit(train_five, train_five_label)
13 classifier2.fit(train_four, train_four_label)
14 
15 # 輸出測試集結果
16 passengers = pa.DataFrame(testData['PassengerId'])
17 # 這裏必須先建立一個列,直接賦值會出錯
18 passengers['Survived'] = ''
19 # isnan()是numpy庫裏的函數
20 #這裏有個問題就是若是直接對passengers['Survived'][i]每行賦值的話會有SettingCopyWarning警告,正確的方法是先生成一個數組temp,而後把數組賦值給列,直接添加會有警告
21 #這裏建立數組不能用np.zeros(),由於用zeros生成的是float數組,最後結果要求int類型
22 temp = [0] * passengers.shape[0]
23 for i in range(len(testData)):
24     if np.isnan(testData['Age'][i]):
25         # 這裏也有一個問題:因爲須要一個一個作預測,可是predict函數要求輸入二維數組,單行數據是一維的
26         #因此要把數據轉爲numpy中的array,而後轉爲二維數組
27         #reshape()函數能夠利用原數組數據改變數組的尺寸,可是主要新舊數組數據量相同,而reshape(1,-1)能夠將[xxx]轉爲[[xxx]]這種,就能夠用了
28         temp[i] = int(classifier2.predict(np.array( testData[['Pclass', 'Sex', 'Embarked', 'family']].ix[i].dropna()).reshape(1,-1)))
29     else:
30         temp[i] = int(classifier.predict(np.array(testData[['Sex', 'Embarked', 'family', 'Age', 'Pclass']].ix[i]).reshape(1,-1)))
31 print temp
32 passengers['Survived'] = temp
33 # 結算準確率
34 acc = 1 - float(sum(abs(answer['Survived'] - passengers['Survived']))) / len(passengers)
35 print "準確率是:"
36 print acc
37 # 輸出文件
38 passengers.to_csv('result.csv',encoding='utf-8',index=False)

 

 

 

 

 最後的結果,準確率有點低,再找找緣由

相關文章
相關標籤/搜索