В этой статье записано вводное упражнение по машинному обучению, а именно: простая бинарная классификация с деревьями решений. В то же время в сочетании с классическим случаем Titanic на Kaggle, чтобы проверить реальный эффект.
1. Набор данных
использоватьKaggleНабор данных Титаник в формате . Данные включают:
- тренировочный набор: тренировочный набор (train.csv)
- Набор тестов: набор тестов (test.csv)
- Критерии подачи: поле_submission.csv
Поскольку Kaggle предполагает работу с научным доступом в Интернет, поэтомуисходный набор данныхОн был скачан и выложен на Gighub.
2. Обработка данных
Сначала импортируйте тренировочный набор и проверьте данные:
from sklearn.tree import DecisionTreeClassifier # 导入模型决策树分类器
from sklearn.model_selection import cross_val_score,train_test_split,GridSearchCV # 导入的模型作用分别为交叉验证、训练集与数据集的划分,网格搜索
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
data = pd.read_csv('/Users/liz/code/jupyter-notebook/sklearn/1- DecisionTree/Titanic_train.csv') # 导入数据集
data.head() # 显示数据集的前五行
[out]:
PassengerId | Survived | Pclass | Name | Sex | Age | SibSp | Parch | Ticket | Fare | Cabin | Embarked | |
---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | 0 | 3 | Braund, Mr. Owen Harris | male | 22.0 | 1 | 0 | A/5 21171 | 7.2500 | NaN | S |
1 | 2 | 1 | 1 | Cumings, Mrs. John Bradley (Florence Briggs Th... | female | 38.0 | 1 | 0 | PC 17599 | 71.2833 | C85 | C |
2 | 3 | 1 | 3 | Heikkinen, Miss. Laina | female | 26.0 | 0 | 0 | STON/O2. 3101282 | 7.9250 | NaN | S |
3 | 4 | 1 | 1 | Futrelle, Mrs. Jacques Heath (Lily May Peel) | female | 35.0 | 1 | 0 | 113803 | 53.1000 | C123 | S |
4 | 5 | 0 | 3 | Allen, Mr. William Henry | male | 35.0 | 0 | 0 | 373450 | 8.0500 | NaN | S |
С приведенными выше данными, показывающими ситуацию, все, что нам нужно сделать, это использовать Survived в качестве метки, а остальные столбцы в качестве функций. Цель: Предсказать метки с известными функциями. Фактический смысл этого набора данных состоит в том, чтобы сделать прогноз выживания пассажиров на основе известных данных.
data.info() # 查看整个训练集的情况
out:
<class 'pandas.core.frame.DataFrame'>
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.7+ KB
анализ данных
- В приведенном выше отображении данных имеется в общей сложности 891 данные, среди которых функции с отсутствующими значениями: Возраст, Каюта, Посадка; нечисловые функции: Имя, Пол, Билет, Каюта, Посадка.
- Когда мы используем существующие функции для прогнозирования ситуации выживания пассажиров, некоторые пары функций, которые являются более хлопотными и менее важными, могут не использоваться. Например, Имя и Билет здесь можно не использовать, потому что в действительности имя пассажира и купленный билет мало влияют на выживаемость пассажира. Другая причина заключается в том, что и те, и другие являются нечисловыми данными, и их сложнее преобразовать в числовую форму (данные, полученные в компьютере, в конечном итоге должны быть представлены в виде чисел).
- Поскольку в Cabin много пропущенных значений, здесь принят метод удаления по тем же причинам, что и выше.
- Хотя пол также является данными характера, на практике пол оказывает определенное влияние на возможность побега, поэтому он резервируется.
- Вменить пропущенные значения; преобразовать нечисловые данные в числовые данные.
# 删除Name、Ticket、Cabin特征列
data.drop(['Name','Cabin','Ticket'],inplace=True,axis=1)
# 缺失值的填补
# 对于Age的缺失值填补的一种策略为:以年龄的平均值作为填补
data.loc[:,'Age'] = data['Age'].fillna(int(data['Age'].mean()))
# Embarked由于只有两条数据具有缺失值,这里采用的方式是删除这两条缺失的数据(缺失两条数据对模型的训练好坏影响不大)
data = data.dropna()
data = data.reset_index(drop = True) # 删除过后,用于重置索引
# 将非数值型数据转化为数值型数据
# 性别只有两类,故可用0\1来表示男女
data['Sex'] = (data['Sex'] == 'male').astype(int) # 0表示女,1表示男
tags = data['Embarked'].unique().tolist() # tags: ['S', 'C', 'Q']
# Embarked只有三类分别以S,C,Q的索引代表他们,0~9均可采用此种方法
data.iloc[:,data.columns == 'Embarked'] = data['Embarked'].apply(lambda x : tags.index(x))
# 查看数据
data.info() # 查看数据信息
out:
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 889 entries, 0 to 888
Data columns (total 9 columns):
PassengerId 889 non-null int64
Survived 889 non-null int64
Pclass 889 non-null int64
Sex 889 non-null int64
Age 889 non-null float64
SibSp 889 non-null int64
Parch 889 non-null int64
Fare 889 non-null float64
Embarked 889 non-null int64
dtypes: float64(2), int64(7)
memory usage: 62.6 KB
# 将特征与标签进行分离
x = data.iloc[:,data.columns != 'Survived'] # 取出Survived以为的列作为特征x
y = data.iloc[:,data.columns == 'Survived'] # 取出Survived列作为特征y
обучение модели
Идея: использовать перекрестную проверку для оценки нашей модели, а также использовать поиск по сетке, чтобы найти лучшие параметры, обычно встречающиеся в деревьях решений.
# 网格搜索:能够帮助我们同时调整多个参数的技术,本质是枚举技术。
# paramerters:用于确定的参数。
parameters = {'splitter':('best','random')
,'criterion':('gini','entropy')
,'max_depth':[*range(1,10)]
,'min_samples_leaf':[*range(1,50,5)]
,'min_impurity_decrease':[*np.linspace(0,0.5,20)]
}
# 网格搜索实例代码,所需要确定的参数越多,耗时越长
clf = DecisionTreeClassifier(random_state=30)
GS = GridSearchCV(clf,parameters,cv=10) # cv=10,做10次交叉验证
GS = GS.fit(x_train,y_train)
# 最佳参数
GS.best_params_
out:
{'criterion': 'gini',
'max_depth': 3,
'min_impurity_decrease': 0.0,
'min_samples_leaf': 1,
'splitter': 'best'}
# 最佳得分
GS.best_score_
Определив оптимальные значения для заданных параметров, приступаем к обучению модели:
# 训练模型,将以上设置参数的最佳值填入模型的实例化中
clf_model = DecisionTreeClassifier(criterion='gini'
,max_depth=3
,min_samples_leaf=1
,min_impurity_decrease=0
,splitter='best'
)
clf_model = clf_model.fit(x,y)
Экспортируйте модель:
# 导出模型
from sklearn.externals import joblib
joblib.dump(clf_model,'/Users/liz/Code/jupyter-notebook/sklearn/1- DecisionTree/clf_model.m')
Обработка тестового набора:
# 导入测试集
data_test = pd.read_csv('/Users/liz/code/jupyter-notebook/sklearn/1- DecisionTree/Titanic_test.csv')
data_test.info()
out:
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 418 entries, 0 to 417
Data columns (total 11 columns):
PassengerId 418 non-null int64
Pclass 418 non-null int64
Name 418 non-null object
Sex 418 non-null object
Age 332 non-null float64
SibSp 418 non-null int64
Parch 418 non-null int64
Ticket 418 non-null object
Fare 417 non-null float64
Cabin 91 non-null object
Embarked 418 non-null object
dtypes: float64(2), int64(4), object(5)
memory usage: 36.0+ KB
# 测试集处理的方法同训练集,同时测试集要与训练集保持同样的特征
# 由于最后,我们需要将处理结果上传到Kaggle上,所以不能够将数据条目减少,即:需要上传418条测试数据;故这里Fare缺失的一条数目同样采用平均值来填补
data_test.drop(['Name','Ticket','Cabin'],inplace=True,axis=1)
data_test['Age'] = data_test['Age'].fillna(int(data_test['Age'].mean()))
data_test['Fare'] = data_test['Fare'].fillna(int(data_test['Fare'].mean()))
data_test.loc[:,'Sex'] = (data_test['Sex'] == 'male').astype(int)
tags = data_test['Embarked'].unique().tolist()
data_test['Embarked'] = data_test['Embarked'].apply(lambda x : tags.index(x))
На этом этапе данные тестового набора предварительно обрабатываются, экспортируйте модель и тестируйте данные:
# 导出模型且测试数据集
model = joblib.load('/Users/liz/Code/jupyter-notebook/sklearn/1- DecisionTree/clf_model.m')
Survived = model.predict(data_test) # 测试结果
# 生成数据
Survived = pd.DataFrame({'Survived':Survived}) # 将结果转换为字典形式并后续作为csv形式导出
PassengerId = data_test.iloc[:,data_test.columns == 'PassengerId'] # 切片,分割出PassengerId
gender_submission = pd.concat([PassengerId,Survived],axis=1)# 将Survived与PassengerId拼接,一一对应
#导出数据
#导出数据
gender_submission.index = np.arange(1, len(gender_submission)+1) # 索引从1开始
gender_submission.to_csv('/Users/liz/Code/jupyter-notebook/sklearn/1- DecisionTree/gender_submission.csv',index=False) # index=False,导出时不显示索引
Экспорт файла:
PassengerId | Survived | |
---|---|---|
0 | 892 | 0 |
1 | 893 | 1 |
2 | 894 | 0 |
3 | 895 | 0 |
4 | 896 | 1 |
... | ... | ... |
413 | 1305 | 0 |
414 | 1306 | 1 |
415 | 1307 | 0 |
416 | 1308 | 0 |
417 | 1309 | 0 |
418 строк × 2 столбца
представить результатыKaggle, окончательный балл:
Окончательная оценка 0,77990, оценка невысокая, а самая высокая оценка заполнена.Эта статья — просто введение в машинное обучение и Kaggle.
Окончательный исходный код и набор данных Kaggle будут загружены в мой репозиторий Github, в том числе некоторые связанные заметки, размещенные в Интернете, также будут загружены в Github, этот репозиторий будет постоянно обновляться...
прикрепил
URL-адрес на гитхабе:GitHub.com/Chem LE at/ml-…