STM32单片机C语言程序使用KNN算法对乳腺肿瘤分类

19 篇文章 2 订阅
9 篇文章 0 订阅

一、概述

之前在《STM32单片机使用KNN算法实现鸢尾花分类》中使用了KNN算法对鸢尾花进行分类,程序采用C语言编写,运行于STM32F103单片机上,效果较好。本篇文章将采用KNN算法对乳腺肿瘤进行分类,看看单片机处理高维数据的表现。数据来自于UCI,下载地址https://archive.ics.uci.edu/ml/datasets/Breast+Cancer+Wisconsin+%28Diagnostic%29,整理好的数据已上传到资源breast_cancer_wisconsin(diagnostic).rar-机器学习文档类资源-CSDN文库 ,可下载使用。
源程序完整工程已上传至面包多([003]STM32单片机C语言程序使用KNN算法对乳腺肿瘤进行分类),可选择下载。

二、数据预处理

在这里插入图片描述
该数据集描述中共有569组,但下载后实际有699组(仔细观察,实际上病例ID有相同的,可能是569是ID的数量,这点不做深究);虽然描述说没有缺失值,但实际有16组数据有缺失值,数据中以“?”代替,将这些数据剔除,还有683组,其中良性肿瘤(benign)444例,恶性肿瘤(malignant)239例。
每组数据11列,但ID和最终的分类不算是数据的特种,因此KNN算法需要处理的数据为9维。
在Excel中,将可用数据做如下处理:
① 将数据按照良性、恶性,分成两类;
② 为使程序简单,因ID不参与计算,去掉ID列;
③ 将两组数据,均随机排列;
④ 每组数据各取前40%作为训练集,剩余60%作为测试集,即良性肿瘤取178组作为训练集,恶性肿瘤取96组作为训练集。

三、主要代码

因为是二分类问题,因此取奇数k=3,使用printf函数打印分类结果,通过串口接收结果,主要代码如下:

/*******************************************************************************
  * 函数名:KNN_Classify
  * 功  能:分类
  * 参  数:无
  * 返回值:无
  * 说  明:无
*******************************************************************************/
void KNN_Classify(void)
{
    uint8_t u8BenignCnt = 0;
    uint8_t u8MalignantCnt = 0;
    uint8_t u8Max = 0;
    uint16_t i, j, m;
    uint16_t *pTest, *pTrain;
	Result_ts sCancerResult;
	uint16_t u16FailCnt = 0;
    for (i = 0; i < TEST_ROW; i++)
    {
        memset(&sCancerResult, 0, sizeof(sCancerResult));
		HAL_IWDG_Refresh(&hiwdg);
        for (j = 0; j < TRAIN_ROW; j++)//
        {
            pTest = (uint16_t *)&u16TestSet[i];
            pTrain = (uint16_t *)&u16TrainSet[j];
			HAL_IWDG_Refresh(&hiwdg);
            sCancerResult.u16Distance[j][0] = EuclideanDistance(pTest, pTrain, TRAIN_COLUMN - 1);//
            //sIrisResult.u16Distance[j][0] = ChebyshevDistance(pTest, pTrain, TRAIN_COLUMN - 1);//
			//sIrisResult.u16Distance[j][0] = ManhattanDistance(pTest, pTrain, TRAIN_COLUMN - 1);
            sCancerResult.u16Distance[j][1] = u16TrainSet[j][9];
			HAL_IWDG_Refresh(&hiwdg);
        }
        BubbleSort(sCancerResult.u16Distance, TRAIN_ROW);//第i个测试集的数据,排序
        u8BenignCnt = 0;
        u8MalignantCnt = 0;
		HAL_IWDG_Refresh(&hiwdg);
        for (m = 0; m < K_VALUE; m++)//前k个数据
        {
            switch (sCancerResult.u16Distance[m][1])
            {
                case BENIGN: u8BenignCnt++; break;                    
                case MALIGNANT: u8MalignantCnt++; break;                    
                default:break;
            }
        }
		
        u8Max = max(u8BenignCnt, u8MalignantCnt);
		u8Max = ((u8Max == u8BenignCnt) ? BENIGN : MALIGNANT);        
        sCancerResult.u8Class = u8Max;//保存分类结果
		for (j = 0; j < TEST_COLUMN - 1; j++)
		{
			printf(" %d",u16TestSet[i][j]);
		} 
		printf(" benignCnt: %d,malignantCnt: %d,", u8BenignCnt, u8MalignantCnt);
		switch(u8Max)
        {
            case BENIGN:
            {                    
                printf("class: benign ");//输出分类结果
                if (sCancerResult.u8Class == u16TestSet[i][9])//分类正确
                {
                    printf(" Success\n");//
                }else
                {
					u16FailCnt++;
                    printf(" Fail\n");
                }
            }break;
            case MALIGNANT:
            {
                printf("class: malignant ");//输出分类结果
                if (sCancerResult.u8Class == u16TestSet[i][9])//分类正确
                {
                    printf(" Success\n");//
                }else
                {
					u16FailCnt++;
                    printf(" Fail\n");
                }
            }break;            
            default:break;
        }		
		HAL_IWDG_Refresh(&hiwdg);
    }
	printf(" FailCnt:%d", u16FailCnt);
}

四、运行效果:

串口接收数据部分截图:
在这里插入图片描述

在这里插入图片描述
最后打印出失败数量是12个,测试集共409组,因此分类正确397组,准确率97.07%。

五、结论

在《STM32单片机使用KNN算法实现鸢尾花分类》中的结论基本也适用于本文对乳腺肿瘤的分类。其他距离公式(详见常用距离计算单片机C语言程序),k取其他值,改变训练集、测试集,都会影响效果,本文不再编程尝试。
另外,由于数据量巨大,需要将配置中的Stack Size设置的大一些;程序运行较慢,409组数据,大约10秒才全部计算完成。本文为了方便,将数据保存为数组在ROM中,如果在实际应用中,可以通过串口接收、内存卡读取等方式实现。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值