背景 關于 Kaggle
https://www.kaggle.com/
這是一個為你提供完美數(shù)據(jù),為你提供實際應用場景,可以與小伙伴在數(shù)據(jù)挖掘領域 high 的不要不要的的地方啊!!!
Kaggle 是一個用來學習、分享和競賽的線上數(shù)據(jù)實驗平臺,有點類似 KDD—CUP(國際知識發(fā)現(xiàn)和數(shù)據(jù)挖掘競賽),企業(yè)或者研究者可以將背景、數(shù)據(jù)、期望指標等發(fā)布在 kaggle 上,用競賽的方式向全世界的數(shù)據(jù)科學家和愛好者尋求解決方案。熱愛數(shù)(dong)據(jù)(shou)挖(zhe)掘(teng)的小伙伴們可以下載/分析數(shù)據(jù),使用統(tǒng)計/機器學習/數(shù)據(jù)挖掘等方面的知識,建立算法模型,得出結(jié)果并提交,排名靠前可能還會有獎勵哦!
關于泰坦尼克號之災https://www.kaggle.com/c/titanic
問題背景頁
下載 Data 的頁面
泰坦尼克號問題背景
就是大家從小到大被洗腦的“u jump I jump”的「jack 和 rose」的故事了。游艇在撞擊了一個冰山后沉沒了。乘客們都驚慌失措,副船長「lady and kid first」,所以模型不會向拋硬幣那樣看臉決定你是否獲救。而是有著一定背景的,至于出了女士和孩子優(yōu)先,還有哪些值得我們考慮,這就是稍后我們在特征工程中解決的問題了。
訓練和測試數(shù)據(jù)是一些乘客的個人信息以及存活情況,嘗試應用這些數(shù)據(jù)來建立一個合適的模型進行預測。
這是一個二分類問題(survived 或者 not),本文嘗試用 logistic regression 來處理問題
說明
「沒有所謂的算法優(yōu)劣,也沒有絕對高性能的機器學習算法,只有在特定的場景、數(shù)據(jù)和特征下更合適的機器學習的算法。」由于還只是在學習階段,對于 XGBC、隨機森林、SVC 還不了解,本文所用的算法只是 logistic regression。
初識數(shù)據(jù)在 Data 下我們會看到官方給的 train.csv 和 test.csv 兩個文件,分別是訓練和測試數(shù)據(jù)。我們可以使用 virtualenv 來創(chuàng)建一個“隔離”的 python 應用環(huán)境(虛擬環(huán)境)。在這里,你不需要考慮系統(tǒng)原有庫的版本,只需要 pip 來管理你需要用到的一切。
import pandas as pd import numpy as np from pandas import Series,DataFrame data_train = pd.read_csv("./train.csv") pd.DataFrame(data_train)
pandas 是常用的 python 數(shù)據(jù)處理包,把 csv 文件讀入成 dataframe 格式,在 jupyter notebook 中,可以看到我們的數(shù)據(jù)長什么樣:
我們就可以把它看作一張 excel 表格,共有 12 列,891 行(代表在 train_csv 中共有 891 個乘客)。Survived 字段代表該乘客是否獲救(1 代表獲救,0 代表沒有獲救),其余是一些個人信息
passengerId => 乘客的 ID
Pclass => 乘客所在艙位的等級(1、2、3 等艙)
Name => 姓名
Sex => 性別
Age => 年齡
SibSp => 兄弟姐妹個數(shù)
Parch => 父母與小孩個數(shù)
Ticket => 船票信息
Fare => 票價
Cabin => 客艙信息
Embarked => 登船所在港口
data_train.info()
這里告訴了我么一些關于 data_train 的基本信息,比如共有 891 個乘客,但是有些字段的數(shù)據(jù)不全。比如 Age(年齡)、Cabin(客艙信息)。
data_train.describe()
在這里我們看到了什么信息呢?從 mean 行中約有 0.38 的人最后獲救了,乘客的平均年齡為 29.7 歲,平均票價為 32.20
數(shù)據(jù)初步分析每個乘客大概有 12 種屬性提供給我們,僅僅對于上面兩行操作對于數(shù)據(jù)的了解還無法為我們提供想法和思路,我們現(xiàn)在不知道哪些有用哪些對于模型沒有用,所以到了最關鍵的特征工程環(huán)節(jié)。我們知道最終的 output 是 Suvived,現(xiàn)在需要尋找最后的 Survived 與各個屬性之間有著什么樣的內(nèi)在關系。從大副的口中已經(jīng)得知「要首先考慮婦女和兒童」。
for x in data1_x: if data1[x].dtype != "float64" : print("Survival Correlation by:", x) print(data1[[x, Target[0]]].groupby(x, as_index=False).mean()) print("-"*10, " ") print(pd.crosstab(data1["Title"],data1[Target[0]]))
在本圖中,我們發(fā)現(xiàn)女性有 0.74 活下來,而男性只有 0.18。歪果盆友果然很尊重 lady,lady first 踐行得不錯。性別無疑要作為重要特征加入最后的模型之中。在 Pclass 中,客艙為等級 1 的乘客獲救的概率高很多,嗯這個一定也影響最后獲救的結(jié)果(等級高的乘客一定也更有錢)。
fig = plt.figure() fig.set(alpha=0.2) Survived_0 = data_train.Pclass[data_train.Survived == 0].value_counts() Survived_1 = data_train.Pclass[data_train.Survived == 1].value_counts() df=pd.DataFrame({"Survived":Survived_1, "unSurvived":Survived_0}) df.plot(kind="bar", stacked=True) plt.title("Survived status of all passenger classes") plt.xlabel("passanger"s level") plt.ylabel("number") plt.show()
從本圖中我們可以看到,明顯如果你是等級為 1 的乘客,你的獲救概率就會很高。對了,這也是會最終影響輸出的獲救結(jié)果的一個特征。
data_train.Age[data_train.Pclass == 1].plot(kind="kde") data_train.Age[data_train.Pclass == 2].plot(kind="kde") data_train.Age[data_train.Pclass == 3].plot(kind="kde") plt.xlabel("age")# plots an axis lable plt.ylabel("dendity") plt.title("Age distribution of passengers levels") plt.legend(("first level", "second level","third level"),loc="best")
從各等級乘客的年齡分布中,我們可以看到「不同艙位/乘客等級可能和財富/地位有關系,最后獲救概率可能會不一樣」,所以年齡也會是影響我們最終結(jié)果的原因之一。
簡單數(shù)據(jù)預處理我們對大體數(shù)據(jù)已經(jīng)看過一遍了,對于感興趣的屬性也有了大概的了解。現(xiàn)在我們需要 簡單處理一下這些數(shù)據(jù),為機器學習建模做點準備了。先從最突出的數(shù)據(jù)屬性開始吧,Cabin 和 Age,因為這兩項有些乘客的信息不包含它們,有丟失的數(shù)據(jù)對于下一步的工作影響太大。
先說 Cabin,暫時我們就按照剛才說的,按 Cabin 有無數(shù)據(jù),將這個屬性處理成 Yes 和 No 兩種類型吧。
再說 Age:
通常遇到缺值的情況,我們會有幾種常見的處理方式
如果缺值的樣本占總數(shù)比例極高,我們可能就直接舍棄了,作為特征加入的話,可能反倒帶入 noise,影響最后的結(jié)果了
如果缺值的樣本適中,而該屬性非連續(xù)值特征屬性(比如說類目屬性),那就把 NaN 作為一個新類別,加到類別特征中
如果缺值的樣本適中,而該屬性為連續(xù)值特征屬性,有時候我們會考慮給定一個 step(比如這里的 age,我們可以考慮每隔 2/3 歲為一個步長),然后把它離散化,之后把 NaN 作為一個 type 加到屬性類目中。
有些情況下,缺失的值個數(shù)并不是特別多,那我們也可以試著根據(jù)已有的值,擬合一下數(shù)據(jù),補充上。
本例中,因為 Cabin 不是影響最終結(jié)果的特征之一。所以直接考慮別的需要用到的特征(性別,等級,等級),并將其中的類目型轉(zhuǎn)化為數(shù)值型特征,我們可以使用 pandas 的“get_dummies”來完成這個工作,并接在原來的“data_train”上
dummies_Embarked = pd.get_dummies(data_train["Embarked"], prefix= "Embarked") dummies_Sex = pd.get_dummies(data_train["Sex"], prefix= "Sex") dummies_Pclass = pd.get_dummies(data_train["Pclass"], prefix= "Pclass") df = pd.concat([data_train, dummies_Embarked, dummies_Sex, dummies_Pclass], axis=1) df.drop(["Pclass", "Name", "Sex", "Ticket", "Embarked"], axis=1, inplace=True) df
na!我們將這些類目屬性成功轉(zhuǎn)化為 0,1 的數(shù)值屬性了。這樣看來,好像差不多都完成了,可是如果再看看 Age 和 Fare 兩個屬性,乘客關于這兩個屬性的數(shù)值變化幅度也太大了!!如果大家了解邏輯回歸與梯度下降的話,會知道各屬性之間的 scale 差距太大,將對收斂速度造成很大的傷害(甚至不收斂)... 所以我們先用 scikit-learn 里面的 preprocessing 模塊對這兩個屬性做一個處理(就是將變化幅度較大的特征化到 [-1,1] 內(nèi))
import sklearn.preprocessing as preprocessing scaler = preprocessing.StandardScaler() age_scale_param = scaler.fit(df["Age"]) df["Age_scaled"] = scaler.fit_transform(df["Age"], age_scale_param) fare_scale_param = scaler.fit(df["Fare"]) df["Fare_scaled"] = scaler.fit_transform(df["Fare"], fare_scale_param) df
嗯,這樣初級的數(shù)據(jù)處理就完成的差不多了
建模我么把需要的 feature 字段提取出來,轉(zhuǎn)成 numpy 格式,使用 scikit-learn 中的 LogisticRegression 建模。
from sklearn import linear_model # 用正則取出我們要的屬性值 train_df = df.filter(regex="Survived|Age_.*|SibSp|Parch|Fare_.*|Cabin_.*|Embarked_.*|Sex_.*|Pclass_.*") train_np = train_df.as_matrix() # y 即 Survival 結(jié)果 y = train_np[:, 0] # X 即特征屬性值 X = train_np[:, 1:] # fit 到 RandomForestRegressor 之中 clf = linear_model.LogisticRegression(C=1.0, penalty="l1", tol=1e-6) clf.fit(X, y) clf
OK!!!通過這樣建模后,我們得到一個 model,然后再把 test.csv 通過同樣的數(shù)據(jù)簡單處理后,就可以得到預測結(jié)果了。
系統(tǒng)優(yōu)化等等,你以為這樣就完了么。這其實只完成了剛剛開始的一步,我們只是做了一個 baseline model,一切都還是基礎的,我們還需要優(yōu)化。
不過在現(xiàn)在的場景下,先不著急做這個事情,我們這個 baseline 系統(tǒng)還有些粗糙,先再挖掘挖掘。
首先,Name 和 Ticket 兩個屬性被我們完整舍棄了 (好吧,其實是因為這倆屬性,幾乎每一條記錄都是一個完全不同的值,我們并沒有找到很直接的處理方式)。
然后,我們想想,年齡的擬合本身也未必是一件非常靠譜的事情,我們依據(jù)其余屬性,其實并不能很好地擬合預測出未知的年齡。再一個,以我們的日常經(jīng)驗,小盆友和老人可能得到的照顧會多一些,這樣看的話,年齡作為一個連續(xù)值,給一個固定的系數(shù),應該和年齡是一個正相關或者負相關,似乎體現(xiàn)不出兩頭受照顧的實際情況,所以,說不定我們把年齡離散化,按區(qū)段分作類別屬性會更合適一些。(大家去 kaggle 上可以看看大神的 kernels)
文 / joeCDC
數(shù)學愛好者編 / 熒聲
本文已由作者授權發(fā)布,版權屬于創(chuàng)宇前端。歡迎注明出處轉(zhuǎn)載本文。本文鏈接:https://knownsec-fed.com/2018...
想要訂閱更多來自知道創(chuàng)宇開發(fā)一線的分享,請搜索關注我們的微信公眾號:創(chuàng)宇前端(KnownsecFED)。歡迎留言討論,我們會盡可能回復。
歡迎點贊、收藏、留言評論、轉(zhuǎn)發(fā)分享和打賞支持我們。打賞將被完全轉(zhuǎn)交給文章作者。
感謝您的閱讀。
文章版權歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/42737.html
showImg(https://segmentfault.com/img/bVbkB4E?w=800&h=400); 背景 關于 Kaggle https://www.kaggle.com/ 這是一個為你提供完美數(shù)據(jù),為你提供實際應用場景,可以與小伙伴在數(shù)據(jù)挖掘領域 high 的不要不要的的地方啊!!! Kaggle 是一個用來學習、分享和競賽的線上數(shù)據(jù)實驗平臺,有點類似 KDD—CUP(國際...
閱讀 2498·2021-11-25 09:43
閱讀 2607·2021-11-16 11:50
閱讀 3290·2021-10-09 09:44
閱讀 3200·2021-09-26 09:55
閱讀 2839·2019-08-30 13:50
閱讀 1031·2019-08-29 13:24
閱讀 2076·2019-08-26 11:44
閱讀 2802·2019-08-26 11:37