数据挖掘入门之Titanic

数据挖掘经验

  1. 应用机器学习,千万不要上来就想做完美的模型,要先撸一个baseline的model出来,再进行分析提高。【后续分析可能包括模型的过/欠拟合、我们模型预测的bad case的产生原因等等,针对去分析】
  2. 大神们的experience:
    1.【对数据的认识太重要了!】
    2.【数据中的特殊点/离群点的分析和处理太重要了!】
    3.【特征工程(feature engineering)太重要了!】
    4.【要做模型融合(model ensemble)啊!】

项目实战

1.流程

1.初探数据

我们得先知道数据长啥样,大体都有哪些基本特征;
常用的函数:

train_data = pd.read_csv("./Train.csv")  #读取路径
train_data.info()	#大体特征浏览
train_data.describe()	#数值型数据的一些分布

【对数据的认识太重要了!】
【对数据的认识太重要了!】
【对数据的认识太重要了!】
我们只看数据也不好分析出个啥,来把数据变成图吧

常用的函数:

import matplotlib.pyplot as plt
fig = plt.figure()
fig.set(alpha=0.2)  # 设定图表颜色alpha参数
plt.subplot2grid((2,3),(0,0))	#第一个参数表示整个图片分成几块,第二个参数表示此子图所在的位置
data_train.Survived.value_counts().plot(kind='bar')	#value_counts统计此特征不同类别出现的数量,kind表示打印图的种类
plt.xlabel(u"年龄")	# x轴
plt.ylabel(u"密度")	# y轴
plt.legend()	#给图加说明
fig.tight_layout()	#固定子图之间的界限
data_train.groupby()	#可以用于统计指定类别对指定类别的影响

2.数据预处理

上个步骤对数据的情况大致看了一遍,对感兴趣的feature心中也有了数,下一步要处理这些数据,为建模做准备辽
【数据工程(feature engineering)太重要了!】
【数据工程(feature engineering)太重要了!】
【数据工程(feature engineering)太重要了!】
处理属性先从最突出的feature入手。

  1. 通常遇到缺值情况,会有几种常见的解决方法:
  • 如果缺值的样本占总数比例极高,我们可能就直接舍弃了,作为特征加入的话,可能反倒带入noise,影响最后的结果了
  • 如果缺值的样本比例适中,而该属性是非连续值特征属性(比如说类目属性),那就把NaN作为一个新类别,加到类别特征中
  • 如果缺值的样本比例适中,而该属性为连续值特征属性,有时候我们会考虑给定一个step(比如这里的age,我们可以考虑每隔2、3岁为一个step),然后把它离散化,之后把NaN作为一个type加到属性类目中
  • 有些情况下,缺失的值个数并不是特别多,那我们也可以试着根据已有的值,拟合数据补全(如随机森林等方法)
  1. 特征因子化:
    将分类型特征因子化
  2. 处理特征值波动大的属性:
    通过上述操作把所有特征的值都转成了数值型,但有的特征的值波动范围太大了,影响收敛速度甚至不收敛,利用scaler归一化

常用函数:

#1. 借助randomForest来拟合补全特征
from sklearn.ensemble import RandomForestRegressor
#训练rfr模型
rfr = RandomForestRegressor(random_state=0, n_estimators=2000, n_jobs=-1)
rfr.fit(X_train, y_train)	#训练
prediction = rfr.predict(X_test)	#预测

train_data.loc()	#按指定维度提取或填充数据

#2. 借助get_dummies()函数因子化类目型特征
dummies_Cabin = pd.get_dummies(data_train['Cabin'], prefix= 'Cabin')

#3. 借助scaler()函数因子化类目型特征
import sklearn.preprocessing as preprocessing
scaler = preprocessing.StandardScaler()
data_train['Age_scaled'] = scaler.fit_transform(data_train['Age'].values.reshape(-1,1))     #fit_transform、fit、transform

3.建模

feature已经处理好了,接下来就是送入model中训练嘞!

#1. 提取需要的feature字段,filter函数
data_train.filter(regex = 'Survived|Age_.*|SibSp|Parch|Fare_.*|Cabin_.*|Embarked_.*|Sex_.*|Pclass_.*')
data_train_feats = data_train.values	#转成np格式
#2. 选择模型,进行训练
from sklearn import linear_model
from sklearn.ensemble import BaggingClassifier
#lg模型及训练
clf = linear_model.LogisticRegression(C=1.0, penalty='l2', tol=1e-6)
clf.fit(data_train_feats[:, 1:], data_train_feats[:, 0])
#bg模型及训练
bagging_clf = BaggingClassifier(clf, n_estimators=20, max_samples=0.8, max_features=1.0, bootstrap=True, bootstrap_features=False, n_jobs=-1)
bagging_clf.fit(data_train_feats[:, 1:], data_train_feats[:, 0])

至此我们的baseline撸好了,同样处理test的数据,送入模型中,查看结果

4.模型分析

4.1模型系数分析

我们刚刚训练好的baseline,但并不知道模型中每个feature对预测结果的影响有多大,所以我们先把得到的模型参数和feature对应起来,打印出来看看

