1 Star 2 Fork 1

atiaisi/py_learn

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
09_05_WorkingWithCategoricalData.py 7.69 KB
一键复制 编辑 原始数据 按行查看 历史
atiaisi 提交于 2022-04-10 11:15 +08:00 . 1、填充缺失的分类值
#!/usr/bin/env python3
# -*- coding:utf-8 -*-
"""
处理分类数据
处理文本
处理日期和时间
"""
def demo_5_1():
"""
对nominal型分类特征编码
:return:
"""
import numpy as np
from sklearn.preprocessing import LabelBinarizer, MultiLabelBinarizer
# 创建特征
feature = np.array([["Texas"],
["California"],
["Texas"],
["Delaware"],
["Texas"]])
# 创建one-hot编码器
one_hot = LabelBinarizer()
# 对特征进行one-hot编码
print(f"对特征进行one-hot编码: \n{one_hot.fit_transform(feature)}")
print(f"查看特征的分类:\n{one_hot.classes_}")
print(f"对特征进行逆转换:\n{one_hot.inverse_transform(one_hot.transform(feature))}")
# 使用pandas对特征进行one-hot编码
import pandas as pd
# 创建虚拟变量
print(f"创建虚拟变量:\n{pd.get_dummies(feature[:, 0])}")
# 创建有多个分类的特征
multiclass_feature = [("Texas", "Florida"),
("California", "Alabama"),
("Texas", "Florida"),
("Delware", "Florida"),
("Texas", "Alabama")]
# 创建能处理多个分类的one-hot编码器
one_hot_multiclass = MultiLabelBinarizer()
# 对特征进行ont-hot编码
print(f"对特征进行one-hot编码:\n{one_hot_multiclass.fit_transform(multiclass_feature)}")
print(f"查看分类: \n{one_hot_multiclass.classes_}")
print("==============================" * 3)
def demo_5_2():
"""
存在一个ordinal分类特征(例如:高、中等、低),对其编码
:return:
"""
import pandas as pd
dataframe = pd.DataFrame({"Score": ["Low", "Low", "Medium", "Medium", "High"]})
# 创建映射器
scale_mapper = {
"Low": 1,
"Medium": 2,
"High": 3
}
# 使用映射器来替换特征
print(f"使用映射器来替换特征:\n{dataframe['Score'].replace(scale_mapper)}")
print("==============================" * 3)
def demo_5_3():
"""
将一个字典转换成一个特征矩阵
:return:
"""
from sklearn.feature_extraction import DictVectorizer
data_dict = [{"Red": 2, "Blue": 4},
{"Red": 4, "Blue": 3},
{"Red": 1, "Yellow": 2},
{"Red": 2, "Yellow": 2}]
# 创建字典向量化容器
dictvectorizer = DictVectorizer(sparse=False)
# 将字典转换位特征矩阵
features = dictvectorizer.fit_transform(data_dict)
print(f"查看转换后的特征矩阵:\n{features}")
feature_names = dictvectorizer.get_feature_names_out()
print(f"获取特征的名字:\n{feature_names}")
# 使用pandas输出结果更清晰
import pandas as pd
print(f"使用pandas输出结果更清晰: \n{pd.DataFrame(features, columns=feature_names)}")
print("==============================" * 3)
def demo_5_4():
"""
有一个分类特征中包含缺失值,需要用预测值来填充。
:return:
"""
print(f"方案一:使用KNN分类器进行预测填充")
import numpy as np
from sklearn.neighbors import KNeighborsClassifier
# 用分类特征创建特征矩阵
X = np.array([[0, 2.10, 1.45],
[1, 1.18, 1.33],
[0, 1.22, 1.27],
[1, -0.21, -1.19]])
print(f"用于训练KNN模型的训练矩阵:\n{X}")
# 创建带有缺失值的特征矩阵
X_with_nan = np.array([[np.nan, 0.87, 1.31],
[np.nan, -0.67, -0.22]])
print(f"原始缺失值矩阵:\n{X_with_nan}")
# 训练KNN分类器
clf = KNeighborsClassifier(3, weights='distance')
# X[x, y],表示选择矩阵X的第x行第y列的元素,x和y都可以写成切片格式,,比如X[1:3, 0,2]表示取第1,2行的第0,1列的数据,范围记得是左闭又开
trained_model = clf.fit(X[:, 1:], X[:, 0])
# 预测缺失值的分类: 根据第2列及之后列的数据预测第1列的NAN值
imputed_values = trained_model.predict(X_with_nan[:, 1:])
# 将预测的分类和它们的其他特征值连接起来
X_with_imputed = np.hstack((imputed_values.reshape(-1, 1), X_with_nan[:, 1:]))
print(f"缺失值使用KNN预测之后的矩阵:\n{X_with_imputed}")
# 连接两个特征矩阵
print(f"连接两个特征矩阵:\n{np.vstack((X_with_imputed, X))}")
print("方案二:使用特征中出现次数最多的值来填充缺失值")
from sklearn.impute import SimpleImputer
# 连接两个特征矩阵
X_complete = np.vstack((X_with_nan, X))
print(f"提前连接两个特征矩阵:\n{X_complete}")
imputer = SimpleImputer(strategy='most_frequent')
print(f"填充之后的矩阵:\n{imputer.fit_transform(X_complete)}")
print("==============================" * 3)
def demo_5_5():
"""
处理一个分类极度不均衡的目标向量
:return:
"""
import numpy as np
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import load_iris
# 加载鸢尾花数据
iris = load_iris()
# 创建特征矩阵
features = iris.data
# 创建目标向量
target = iris.target
# 移除前40个观察值
features = features[40:, :]
target = target[40:]
# 创建二元目标向量来标识观察值是否为类别0
target = np.where((target == 0), 0, 1)
# 查看不均衡的目标向量
print(f"查看不均衡的目标向量:\n{target}")
print(f"方案一:针对目标向量不均衡的情况可以使用随机森林,因为随机森林嵌入了分类权重,可以进行加权操作")
# 创建加权的权重, 值为0需要加权0.9,值为1需要加权0.1,权重最终都加到了1.
weights= {0: .9, 1: 0.1}
# 创建带权重的随机森林分类器
print(RandomForestClassifier(class_weight=weights))
print(f"方案二:对占多数的分类进行下采样")
# 给每个分类的观察值打标签
i_class0 = np.where(target == 0)[0]
i_class1 = np.where(target == 1)[0]
# 确定每个分类的观察值的数量
n_class0 = len(i_class0)
n_class1 = len(i_class1)
# 对于每个分类为0的观察值,从分类为1的数据中进行无放回的随机采样
i_class1_downsampled = np.random.choice(i_class1, size=n_class0, replace=False)
# 将分类为0的目标向量和下采样的分类为1的目标向量连接起来
print(f"将分类为0的目标向量和下采样的分类为1的目标向量连接起来:\n{np.hstack((target[i_class0], target[i_class1_downsampled]))}")
# 将分类为0的特征矩阵和下采样的分类为1的特征矩阵连接起来
print(f"将分类为0的特征矩阵和下采样的分类为1的特征矩阵连接起来:\n{np.vstack((features[i_class0,:], features[i_class1_downsampled,:]))[0:5]}")
print(f"方案三:对占多数的分类,从占少数的分类中进行有放回的随机采样")
i_class0_upsampled = np.random.choice(i_class0, size=n_class1, replace=True)
# 将上采样得到的分类为0的目标向量和分类为1的目标向量连接起来
print(f"将上采样得到的分类为0的目标向量和分类为1的目标向量连接起来: \n{np.concatenate((target[i_class0_upsampled], target[i_class1]))}")
# 将上采样的到的分类为0的特征矩阵和分类为1的特征矩阵连接起来
print(f"将上采样的到的分类为0的特征矩阵和分类为1的特征矩阵连接起来:\n{np.vstack((features[i_class0_upsampled,:], features[i_class1, :]))[0:5]}")
print("==============================" * 3)
if __name__ == "__main__":
demo_5_1()
demo_5_2()
demo_5_3()
demo_5_4()
demo_5_5()
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/atiaisi/py_learn.git
git@gitee.com:atiaisi/py_learn.git
atiaisi
py_learn
py_learn
master

搜索帮助