关于数据集
描述:乳腺癌是世界上女性中最常见的癌症。它占所有癌症病例的25%,仅在2年就影响了超过1万人。当乳房中的细胞开始失控生长时,它就开始了。这些细胞通常形成肿瘤,可以通过X射线看到或在乳房区域感觉为肿块。
预测的主要挑战是如何将肿瘤分为恶性(癌性)或良性(非癌性)。这里使用fisher线性判别和威斯康星州乳腺癌(诊断)数据集完成对这些肿瘤进行分类的分析。
数据来源:Breast Cancer Dataset | Kaggle
算法思想及步骤:https://blog.csdn.net/qq_42585108/article/details/105918590
目的:
- 了解数据集和清理(如果需要)。
- 建立分类模型以预测癌症类型是恶性还是良性。
- 还可以微调超参数并比较各种分类算法的评估指标。
代码实现:
# 导入程序所需的包 import matplotlib.pyplot as plt import numpy as np import pandas as pd from sklearn.preprocessing import StandardScaler # 读取 breast-cancer.csv 数据集 datasource = pd.read_csv('breast-cancer.csv') # 从 breast-cancer.csv 数据集中提取特征列表 area_mean 和 texture_mean 作为变量,diagnosis 值为肿瘤的良性与恶性(M为恶性,B为良性) data = datasource[['area_mean', 'texture_mean', 'diagnosis']] # 提取特征列进行标准化 features = data[['area_mean', 'texture_mean']] scaler = StandardScaler() scaled_features = scaler.fit_transform(features) # 将标准化后的特征替换原来的特征列 data[['area_mean', 'texture_mean']] = scaled_features # 划分数据集,diagnosis值为M的为X1,diagnosis值为B的划分为X2 X1 = data.loc[data['diagnosis'] == 'M'] X2 = data.loc[data['diagnosis'] == 'B'] # print('X1:', X1) # print('X2:', X2) # 将 ‘area_mean’ 和 ‘texture_mean’ 列分别作为 X 轴和 Y 轴绘制散点图。其中 ‘X1’ 数据绘制为红色散点,‘X2’ 数据绘制为蓝色散点。 plt.scatter(X1['area_mean'], X1['texture_mean'], color='red', label='M') plt.scatter(X2['area_mean'], X2['texture_mean'], color='blue', label='B') plt.title('Breast Cancer Diagnosis') plt.xlabel('Area Mean') plt.ylabel('Texture Mean') plt.legend() plt.show() # 分别计算 ‘X1’ 和 ‘X2’ 数据均值向量 mean_X1 = X1.mean()[['area_mean', 'texture_mean']].values mean_X2 = X2.mean()[['area_mean', 'texture_mean']].values print('X1的均值向量:', mean_X1) print('X2的均值向量:', mean_X2) # 分别计算 ‘X1’ 和 ‘X2’ 数据的协方差矩阵 cov_X1 = X1[['area_mean', 'texture_mean']].cov().values cov_X2 = X2[['area_mean', 'texture_mean']].cov().values print('X1的协方差矩阵:', cov_X1) print('X2的协方差矩阵:', cov_X2) # 使用联合无偏估计来估计总体协方差矩阵 n1 = X1.shape[0] n2 = X2.shape[0] S1 = cov_X1 * (n1 - 1) S2 = cov_X2 * (n2 - 1) Spooled = (S1 + S2) / (n1 + n2 - 2) print('Spooled:', Spooled) # 求判别函数的系数a Spooled_inv = np.linalg.inv(Spooled) # 计算总体协方差矩阵的逆矩阵 a = Spooled_inv @ (mean_X1 - mean_X2) # 计算判别函数的系数向量a print("fisher判别函数系数a:", a) # 计算 'X1' 和 ‘X2’ 类的投影中心值 f_mean_X1 = mean_X1 @ a f_mean_X2 = mean_X2 @ a print("类 X1 的投影中心值为:", f_mean_X1) print("类 X2 的投影中心值为:", f_mean_X2) # 生成Fisher判别的结果 X = data[['area_mean', 'texture_mean']].values y = data['diagnosis'].values y[y == 'M'] = 1 y[y == 'B'] = 0 f_data = X @ a # 将样本数据集投影到Fisher判别的一维空间 # 绘制Fisher判别结果散点图 plt.scatter(f_data[y == 0], np.zeros(f_data[y == 0].shape), color='blue', label='B') plt.scatter(f_data[y == 1], np.zeros(f_data[y == 1].shape), color='red', label='M') plt.title('Fisher Discriminant') plt.xlabel('Fisher Score') plt.legend() plt.show() def decision_boundary(x, a, mean_X1, mean_X2): return (1 / a[1]) * (np.dot(a.T, (mean_X1 + mean_X2) / 2) - a[0] * x) # 在原有的散点图上添加决策边界 x_values = np.linspace(data['area_mean'].min(), data['area_mean'].max(), num=100) y_values = decision_boundary(x_values, a, mean_X1, mean_X2) plt.scatter(X1['area_mean'], X1['texture_mean'], color='red', label='M') plt.scatter(X2['area_mean'], X2['texture_mean'], color='blue', label='B') plt.plot(x_values, y_values, color='green', label='Decision Boundary') plt.title('Breast Cancer Diagnosis') plt.xlabel('Area Mean') plt.ylabel('Texture Mean') plt.legend() plt.show() # 预测 if __name__ == '__main__': # 对新数据进行投影并进行分类判别 new_data = np.array([1049, 100]) print("要预测的数据为:", new_data) # 对新数据进行标准化 scaled_new_data = scaler.transform([new_data]) # 将数据点投影到Fisher判别的一维空间 f_new_data = scaled_new_data @ a print('预测数据的投影值:', f_new_data) # 计算该样本到类 X1 投影中心值的距离和到类 X2 投影中心值的距离 distance_to_mean_X1 = abs(f_new_data - f_mean_X1) distance_to_mean_X2 = abs(f_new_data - f_mean_X2) # print('distance_to_mean_X1', distance_to_mean_X1) # print('distance_to_mean_X2', distance_to_mean_X2) # 根据距离进行分类判别 if distance_to_mean_X1 < distance_to_mean_X2: print("预测结果:该样本为恶性肿瘤") else: print("预测结果:该样本为良性肿瘤")
运行结果:
总结:
算法心得:Fisher判别是一种经典的线性学习方法,目标是通过寻找投影,使得在投影后的一维空间上同一类别样本的投影点尽可能接近,不同类别样本的投影点尽可能远离。它通过计算类别之间的散布矩阵和类别内散布矩阵,来确定最佳投影方向。Fisher判别在实际应用中常用于特征提取、数据可视化和模式识别等领域。它在处理线性可分问题上表现良好,但对于非线性可分问题效果有限。在处理复杂数据时,可以结合其他方法或使用非线性判别方法来改进分类性能。