最近在用DataFrame以及sklearn进行建模随机搜索参数和获取F1值、recall值的时候遇到了一个类似下面这样的报错:
raise ValueError("{0} is not supported".format(y_type))
ValueError: unknown is not supported
或
ValueError: Can't handle mix of unknown and binary
明明训练数据在xgb上可以训练,也能计算出acc、auc值,但求F1和RandomizedSearchCV就会报这个’unknown’的错误。
然后在网上找到一些说让转换成list或者np.array就可以解决,但实际操作了并不能解决问题。
后来把DataFrame保存为csv,然后再读进去就没有报错了。这是为什么呢?就觉得很奇快。
最后对比了下数据结构,结合报错的信息分析了下,找到了根本原因,其实是因为sklearn里面计算二分类的F1或者随机搜索等都要求预测值和真实值的type_of_target 为 'binary’的情况,可以这样来查看:
from sklearn.utils.multiclass import type_of_target
print(type_of_target(y))
>> 'unknown'
那么如何让数据的type_of_target 为 'binary’呢?其实关键就在于dtype
可以打印出来看报错的数据,它的dtype是object
这段是在网上看到关于object的一段描述
The dtype object comes from NumPy, it describes the type of element in a ndarray. Every element in a ndarray must has the same size in byte. For int64 and float64, they are 8 bytes. But for strings, the length of the string is not fixed. So instead of save the bytes of strings in the ndarray directly, Pandas use object ndarray, which save pointers to objects, because of this the dtype of this kind ndarray is object.
我的理解是dtype=object主要是用于存储string类型的数据结构,可以更为灵活地处理元素,例如
所以如果将数据类型转换成整数型,那数据的type_of_target 就是 'binary’了。
回到这个报错问题上来,最终的解决方案就是:
- 用astype转换数据结构
y = y.astype('int64')
或者:
- 重新设置dtype
y = pd.DataFrame(y, dtype='int64')