纪修染367 2026-05-20 17:30 采纳率: 78.6%
浏览 5

机器学习运行报编码错误但是其他的机器学习程序又能正常运行


# -*- coding: utf-8 -*-
import sys
import io
from sklearn.datasets import load_iris
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.preprocessing import StandardScaler

# 设置默认编码为 UTF-8(解决中文输出问题)
sys.stdout = io.TextIOWrapper(sys.stdin.buffer, encoding='utf-8')

def iris_knn_grid_search():
    # 1. 加载数据
    data = load_iris()
    X = data.data
    y = data.target

    # 2. 划分训练集、测试集
    x_train, x_test, y_train, y_test = train_test_split(
        X, y, test_size=0.2, random_state=42
    )

    # 3. 数据标准化(KNN基于距离,必须做!)
    scaler = StandardScaler()
    x_train = scaler.fit_transform(x_train)
    x_test = scaler.transform(x_test)

    # 4. 定义基础模型
    knn = KNeighborsClassifier()

    # 5. 定义要搜索的超参数网格(核心!)
    param_grid = {
        "n_neighbors": [1, 3, 5, 7, 9, 11],  # 要搜索的邻居数量
        "weights": ["uniform", "distance"],  # 权重:均匀/距离加权
        "p": [1, 2]  # 距离度量:1=曼哈顿距离,2=欧氏距离
    }

    # 6. 网格搜索 + 5折交叉验证
    # cv=5:把训练集分成5份做交叉验证
    grid_search = GridSearchCV(
        estimator=knn,    # 要调参的模型
        param_grid=param_grid,  # 超参数范围
        cv=5,  # 5折交叉验证
        n_jobs=-1  # 调用所有CPU核心加速
    )

    # 7. 在训练集上搜索最优参数
    grid_search.fit(x_train, y_train)

    # 8. 输出网格搜索最优结果
    print("="*50)
    print(f" 交叉验证最优准确率:{grid_search.best_score_:.4f}")
    print(f" 最优超参数组合:{grid_search.best_params_}")
    print(f" 最优模型:{grid_search.best_estimator_}")
    print("="*50)

    # 9. 用最优模型在测试集上评估
    best_model = grid_search.best_estimator_
    test_acc = best_model.score(x_test, y_test)
    print(f" 最优模型在测试集上的准确率:{test_acc:.4f}")

if __name__ == '__main__':
    iris_knn_grid_search()

运行时报编码错误UnicodeEncodeError: 'ascii' codec can't encode characters in position 18-19: ordinal not in range(128)

img

  • 写回答

2条回答 默认 最新

  • 檀越@新空间 2026-05-20 17:33
    关注

    下午好🌅🌅🌅
    本答案参考通义千问

    你遇到的错误是:

    UnicodeEncodeError: 'ascii' codec can't encode characters in position 18-19: ordinal not in range(128)
    

    这个错误通常发生在 输出中文字符时,系统默认使用的是 ASCII 编码,而你的代码中包含了中文字符(例如 print("="*50) 中的 = 符号虽然不是中文,但可能在某些系统中会引发编码问题),或者是在输出内容中包含非 ASCII 字符。


    重点原因分析:

    错误发生的原因是:
    Python 默认的 stdout 编码不是 UTF-8,导致在打印中文或特殊字符时抛出 UnicodeEncodeError。

    你尝试通过以下代码设置标准输出为 UTF-8:

    sys.stdout = io.TextIOWrapper(sys.stdin.buffer, encoding='utf-8')
    

    但是这行代码的作用是 将输入流转换为 UTF-8,而不是设置输出流的编码。因此,它并不能真正解决输出时的编码问题


    解决方案:

    1. 正确设置 stdout 的编码为 UTF-8

    你需要重新定义 sys.stdout 为一个支持 UTF-8 的 TextIOWrapper,而不是从 stdin 转换而来。修改如下:

    import sys
    import io
    
    # 正确设置 stdout 的编码为 UTF-8
    sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8', newline='')
    

    注意: 使用 sys.stdout.buffer 是为了获取原始字节流,再包装成 UTF-8 编码的文本流。


    2. 确保文件保存为 UTF-8 编码格式

    请确认你的 Python 文件(如 your_script.py)是以 UTF-8 格式保存的。如果使用了其他编码(如 GBK、Latin-1 等),也会导致编码错误。


    3. 避免在 print 中使用非 ASCII 字符

    如果你的代码中有中文字符(如注释、字符串等),请确保它们被正确处理。比如:

    print("最优模型在测试集上的准确率:", test_acc)
    

    或者:

    print(f" 最优模型在测试集上的准确率:{test_acc:.4f}")
    

    这些语句本身不会有问题,但需要确保整个运行环境支持 UTF-8。


    修改后的完整代码示例:

    # -*- coding: utf-8 -*-
    import sys
    import io
    from sklearn.datasets import load_iris
    from sklearn.neighbors import KNeighborsClassifier
    from sklearn.model_selection import train_test_split, GridSearchCV
    from sklearn.preprocessing import StandardScaler
    
    # 正确设置 stdout 的编码为 UTF-8
    sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8', newline='')
    
    def iris_knn_grid_search():
        # 1. 加载数据
        data = load_iris()
        X = data.data
        y = data.target
    
        # 2. 划分训练集、测试集
        x_train, x_test, y_train, y_test = train_test_split(
            X, y, test_size=0.2, random_state=42
        )
    
        # 3. 数据标准化(KNN基于距离,必须做!)
        scaler = StandardScaler()
        x_train = scaler.fit_transform(x_train)
        x_test = scaler.transform(x_test)
    
        # 4. 定义基础模型
        knn = KNeighborsClassifier()
    
        # 5. 定义要搜索的超参数网格(核心!)
        param_grid = {
            "n_neighbors": [1, 3, 5, 7, 9, 11],  # 要搜索的邻居数量
            "weights": ["uniform", "distance"],  # 权重:均匀/距离加权
            "p": [1, 2]  # 距离度量:1=曼哈顿距离,2=欧氏距离
        }
    
        # 6. 网格搜索 + 5折交叉验证
        grid_search = GridSearchCV(
            estimator=knn,
            param_grid=param_grid,
            cv=5,
            n_jobs=-1
        )
    
        # 7. 在训练集上搜索最优参数
        grid_search.fit(x_train, y_train)
    
        # 8. 输出网格搜索最优结果
        print("=" * 50)
        print(f" 交叉验证最优准确率:{grid_search.best_score_:.4f}")
        print(f" 最优超参数组合:{grid_search.best_params_}")
        print(f" 最优模型:{grid_search.best_estimator_}")
        print("=" * 50)
    
        # 9. 用最优模型在测试集上评估
        best_model = grid_search.best_estimator_
        test_acc = best_model.score(x_test, y_test)
        print(f" 最优模型在测试集上的准确率:{test_acc:.4f}")
    
    if __name__ == '__main__':
        iris_knn_grid_search()
    

    总结步骤:

    1. 正确设置 stdout 编码为 UTF-8,使用 sys.stdout.buffer 包装。
    2. 确认文件保存为 UTF-8 格式
    3. 避免在 print 中使用非 ASCII 字符,或确保它们被正确编码。
    4. 检查是否在代码中存在中文字符,并确保其正确显示。

    如果仍然报错?

    你可以尝试以下方法:

    import os
    os.environ['PYTHONIOENCODING'] = 'utf-8'
    

    放在脚本开头,可以强制 Python 使用 UTF-8 编码处理输入输出。


    如有更多问题,欢迎继续提问!

    评论

报告相同问题?

问题事件

  • 创建了问题 5月20日