kaggle(02)-房價預測案例(基礎版)

房價預測案例

Step 1: 檢視源數據集

import numpy as np
import pandas as pd

讀入數據

  • 一般來說源數據的index那一欄沒什么用,我們可以用來作為我們pandas dataframe的index。這樣之后要是檢索起來也省事兒。

  • 有人的地方就有鄙視鏈。跟知乎一樣。Kaggle的也是個處處呵呵的危險地帶。Kaggle上默認把數據放在input文件夾下。所以我們沒事兒寫個教程什么的,也可以依據這個convention來,顯得自己很有逼格。。

train_df = pd.read_csv('train.csv', index_col=0)
test_df = pd.read_csv('test.csv', index_col=0)

檢視源數據

train_df.head()
# print(train_df.info)
# print(train_df.shape)
MSSubClassMSZoningLotFrontageLotAreaStreetAlleyLotShapeLandContourUtilitiesLotConfig...PoolAreaPoolQCFenceMiscFeatureMiscValMoSoldYrSoldSaleTypeSaleConditionSalePrice
Id
160RL65.08450PaveNaNRegLvlAllPubInside...0NaNNaNNaN022008WDNormal208500
220RL80.09600PaveNaNRegLvlAllPubFR2...0NaNNaNNaN052007WDNormal181500
360RL68.011250PaveNaNIR1LvlAllPubInside...0NaNNaNNaN092008WDNormal223500
470RL60.09550PaveNaNIR1LvlAllPubCorner...0NaNNaNNaN022006WDAbnorml140000
560RL84.014260PaveNaNIR1LvlAllPubFR2...0NaNNaNNaN0122008WDNormal250000

5 rows × 80 columns

這時候大概心里可以有數,哪些地方需要人為的處理一下,以做到源數據更加好被process。

Step 2: 合并數據:將測試集和訓練集的數據進行合并,因為要對數據做預處理

這么做主要是為了用DF進行數據預處理的時候更加方便。等所有的需要的預處理進行完之后,我們再把他們分隔開。

首先,SalePrice作為我們的訓練目標,只會出現在訓練集中,不會在測試集中(要不然你測試什么?)。所以,我們先把SalePrice這一列給拿出來,不讓它礙事兒。

我們先看一下SalePrice長什么樣紙:

%matplotlib inline
prices = pd.DataFrame({"price":train_df["SalePrice"], "log(price + 1)":np.log1p(train_df["SalePrice"])})
prices.hist()
array([[<matplotlib.axes._subplots.AxesSubplot object at 0x7fbf9f8703c8>,<matplotlib.axes._subplots.AxesSubplot object at 0x7fbf97340400>]],dtype=object)

png

可見,label本身并不平滑。為了我們分類器的學習更加準確,我們會首先把label給“平滑化”(正態化)

這一步大部分同學會miss掉,導致自己的結果總是達不到一定標準。

這里我們使用最有逼格的log1p, 也就是 log(x+1),避免了復值的問題。

記住喲,如果我們這里把數據都給平滑化了,那么最后算結果的時候,要記得把預測到的平滑數據給變回去。

按照“怎么來的怎么去”原則,log1p()就需要expm1(); 同理,log()就需要exp(), … etc.

對于分類問題,不需要對標簽進行平滑處理,因為其結果本來就是需要離散化的;但是對于回歸問題,由于需要預測的是一個連續的值,所以需要訓練模型的數據的標簽也是平滑的,而對于訓練集,我們得到的標簽往往又是離散的,所以要先做平滑處理!

注:在比賽中,由于訓練集和測試集已經知道,所以常常為了更大的得到好的結果,常常將測試集和訓練集先混合在一起,然后在整體做數據的預處理;但是在實際的過程中,由于測試集是未知的,所以先對訓練集做處理,再用相同的方法去處理測試集。

y_train = np.log1p(train_df.pop('SalePrice'))

然后我們把剩下的部分合并起來

all_df = pd.concat((train_df, test_df), axis=0)

此刻,我們可以看到all_df就是我們合在一起的DF

all_df.shape
(2919, 79)

y_train則是SalePrice那一列

y_train.head()
Id
1    12.247699
2    12.109016
3    12.317171
4    11.849405
5    12.429220
Name: SalePrice, dtype: float64

Step 3: 變量轉化

