版權聲明:本文為部落客原創文章,未經部落客允許不得轉載。 https://blog.csdn.net/sinat_32502811/article/details/80712435
最近想要把學的機器學習算法用起來,是以開始看看kaggle上的比賽。看了兩個新人入門賽泰坦尼克号生還預測和房屋價格預測。總結一下看代碼的一些經驗吧。
總體感覺是,在建立特征工程上耗費的時間,要遠遠大于訓練模型和調參的過程。可見特征的重要性。而且,在資料科學的比賽中,用xgboost方法的占到大多數,這裡再次膜拜一下陳天奇大神······
-
和pandas
資料的一般格式都是.csv檔案,處理用的包是numpy
。其基本的資料結構為pandas
dataframe
.series
import pandas as pd
import numpy as np
#建立dataframe對象
df1 = pd.DataFrame({'col1':[1,3],'col2':[2,4]},index = ['a','b'])
df2 = pd.DataFrame(np.array([[1,3,5],[2,4,6]]),columns = ['col1','col2'])#大小2*3
#如果不加index,預設行索引為0,1,2...數字
#建立dataframe對象的資料可以為清單,字典,數組。
#基本操作:
#1.索引操作
df1.index#行
df2.columns#列
df1.loc['a']#索引這一行的資料
#df.loc[]與df.iloc[]的差別:.loc[]索引的是行名,.iloc[]索引的是行數字
df2['col1']#通路列資料
#支援組合選擇
df2[['col1','col2']]
#行列索引
df2.iloc[2]['a']
#2.資料合并
#三種方法:join,concat,append,merge
pd.concat(objs, axis=0, join='outer', join_axes=None, ignore_index=False,
keys=None, levels=None, names=None, verify_integrity=False,
copy=True)
#concat可橫向,可縱向,axis = 0,表示橫向,axis=1,表示縱向。
#join:{inner,outer}:合并方式,預設為outer,表示并集,inner表示交集
#ignore_index:{False,True},是否忽略原index,預設為不忽略
#keys:為原始dataframe添加一個鍵,預設為無
df1 = df1.append(df2)
#橫向和縱向同時擴充
df1.join(df2,how = 'inner')
#3.丢棄資料
#drop方法
df1 = df1.drop('a',axis = 1)#丢掉列
-
matplotlib,seaborn
用于資料的可視化
- scipy
統計子產品
from scipy import stats
from scipy.stats import skew, norm
from scipy.special import boxcox1p
from scipy.stats.stats import pearsonr#皮爾森相關系數矩陣
-
sklearn
這是主要的子產品。裡面包含各種機器學習算法,資料預處理方法,模型選擇、特征選擇方法等。
pd.read_csv(filename)
-
缺失值處理
首先通過
方法,把訓練集和資料集連接配接在一起處理。concat
# First of all, save the length of the training and test data for use later
ntrain = train.shape[0]
ntest = test.shape[0]
# Also save the target value, as we will remove this
y_train = train.SalePrice.values
# concatenate training and test data into all_data
all_data = pd.concat((train, test)).reset_index(drop=True)
all_data.drop(['SalePrice'], axis=1, inplace=True)
主要兩種處理方法,要不就删去,要不就補全。是以要觀察缺失值缺的是啥,為什麼會缺失。
比如:大量的缺失,可能是因為這個不重要,或者大多數不存在,是以可以酌情删除這個特征。如果缺失的數量較少,那麼觀察這個數值類型,是數值型還是标簽類型。是不是可以用衆數、中位數、或者均值來進行填充。
-
異常值處理(outlier)
可以通過plot的方式,看看是否存在明顯的異常值或者離群值,然後手動剔除就行。
- 常用方法
:groupby可以通過傳入需要分組的參數實作對資料的分組.groupby之後的資料并不是DataFrame格式的資料,而是特殊的groupby類型,此時,可以通過size()方法傳回分組後的記錄數目統計結果,該結果是Series類型.通過groupby完成對資料的分組後,可以通過get_group方法來擷取某一制定分組的結果data.groupby()
:判斷是否包含空值。可再使用sum方法計算空值數量。data.isnull()
統計出來的結果是每一列的空值總數。data.isnull().sum()
:填充空值data.fillna()
接下來到了重要且費時的部分了。分析資料之間的關系,通過去除或合并備援特征,降維等方式,建立特征工程。選擇到一組好的特征,即使與别人用相同的學習方法,也能得到秒殺衆人的結果。是以在資料科學的比賽中,我感覺特征是第一重要,其次才是機器學習方法和參數。
通過前面的處理,把缺失值補全,而且異常值也去除。接下來,首先對所有資料之間的相關性進行總體的預覽。這就用到了計算相關系數的方法。
DataFrame.corr(method='pearson', min_periods=1)
Compute pairwise correlation of columns, excluding NA/null values.這裡預設用pearson相關系數
然後可以用seaborn的熱力圖進行顯示。
sns.heatmap(corr, cmap="RdYlBu", vmax=1, vmin=-0.6, center=0.2, square=True, linewidths=0, cbar_kws={"shrink": .5}, annot = True);
也可以用seaborn的
pairplot
方法:
Plot pairwise relationships in a dataset.
seaborn.pairplot(data, hue=None, hue_order=None, palette=None, vars=None, x_vars=None, y_vars=None, kind='scatter', diag_kind='hist', markers=None, size=2.5, aspect=1, dropna=True, plot_kws=None, diag_kws=None, grid_kws=None)¶
有了對資料之間的相關性的初步了解,接下來就是建立特征工程了。這一部分比較方法比較個性化感覺,但大概意思應該是一一分析,兩兩之間通過畫圖直覺觀察可能有怎樣的相關性,是線性關系,平方關系還是什麼的。最終确定應用到學習算法中的資料有哪些。
這裡常用到的一些方法總結如下:
sns.boxplot()
sns.stripplot()
sns.barplot()
sns.regplot()
- 将數值型轉化為标簽型,即将數值離散化
pandas.cut(x, bins, right=True, labels=None, retbins=False, precision=3, include_lowest=False)
#for example
>>> pd.cut(np.array([.2, 1.4, 2.5, 6.2, 9.7, 2.1]),
... 3, labels=["good", "medium", "bad"])
...
>>> [good, good, good, medium, bad, good]
Categories (3, object): [good < medium < bad]
- 啞變量
pandas.get_dummies(data, prefix=None, prefix_sep='_', dummy_na=False, columns=None, sparse=False, drop_first=False, dtype=None)
#for example
s = pd.Series(list('abca'))
>>> pd.get_dummies(s)
a b c
0 1 0 0
1 0 1 0
2 0 0 1
3 1 0 0
Convert categorical variable into dummy/indicator variables.
在很多資料進行中,我們都需要對資料進行啞變量處理。例如,某個資料中的月份用1-12進行表示,但是月份的值本身并沒有數值上的意義,比方說2月份比1月份多,這顯然是不合理的。
對目标變量的處理:
這裡主要是對目标變量分布所做的一點變換。因為大部分機器學習算法在正态分布上可能應用的更好/但是通過觀察資料的頻率分布直方圖,可以看出他們是偏态分布,此時需要做一點變換,使之與正态分布相近,這樣可以的到更好的預測效果。但是,需要注意的是,當做出變換之後,在最後的時候,還要變換回來。這裡以房價預測中所應用的方法為例:
g = sns.distplot(train['SalePrice'], fit=norm, label = "Skewness : %.2f"%(train['SalePrice'].skew()));
#觀察到分布為正偏态。
#We use the numpy fuction log1p which applies log(1+x) to all elements of the column
train["SalePrice"] = np.log1p(train["SalePrice"])
以上為對目标變量的變換。
對于數值類型為數值的特征變量,也需要進行類似的變換。通過統計每一變量的skew值(偏度/偏态值,越接近0,越符合正态分布。大于0為正偏态,小于0為負偏态),對絕對值大于0.5的進行boxcox變換。
box - cox變換
可以使線性回歸模型滿足線性性、獨立性、方差齊性以及正态性的同時,又不丢失資訊,此種變換稱之為Box—Cox變換。這種變換是對變量y進行變換
誤差與y相關,不服從正态分布,于是給線性回歸的最小二乘估計系數的結果帶來誤差
使用Box-Cox變換族一般都可以保證将資料進行成功的正态變換,但在二分變量或較少水準的等級變量的情況下,不能成功進行轉換,此時,我們可以考慮使用廣義線性模型,如LOGUSTICS模型、Johnson轉換等。
Box-Cox變換後,殘差可以更好的滿足正态性、獨立性等假設前提,降低了僞回歸的機率
scipy裡面的變換公式為:y=xλ−1λ,λ!=0;y=xλ−1λ,λ!=0;
y=log(x),λ==0y=log(x),λ==0
其中 x 代表需要變換的資料,y代表資料變換後的結果
此處先按下不表,以後再詳細寫
将
dataframe
生成
.csv
檔案,然後送出就OK啦!
dataframe.to_csv('final_submission.csv',index=False)