pd.DataFrame({"columns":list(data_train.columns)[1:], "coef":list(clf.coef_.T)}

通过观看不同feature的权重,可以进一步去做出一定的分析与判断,来进一步的去做特征工程等

4.2交叉验证

【要做交叉验证(cross validation)!】
【要做交叉验证(cross validation)!】
【要做交叉验证(cross validation)!】
由于test集中的结果未知,不好让我们更好的去对我们模型产生的结果去分析,所以我们要做交叉验证!!!
交叉验证:我们通常将train集分出两部分,一部分用来训练模型,一部分用来预测结果

  1. 在小数据集上通常用cross_validate来查看打分情况
from sklearn.model_selection import cross_validate
print (cross_validate(clf, data_train_feats[:, 1:], data_train_feats[:, 0], cv=5))
  1. 我们把交叉验证里的bad case打印从出来,与我们所想的做对比,看看是不是哪个feature权重考虑错了,逐个分析看看
###利用交叉验证打印bad case
from sklearn.model_selection import train_test_split
#用分出的train去训练
split_train, split_cv = train_test_split(data_train, test_size=0.3, random_state=0)
split_train_filter = split_train.filter(regex='Survived|Age_.*|SibSp|Parch|Fare_.*|Cabin_.*|Embarked_.*|Sex_.*|Pclass_.*')
clf_cv = linear_model.LogisticRegression(C=1.0, penalty='l2', tol=1e-6)
clf_cv.fit(split_train_filter.values[:,1:], split_train_filter.values[:,0])
#用分出的cv去测试
split_cv_filter = split_cv.filter(regex='Survived|Age_.*|SibSp|Parch|Fare_.*|Cabin_.*|Embarked_.*|Sex_.*|Pclass_.*')
pre_cv = clf_cv.predict(split_cv_filter.values[:, 1:])
#打印出预测与真实不同的data
bad_case = data_train.loc[data_train['PassengerId'].isin(split_cv[pre_cv != split_cv_filter.values[:,0]]['PassengerId'].values)]
bad_case

通过bad case的实际情况和上节我们关于各feature权重对结果影响的猜想,可以进一步去分析挖掘。

4.3learning curves

利用learning curves曲线去分析我们模型的情况,针对不同的情况去做不同的调整:
在这里插入图片描述 1. 左上图片曲线收敛,但没达到预期效果——欠拟合,高偏差
解决方法:增加参数(如,增加feature的种类,model的复杂度);减少正则项
2. 右上图片曲线未收敛——过拟合,高方差
解决方法:增大训练集,减少参数(如,减少feature的数量,降低模型复杂度),增加正则项
3. 右下是理想情况,收敛且误差较小

# 绘制learning curve
from sklearn.model_selection import learning_curve
def plot_learning_curve(estimator, title, X, y, ylim=None, cv=None, n_jobs=1,
                        train_sizes=np.linspace(.05, 1., 20), verbose=0, plot=True):
    """
    打印learning_curve
    :param estimator: 模型
    :param title: 图标的标题
    :param X: 训练集的训练特征数据
    :param y: 训练集的目标特征数据
    :param ylim: 设置纵坐标点最高和最低点
    :param cv: cv的k值
    :param n_jobs: 并行任务数
    :param train_sizes: 
    :param verbose:
    :param plot:
    """
    
    train_sizes, train_scores, test_scores = learning_curve(
        estimator, X, y, cv=cv, n_jobs=n_jobs, train_sizes=train_sizes,verbose=verbose
    )
    train_scores_mean = np.mean(train_scores, axis=1)
    train_scores_std = np.std(train_scores, axis=1)
    test_scores_mean = np.mean(test_scores, axis=1)
    test_scores_std = np.std(test_scores, axis=1)

    if plot:
        plt.figure()
        plt.title(title)
        if ylim is not None:
            plt.ylim(*ylim)
        plt.xlabel(u"训练样本数")
        plt.ylabel(u"得分")
        plt.gca().invert_yaxis()    #将y轴的位置设置在左边
        plt.grid()      #设置网格

    plt.fill_between(train_sizes, train_scores_mean - train_scores_std, train_scores_mean + train_scores_std,
                     alpha=0.1, color="b")      #均值范围内加颜色
    plt.fill_between(train_sizes, test_scores_mean - test_scores_std, test_scores_mean + test_scores_std,
                     alpha=0.1, color="r")
    plt.plot(train_sizes, train_scores_mean, 'o-', color="b", label=u"训练集上得分")
    plt.plot(train_sizes, test_scores_mean, 'o-', color="r", label=u"交叉验证集上得分")

    plt.legend(loc="best")

    plt.draw()
    plt.show()
    plt.gca().invert_yaxis()

    #训练模型的train和test的差异
    midpoint = ((train_scores_mean[-1] + train_scores_std[-1]) + (test_scores_mean[-1] - test_scores_std[-1])) / 2
    diff = (train_scores_mean[-1] + train_scores_std[-1]) - (test_scores_mean[-1] - test_scores_std[-1])

    return midpoint, diff

5.模型融合

机器学习、数据挖掘中的大杀器!
【模型融合(model ensemble)很重要!】
【模型融合(model ensemble)很重要!】
【模型融合(model ensemble)很重要!】

由于初入门数据挖掘,其他模型还不会,这里只用到了Bagging方法。

# fit到BaggingClassifier之中
from sklearn.ensemble import BaggingClassifier
clf = linear_model.LogisticRegression(C=1.0, penalty='l2', tol=1e-6)
bagging_clf = BaggingClassifier(clf, n_estimators=20, max_samples=0.9, max_features=1.0, bootstrap=True, bootstrap_features=False, n_jobs=-1)
bagging_clf.fit(data_train_filter_np[:, 1:], data_train_filter_np[:, 0])
predictions_bag = bagging_clf.predict(data_test_filter_np)

常规操作小知识

  1. jupyter notebook切换使用环境,需先在anaconda下激活
python -m ipykernel install --user --name 环境名称 --display-name "Python (环境名称)"

知识点

  • 随机森林 参数讲解:https://blog.csdn.net/R18830287035/article/details/89257857
  • bagging
  • 回归与分类
  • 过拟合与欠拟合:https://blog.csdn.net/aliceyangxi1987/article/details/73598857

参考:

  1. https://blog.csdn.net/han_xiaoyang/article/details/49797143

实现代码:

https://github.com/wangdepeng1/Titanic

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值