類似『特征工程』。就是把不方便處理或者不unify的數據給統一了。

正確化變量屬性

首先,我們注意到,MSSubClass 的值其實應該是一個category,

但是Pandas是不會懂這些事兒的。使用DF的時候,這類數字符號會被默認記成數字。

這種東西就很有誤導性,我們需要把它變回成string

all_df['MSSubClass'].dtypes
dtype('int64')
all_df['MSSubClass'] = all_df['MSSubClass'].astype(str) #這個根據給出的數據集的描述可知,該屬性應該是表示的為級別,但是PD在讀取數據的時候會自動將其認為是數字,所以需要轉換為字符串

變成str以后,做個統計,就很清楚了

all_df['MSSubClass'].value_counts()
20     1079
60      575
50      287
120     182
30      139
160     128
70      128
80      118
90      109
190      61
85       48
75       23
45       18
180      17
40        6
150       1
Name: MSSubClass, dtype: int64

把category的變量轉變成numerical表達形式

當我們用numerical來表達categorical的時候,要注意,數字本身有大小的含義,所以亂用數字會給之后的模型學習帶來麻煩。于是我們可以用One-Hot的方法來表達category。

pandas自帶的get_dummies方法,可以幫你一鍵做到One-Hot。

pd.get_dummies(all_df['MSSubClass'], prefix='MSSubClass').head()#將分類數據轉換為數值型數據
MSSubClass_120MSSubClass_150MSSubClass_160MSSubClass_180MSSubClass_190MSSubClass_20MSSubClass_30MSSubClass_40MSSubClass_45MSSubClass_50MSSubClass_60MSSubClass_70MSSubClass_75MSSubClass_80MSSubClass_85MSSubClass_90
Id
10000000000100000
20000010000000000
30000000000100000
40000000000010000
50000000000100000

此刻MSSubClass被我們分成了12個column,每一個代表一個category。是就是1,不是就是0。

同理,我們把所有的category數據,都給One-Hot了

all_dummy_df = pd.get_dummies(all_df)
all_dummy_df.head()
LotFrontageLotAreaOverallQualOverallCondYearBuiltYearRemodAddMasVnrAreaBsmtFinSF1BsmtFinSF2BsmtUnfSF...SaleType_ConLwSaleType_NewSaleType_OthSaleType_WDSaleCondition_AbnormlSaleCondition_AdjLandSaleCondition_AllocaSaleCondition_FamilySaleCondition_NormalSaleCondition_Partial
Id
165.084507520032003196.0706.00.0150.0...0001000010
280.0960068197619760.0978.00.0284.0...0001000010
368.0112507520012002162.0486.00.0434.0...0001000010
460.0955075191519700.0216.00.0540.0...0001100000
584.0142608520002000350.0655.00.0490.0...0001000010

5 rows × 303 columns

處理好numerical變量

就算是numerical的變量,也還會有一些小問題。

比如,有一些數據是缺失 的:

all_dummy_df.isnull().sum().sort_values(ascending=False).head(10) #將數據中有缺失項的屬性統計出來并從大到小排序
LotFrontage     486
GarageYrBlt     159
MasVnrArea       23
BsmtHalfBath      2
BsmtFullBath      2
BsmtFinSF2        1
GarageCars        1
TotalBsmtSF       1
BsmtUnfSF         1
GarageArea        1
dtype: int64

可以看到,缺失最多的column是LotFrontage

處理這些缺失的信息,得靠好好審題。一般來說,數據集的描述里會寫的很清楚,這些缺失都代表著什么。當然,如果實在沒有的話,也只能靠自己的『想當然』。。

在這里,我們用平均值來填滿這些空缺。

mean_cols = all_dummy_df.mean()#得到所有列的平均值
mean_cols.head(10)   #打印出前10列數據的平均值
LotFrontage        69.305795
LotArea         10168.114080
OverallQual         6.089072
OverallCond         5.564577
YearBuilt        1971.312778
YearRemodAdd     1984.264474
MasVnrArea        102.201312
BsmtFinSF1        441.423235
BsmtFinSF2         49.582248
BsmtUnfSF         560.772104
dtype: float64
all_dummy_df = all_dummy_df.fillna(mean_cols) #用每一列的平均值填充每一列中的NAN項

看看是不是沒有空缺了?

all_dummy_df.isnull().sum().sum()
0

