📜  字符串到向量 c++ (1)

📅  最后修改于: 2023-12-03 15:39:02.431000             🧑  作者: Mango

字符串到向量转换

在很多机器学习的应用中,我们需要把字符串转换成向量以便计算。向量可以直接用于支持向量机(SVM)、K-最近邻(KNN)等算法,这些算法都是基于向量之间的距离(欧氏距离、余弦相似度等)计算的。

由于C++是一种高效的语言,我们通常用C++来实现字符串到向量的转换。下面我们会介绍两种方法来实现这一任务。

方法一:词袋模型

词袋模型是一种无序的向量表示方法,它将文本看做是一个由单词构成的集合,每个单词的出现都是相互独立的,因此将文本表示成一个包含所有单词在内的向量即可。

下面是一个简单的实现:

#include <iostream>
#include <string>
#include <vector>
#include <map>

using namespace std;

vector<int> stringToVector(const string &str, const map<string, int> &dict) {
    vector<int> res(dict.size(), 0);
    string word = "";
    for (char c : str) {
        if (c == ' ' || c == '\n' || c == '\r' || c == '\t') {
            if (word != "") {
                if (dict.find(word) != dict.end()) {
                    res[dict[word]]++;
                }
                word = "";
            }
        } else {
            word += c;
        }
    }
    if (word != "") {
        if (dict.find(word) != dict.end()) {
            res[dict[word]]++;
        }
    }
    return res;
}

int main() {
    string str = "apple banana orange\napple orange pear\nbanana banana orange";
    map<string, int> dict = {{"apple", 0}, {"banana", 1}, {"orange", 2}, {"pear", 3}};
    vector<int> vec = stringToVector(str, dict);
    for (int i : vec) {
        cout << i << " ";
    }
    cout << endl;
    return 0;
}

在这个实现中,我们首先定义了一个词典(dict),然后遍历字符串(str)中的每个单词,统计每个单词在词典中的出现次数,最终返回词典大小的向量。

方法二:TF-IDF模型

相比于词袋模型,TF-IDF模型是一种有序的向量表示方法,它不仅考虑了单词出现的频率,还考虑了单词在整个语料库(corpus)中的重要性。

一般而言,我们会先计算每个单词的频率(tf),然后根据单词在语料库中出现的文档数(idf)给每个单词赋予一个权重。最后,我们将每个文本表示成一个由所有单词向量按权重加权和的向量即可。

下面是一个简单的实现:

#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <cmath>

using namespace std;

vector<double> stringToVector(const string &str, const map<string, int> &dict, const map<string, double> &idf) {
    vector<double> res(dict.size(), 0);
    string word = "";
    int totalWords = 0;
    map<string, int> freq;
    for (char c : str) {
        if (c == ' ' || c == '\n' || c == '\r' || c == '\t') {
            if (word != "") {
                if (dict.find(word) != dict.end()) {
                    freq[word]++;
                    totalWords++;
                }
                word = "";
            }
        } else {
            word += c;
        }
    }
    if (word != "") {
        if (dict.find(word) != dict.end()) {
            freq[word]++;
            totalWords++;
        }
    }
    for (auto it : freq) {
        string w = it.first;
        int f = it.second;
        double tf = 1.0 * f / totalWords;
        double wTfIdf = tf * idf[w];
        res[dict[w]] = wTfIdf;
    }
    return res;
}

int main() {
    string str = "apple banana orange\napple orange pear\nbanana banana orange";
    map<string, int> dict = {{"apple", 0}, {"banana", 1}, {"orange", 2}, {"pear", 3}};
    map<string, double> idf = {{"apple", 0.4054651081081644}, {"banana", 0.0}, {"orange", 0.0}, {"pear", 0.4054651081081644}};
    vector<double> vec = stringToVector(str, dict, idf);
    for (double i : vec) {
        cout << i << " ";
    }
    cout << endl;
    return 0;
}

在这个实现中,我们首先定义了一个词典(dict)和一个idf字典,然后遍历字符串(str)中的每个单词,统计每个单词在词典中的出现次数和总词数,最后根据tf和idf计算单词权重,并计算出向量加权和。