量化投資學習筆記19——迴歸分析:實操,泰坦尼克號乘客生還機會預測,線性迴歸方法。

用kaggle上的泰坦尼克的數據來實操。
https://www.kaggle.com/c/titanic/overview
在主頁上下載了數據。
任務:使用泰坦尼克號乘客數據建立機器學習模型,來預測乘客在海難中是否生存。
在實際海難中,2224位乘客中有1502位遇難了。似乎有的乘客比其它乘客更有機會獲救。本任務的目的就是找出哪類人更容易獲救。
數據集有兩個,一個是訓練數據集"train.csv",另一個是測試數據集"test.csv"。
官方推薦一個教程:https://www.kaggle.com/alexisbcook/titanic-tutorial
先照着來吧。
就是熟悉了整個結果上傳流程,使用了隨機樹森林算法,結果正確率是77.551%,排9444位。
接下來就是我自己折騰了。
讀取數據後,用info函數看看。
print(train_data.info())
print(test_data.info())

有三列數據有缺失值。先將數據可視化吧。

第一張是遇難者與獲救者的比例,第二張是三個票價等級的人數,第三張是遇難者及獲救者的年齡分佈,第四張是按船票等級的年齡分佈,最後一張是三個港口的登船人數。
再畫一個不同船票等級的乘客的獲救率。

可見高等級的獲救率更高。
再畫圖看性別與獲救的關係

真是lady first
下面再看各個艙別的獲救人數。

高等艙的女性生還率最高,其次是高等艙男性,低等艙男性生還率最低。
再看各港口登船的情況。

三個港口登船人數依次下降,死亡率差不多。
有堂兄弟妹,有子女父母對死亡率的影響。
g = train_data.groupby(["SibSp", "Survived"])
df = pd.DataFrame(g.count()["PassengerId"])
print(df)

g = train_data.groupby(["Parch", "Survived"])
df = pd.DataFrame(g.count()["PassengerId"])
print(df)

沒看出啥來。
Cabin缺失數據太多,畫圖看看數據缺失的和有數據的兩組死亡率是否有差別。

貌似有cabin記錄的獲救率高一些。
接下來就要清洗數據了,主要是處理缺失的數據,進行數據轉換。
(下面參考了https://blog.csdn.net/weixin_44451032/article/details/100103998)
先查看缺失值
print(train_data.isnull().sum())
print(test_data.isnull().sum())

主要是Age、Embarked和Cabin三個字段的缺失數據較多。
Age用年齡中位數填充,登船地點填充爲衆數,Cabin則採用因子化,即根據有無Cabin數據分爲兩類。
train_data["Age"].fillna(train_data["Age"].median(), inplace = True)
test_data["Age"].fillna(test_data["Age"].median(), inplace = True)
train_data["Embarked"] = train_data["Embarked"].fillna('S')
train_data.loc[(train_data.Cabin.notnull()), "Cabin"] = 1
train_data.loc[(train_data.Cabin.isnull()), "Cabin"] = 0
test_data.loc[(test_data.Cabin.notnull()), "Cabin"] = 1
test_data.loc[(test_data.Cabin.isnull()), "Cabin"] = 0
再看看有沒有缺失數據的

行啦。
接下來把非數值數據轉換爲數值數據
將性別數據轉換爲數值數據
train_data.loc[train_data["Sex"] == "male", "Sex"] = 0
train_data.loc[train_data["Sex"] == "female", "Sex"] = 1
test_data.loc[test_data["Sex"] == "male", "Sex"] = 0
test_data.loc[test_data["Sex"] == "female", "Sex"] = 1
將登船地點數據轉換爲數值數據
C:0, Q:1, S:2
train_data.loc[train_data["Embarked"] == 'C', "Embarked"] = 0
train_data.loc[train_data["Embarked"] == 'Q', "Embarked"] = 1
train_data.loc[train_data["Embarked"] == 'S', "Embarked"] = 2
test_data.loc[test_data["Embarked"] == 'C', "Embarked"] = 0
test_data.loc[test_data["Embarked"] == 'Q', "Embarked"] = 1
test_data.loc[test_data["Embarked"] == 'S', "Embarked"] = 2

print(train_data.head())
print(test_data.head())

最後,提取我們認爲在預測模型中重要的特徵: Pclass,Sex,Age,Embarked,SibSp,Parch,Cabin
構建一個新的數據表。
columns = ['Pclass', 'Sex', 'Age', 'SibSp', 'Parch', 'Embarked', 'Survived', 'Cabin']
new_train_data = train_data[columns]
print(new_train_data.info())

OK,可以開始建模了。
先用剛學的線性迴歸模型。
線性迴歸模型
特徵變量
predictors = ['Pclass', 'Sex', 'Age', 'SibSp', 'Parch', 'Embarked', 'Cabin']
LR = LinearRegression()
設置進行交叉驗證
kf = KFold(5, random_state = 0)
train_target = new_train_data["Survived"]
accuracys = []
for train, test in kf.split(new_train_data):
LR.fit(new_train_data.loc[train, predictors], new_train_data.loc[train, "Survived"])
pred = LR.predict(new_train_data.loc[test, predictors])
pred[pred >= 0.6] = 1
pred[pred < 0.6] = 0
accuracy = len(pred[pred == new_train_data.loc[test, "Survived"]])/len(test)
accuracys.append(accuracy)
print(np.mean(accuracys))
結果:0.799083547799887
提交kaggle以後結果並不好。

再看看回歸的具體結果。
print("迴歸係數:", LR.coef_)
print("截距:", LR.intercept_)
X = new_train_data[predictors]
y = new_train_data["Survived"]
Y = LR.predict(X)
print("模型評分:", LR.score(X, y))
i = 241
for index in predictors:
X = new_train_data[index]
fig = plt.subplot(i)
i += 1
plt.plot(X, Y, "*")
plt.plot(X, y, "o")
plt.savefig("LRtest.png")
結果:
迴歸係數: [-0.13393963 0.50834201 -0.00505791 -0.03254537 -0.03019912 -0.02651349
0.11037934]
截距: 0.7106465692231267
0.40082362319192455
模型的R²才0.4(越接近1越理想)。

看着也沒啥聯繫。再看看每個迴歸係數的檢驗吧。sklearn裏似乎沒有相關函數,還是用statsmodels模塊裏的函數。
# 看模型的假設檢驗
X = new_train_data[predictors]
X = sm.add_constant(X)
model = sm.OLS(Y, X).fit()
res = get_index(model)
print("迴歸參數", model.params)
print("迴歸結果", res)
print(model.summary())

迴歸係數跟用sklearn算的一樣,但檢驗結果卻特別好,有點詭異。可能是因爲這個問題很多變量只有少數幾個值,甚至兩個值,是離散變量,不適合直接用線性迴歸。
再試試其它方法。
本文代碼: https://github.com/zwdnet/MyQuant/tree/master/titanic
以後關於這個問題的代碼都放到這裏面。

我發文章的四個地方,歡迎大家在朋友圈等地方分享,歡迎點“在看”。
我的個人博客地址:https://zwdnet.github.io
我的知乎文章地址: https://www.zhihu.com/people/zhao-you-min/posts
我的博客園博客地址: https://www.cnblogs.com/zwdnet/
我的微信個人訂閱號:趙瑜敏的口腔醫學學習園地

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章