在运行一个基于随机森林实现电信用户流失预测分析实训项目时,到smote函数时出现了一个错误
Found array with 0 sample(s) (shape=(0, 22)) while a minimum of 1 is required.
应该怎么解决
Found array with 0 sample(s) (shape=(0, 22)) while a minimum of 1 is required.
import random
from sklearn.neighbors import NearestNeighbors # k近邻算法
from imblearn.over_sampling import SMOTE
class Smote:
def __init__(self,samples,N,k):
self.n_samples,self.n_attrs=samples.shape
self.N=N
self.k=k
self.samples=samples
self.newindex=0
def over_sampling(self):
N=int(self.N)
self.synthetic = np.zeros((self.n_samples * N, self.n_attrs))
neighbors=NearestNeighbors(n_neighbors=self.k).fit(self.samples)# 1.对每个少数类样本均求其在所有少数类样本中的k近邻
for i in range(len(self.samples)):
nnarray=neighbors.kneighbors(self.samples[i].reshape(1,-1),return_distance=False)[0]
self._populate(N,i,nnarray)
return self.synthetic
# 2.为每个少数类样本选择k个最近邻中的N个;3.并生成N个合成样本
def _populate(self,N,i,nnarray):
for j in range(N):
nn=random.randint(0,self.k-1)
dif=self.samples[nnarray[nn]]-self.samples[i]
gap=random.random()
self.synthetic[self.newindex]=self.samples[i]+gap*dif
self.newindex+=1
# 每个正样本用SMOTE方法随机生成两个新的样本
posDf = data[data['Churn'] == 1].drop(['Churn'], axis=1) # 共1869条正样本, 取其所有特征列
posArray = posDf.values # pd.DataFrame -> np.array, 以满足SMOTE方法的输入要求
newPosArray = Smote(posArray, 2, 5).over_sampling()
newPosDf = pd.DataFrame(newPosArray) # np.array -> pd.DataFrame
newPosDf.head(10) # 观察此时的新样本
#调整为正样本的数据集中应有的格式
newPosDf.columns = posDf.columns # 还原特征名
cateCols = list(newPosDf.columns.drop(['tenure', 'MonthlyCharges'])) # 提取离散特征名组成的列表
for i in cateCols:
newPosDf[i] = newPosDf[i].apply(lambda x: 1 if x >= 0.5 else 0) # 将特征值变回0、1二元数值
newPosDf['Churn'] = 1 # 添加目标变量列
newPosDf.head(10) # 观察此时的新样本
print("原本的正样本有%d条" %posDf.shape[0])
print("原本的负样本有%d条" % (data.shape[0] - posDf.shape[0]))
###### 运行结果及详细报错内容
检查一下,你的样本为0
检查351、333行语句的输入实参是否是空的,最好打印一下shape
你贴的程序不完整。
问题出在数据输入,样本数据导入有问题。但由于你贴的程序不完整,所以看不出来具体是哪一句有错误。
例如, “# 共1869条正样本, 取其所有特征”,你可以检查一下 posDf 是否正常