分类任务中如何将英文语句转为整数编码训练KNN分类算法
中文文本转整数表示训练KNN的实现方案
核心流程
1. 数据预处理
首先提取表格有效字段:statement列为输入文本,最右侧的0/1列为分类标签,删除重复的冗余index列、空值样本。
中文没有天然分词边界,需要先做基础文本清洗和分词:
- 统一字符全角/半角格式,剔除无意义特殊符号
- 用jieba等中文分词工具将每条语句切分为独立词单元
- 可按需过滤停用词(比如“的”“了”这类无分类区分度的虚词),压缩后续向量维度。
2. 文本转整数特征(适配KNN要求)
KNN基于样本间距离做分类,要求输入为固定长度数值向量,最直接的整数转换方案是词频整数编码(词袋模型),实现逻辑:
- 遍历整个训练集的分词结果,给每个不重复的词分配唯一整数ID,构建固定全局词表
- 对每条语句,按照词表ID顺序,统计每个词在当前语句中的出现次数,生成和词表等长的向量,向量每个位置的取值就是对应词的出现次数(非负整数),未出现的词对应位置填0。
举个简化示例:若词表为{0:"医疗",1:"法案",2:"奥巴马",3:"犹太"},第一条涉及医疗保健法案的语句,对应向量中0、1位置取值为1,其余位置为0,整体全为整数值。
如果不需要严格纯整数输入,也可以在词频基础上计算TF-IDF权重提升分类效果,但输出为浮点数。
3. KNN训练适配要点
- 词表必须在训练阶段固定,后续预测新样本时必须复用同一套词表做转换,不能重新生成词表,否则向量维度、词ID映射关系会错乱
- 生成的整数词频向量需要做归一化处理(比如L2归一化),因为KNN对数值尺度敏感,长文本总词数更高、词频整体偏大,会干扰距离计算结果
- 如果语料规模大、词表维度太高,可以限制词表最大长度(比如仅保留出现频率最高的前1000-5000个词),降低向量稀疏性,提升KNN计算效率和分类精度。
可直接运行的代码示例
import jieba import pandas as pd from sklearn.feature_extraction.text import CountVectorizer from sklearn.model_selection import train_test_split from sklearn.neighbors import KNeighborsClassifier from sklearn.preprocessing import Normalizer # 加载数据集,你可以把表格导出为csv后用pd.read_csv读取,这里直接用你提供的示例数据 df = pd.DataFrame({ "statement": [ "称医疗保健法案会效仿加拿大、英国的医疗体系实行医疗配给制度", "奥巴马刻意否认巴黎犹太洁食杂货店袭击事件存在恶劣的反犹太主义动机", "过去一年间,我始终受到审查、被剥夺发声权利" ], "label": [0, 1, 0] }) # 中文分词:将每条文本转为空格分隔的词序列,适配特征转换器 df["cut_text"] = df["statement"].apply(lambda x: " ".join(jieba.lcut(x))) # 文本转整数词频矩阵,CountVectorizer默认输出整数计数,符合整数表示要求 # 可加max_features参数限制词表大小,比如CountVectorizer(max_features=1000) vectorizer = CountVectorizer() X = vectorizer.fit_transform(df["cut_text"]).toarray() # X即为转换完成的整数特征矩阵 y = df["label"].values # 特征归一化,适配KNN距离计算逻辑 normalizer = Normalizer() X_norm = normalizer.fit_transform(X) # 拆分训练测试集,训练KNN模型 X_train, X_test, y_train, y_test = train_test_split(X_norm, y, test_size=0.2, random_state=42) knn = KNeighborsClassifier(n_neighbors=3) knn.fit(X_train, y_train) # 新样本预测流程(必须复用训练阶段的vectorizer和normalizer) # def predict_new(text): # cut_text = " ".join(jieba.lcut(text)) # vec = normalizer.transform(vectorizer.transform([cut_text]).toarray()) # return knn.predict(vec)[0]
内容的提问来源于stack exchange,提问作者Hasibul Hasan Rupok
相关产品推荐
相关产品推荐

