#includeiostream#includevector#includecmath#includealgorithm#includenumeric#includestdexcept#includelimits#includeunordered_map#includestring// 数据离散化 std::vectorintdiscretize(conststd::vectordoubledata,intn_bins10){if(data.empty())return{};doublemin_val*std::min_element(data.begin(),data.end());doublemax_val*std::max_element(data.begin(),data.end());if(max_valmin_val)returnstd::vectorint(data.size(),0);doublebin_width(max_val-min_val)/n_bins;std::vectorintresult(data.size());for(size_t i0;idata.size();i){intbinstatic_castint((data[i]-min_val)/bin_width);binstd::min(bin,n_bins-1);result[i]bin;}returnresult;}// 互信息计算 doublemutualInformation(conststd::vectorintx,conststd::vectorinty){if(x.size()!y.size()||x.empty())throwstd::invalid_argument(输入向量长度不匹配或为空);size_t nx.size();std::unordered_mapint,intcount_x,count_y;std::unordered_maplonglong,intcount_xy;for(size_t i0;in;i){count_x[x[i]];count_y[y[i]];longlongkey(static_castlonglong(x[i])32)|static_castunsignedint(y[i]);count_xy[key];}doublemi0.0;for(constautopair:count_xy){intxistatic_castint(pair.first32);intyistatic_castint(pair.first0xFFFFFFFF);doublep_xystatic_castdouble(pair.second)/n;doublep_xstatic_castdouble(count_x[xi])/n;doublep_ystatic_castdouble(count_y[yi])/n;mip_xy*std::log2(p_xy/(p_x*p_y));}returnmi;}// mRMR 核心算法 enumclassScoreMethod{MID,MIQ};std::vectorintmrmrSelect(conststd::vectorstd::vectorintfeatures,conststd::vectorintlabels,intK,ScoreMethod methodScoreMethod::MID){if(features.empty()||labels.empty())throwstd::invalid_argument(特征矩阵或标签为空);size_t n_sampleslabels.size();size_t n_featuresfeatures.size();for(constautofeat:features){if(feat.size()!n_samples)throwstd::invalid_argument(特征长度与样本数不匹配);}if(K0||static_castsize_t(K)n_features)throwstd::invalid_argument(K 超出有效范围);std::vectordoublerelevance(n_features);for(size_t i0;in_features;i){relevance[i]mutualInformation(features[i],labels);}std::vectorintselected;std::vectorboolselected_flag(n_features,false);selected.reserve(K);for(intk0;kK;k){intbest_feature-1;doublebest_score-std::numeric_limitsdouble::infinity();for(size_t i0;in_features;i){if(selected_flag[i])continue;doubleredundancy0.0;if(!selected.empty()){doublesum_mi0.0;for(ints:selected){sum_mimutualInformation(features[i],features[s]);}redundancysum_mi/selected.size();}doublescore;if(methodScoreMethod::MID){scorerelevance[i]-redundancy;}else{score(redundancy1e-12)?(relevance[i]/redundancy):relevance[i]*1e12;}if(scorebest_score){best_scorescore;best_featurestatic_castint(i);}}if(best_feature-1)break;selected.push_back(best_feature);selected_flag[best_feature]true;}returnselected;}// 使用示例 intmain(){// 构造示例数据6 个样本4 个特征// 特征矩阵每行一个特征每列一个样本std::vectorstd::vectorintfeatures{{0,0,0,1,1,1},// 特征 0{0,0,1,1,1,1},// 特征 1{1,1,1,0,0,0},// 特征 2{0,1,0,1,0,1}// 特征 3};std::vectorintlabels{0,0,0,1,1,1};intK2;autoselected_midmrmrSelect(features,labels,K,ScoreMethod::MID);autoselected_miqmrmrSelect(features,labels,K,ScoreMethod::MIQ);std::cout MID 准则选出的特征索引 std::endl;for(intidx:selected_mid)std::coutidx ;std::coutstd::endl;std::cout MIQ 准则选出的特征索引 std::endl;for(intidx:selected_miq)std::coutidx ;std::coutstd::endl;// 离散化部分使用相同的连续数据模式std::vectorstd::vectordoubleraw_features{{0.1,0.1,0.1,0.9,0.9,0.9},// 特征 0 连续版{0.1,0.1,0.8,0.8,0.8,0.8},// 特征 1 连续版{0.9,0.9,0.9,0.1,0.1,0.1},// 特征 2 连续版{0.1,0.9,0.1,0.9,0.1,0.9}// 特征 3 连续版};std::vectorstd::vectorintdiscretized;for(size_t i0;iraw_features.size();i){discretized.push_back(discretize(raw_features[i],3));}autoselected_discretemrmrSelect(discretized,labels,K,ScoreMethod::MID);std::cout 离散化后 MID 选出的特征索引 std::endl;for(intidx:selected_discrete)std::coutidx ;std::coutstd::endl;return0;}