PyStan报错TypeError:无法将Series转换为<int>类型求助
PyStan运行报错:
TypeError: cannot convert the series to <class 'int'> 问题排查与修复 问题场景
在Jupyter Notebook中使用PyStan,通过nest_asyncio.apply()适配异步运行,传入整数类型NumPy数组时触发上述错误,但输入已显式为整数类型。可复现代码如下:
import numpy as np import pandas as pd import stan import nest_asyncio nest_asyncio.apply() def sigmoid(x): return 1 / (1 + np.exp(-x)) treatment_slope = 0.2 test_slope = 0.15 intercept = 0.7 def link(X): theta = sigmoid(X[0] * treatment_slope + X[1] * test_slope + intercept) return theta ctrl = np.random.binomial(n=1, p=link([0,0]), size=500) test_no_exp = np.random.binomial(n=1, p=link([0,1]), size=250) test_w_exp = np.random.binomial(n=1, p=link([0,1]), size=250) data = {'test':[], 'exposure':[], 'outcome':[]} for c in ctrl: data['test'].append(0) data['exposure'].append(0) data['outcome'].append(c) for t in test_no_exp: data['test'].append(1) data['exposure'].append(0) data['outcome'].append(t) for e in test_w_exp: data['test'].append(1) data['exposure'].append(1) data['outcome'].append(e) df = pd.DataFrame(data) X = df[['test','exposure']].to_numpy() y = df['outcome'] payload = {'X':X, 'y':y, 'K':1000, 'N':2} logistic_regression_model = """ // logistic regression code data { int<lower=0> N; // number of observations int<lower=0> K; // number of predictor variables matrix[N, K] X; // predictor matrix int<lower=0,upper=1> y[N]; // outcome vector } parameters { real alpha; // intercept vector[K] theta; // coefficients on Q_ast real<lower=0> sigma; // error scale } model { // priors for (d in 1:D) { theta[d] ~ normal(0, 1); } alpha ~ normal(0, 10); // likelihood y ~ bernoulli_logit(X * theta + alpha); } """ posterior = stan.build(logistic_regression_model, data=payload) fit = posterior.sample(num_chains=4, num_samples=1000)
错误原因
- N与K参数完全颠倒:Stan代码中
N是观测样本数(此处应为1000),K是特征数(此处应为2),但payload里把两者赋值反了,导致矩阵维度不匹配,触发类型转换错误。 - y的类型不匹配:
y = df['outcome']得到的是Pandas Series对象,Stan要求传入整数类型的NumPy数组,直接传入Series会引发类型转换失败。 - 未定义的循环变量D:Stan模型中
for (d in 1:D)的D未在data块声明,实际应该用已定义的K来遍历系数。 - 冗余的sigma参数:逻辑回归使用伯努利分布,不需要尺度参数
sigma,该参数无意义且会增加模型冗余。
修正后的代码
import numpy as np import pandas as pd import stan import nest_asyncio nest_asyncio.apply() def sigmoid(x): return 1 / (1 + np.exp(-x)) treatment_slope = 0.2 test_slope = 0.15 intercept = 0.7 def link(X): theta = sigmoid(X[0] * treatment_slope + X[1] * test_slope + intercept) return theta ctrl = np.random.binomial(n=1, p=link([0,0]), size=500) test_no_exp = np.random.binomial(n=1, p=link([0,1]), size=250) test_w_exp = np.random.binomial(n=1, p=link([0,1]), size=250) data = {'test':[], 'exposure':[], 'outcome':[]} for c in ctrl: data['test'].append(0) data['exposure'].append(0) data['outcome'].append(c) for t in test_no_exp: data['test'].append(1) data['exposure'].append(0) data['outcome'].append(t) for e in test_w_exp: data['test'].append(1) data['exposure'].append(1) data['outcome'].append(e) df = pd.DataFrame(data) X = df[['test','exposure']].to_numpy() # 修正点1:将y转为NumPy整数数组 y = df['outcome'].to_numpy(dtype=int) # 修正点2:颠倒N和K的赋值,匹配Stan定义 payload = {'X':X, 'y':y, 'K':2, 'N':1000} logistic_regression_model = """ // logistic regression code data { int<lower=0> N; // number of observations int<lower=0> K; // number of predictor variables matrix[N, K] X; // predictor matrix int<lower=0,upper=1> y[N]; // outcome vector } parameters { real alpha; // intercept vector[K] theta; // coefficients on predictors } model { // priors // 修正点3:用K替代未定义的D for (d in 1:K) { theta[d] ~ normal(0, 1); } alpha ~ normal(0, 10); // likelihood y ~ bernoulli_logit(X * theta + alpha); } """ posterior = stan.build(logistic_regression_model, data=payload) fit = posterior.sample(num_chains=4, num_samples=1000)
内容的提问来源于stack exchange,提问作者jbuddy_13
相关产品推荐
相关产品推荐

