数据挖掘 K近邻算法 泰坦尼克号数据集乘客幸存分析

一、分析目的

(1)分析泰坦尼克号数据集,说明每个属性的类别;

(2)将幸存属性设置为类别标签,使用K近邻算法作为分类算法(无需考虑PassengerID,name,ticket和cabin,去掉带缺失属性的样本),在测试集上预测乘客的幸存情况并计算准确率。

二、分析属性类别

使用pd.read_csv读入train.csv。打印data_train.info()以及data_train的所有列,如下图所示。

由图一可知,Age, Cabin, Embarked属性有缺失;PassengerId, Survived, Pclass, SibSp, Parch为int类型;Age, Fare为float类型;Name, Sex, Ticket, Cabin, Embarked为object类型,即string类型。

由图二进一步分析可知各个属性的类别:PassengerId, Name, Ticket, Cabin, Embarked为标称属性,代表的是事物的名称或一些符号;Survived和Sex为二元属性,Survived仅有两个取值0/1,Sex仅有两个取值male/female,且Survived为非对称二元属性,Sex为对称二元属性;Pclass为序数属性,取值1、2、3表示不同的社会地位;Age, SibSp, Parch, Fare为数值属性,均为可度量的量。

 三、K近邻算法分类

1. 去除相关属性,删去缺失值,设置标签,将Sex和Embarked属性由str属性编码为int,便于进一步计算混合属性距离。完成相关处理后打印数据集如下图所示:

 相关代码如下所示:

data_train = data_train.drop(['PassengerId', 'Name', 'Ticket', 'Cabin'], axis=1)  
data_train = data_train.dropna()  
data_train['Survived'] = data_train['Survived'].astype('category')  
  
label_encoder = LabelEncoder()  
data_train['Sex'] = label_encoder.fit_transform(data_train['Sex'])  
data_train['Embarked'] = label_encoder.fit_transform(data_train['Embarked'])  
print(data_train)  

2. 划分训练集

使用train_test_split将训练集划出30%作为测试集。打印划分后的训练集测试集信息如下:

 

(训练集信息) 

(测试集信息)  

 可以看出按照7:3划分了训练集和测试集。相关代码如下所示:

 

X = data_train.drop('Survived', axis=1)  
y = data_train['Survived']  
# print(X)  
# print(y)  
  
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=33)  
print(X_train.info())  
print(X_test.info())  

3. 自定义混合距离函数

按照定义对数值属性、标称属性/二元属性、序数属性进行相应处理,最后用公式求平均值,得出mixed_distance。

 

1)序数属性

先转换为数值属性再计算相异性,转换后的取值范围为[0, 1.0]。

2)标称属性/二元属性

比较两个对象的该属性值是否相等,相等距离为0,不相等距离为1。

3)数值属性

先找出各个属性在数据集上的最大值和最小值,按照的公式计算距离。

完整函数实现代码如下所示: 

age_max = data_train['Age'].max()  
age_min = data_train['Age'].min()  
sibsp_max = data_train['SibSp'].max()  
sibsp_min = data_train['SibSp'].min()  
parch_max = data_train['Parch'].max()  
parch_min = data_train['Parch'].min()  
fare_max = data_train['Fare'].max()  
fare_min = data_train['Fare'].min()  
	  
def mixed_distance(x1, x2):  
   # 序数属性Pclass  
   x1[0] = (x1[0] - 1) / (3.0 - 1)  # 转换成数值属性  
   x2[0] = (x2[0] - 1) / (3.0 - 1)  
   pclass_distance = abs(x1[0] - x2[0]) / (1.0 - 0)  
	  
   # Sex(二元),Embarked(标称)  
   # 看x1,x2的'Sex'和'Embarked'值是否相等,相等距离为 0,不相等距离为 1  
   sex_distance = 0 if x1[1] == x2[1] else 1  
   embarked_distance = 0 if x1[6] == x2[6] else 1  
	  
   # 数值属性:Age,SibSp,Parch,Fare  
   age_distance = abs(x1[2] - x2[2]) / (age_max - age_min)  
   sib_distance = abs(x1[3] - x2[3]) / (sibsp_max - sibsp_min)  
   parch_distance = abs(x1[4] - x2[4]) / (parch_max - parch_min)  
   fare_distance = abs(x1[5] - x2[5]) / (fare_max - fare_min)  
  
   distance = 1 / 7 * (  
           pclass_distance + sex_distance + embarked_distance + age_distance + sib_distance + parch_distance + fare_distance)  
   return distance  

4. 交叉验证

使用5折交叉验证,选择最优的k,使用cross_val_score函数进行K折交叉验证。在使用KNeighborsClassifier时设置参数metric=mixed_distance。打印出最优的k,结果如下: 

 

 相关代码如下所示:

k_values = list(range(1, 21))  
kfold = KFold(n_splits=10, shuffle=True, random_state=22)  
cv_scores = []  
for k in k_values:  
    knn = KNeighborsClassifier(n_neighbors=k, metric=mixed_distance)  
    scores = cross_val_score(knn, X_train, y_train, cv=kfold, scoring='accuracy')  
    cv_scores.append(scores. Mean())  
best_k = k_values[cv_scores.index(max(cv_scores))]  
print("best_k is:",best_k)  

5. KNN模型训练及测试

设置KNeighborsClassifier的参数n_neighbors=best_k, metric=mixed_distance。打印准确率:

 

 相关代码如下所示:

knn = KNeighborsClassifier(n_neighbors=best_k, metric=mixed_distance)  
knn.fit(X_train, y_train)  
  
y_pred = knn.predict(X_test)  
test_accuracy = accuracy_score(y_test, y_pred)  
print(test_accuracy)  

四、结论与总结

1. 各个属性的类型:

2. 混合类型属性集的相异性量度需要分三个部分考虑。

序数属性:

先转换为数值属性再计算相异性,转换后的取值范围为[0, 1.0]。

标称属性/二元属性:

比较两个对象的该属性值是否相等,相等距离为0,不相等距离为1。

数值属性:

先找出各个属性在数据集上的最大值和最小值,按照的公式计算距离。

最后对所有距离求平均得到混合属性距离。 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值