標準化numerical數據

這一步并不是必要,但是得看你想要用的分類器是什么。一般來說,regression的分類器都比較傲嬌,最好是把源數據給放在一個標準分布內。不要讓數據間的差距太大。

這里,我們當然不需要把One-Hot的那些0/1數據給標準化。我們的目標應該是那些本來就是numerical的數據:

先來看看 哪些是numerical的:

numeric_cols = all_df.columns[all_df.dtypes != 'object']
numeric_cols
Index(['LotFrontage', 'LotArea', 'OverallQual', 'OverallCond', 'YearBuilt','YearRemodAdd', 'MasVnrArea', 'BsmtFinSF1', 'BsmtFinSF2', 'BsmtUnfSF','TotalBsmtSF', '1stFlrSF', '2ndFlrSF', 'LowQualFinSF', 'GrLivArea','BsmtFullBath', 'BsmtHalfBath', 'FullBath', 'HalfBath', 'BedroomAbvGr','KitchenAbvGr', 'TotRmsAbvGrd', 'Fireplaces', 'GarageYrBlt','GarageCars', 'GarageArea', 'WoodDeckSF', 'OpenPorchSF','EnclosedPorch', '3SsnPorch', 'ScreenPorch', 'PoolArea', 'MiscVal','MoSold', 'YrSold'],dtype='object')

計算標準分布:(X-X’)/s

讓我們的數據點更平滑,更便于計算。

注意:我們這里也是可以繼續使用Log的,我只是給大家展示一下多種“使數據平滑”的辦法。

numeric_col_means = all_dummy_df.loc[:, numeric_cols].mean()#算出每一個數值型的屬性下數據的平均值
numeric_col_std = all_dummy_df.loc[:, numeric_cols].std()#算出每一個數值型的屬性下數據的方差
all_dummy_df.loc[:, numeric_cols] = (all_dummy_df.loc[:, numeric_cols] - numeric_col_means) / numeric_col_std #計算標準分布

Step 4: 建立模型

把數據集分回 訓練/測試集

dummy_train_df = all_dummy_df.loc[train_df.index]
dummy_test_df = all_dummy_df.loc[test_df.index]
dummy_train_df.shape, dummy_test_df.shape
((1460, 303), (1459, 303))

Ridge Regression

用Ridge Regression模型來跑一遍看看。(對于多因子的數據集,這種模型可以方便的把所有的var都無腦的放進去)

from sklearn.linear_model import Ridge
from sklearn.model_selection import cross_val_score

這一步不是很必要,只是把DF轉化成Numpy Array,這跟Sklearn更加配

X_train = dummy_train_df.values
X_test = dummy_test_df.values

用Sklearn自帶的cross validation方法來測試模型

alphas = np.logspace(-3, 2, 50)
test_scores = []
for alpha in alphas:clf = Ridge(alpha)test_score = np.sqrt(-cross_val_score(clf, X_train, y_train, cv=10, scoring='neg_mean_squared_error'))test_scores.append(np.mean(test_score))

存下所有的CV值,看看哪個alpha值更好(也就是『調參數』)

import matplotlib.pyplot as plt
%matplotlib inline
plt.plot(alphas, test_scores)
plt.title("Alpha vs CV Error");

png

可見,大概alpha=10~20的時候,可以把score達到0.135左右。

Random Forest

from sklearn.ensemble import RandomForestRegressor
max_features = [.1, .3, .5, .7, .9, .99]
test_scores = []
for max_feat in max_features:clf = RandomForestRegressor(n_estimators=200, max_features=max_feat)test_score = np.sqrt(-cross_val_score(clf, X_train, y_train, cv=5, scoring='neg_mean_squared_error'))test_scores.append(np.mean(test_score))
plt.plot(max_features, test_scores)
plt.title("Max Features vs CV Error");

png

用RF的最優值達到了0.137

Step 5: Ensemble

這里我們用一個Stacking的思維來汲取兩種或者多種模型的優點

首先,我們把最好的parameter拿出來,做成我們最終的model

ridge = Ridge(alpha=15)
rf = RandomForestRegressor(n_estimators=500, max_features=.3)
ridge.fit(X_train, y_train)
rf.fit(X_train, y_train)
RandomForestRegressor(bootstrap=True, criterion='mse', max_depth=None,max_features=0.3, max_leaf_nodes=None,min_impurity_decrease=0.0, min_impurity_split=None,min_samples_leaf=1, min_samples_split=2,min_weight_fraction_leaf=0.0, n_estimators=500, n_jobs=1,oob_score=False, random_state=None, verbose=0, warm_start=False)

