kaggle 入门 泰坦尼克 处理过程

一、数据预处理

  1. pandas库的内容(数据分析处理):
  • read_csv :读取文件,变为矩阵

  • head(n) : 输出前n行内容,默认5

PassengerId  Survived  Pclass  \
0            1         0       3   
1            2         1       1   
2            3         1       3   

                                                Name     Sex   Age  SibSp  \
0                            Braund, Mr. Owen Harris    male  22.0      1   
1  Cumings, Mrs. John Bradley (Florence Briggs Th...  female  38.0      1   
2                             Heikkinen, Miss. Laina  female  26.0      0   

   Parch            Ticket     Fare Cabin Embarked  
0      0         A/5 21171   7.2500   NaN        S  
1      0          PC 17599  71.2833   C85        C  
2      0  STON/O2. 3101282   7.9250   NaN        S 
  • describe() : 对特征值进行描述
       PassengerId    Survived      Pclass         Age       SibSp  \
count   891.000000  891.000000  891.000000  714.000000  891.000000   
mean    446.000000    0.383838    2.308642   29.699118    0.523008   
std     257.353842    0.486592    0.836071   14.526497    1.102743   
min       1.000000    0.000000    1.000000    0.420000    0.000000   
25%     223.500000    0.000000    2.000000   20.125000    0.000000   
50%     446.000000    0.000000    3.000000   28.000000    0.000000   
75%     668.500000    1.000000    3.000000   38.000000    1.000000   
max     891.000000    1.000000    3.000000   80.000000    8.000000   

            Parch        Fare  
count  891.000000  891.000000  
mean     0.381594   32.204208  
std      0.806057   49.693429  
min      0.000000    0.000000  
25%      0.000000    7.910400  
50%      0.000000   14.454200  
75%      0.000000   31.000000  
max      6.000000  512.329200  
  • info() : 每个特征值有多少项,是否有缺失值及数据类型
RangeIndex: 891 entries, 0 to 890
Data columns (total 12 columns):
PassengerId    891 non-null int64
Survived       891 non-null int64
Pclass         891 non-null int64
Name           891 non-null object
Sex            891 non-null object
Age            714 non-null float64
SibSp          891 non-null int64
Parch          891 non-null int64
Ticket         891 non-null object
Fare           891 non-null float64
Cabin          204 non-null object
Embarked       889 non-null object
dtypes: float64(2), int64(5), object(5)
memory usage: 83.6+ KB
None
  • 数据填充
    fillna( ) : 将空白的数据进行填充
train['Age'] = train['Age'].fillna(train['Age'].median)
train['Embarked'] = train['Embarked'].fillna('S')
  • 字符变数字
    定位函数 loc :定位特征值等于XX的行,某个特征值=?
    loc——通过行标签索引行数据
    iloc——通过行号索引行数据 (a,b)a代表行,b代表列
    ix——通过行标签或者行号索引行数据(基于loc和iloc 的混合)
train.loc[train['Sex']=='male','Sex'] = 0
train.loc[train['Sex']=='female','Sex'] = 1

train.loc[train['Embarked']=='S','Embarked'] = 0
train.loc[train['Embarked']=='C','Embarked'] = 1
train.loc[train['Embarked']=='Q','Embarked'] = 2

二、数据图表处理

1.将各特征值用图标显示

kaggle 入门 泰坦尼克 处理过程_第1张图片

  • 获救人数300多人,不到一半
  • 三等舱人最多,二等舱人最少
  • 获救与否,人的年龄分布广泛
  • 舱位等级越高,年龄普遍越大
  • 上船位置排序,S>C>Q

2.查看舱位等级、性别与获救人数关系

kaggle 入门 泰坦尼克 处理过程_第2张图片
kaggle 入门 泰坦尼克 处理过程_第3张图片

  • 头等舱的获救比例明显高很多
  • 获救人数中女性比例明显高很多

3.性别+等级

kaggle 入门 泰坦尼克 处理过程_第4张图片

  • 同第二个相同

4.登船口与获救关系

kaggle 入门 泰坦尼克 处理过程_第5张图片

  • 获救人数S>C>Q

5.堂兄弟妹、孩子父母

kaggle 入门 泰坦尼克 处理过程_第6张图片 kaggle 入门 泰坦尼克 处理过程_第7张图片

6.统计 Cabin

  • 缺失值较多,800个人只有147个有,考虑统计是否有cabin
C23 C25 C27        4
B96 B98            4
G6                 4
F33                3
F2                 3
D                  3
C22 C26            3
E101               3
D17                2
C83                2
B58 B60            2
C65                2
C78                2
E24                2
C2                 2
B18                2
B35                2
C68                2
。。。。。。。
E46                1
A32                1
C128               1
Name: Cabin, Length: 147, dtype: int64

kaggle 入门 泰坦尼克 处理过程_第8张图片

  • 可以看出有这个属性的人获救比例更高

三、特征工程

  1. 缺失值处理:(根据数据的info属性,得到age、cabin缺失最多)
  • 如果缺值的样本占总数比例极高,我们可能就直接舍弃了,作为特征加入的话,可能反倒带入noise,影响最后的结果了
  • 如果缺值的样本适中,而该属性非连续值特征属性(比如说类目属性),那就把NaN作为一个新类别,加到类别特征中
  • 如果缺值的样本适中,而该属性为连续值特征属性,有时候我们会考虑给定一个step(比如这里的age,我们可以考虑每隔2/3岁为一个步长),然后把它离散化,之后把NaN作为一个type加到属性类目中。(把age属性作为类目属性)
  • 有些情况下,缺失的值个数并不是特别多,那我们也可以试着根据已有的值,拟合一下数据,补充上。
  1. 用scikit-learn中的RandomForest(随机森林)来补充Age中的缺失值

用’Fare’, ‘Parch’, ‘SibSp’, 'Pclass属性,来预测age。将完好的数据,数值型的特征输入RFR进行fit;然后将缺失age的样本其他特征输入获得age

def miss_age(df):     
    # 把已有的数值型特征取出来丢进Random Forest Regressor中
    age_df = df[['Age','Fare', 'Parch', 'SibSp', 'Pclass']]
    # 乘客分成已知年龄和未知年龄两部分
    known_age = age_df[age_df.Age.notnull()].as_matrix()
    unknown_age = age_df[age_df.Age.isnull()].as_matrix()
    
    # y即目标年龄([x,y]表示x取全部,y只取第一位)
    y = known_age[:, 0] 
    # X即特征属性值
    X = known_age[:, 1:]
    
    # fit到RandomForestRegressor之中
    rfr = RandomForestRegressor(random_state=0, n_estimators=2000, n_jobs=-1)
    rfr.fit(X, y)
 
    # 用得到的模型进行未知年龄结果预测
    predictedAges = rfr.predict(unknown_age[:, 1:])
    # 用得到的预测结果填补原缺失数据
    df.loc[ (df.Age.isnull()), 'Age' ] = predictedAges 
 
    return df, rfr
  1. 将所有特征改为数值型
    离散特征的编码分为两种情况:
  • 离散特征的取值之间没有大小的意义,比如color:[red,blue],那么就使用one-hot编码
    利用pandas中的get_dummies 对离散特征进行编码

有一篇教学直接这些属性用数字0,1,2,3代替,其实是不严谨的,因为本来他只是一个属性没有数值意义,数字使他们有了大小区分,这跟将每个特征的属性作为一个特征,得到的模型肯定不一样,精确度应该也是one-hot更好。

pandas.get_dummies(data, prefix=None, prefix_sep=’_’, dummy_na=False, columns=None, sparse=False, drop_first=False)

data : array-like, Series, or DataFrame 
输入的数据
prefix : string, list of strings, or dict of strings, default None 
get_dummies转换后,列名的前缀 
*columns : list-like, default None 
指定需要实现类别转换的列名
dummy_na : bool, default False 
增加一列表示空缺值,如果False就忽略空缺值
drop_first : bool, default False 
获得k中的k-1个类别值,去除第一个

kaggle 入门 泰坦尼克 处理过程_第9张图片

  • 离散特征的取值有大小的意义,比如size:[X,XL,XXL],那么就使用数值的映射{X:1,XL:2,XXL:3}
df = pd.DataFrame([  
            ['green', 'M', 10.1, 'class1'],   
            ['red', 'L', 13.5, 'class2'],   
            ['blue', 'XL', 15.3, 'class1']])  
  
df.columns = ['color', 'size', 'prize', 'class label'] 
size_mapping = {  
           'XL': 3,  
           'L': 2,  
           'M': 1}  
df['size'] = df['size'].map(size_mapping)  
  • 然后再将更改后的数据加入到原数据中:(用concat函数)
pd.concat(objs, axis=0, join='outer', join_axes=None, ignore_index=False,keys=None, levels=None, names=None, verify_integrity=False)
1, axis=0, 对行操作    axis=1, 对列操作
 2. join='outer', 连接各个数据    join='inner',只取各个数据的公共部分
 3. join_axes=[df1.index], 保留与df1的行标签一样的数据,配合axis=1一起用    
    join_axes=[df1.columns],保留与df1的列标签一样的数据,不要添加axis=1
 4. ignore_index=False, 保留原索引    ignore_index=True,忽略原索引并生成新索引
 5. keys=['x', 'y', 'z'] 对组成的每个df重新添加个索引

运行代码之后得到如图所示:

#将数据转化为数值型
dummies_Cabin = pd.get_dummies(train['Cabin'], prefix= 'Cabin')
dummies_Embarked = pd.get_dummies(train['Embarked'], prefix= 'Embarked')
dummies_Sex = pd.get_dummies(train['Sex'], prefix= 'Sex') 
dummies_Pclass = pd.get_dummies(train['Pclass'], prefix= 'Pclass')
 
df = pd.concat([train, dummies_Cabin, dummies_Embarked, dummies_Sex, dummies_Pclass], axis=1)
#axis 删除列;inplace代表删除后直接替换该值
df.drop(['Pclass', 'Name', 'Sex', 'Ticket', 'Cabin', 'Embarked'], axis=1, inplace=True)

在这里插入图片描述

  1. 特征归一化:(sklearn.preprocessing.StandardScaler() ====scaler)
#归一化
import sklearn.preprocessing as preprocessing
scaler = preprocessing.StandardScaler()

#age_scale_param = scaler.fit(df['Age'].values.reshape(-1,1))
df['Age_scaled'] = scaler.fit_transform(df['Age'].values.reshape(-1,1))
#fare_scale_param = scaler.fit(df['Fare'].values.reshape(-1,1))
df['Fare_scaled'] = scaler.fit_transform(df['Fare'].values.reshape(-1,1))

被调用的方法
fit(X,y=None):计算输入数据各特征的平均值,标准差已经之后的缩放系数
X 为array 或者 稀疏矩阵,[样本数量,样本特征数]
y: 传入为了使得和Pipeline兼容
就可以直接查询相关系数,scale.mean_

scale_: 缩放比例,同时也是标准差
mean_: 每个特征的平均值
var_:每个特征的方差
n_sample_seen_:样本数量,可以通过patial_fit 增加

fit_transform(X,y=None,**fit_params): 通过fit_params调整数据X,y得到一个调整后的X
X 为array:训练集
y 为标签
返回一个改变后的X

四、逻辑回归建模

LogisticRegression(C=1.0, penalty=‘l1’, tol=1e-6)

  • penalty:惩罚项,str类型,可选参数为l1和l2,默认为l2。用于指定惩罚项中使用的规范。newton-cg、sag和lbfgs求解算法只支持L2规范。L1G规范假设的是模型的参数满足拉普拉斯分布,L2假设的模型参数满足高斯分布,所谓的范式就是加上对参数的约束,使得模型更不会过拟合(overfit),但是如果要说是不是加了约束就会好,这个没有人能回答,只能说,加约束的情况下,理论上应该可以获得泛化能力更强的结果。
  • c:正则化系数λ的倒数,float类型,默认为1.0。必须是正浮点型数。像SVM一样,越小的数值表示越强的正则化。
  • tol:停止求解的标准,float类型,默认为1e-4。就是求解到多少的时候,停止,认为已经求出最优解
    参数详解
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 = train_np[:,0]
X = train_np[:,1:]
clf = linear_model.LogisticRegression(C=1.0, penalty='l1', tol=1e-6)
clf.fit(X,y)

五、小结:

以上为baseling的结果,只是对数据进行了处理,并且直接放入逻辑回归模型中,参数也没有进行调整;一共10个特征,提取的特征只有(Age_.|SibSp|Parch|Fare_.|Cabin_.|Embarked_.|Sex_.|Pclass_.)8个
(查看数据info等选取特征值、缺失值少的随机森林填补,缺失多的可以将是否缺失作为一个特征、特征进行onehot处理(get_dummies)、范围大的数值型数据进行归一化处理、训练集放入逻辑回归中、测试集同样处理后predict)
kaggle 入门 泰坦尼克 处理过程_第10张图片

六、进阶

  1. 猜测:
  • name、ticket 属性没有用,主要是数据共同点少
  • 预测的年龄值可能并不准确,毕竟年龄与其他属性不一定有什么关系,而且年龄大的和小的理论最容易获救,所以这个关系应该不是线性的
  1. 查看逻辑回归系数(系数越大正相关,负即位负相关)
a = pd.DataFrame({"columns":list(train_df.columns)[1:], "coef":list(clf.coef_.T)})
print(a)
                 coef      columns
0   [-0.344235547502]        SibSp
1   [-0.104916059432]        Parch
2               [0.0]     Cabin_No
3    [0.902108372278]    Cabin_Yes
4               [0.0]   Embarked_C
5               [0.0]   Embarked_Q
6   [-0.417264091571]   Embarked_S
7     [1.95657115809]   Sex_female
8    [-0.67742062132]     Sex_male
9    [0.341158456052]     Pclass_1
10              [0.0]     Pclass_2
11   [-1.19413034174]     Pclass_3
12  [-0.523766665956]   Age_scaled
13  [0.0844348218785]  Fare_scaled

SibSp、Parch:略微的负相关
Cabin:有的更容易获救
Embarked:影响不大
sex : female影响明显
Pclass :1舱使获救升高,3舱大大降低
Age:负相关,年龄越小越好
Fare:很小的正相关

3.交叉验证(cross validation)

  • cross_val_score(测试集进行循环5次交叉验证)
sklearn.cross_validation.cross_val_score
(estimator, X, y=None, scoring=None, cv=None, n_jobs=1, verbose=0, fit_params=None, pre_dispatch=‘2*n_jobs’)
estimator:数据对象 
X:数据 
y:预测数据 
soring:调用的方法
cv:交叉验证生成器或可迭代的次数 
n_jobs:同时工作的cpu个数(-1代表全部)
verbose:详细程度
fit_params:传递给估计器的拟合方法的参数
pre_dispatch:控制并行执行期间调度的作业数量。减少这个数量对于避免在CPU发送更多作业时CPU内存消耗的扩大是有用的。该参数可以是:
from sklearn import cross_validation
clf = linear_model.LogisticRegression(C=1.0, penalty='l1', tol=1e-6)
xcross = train_np[:,1:]
ycross = train_np[:,0]
print(cross_validation.cross_val_score(clf, xcross, ycross, cv=5))

通过交叉验证,训练集分成5份,然后4分作为训练集,1份作为测试集,检验训练模型的结果,输出为:
[0.81564246 0.81005587 0.78651685 0.78651685 0.81355932]

  • train_test_split(将矩阵随机划分为训练子集和测试子集,并返回划分好的训练集测试集样本和训练集测试集标签。)查看那些预测错的案例
X_train,X_test, y_train, y_test =cross_validation.train_test_split(train_data,train_target,test_size=0.3, random_state=0)
参数解释:

train_data:被划分的样本特征集

train_target:被划分的样本标签

test_size:如果是浮点数,在0-1之间,表示样本占比;如果是整数的话就是样本的数量

random_state:是随机数的种子。

随机数种子:其实就是该组随机数的编号,在需要重复试验的时候,保证得到一组一样的随机数。比如你每次都填1,其他参数一样的情况下你得到的随机数组是一样的。但填0或不填,每次都会不一样。
随机数的产生取决于种子,随机数和种子之间的关系遵从以下两个规则:种子不同,产生不同的随机数;种子相同,即使实例不同也产生相同的随机数。

将数据按训练集、测试集 7:3分开,然后训练出的模型,预测结果与真实比较,查看预测错的案例

split_train, split_cv = cross_validation.train_test_split(df, test_size=0.3, random_state=0)
train_df0 = split_train.filter(regex='Survived|Age_.*|SibSp|Parch|Fare_.*|Cabin_.*|Embarked_.*|Sex_.*|Pclass_.*')
# 生成模型
clf = linear_model.LogisticRegression(C=1.0, penalty='l1', tol=1e-6)
clf.fit(train_df0.as_matrix()[:,1:], train_df0.as_matrix()[:,0])
 
# 对cross validation数据进行预测
cv_df = split_cv.filter(regex='Survived|Age_.*|SibSp|Parch|Fare_.*|Cabin_.*|Embarked_.*|Sex_.*|Pclass_.*')
predictions = clf.predict(cv_df.as_matrix()[:,1:])
 
origin_data_train = pd.read_csv("train.csv")
bad_cases = origin_data_train.loc[origin_data_train['PassengerId'].isin(split_cv[predictions != cv_df.as_matrix()[:,0]]['PassengerId'].values)]

通过对错误案例的分析,来对特征工程进行改进,再进行验证

sklearn 模型选择(https://scikit-learn.org/stable/index.html)

  • KFLOD(用于交叉验证的函数。在机器学习中,样本量不充足时,通常使用交叉训练验证)
    —— 将A分为K等份,1个最为测试集,其他作为训练集

KFold(n_splits=3, shuffle=False, random_state=None)
n_splits:表示划分几等份

shuffle:在每次划分时,是否进行洗牌

①若为Falses时,其效果等同于random_state等于整数,每次划分的结果相同

②若为True时,每次划分的结果都不一样,表示经过洗牌,随机取样的

random_state:随机种子数

KFold(n, n_folds=3, shuffle=False, random_state=None)
n为总数
n_folds为分为多少个交叉验证集
shuffle为是否随机
random_state设置随机因子

  • 线性回归、逻辑回归
    直接输入fit(特征值,lable值)然后predict(训练集特征值)
	#线性回归
	from sklearn.linear_model import LinearRegression
	#交叉验证
	from sklearn.cross_validation import KFold
	alg.fit(tr_pre,tr_tar)
    #te行的所有列
    te_pre = (train[predictors].iloc[te,:])
    te_tar = alg.predict(te_pre)

你可能感兴趣的:(机器学习)