You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MLP模型导出后预测异常的原因排查及修正方案咨询

问题

我尝试训练一个MLP模型,将数据点转换为哈希值后输入模型。训练阶段代码运行后准确率达93%,预测聚类为0,结果正常;但使用joblib导出模型并重新加载后,预测准确率仅为17%,聚类结果为-1。多次重复训练均出现该问题,怀疑是哈希函数(hashing_trick)存在问题,请问该问题的原因是什么?如何修正?

训练阶段代码:

import pandas as pd
import numpy as np
import json
from sklearn.model_selection import train_test_split
from sklearn.neural_network import MLPClassifier
from sklearn.metrics import accuracy_score
from sklearn.cluster import DBSCAN
import joblib

def hashing_trick(open_ports, n_features=1000):
    hashed_features = np.zeros(n_features)
    for port in open_ports:
        hash_value = hash(port) % n_features
        hashed_features[hash_value] = 1
    return hashed_features

output_file_path = "shodan_fetched_data.json"
with open(output_file_path, "r") as output_file:
    data = json.load(output_file)
# Create a DataFrame
df = pd.DataFrame.from_dict(data, orient='index')
df.reset_index(inplace=True)
df.drop("index",axis =1,inplace = True)

df['hashed_open_ports'] = df['open_ports'].apply(lambda x: hashing_trick(x))
hashed_features = np.array(df['hashed_open_ports'].to_list())
dbscan = DBSCAN(eps =0.4,min_samples=2)
clusters = dbscan.fit_predict(hashed_features)
df['port_cluster'] = clusters

X = np.vstack(df['hashed_open_ports'].values)
y = df['port_cluster']
X_train, X_test, y_train, y_test = train_test_split(X, y,test_size =0.2, random_state=42)

model = MLPClassifier(random_state=42)

model.fit(X_train, y_train)
y_pred = model.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)
print(f"Accuracy: {accuracy:.2f}")
new_open_ports = hashing_trick(['22/ssh', '80/http', '443/https'])

new_entry = np.array([new_open_ports]).reshape(1, -1)
model.predict(new_entry)
model_filename = 'mlp_model.joblib'
joblib.dump(model, model_filename)

模型加载预测代码:

import joblib
import numpy as np

def hashing_trick(open_ports, n_features=1000):
    hashed_features = np.zeros(n_features)
    for port in open_ports:
        hash_value = hash(port) andulames_in
https  thermostat_popold完成_� inputs整active
        hashed_features[hash_value] = 1
    return hashed_features
model_filename = 'mlp_model.joblib'

# Load the saved model
loaded_model = joblib.load(model_filename)

# Predict using the loaded model
new_open_ports = hashing_trick(['22/ssh', '80/http', '443/https'])
new_entry = np.array([new_open_ports]).reshape(1, -1)
predicted_cluster = loaded_model.predict(new_entry)
print(f"Predicted Cluster: {predicted_cluster[0]}")
原因分析

问题核心在于Python内置的hash()函数:

  • Python默认开启哈希随机化(PYTHONHASHSEED环境变量默认随机),同一个字符串在不同Python进程中会生成不同的哈希值。
  • 训练模型时,当前进程的hash()生成特征向量;加载模型预测时是新进程,hash()生成的哈希值和训练阶段完全不一致,导致输入模型的特征完全错位,最终预测结果错误。
解决方案

有两种可靠的修正方式:

方式一:禁用哈希随机化

通过固定PYTHONHASHSEED环境变量,确保不同进程的hash()结果一致:

  • 命令行启动Python前执行:
    Linux/macOS:export PYTHONHASHSEED=0
    Windows:set PYTHONHASHSEED=0
  • 或者在代码最开头添加(必须在导入其他模块前设置):
import os
os.environ['PYTHONHASHSEED'] = '0'
import sys
sys.modules['hashlib'].__PYTHONHASHSEED__ = 0

方式二:使用稳定的哈希函数

替换内置hash()为可复现的哈希算法,比如hashlib,或直接使用scikit-learn的HashingVectorizer:

用hashlib实现稳定哈希

修改hashing_trick函数:

import hashlib

def hashing_trick(open_ports, n_features=1000):
    hashed_features = np.zeros(n_features)
    for port in open_ports:
        # 用MD5哈希生成稳定整数,再取模
        hash_obj = hashlib.md5(port.encode('utf-8'))
        hash_value = int(hash_obj.hexdigest(), 16) % n_features
        hashed_features[hash_value] = 1
    return hashed_features

用scikit-learn的HashingVectorizer(推荐)

直接使用官方提供的特征哈希工具,稳定性和兼容性更好:

from sklearn.feature_extraction.text import HashingVectorizer

# 初始化向量器
vectorizer = HashingVectorizer(n_features=1000, binary=True, tokenizer=lambda x: x)

# 训练时转换特征
X = vectorizer.transform(df['open_ports'])

# 预测时转换特征
new_entry = vectorizer.transform([['22/ssh', '80/http', '443/https']])
loaded_model.predict(new_entry)

内容的提问来源于stack exchange,提问作者Aditya Bhat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 06:14:59