上面提到了,因為最前面我們給label做了個log(1+x), 于是這里我們需要把predit的值給exp回去,并且減掉那個"1"

所以就是我們的expm1()函數。

y_ridge = np.expm1(ridge.predict(X_test))
y_rf = np.expm1(rf.predict(X_test))

一個正經的Ensemble是把這群model的預測結果作為新的input,再做一次預測。這里我們簡單的方法,就是直接『平均化』。

y_final = (y_ridge + y_rf) / 2  #對模型進行融合

Step 6: 提交結果

submission_df = pd.DataFrame(data= {'Id' : test_df.index, 'SalePrice': y_final})  

我們的submission大概長這樣:

submission_df.head(10)
IdSalePrice
01461120284.850938
11462151366.179663
21463174792.133120
31464190099.605945
41465195500.170436
51466175876.563502
61467177675.128914
71468169318.651321
81469184796.699921
91470122328.836416

走你~

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/445514.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/445514.shtml
英文地址,請注明出處:http://en.pswp.cn/news/445514.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

為什么Python中整型不會溢出

前言 本次分析基于 CPython 解釋器&#xff0c;python3.x版本 在python2時代&#xff0c;整型有 int 類型和 long 長整型&#xff0c;長整型不存在溢出問題&#xff0c;即可以存放任意大小的整數。在python3后&#xff0c;統一使用了長整型。這也是吸引科研人員的一部分了&am…

如何使用github中的pull request功能?

* pull request是社會化編程的象征&#xff0c;通過這個功能&#xff0c;你可以參與到別人開發的項目中&#xff0c;并做出自己的貢獻。pull request是自己修改源代碼后&#xff0c;請求對方倉庫采納的一種行為*–《github入門與實踐》 下面具體說一下github中使用pull reque…

「假裝努力」

有多少人在「假裝努力」&#xff1f; 又有多少人在「真正成長」&#xff1f; 再努力努力 回想起當年畢業后&#xff0c;在北京和室友合租的日子。 那時&#xff0c;我在工作&#xff0c;室友在培訓。 一天&#xff0c;我下班回來&#xff0c;聽見他在電話里和家人爭吵&…

如何閱讀論文?

本文主要講述了如何才能高效的閱讀一篇論文&#xff01;&#xff01;

貪吃蛇js

python都學不懂&#xff0c;c又不會&#xff0c;只能寫寫js來維持生活了。555555 js&#xff1a; window.onload function() {var wrap document.getElementsByClassName("wrap")[0];var uls document.getElementsByClassName("sbody")[0];var hand …

Android studio安裝過程中入的坑的記錄與記錄

Android studio安裝過程中入的坑的記錄與記錄 * 由于最近項目的需求&#xff0c;所以最近一直在配置安卓的開發環境&#xff0c;之前用的是Eclipse ADT的模式開發的&#xff0c;配置環境也花了一些時間&#xff0c;但是由于谷歌大力扶持它的親兒子Android Studio&#xff0c;…

動態規劃基礎水題提綱

提綱 漢諾塔 漢諾塔&#xff1a;漢諾塔&#xff08;又稱河內塔&#xff09;問題是源于印度一個古老傳說的益智玩具。大梵天創造世界的時候做了三根金剛石柱子&#xff0c;在一根柱子上從下往上按照大小順序摞著64片黃金圓盤。大梵天命令婆羅門把圓盤從下面開始按大小順序重新…

數據結構課上筆記8

串的概念&#xff1a;串&#xff08;字符串&#xff09;&#xff1a;是由 0 個或多個字符組成的有限序列。 通常記為&#xff1a;s ‘ a1 a2 a3 … ai …an ’ ( n≥0 )。 串的邏輯結構和線性表極為相似。 一些串的類型&#xff1a; 空串&#xff1a;不含任何字符的串&#x…

數據結構課上筆記9

數組&#xff1a;按一定格式排列起來的具有相同類型的數據元素的集合。 二維數組&#xff1a;若一維數組中的數據元素又是一維數組結構&#xff0c;則稱為二維數組。 同理&#xff0c;推廣到多維數組。若 n -1 維數組中的元素又是一個一維數組結構&#xff0c;則稱作 n 維數組…

