El conjunto de datos se puede descargar aquí:
https://www.kaggle.com/c/titanic
En este proyecto, utilizaremos las siguientes bibliotecas de Python:
- Biblioteca de computación científica Numpy -Python (operación matricial)
- Pandas - Biblioteca de análisis y procesamiento de datos de Python
- Scikit-learn -Python machine learning library (algoritmo de aprendizaje automático)
1. Primero mira los datos
import pandas as pd
titanic = pd.read_csv(r"S:\数据分析\kaggle_Titanic\train.csv")
titanic.head() # 默认前五行
Podemos ver qué características hay en los datos del Titanic y analizar qué características tienen un mayor impacto en la probabilidad de supervivencia.
En segundo lugar, el siguiente preprocesamiento de datos
print(titanic.describe()) # 按列统计特征
A través de las estadísticas de las características de la columna, encontramos que falta el valor de Edad, por lo que lo siguiente es tratar con el valor que falta:
import pandas as pd
titanic['Age'] = titanic['Age'].fillna(titanic['Age'].mean()) # 使用均值填充缺失值
print(titanic.describe())
Por lo tanto, los datos de edad se llenan.
Luego, codificación única de características sexuales:
print(titanic['Sex'].unique()) # 查看Sex特征有哪些值
>>> ['male' 'female']
# loc定位到目标行,对Sex特征进行独热编码
titanic.loc[titanic['Sex'] == 'male', 'Sex'] = 0 # 令Sex等于male那行的Sex值为1
titanic.loc[titanic['Sex'] == 'female', 'Sex'] = 1 # 令Sex等于female那行的Sex值为0
Luego, realice el procesamiento del valor perdido y la codificación de una sola vez en las funciones Embarcadas:
print(titanic['Embarked'].unique())
>>> ['S' 'C' 'Q' nan] # 存在缺失值
titanic['Embarked'] = titanic['Embarked'].fillna('S') # S数量多,可以用S补充缺失值
titanic.loc[titanic['Embarked'] == 'S', "Embarked"] = 0
titanic.loc[titanic['Embarked'] == 'C', "Embarked"] = 1
titanic.loc[titanic['Embarked'] == 'Q', "Embarked"] = 2
3. Utilice el modelo de regresión lineal para predecir la probabilidad de supervivencia.
from sklearn.linear_model import LinearRegression # 导入线性回归的类,采用二分类进行分类预测
from sklearn.model_selection import KFold # K折交叉验证,取平均,调参
predictors = ["Pclass", "Sex", "Age", "SibSp", "Parch", "Fare", "Embarked"] # 输入机器学习算法的特征
alg = LinearRegression() # 初始化线性回归类
kf = KFold(n_splits=3, random_state=1) # KFold类实例化
# kf.get_n_splits(titanic) # 交叉验证集的拆分迭代次数
predictions = []
# 有3次for循环,每次建立一个回归模型
for train, test in kf.split(titanic):
train_predictors = (titanic[predictors].iloc[train,:]) # 取出训练数据
train_target = titanic["Survived"].iloc[train] # 获取到数据集中交叉分类好的标签,即是否活了下来
alg.fit(train_predictors, train_target) # 训练模型
test_predictions = alg.predict(titanic[predictors].iloc[test,:]) # 检验模型误差
predictions.append(test_predictions)
En sklearn 0.18 y superior, el paquete cross_validation ha quedado en desuso.
Documentación de KFold: https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.KFold.html?highlight=kfold#sklearn.model_selection.KFold
Mire el efecto del entrenamiento modelo:
import numpy as np
predictions = np.concatenate(predictions, axis=0) # 转换成数组,才能比较大小
# 使用线性回归得到的结果是在区间[0,1]上的某个值,需要将该值转换成0或1
predictions[predictions > 0.5] = 1
predictions[predictions <= 0.5] = 0
print("测试数据的总数量:", len(predictions))
print("正确的数量:", sum(predictions == titanic["Survived"]))
accuracy = sum(predictions == titanic["Survived"]) / len(predictions)
print("准确率为:", accuracy)
4. Utilice el modelo de regresión logística para predecir la probabilidad de supervivencia
from sklearn import model_selection
from sklearn.linear_model import LogisticRegression
alg = LogisticRegression(random_state=1, solver='liblinear') # 初始化逻辑回归类
# 逻辑回归交叉验证
score = model_selection.cross_val_score(alg, titanic[predictors], titanic["Survived"], cv=3)
print("准确率为:", score.mean())
Parece que el modelo de regresión se usa para la predicción, y el efecto no es tan bueno ...
Cinco, use un modelo de bosque aleatorio para predecir la probabilidad de supervivencia
Significado aleatorio:
- Muestreo aleatorio de muestras de datos.
- Muestreo aleatorio de características
Quizás algunas características son negativas. Los bosques aleatorios pueden neutralizar las características, por lo que los bosques aleatorios pueden evitar el sobreajuste y hacer que la precisión del algoritmo sea más confiable.
from sklearn import model_selection
from sklearn.ensemble import RandomForestClassifier
predictors = ["Pclass", "Sex", "Age", "SibSp", "Parch", "Fare", "Embarked"]
alg = RandomForestClassifier(random_state=1, n_estimators=50, min_samples_split=4, min_samples_leaf=2)
kf = model_selection.KFold(n_splits=3, random_state=1) # 三次交叉验证
# print(kf.get_n_splits(titanic)) # 交叉验证集的拆分迭代次数
score = model_selection.cross_val_score(alg, titanic[predictors], titanic["Survived"], cv=kf.split(titanic))
print("准确率为:", score.mean())
Se puede ver que la precisión obtenida por los dos modelos de regresión anteriores es mayor.
Comprenda los parámetros del clasificador de bosque aleatorio:
-
random_state
genera una semilla de número aleatorio cada vez. -
n_estimators (int, opcional (predeterminado = 100))
El número de árboles en el bosque. -
min_samples_split (int, float, opcional (predeterminado = 2)
El número mínimo de muestras necesarias para dividir los nodos internos.
如果为int,则认为 min_samples_split 是最小值。
如果为 float,min_samples_split则为分数,是每个拆分的最小样本数。
-
min_samples_leaf (int, float, opcional (predeterminado = 1))
El número mínimo de muestras requeridas en el nodo hoja.
Solo si min_samples_leaf tiene al menos muestras de entrenamiento en cada una de las ramas izquierda y derecha, se considerará cualquier profundidad de los puntos divididos. Esto puede tener el efecto de suavizar el modelo, especialmente en regresión.
如果为int,则认为 min_samples_leaf 是最小值。
如果为float,min_samples_leaf 则为分数,是每个节点的最小样本数。
Seis, establecer un proyecto de características
# 第一个特征:亲属数量
titanic["FamilySize"] = titanic["SibSp"] + titanic["Parch"]
# 第二个特征:名字长度
titanic["NameLength"] = titanic["Name"].apply(lambda x:len(x))
titanic
import re
def get_title(name):
title_search = re.search('([A-Za-z]+)\.', name) # \.匹配.(转义)
if title_search:
return title_search.group(1)
return ""
titles = titanic["Name"].apply(get_title)
print(pd.value_counts(titles))
title_mapping = {"Mr": 1, "Miss": 2, "Mrs": 3, "Master": 4, "Dr": 5, "Rev": 6, "Major": 7, "Col": 7, "Mlle": 8,
"Mme": 8, "Don": 9, "Lady": 10, "Countess": 10, "Jonkheer": 10, "Sir": 9, "Capt": 7, "Ms": 2}
for k, v in title_mapping.items():
titles[titles == k] = v
print(pd.value_counts(titles))
titanic["Title"] = titles # 添加新特征:身份
Siete, selección de características
Al agregar ruido, analice la importancia de las características:
from sklearn.feature_selection import SelectKBest, f_classif # 特征选择库
import matplotlib.pyplot as plt # 画出直方图,分析特征的权重
predictors = ["Pclass", "Sex", "Age", "SibSp", "Parch", "Fare", "Embarked", "FamilySize", "Title", "NameLength"]
selector = SelectKBest(f_classif, k=5) # f_classif:基于方差分析的检验统计f值,根据k个最高分数选择功能
selector.fit(titanic[predictors], titanic["Survived"])
scores = -np.log10(selector.pvalues_)
plt.bar(range(len(predictors)), scores)
plt.xticks(range(len(predictors)), predictors, rotation='vertical')
plt.show()
predictors = ["Pclass", "Sex", "Fare", "Title"]
alg = RandomForestClassifier(random_state=1, n_estimators=50, min_samples_split=8, min_samples_leaf=4)
kf = model_selection.KFold(n_splits=3, random_state=1)
scores = model_selection.cross_val_score(alg, titanic[predictors], titanic["Survived"], cv=kf)
print("再次利用随机森林模型的准确率:" + str(scores.mean()))
Ocho, integra múltiples algoritmos
from sklearn.ensemble import GradientBoostingClassifier
import numpy as np
algorithms = [
[GradientBoostingClassifier(random_state=1, n_estimators=45, max_depth=6), ['Pclass','Sex','Age','SibSp','Parch','Fare','Embarked','FamilySize','NameLength','Title']],
[LogisticRegression(random_state=1, solver='liblinear'), ['Pclass','Sex','Age','SibSp','Parch','Fare','Embarked','FamilySize','NameLength','Title']]
]
kf = KFold(n_splits=3, random_state=1)
predictions = []
for train, test in kf.split(titanic):
train_target = titanic["Survived"].iloc[train]
full_test_predictions = []
for alg, predictors in algorithms:
alg.fit(titanic[predictors].iloc[train,:], train_target)
test_predictions = alg.predict_proba(titanic[predictors].iloc[test,:].astype(float))[:,1]
full_test_predictions.append(test_predictions)
test_predictions = (full_test_predictions[0] + full_test_predictions[1]) / 2
test_predictions[test_predictions <= 0.5] = 0
test_predictions[test_predictions > 0.5] = 1
predictions.append(test_predictions)
predictions = np.concatenate(predictions, axis=0)
accuracy = sum(predictions == titanic["Survived"]) / len(predictions)
print("准确率为:", accuracy)
Referencia: Tianshan Intelligent Cloud Classroom Python Machine Learning Kaggle Case