加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

数据挖掘 workfolw 总结

发布时间:2020-12-14 05:06:50 所属栏目:大数据 来源:网络整理
导读:个人将数据挖掘的流程简单表示为“ 数据 → 特征 → 模型 ”。 ? 首先,明确问题的性质和任务(分类、回归、聚类、推荐、排序、关联分析、异常检测等); 其次,理解数据(含义、类型、值的范围),并通过描述性统计分析(describing data)和可视化分析(vi
  
个人将数据挖掘的流程简单表示为“ 数据特征模型 ”。
?
  • 首先,明确问题的性质和任务(分类、回归、聚类、推荐、排序、关联分析、异常检测等);
  • 其次,理解数据(含义、类型、值的范围),并通过描述性统计分析(describing data)和可视化分析(visualizing data)等工作对数据进行探索性分析(exploratory data analysis,EDA);
  • 然后,明确与预测结果显著相关的特征/变量(以kaggle-Titanic为例),进行数据预处理(特征选择、特征工程);
  • 最后,进行模型选择、建模、调参、交叉验证、模型评估,并得出最终的解决方案。
?
思考下来整个数据建模的过程,重点不在于建模,而在于前者,即如何理解数据,处理数据,针对模型的需求和特点做数据工程、特征工程,将数据以更好的方式特征化。在实际的数据挖掘过程中,前者占据差不多70%的工作量。

以 Titanic 为例,以下是数据挖掘 workflow 总结。

明确任务目标:预测泰坦尼克号的乘客是否生还。它是个二分类任务,生还为1,否则为0。

前期准备:导入相应的库

pandas?→ 载入数据
matplotlibseaborn?→ 可视化
sklearn?→ 机器学习
?
# data analysis and wrangling
import pandas as pd
import numpy as np
import random as rnd

# visualization import seaborn as sns import matplotlib.pyplot as plt # machine learning from sklearn.linear_model import LogisticRegression from sklearn.svm import SVC,LinearSVC from sklearn.ensemble import RandomForestClassifierfrom sklearn.tree import DecisionTreeClassifier ......

?

step 1. 读取数据

使用Pandas DataFrame读取数据。
# 使用Pandas DataFrame读取数据

train_df = pd.read_csv(./xxx/train.csv)
test_df = pd.read_csv(./xxx/test.csv)
combine = [train_df,test_df]

?

step 2.1 描述性统计分析

  • 查看总共有哪些特征;
    • ?[‘PassengerId‘ ‘Survived‘ ‘Pclass‘ ‘Name‘ ‘Sex‘ ‘Age‘ ‘SibSp‘ ‘Parch‘ ‘Ticket‘ ‘Fare‘ ‘Cabin‘ ‘Embarked‘] 共12个特征/变量
  • 简单展示数据;
  • 查看数据的类型和缺失值;分辨清楚数据的类型有助于挑选合适的图案进行可视化。
  • 查看数据离散分布情况(箱型图:均值、标准差、最小值、分位数、最大值、众数、中位数),描述事件总体情况及相关细节。
  • 查看离散型变量的分布情况。
# column 列名 index 行名  查看总共有哪些特征
print(train_df.columns.values)
# preview the data
train_df.head() train_df.tail()
# 查看数据类型和缺失值
train_df.info() print(_*40) test_df.info()
# 查看数据离散分布情况
train_df.describe()
# 只输出离散型变量的分布情况
train_df.describe(include=[O])

?

下图介绍了不同的数据类型。数据可以按 Nominal(名义)、Ordinal(顺序)、Interval(区间) 以及 Ratio(比率) 分;也可以按 Discrete (离散)、Continuous (连续)分;还能按照 Int (整数)、Float (浮点数)或者 String (字符串)、Object (对象)区分。

?

数据观察和假设

Correlating

我们想知道哪些特征与?Survival?相关。

Completing

  1. 我们想填充?Age?特征的缺失值,因为这个特征与?Survival?显著相关。
  2. 我们也想填充?Embarked?特征因为它可能与?Survival?相关。

Correcting

  1. Ticket?特征可能会在我们的分析中被移除,因为它有较高的重复率(24%),因此?Ticket?与?Survival?之间可能不存在联系。
  2. Cabin?特征可能会被移除,因为它在训练集以及测试集中存在大量缺失值。
  3. PassengerID?可能会被移除,因为它对?Survival?没有贡献。
  4. Name?特征不是非标准的数据,不能直接对?Survival?产生贡献,因此可能被移除。

Creating

  1. 我们可能基于?Parch?和?SibSp?新建一个?“Family”?特征,计算每个家庭登船的总成员数。
  2. 我们可能要从?Name?特征里提取新特征?Title?
  3. 我们可能根据?Age?进行分组,新建特征。将连续型数值特征转化为次序级分类特征。
  4. 我们也可能创建?Fare?分类特征如果它有助于我们进行分析。

Classifing

  1. Women(Sex=Female)更容易幸存下来。
  2. Children(Age<?)更容易幸存下来。
  3. The upper-class passengers(Pclass=1)更容易幸存下来。

?

step 2.2 旋转特征分析

特征,即变量。在建模之前,我们要寻找与预测结果显著相关的特征【特征选择】,判断哪些特征与预测结果具备显著相关性(正相关或者负相关)。

为了证实我们的假设,我们可以通过旋转特征来分析特征的相关性。在这一阶段,我们只能分析不存在缺失值的特征。比如?categorical(Sex)ordinal(Pclass)以及discrete(SibSp,Parch)类型的特征。

    • Pclass
      一等座(Pclass=1)的幸存率高达62%,符合假设(classifing #3).
    • Sex
      女性的幸存率(Sex=Female)高达74%,符合假设(classifing #1).
    • SibsP和Parch
      对于确定的值没有显著相关性。建议创建新特征(creating #1).
# 分别计算一等座、二等座、三等座的存活率,并按存活率从高到低进行排序
train_df[[Pclass,Survived]].groupby([Pclass],as_index=False).mean().sort_values(by=Survived,ascending=False)
# 得出结果 存活率:一等座>二等座>三等座

# 分别计算男性和女性的存活率,并按存活率从高到低排序
train_df[[Sex,Survived]].groupby([Sex],ascending=False)
# 得出结论 存活率:女性>男性

# 分别计算不同的配偶和兄弟姐妹数量的存活率,并按存活率从高到低排序
train_df[[SibSp,Survived]].groupby([SibSp],ascending=False)
# 分别计算不同的父母和子女数量的存活率,并按存活率从高到低排序
train_df[[Parch,Survived]].groupby([Parch],ascending=False)
# 没有规律可循,后面创建新特征查看

?

step 2.3 可视化分析

以 Age 变量为例。

直方图对于分析连续的数值变量(比如?Age?)很有用,能够通过形状以及范围来识别样本特征。直方图还可以指定样本分布的区间,有助于我们分析特定问题(婴儿的生还率是否更高?)。

X轴:Age

Y轴:Survived

Observations

  • 婴孩(Age<=4)有很高的生还率。
  • 高龄乘客(80岁)幸存下来。
  • 大多数乘客年龄在15~35岁之间。
  • 15~25岁年龄段的乘客大部分没有生还。

Decisions

这一阶段的分析帮助我们证实假设并为后面的工作作出决定。

  • 我们应该在模型训练中考虑?Age(classifing #2)。
  • 我们应该为?Age?填补缺失值(completing #1)。
  • 我们应该将连续的数值?Age?离散化。(creating #3)。

?

step 3 特征工程

在特征选择后,根据做出的decisions,我们要进行 特征工程,下图为特征工程的工作内容。

?

Correcting by dropping features(删除特征)

这是一个很好的开头。通过删除特征,我们可以处理更少的数据点,提高运行速度,简化分析。

根据我们的 assumptions 和 decisions ,我们将删除Cabin(correcting #2)和Ticket(Correcting #1)特征。

注意,在合适的情况下,我们同时对训练集和测试集执行操作,以保持一致

print("Before",train_df.shape,test_df.shape,combine[0].shape,combine[1].shape)
# 删除特征 train_df
= train_df.drop([Ticket,Cabin],axis=1) test_df = test_df.drop([Ticket,axis = 1) combine = [train_df,test_df] "After",combine[1].shape

?

Creating new feature extracting from existing (从现有特征里提取新特征)

在删除 Name 和 Passengerid 特征之前,我们尝试从 Name 提取?Title 特征?(头衔/称谓),并测试 Title 和 survival 之间的相关性。

在下面的代码中,我们使用正则表达式提取 Title 特征。RegEx pattern?(w+)?匹配 Name 特征中以点字符结尾的第一个单词。expand=false?标志返回 Dataframe。

# 使用正则表达式提取 Title 特征。RegEx pattern (w+) 匹配 Name 特征中以点字符结尾的第一个单词。expand=false 标志返回 Dataframe。
for dataset in combine:
    dataset[Title] = dataset.Name.str.extract(([A-Za-z]+).,expand=False)

pd.crosstab(train_df[Title],train_df[Sex])

# 用更加常见的名称来替换大量 titles ,或者将它们归类为 Rare(稀有的)。
for dataset in combine:
    dataset[Title] = dataset[Title].replace([Lady,Countess,Capt,Col,Don,Dr,Major,Rev,Sir,Jonkheer,Dona],Rare)
    
    dataset[Title] = dataset[Title].replace(Mlle,Miss)
    dataset[Title] = dataset[Title].replace(Ms,Miss)
    dataset[Title] = dataset[Title].replace(Mme,Mrs)
    
train_df[[Title,Survived]].groupby([Title],as_index=False).mean()

# 将分类变量(categorical)转换为顺序变量(ordinal)。
title_mapping = {"Mr": 1,"Miss": 2,"Mrs": 3,"Master": 4,"Rare": 5}
for dataset in combine:
    dataset[Title] = dataset[Title].map(title_mapping)
    dataset[Title] = dataset[Title].fillna(0)

train_df.head()

?

Completing a categorical feature(填充分类特征)

Embarked 特征涵盖 S、Q、C 值。我们的训练集缺少两个值。我们简单地用众数来进行填充。

# 众数填充
freq_port = train_df.Embarked.dropna().mode()[0]

for dataset in combine:
    dataset[Embarked] = dataset[Embarked].fillna(freq_port)
    
# 旋转特征分析
train_df[[Embarked,Survived]].groupby([Embarked],ascending=False)

?

Create new feature combining existing features(从现有特征创建新特征)

结合 Parch 和 Sibsp,为 FamilySize 创建一个新特征。这使我们能够从数据集中删除 Parch 和 Sibsp 。

for dataset in combine:
    dataset[FamilySize]=dataset[SibSp] + dataset[Parch]+1
    
train_df[[FamilySize,Survived]].groupby([FamilySize],ascending=False)

# 创建一个名为 IsAlone 的新特征
for dataset in combine:
    dataset[IsAlone] = 0
    dataset.loc[dataset[FamilySize]==1,IsAlone]=1
    
train_df[[IsAlone,Survived]].groupby([IsAlone],as_index=False).mean()

?

converting a categorical feature (分类特征离散化)

现在,将包含字符串的特征转换为数值。这是大多数模型算法所要求的,同时也将帮助我们实现特征 completing 的目标。

首先,将 sex 特征转换为一个名为 gender 的新特征,其中 female=1,male=0。

for dataset in combine:
    dataset[Sex] = dataset[Sex].map({female:1,male:0}).astype(int)

train_df.head()

?

Quick completing and converting a numeric feature(快速填充和离散化数值特征)

使用 mode 获取 Fare 特征最常出现的值并填充测试集中存在单个缺失值的 Fare 特征。

test_df[Fare].fillna(test_df[Fare].dropna().median(),inplace=True)
test_df.head()

# 创建新特征 FareBand
train_df[FareBand] = pd.qcut(train_df[Fare],4)

train_df[[FareBand,Survived]].groupby([FareBand],ascending=True)

# 基于 FareBand 将 Fare 特征转换为 顺序级
for dataset in combine:
    dataset.loc[ dataset[Fare] <= 7.91,Fare] = 0
    dataset.loc[(dataset[Fare] > 7.91) & (dataset[Fare] <= 14.454),Fare] = 1
    dataset.loc[(dataset[Fare] > 14.454) & (dataset[Fare] <= 31),Fare]   = 2
    dataset.loc[ dataset[Fare] > 31,Fare] = 3
    dataset[Fare] = dataset[Fare].astype(int)

train_df = train_df.drop([FareBand],axis=1)
combine = [train_df,test_df]
    
train_df.head(10)

?

step 4. 模型选择、建模和评估?

现在,训练模型并预测解决方案。有60多种预测建模算法可供选择。我们必须了解问题的类型和解决方案的要求,以便将建模算法的选择范围缩小。我们的问题是一个分类和回归问题,确定输出(存活与否)与其他变量或特征(性别、年龄、港口…)之间的关系。当我们使用给定的数据集训练模型时,我们也在执行一类称为监督学习的机器学习。有了这两个准则——监督学习加上分类和回归,我们可以将模型的选择范围缩小到少数。其中包括:

  • Logistic Regression
  • KNN or k-Nearest Neighbors
  • Support Vector Machines
  • Naive Bayes classifier
  • Decision Tree
  • Random Forrest
  • Perceptron
  • Artificial neural network
  • RVM or Relevance Vector Machine

Random Forrest

随机森林模型是最流行的模型之一。随机森林或随机决策森林是一种用于分类、回归和其他任务的集成学习方法。它在训练时构造多个决策树(n_estimators=100),并通过输出类别(分类)或预测个别树均值(回归)来输出分类结果。-参考维基百科。

到目前为止,随机森林模型的置信度得分是所有模型中最高的。我们决定使用此模型的输出(y_pred)来提交预测结果。

# Random Forrest

random_forest = RandomForestClassifier(n_estimators=100)
random_forest.fit(X_train,Y_train)
Y_pred = random_forest.predict(X_test)
acc_random_forest = round(random_forest.score(X_train,Y_train)*100,2)
acc_random_forest

保存预测结果。

submission = pd.DataFrame({
        "PassengerId": test_df["PassengerId"],"Survived": Y_pred
    })

submission.to_csv(submission.csv,index=False)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读