pySerial -- Python的串口通訊模塊

pySerial Overview This module encapsulates the access for the serial port. It provides backends for Python running on Windows, Linux, BSD (possibly any POSIX compliant system), Jython and IronPython (.NET and Mono). The module named “serial” automatica…

串的堆分配實現

今天&#xff0c;線性結構基本就這樣了&#xff0c;以后&#xff08;至少是最近&#xff09;就很少寫線性基礎結構的實現了。 串的類型定義 typedef struct {char *str;int length; }HeapString; 初始化串 InitString(HeapString *S) {S->length0;S->str\0; } 長度 …

Numpy 入門

Numpy 入門 Numpy簡介 官網鏈接&#xff1a;http://www.numpy.org/NumPy是Python語言的一個擴充程序庫。支持高級大量的維度數組與矩陣運算&#xff0c;此外也針對數組運算提供大量的數學函數庫 Numpy的基本功能 快速高效的多維數組對象ndarray用于對數組執行元素級計算以…

數據結構課上筆記10

樹 樹的定義&#xff1a;樹(Tree)是 n(n≥0)個結點的有限集。若 n0&#xff0c;稱為空樹&#xff1b;若 n > 0&#xff0c;則它滿足如下兩個條件&#xff1a; (1) 有且僅有一個特定的稱為根 (Root) 的結點&#xff1b; (2) 其余結點可分為 m (m≥0) 個互不相交的有限…

pandasStudyNoteBook

pandas 入門培訓 pandas簡介 - 官網鏈接&#xff1a;http://pandas.pydata.org/ - pandas pannel data data analysis - Pandas是python的一個數據分析包 , Pandas最初被作為金融數據分析工具而開發出來&#xff0c;因此&#xff0c;pandas為時間序列分析提供了很好的支持 …

最大搜索子樹

給定一個二叉樹的頭結點&#xff0c;返回最大搜索子樹的大小。 我們先定義結點&#xff1a; public static class Node {public int value;public Node left;public Node right;public Node(int data) {this.value data;}} 分析&#xff1a; 直接判斷每個節點左邊小右邊大是…

二叉樹最長路徑

分析&#xff1a; 暴力求每一段距離也可。 對于以本節點為根的二叉樹&#xff0c;最遠距離有三種可能&#xff1a; 1&#xff09;最遠路徑來自左子樹 2 &#xff09;最遠路徑來自右子樹&#xff08;圖示與左子樹同理&#xff09; 3&#xff09;最遠路徑為左右子樹距離根最遠…

判斷完全二叉樹

完全二叉樹的定義: 一棵二叉樹&#xff0c;除了最后一層之外都是完全填充的&#xff0c;并且最后一層的葉子結點都在左邊。 https://baike.baidu.com/item/%E5%AE%8C%E5%85%A8%E4%BA%8C%E5%8F%89%E6%A0%91/7773232?fraladdin 百度定義 思路&#xff1a;層序遍歷二叉樹 如果…

判斷二叉搜索樹

二叉查找樹&#xff08;Binary Search Tree&#xff09;&#xff0c;&#xff08;又&#xff1a;二叉搜索樹&#xff0c;二叉排序樹&#xff09;它或者是一棵空樹&#xff0c;或者是具有下列性質的二叉樹&#xff1a; 若它的左子樹不空&#xff0c;則左子樹上所有結點的值均小于…

劍指offer_01

文章目錄[toc]第一章 面試流程1.1 面試官談面試1.2 面試3種形式1.3 面試的3個環節第一章 面試流程 1.1 面試官談面試 初級的程序員談算法和數據結構&#xff0c;高級的程序員談項目經驗要對公司近況和項目情況了解不要緊張&#xff0c;不要馬上上手寫代碼 1.2 面試3種形式 …

判斷平衡二叉樹

平衡二叉樹&#xff08;Balanced Binary Tree&#xff09;具有以下性質&#xff1a;它是一棵空樹或它的左右兩個子樹的高度差的絕對值不超過1。并且左右兩個子樹都是一棵平衡二叉樹 &#xff08;不是我們平時意義上的必須為搜索樹&#xff09; 判斷一棵樹是否為平衡二叉樹&am…