【高频考点】二分类逻辑回归模型预测(梯度下降法)
·
2025年10月29日 商品购买预测(未考虑正则化,通过率80%)
#include<bits/stdc++.h>
using namespace std;
vector<double> w(3,0.0);//全局权重 每个epoch更新
double b=0.0;//全局偏置 每个epoch更新
double pre_loss = 1e18; // 初始化为较大值
struct sample{//样本组结构体定义
double age;
double money;
double time;
int label;
};
// sigmoid 激活函数
double sigmoid(double z){
if(z<-708) return 0.0;
else if(z>708) return 1.0;
return 1.0 / (1.0 + exp(-z));
}
void train(vector<sample> x,int max_iter,double a,double k,double tol){
for(int i=0;i<max_iter;i++){ //总迭代训练epoch
double total_loss=0.0;
vector<double> gradient(3,0.0);//初始化本轮权重梯度
double gradient_b=0.0;//初始化本轮偏置梯度
for(int j=0;j<x.size();j++){ //遍历每一个样本
//每个样本的多维特征和真是标签初始化
double x1=x[j].age;
double x2=x[j].money;
double x3=x[j].time;
double y=x[j].label;
//预测
double z=x1*w[0]+x2*w[1]+x3*w[2]+b;
double y_pred=sigmoid(z);
//交叉熵loss
total_loss+= -y*log(y_pred+1e-8)-(1-y)*log(1-y_pred+1e-8);
//每个维度的梯度=每个样本的(预测-真实)*对应维度特征
gradient[0]+=(y_pred-y)*x1;
gradient[1]+=(y_pred-y)*x2;
gradient[2]+=(y_pred-y)*x3;
gradient_b+=y_pred-y;//每个样本偏置的梯度=预测值-真实值
}
total_loss=total_loss/x.size();//衡量用的是平均loss
for(int j=0;j<3;j++)//总梯度=累计所有样本的梯度/样本数
gradient[j]=gradient[j]/x.size();
gradient_b=gradient_b/x.size();
//参数更新 每个维度的权重=权重-梯度*学习率
for(int j=0;j<3;j++)
w[j]-=gradient[j]*a;
b-=gradient_b*a; //更新梯度=偏置梯度-偏置梯度*学习率
if(fabs(total_loss-pre_loss)<tol) break;
pre_loss=total_loss; //记录当前轮的损失以供计算两轮的损失差
}
}
int main(){
int n,max_iter;
double a,k,tol;
cin>>n>>max_iter>>a>>k>>tol;
vector<sample> samples(n);
for(int i=0;i<n;i++){
cin>>samples[i].age>>samples[i].money>>samples[i].time>>samples[i].label;
}
int m;
cin>>m;
vector<sample> test_samples(m);
for(int i=0;i<m;i++){
cin>>test_samples[i].age>>test_samples[i].money>>test_samples[i].time;
}
train(samples, max_iter, a,k,tol);
for(int i=0;i<m;i++){
double x1=test_samples[i].age;
double x2=test_samples[i].money;
double x3=test_samples[i].time;
//测试样例预测
double z=x1*w[0]+x2*w[1]+x3*w[2]+b;
double y_pred=sigmoid(z);
cout<<fixed<<setprecision(4);//保留四位小数
if(y_pred>=0.5)
cout<<int(1)<<" "<<y_pred<<endl;
else
cout<<int(0)<<" "<<y_pred<<endl;
}
return 0;
}
cout<<fixed<<setprecision()四舍五入保留小数
double num1 = 12.3456;
double num2 = 0.987654;
int num3 = 100;
cout << fixed << setprecision(2) << num1 << " "; // 输出 12.35
cout << fixed << setprecision(4) << num2 << " "; // 输出 0.9877
cout << num3 << endl; // 输出 100
2025年10月10日 基于逻辑回归的意图分类器(通过率100%)
#include<iostream>
#include<vector>
#include<cmath>
using namespace std;
vector<double> wgt(7, 0.0);//权重7*1
double bias=0.0;
//one hot编码
vector<double> encode(string x){//编码1*7
vector<double> res(7,0.0);
for(auto c : x){
int idx=c-'A';
res[idx]=1.0;
}
return res;
}
//sigmoid函数计算预测值
int predict(vector<double> x){
double res;
double sum=0.0;
for(int i=0;i<7;i++){
sum+=wgt[i]*x[i];
}
double z=sum+bias;
res=1/(1+exp(-z));
return res>0.5 ? 1 : 0;
}
//训练 交叉熵损失,SDG,lr=0.1,epochs=20,batch=1
void train(vector<vector<double>> x,vector<double> y){
double lr=0.1;
int epochs=20;
int batch=1;
for(int i=0;i<7;i++) wgt[i]=0.0;
bias=0.0;
for(int i=0;i<epochs;i++){
for(int j=0;j<x.size();j++){
vector<double> xi=x[j];
int yi=y[j];
double res;
double sum=0.0;
for(int k=0;k<7;k++){
sum+=wgt[k]*xi[k];
}
double z=sum+bias;
res=1.0/(1.0+exp(-z));
double dz=res-yi;//损失对z的梯度
for(int k=0;k<7;k++){
wgt[k]=wgt[k]-lr*dz*xi[k];//z对权重的梯度xi[k],dz*xi[k]是损失对权重的梯度
}
bias=bias-lr*dz;
}
}
}
int main(){
int n,m;
cin>>n>>m;
vector<vector<double>> sample(n);
vector<double> label(n);
for(int i=0;i<n;i++){
string s;double y;
cin>>s>>y;
sample[i]=encode(s);
label[i]=y;
}
train(sample,label);
for(int i=0;i<m;i++){
string s;
cin>>s;
cout<<predict(encode(s))<<endl;
}
return 0;
}
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)