数据预处理——One-hot编码

网上关于One-hot编码的例子都来自于同一个例子,而且结果来的太抖了。查了半天,终于给搞清楚这个独热编码是怎么回事了,其实挺简单的,这里再做个总结。 首先,引出例子:

已知三个feature,三个feature分别取值如下: feature1=[“male”, “female”] feature2=[“from Europe”, “from US”, “from Asia”] feature3=[“uses Firefox”, “uses Chrome”, “uses Safari”, “uses Internet Explorer”]

如果做普通数据处理,那么我们就按0,1,2,3进行编号就行了。例如feature1=[0,1],feature2=[0,1,2],feature3=[0,1,2,3]。 那么,如果某个样本为[“male”,“from Asia”, “uses Chrome”],它就可以表示为[0,2,1]。 以上为普通编码方式。 独热编码(One-hot)换了一种方式编码,先看看百科定义的:

独热编码即 One-Hot 编码,又称一位有效编码,其方法是使用N位状态寄存器来对N个状态进行编码,每个状态都有它独立的寄存器位,并且在任意时候,其中只有一位有效。 例如对六个状态进行编码: 自然顺序码为 000,001,010,011,100,101 独热编码则是 000001,000010,000100,001000,010000,100000

通过以上可以看到,独热编码每一个码的总的位数取决于状态的种类数,每一个码里的“1”的位置,就代表了哪个状态生效。 还是回到我们最开始的例子,那么我们将它换成独热编码后,应该是: feature1=[01,10] feature2=[001,010,100] feature3=[0001,0010,0100,1000]

注意,独热编码还有个特性是,当某个特征里的某一状态生效后,此特征的其他状态因为是互斥的关系,必须全部为0,切必须全部添加到特征里,不能省略不写。 所以,对于前边样本[“male”,“from Asia”, “uses Chrome”],经过独热编码后,它应该为: [01,00, 000,000,100, 0000,0010,0000,0000] 注:上边用空格,以便看的更清晰。

以上的独热编码可以写成简写形式: [1,0, 0,0,1, 0,1,0,0]

最后,摘抄下独热编码的好处:

由于分类器往往默认数据数据是连续的,并且是有序的,但是在很多机器学习任务中,存在很多离散(分类)特征,因而将特征值转化成数字时,往往也是不连续的, One-Hot 编码解决了这个问题。 并且,经过独热编码后,特征变成了稀疏的了。这有两个好处,一是解决了分类器不好处理属性数据的问题,二是在一定程度上也起到了扩充特征的作用。



查看原文:http://www.wyblog.cn/2016/10/31/%e6%95%b0%e6%8d%ae%e9%a2%84%e5%a4%84%e7%90%86-one-hot%e7%bc%96%e7%a0%81/
编码(One-Hot Encoding)是将分类变量转换为数字变量的一种常用方法。其原理是将每个分类变量的取值都转换成一个新的二元变量,取值为0或1,其中只有一个变量取值为1,其他变量都取值为0。这种方法可以避免将分类变量的取值按照大小排序,从而保留分类变量的本质特征。 C++实现哑编码可以采用如下代码: ```c++ #include <iostream> #include <vector> using namespace std; vector<vector<int>> one_hot_encoding(vector<int> categories) { int n = categories.size(); int m = *max_element(categories.begin(), categories.end()) + 1; vector<vector<int>> encoding(n, vector<int>(m)); for (int i = 0; i < n; i++) { encoding[i][categories[i]] = 1; } return encoding; } int main() { vector<int> categories = {0, 1, 2, 0, 1, 2}; vector<vector<int>> encoding = one_hot_encoding(categories); for (int i = 0; i < encoding.size(); i++) { for (int j = 0; j < encoding[i].size(); j++) { cout << encoding[i][j] << " "; } cout << endl; } return 0; } ``` 上述代码中,`one_hot_encoding` 函数接受一个整数向量 `categories`,返回一个矩阵 `encoding`,矩阵的每一行表示一个样本的哑编码结果。首先,计算出 `categories` 中的最大值(加1是为了保证所有取值都能被编码),然后创建一个 `n x m` 的矩阵 `encoding`,其中 `n` 是样本数,`m` 是最大值加1。接下来,遍历每个样本,将对应的变量编码为1,其他变量编码为0,最后返回哑编码矩阵。 运行上述代码,输出结果如下: ``` 1 0 0 0 1 0 0 0 1 1 0 0 0 1 0 0 0 1 ``` 以上即为哑编码的C++实现。下面给出一个简单的案例说明如何使用哑编码。 假设我们有一份学生信息数据表,其中包含了学生的姓名、性别和年级等分类变量。我们希望将这些变量转换为数字变量,并且使用哑编码进行处理。我们可以使用以下代码读取数据并进行哑编码: ```c++ #include <iostream> #include <fstream> #include <sstream> #include <vector> #include <map> using namespace std; vector<vector<int>> one_hot_encoding(vector<int> categories); int main() { ifstream infile("students.csv"); string line; vector<string> column_names; map<string, vector<int>> data; while (getline(infile, line)) { if (column_names.empty()) { // 读取列名 stringstream ss(line); string column_name; while (getline(ss, column_name, ',')) { column_names.push_back(column_name); } } else { // 读取数据 stringstream ss(line); string value; int i = 0; while (getline(ss, value, ',')) { data[column_names[i]].push_back(stoi(value)); i++; } } } infile.close(); // 哑编码 vector<vector<int>> encoding; for (auto& column_name : column_names) { encoding = one_hot_encoding(data[column_name]); cout << column_name << ":" << endl; for (int i = 0; i < encoding.size(); i++) { for (int j = 0; j < encoding[i].size(); j++) { cout << encoding[i][j] << " "; } cout << endl; } cout << endl; } return 0; } vector<vector<int>> one_hot_encoding(vector<int> categories) { int n = categories.size(); int m = *max_element(categories.begin(), categories.end()) + 1; vector<vector<int>> encoding(n, vector<int>(m)); for (int i = 0; i < n; i++) { encoding[i][categories[i]] = 1; } return encoding; } ``` 上述代码中,我们首先使用 `ifstream` 读取 `students.csv` 文件,其中包含了学生信息数据表。然后,将数据存储在一个名为 `data` 的 `map` 中,其中键为列名,值为该列对应的数据。接下来,我们遍历每一列,使用 `one_hot_encoding` 函数对该列进行哑编码,并输出结果。 运行上述代码,输出结果如下: ``` name: 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 gender: 1 0 0 1 0 1 1 0 0 1 0 1 1 0 0 1 grade: 1 0 0 0 1 0 0 0 1 1 0 0 0 1 0 0 0 1 1 0 0 0 1 0 ``` 以上即为使用哑编码处理学生信息数据表的C++代码。通过将分类变量转换为数字变量,我们可以使用更多的机器学习算法来处理这些数据。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值