开头
我想实现一个薪资的预测,但是没有学过Python的机器学习,只能根据要求来进行相应学习,所以也是自己记录一下
步骤
步骤一般是这样子的
1.数据预处理
首先,对于机器学习任务,需要对数据进行预处理和清洗
。这包括处理缺失值、处理异常值、特征编码、特征缩放等
2. 特征选择和转换
根据预测任务,选择合适的特征字段,排除不相关的字段,并选择与预测目标相关的特征。还可以进行特征转换,如独热编码、标签编码等
,以便将类别型特征转换为数值型特征。
3. 划分数据集
将数据集划分为训练集和测试集。训练集用于训练模型,测试集用于评估模型的性能。常见的划分比例是将数据集的大约70-80%用于训练,20-30%用于测试
。
4. 选择模型和训练
根据预测任务选择合适的机器学习算法或模型,如线性回归、决策树、随机森林
、支持向量机等。使用训练集对模型进行训练,并调整模型的超参数以提高性能。
5. 模型评估和验证
使用测试集对训练好的模型进行评估和验证。常见的评估指标包括准确率、精确率、召回率、F1-score等。根据评估结果,对模型进行调整和改进。
6. 使用模型进行预测
在完成模型训练和验证后,可以使用训练好的模型对新的数据进行预测。
演示
安装库
pip install scikit-learn # 机器学习库
pip install sqlalchemy # 使用pandas从数据库读取数据
代码如下
import pandas as pd
from sqlalchemy import create_engine
# 随机森林回归模型
from sklearn.ensemble import RandomForestRegressor
# 拆分数据集(训练集和测试集)
from sklearn.model_selection import train_test_split
# 特征编码(独热编码)
from sklearn.preprocessing import OneHotEncoder
# 读取数据
engine = create_engine('mysql+pymysql://root:123456@localhost:3306/bosszhipin')
sql = 'select * from jobinfo'
data = pd.read_sql(sql, engine)
# 数据预处理
data['salary'] = data['salary'].apply(lambda x: [int(i) for i in x.strip('[]').split(',')])
data.drop_duplicates(subset='id', inplace=True)
data.fillna(value=0, inplace=True)
# 选择特征列
features = ['address', 'educational', 'type', 'workExperience']
# 提取特征和目标变量
X = data[features]
y = data['salary']
# 使用独热编码对分类特征进行编码
onehot_encoder = OneHotEncoder()
X_encoded = onehot_encoder.fit_transform(X)
# 将薪资区间转换为单个数字
y_mean = y.apply(lambda x: (x[0] + x[1]) / 2)
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X_encoded, y_mean, test_size=0.2, random_state=42)
# 初始化随机森林回归模型
rf_model = RandomForestRegressor(n_estimators=20)
# 训练模型
rf_model.fit(X_train, y_train)
# 获取新数据并进行预测
# new_data = pd.DataFrame({'address': ['北京'], 'educational': ['本科'], 'type': ['go'], 'workExperience': ['1年以内']})
# new_data_encoded = onehot_encoder.transform(new_data)
# prediction = rf_model.predict(new_data_encoded)
# print('预测薪资:', prediction)
# 关闭连接
engine.dispose()
遇到的问题
在对非数值型特征值进行编码的时候,标签编码找不到相关的key
,于是不使用标签编码,使用独热编码
解决(我是这样解决的,没有想到别的方法,了解的不多)。
Traceback (most recent call last):
File "D:\PycharmProjects\code\BossZhiPin\myvenv\lib\site-packages\sklearn\utils\_encode.py", line 225, in _encode
return _map_to_integer(values, uniques)
File "D:\PycharmProjects\code\BossZhiPin\myvenv\lib\site-packages\sklearn\utils\_encode.py", line 165, in _map_to_integer
return np.array([table[v] for v in values])
File "D:\PycharmProjects\code\BossZhiPin\myvenv\lib\site-packages\sklearn\utils\_encode.py", line 165, in <listcomp>
return np.array([table[v] for v in values])
File "D:\PycharmProjects\code\BossZhiPin\myvenv\lib\site-packages\sklearn\utils\_encode.py", line 159, in __missing__
raise KeyError(key)
KeyError: '广州'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "D:\PycharmProjects\code\BossZhiPin\BossApp\tests.py", line 294, in <module>
new_data_encoded = new_data.apply(label_encoder.transform)
File "D:\PycharmProjects\code\BossZhiPin\myvenv\lib\site-packages\pandas\core\frame.py", line 10034, in apply
return op.apply().__finalize__(self, method="apply")
File "D:\PycharmProjects\code\BossZhiPin\myvenv\lib\site-packages\pandas\core\apply.py", line 837, in apply
return self.apply_standard()
File "D:\PycharmProjects\code\BossZhiPin\myvenv\lib\site-packages\pandas\core\apply.py", line 965, in apply_standard
results, res_index = self.apply_series_generator()
File "D:\PycharmProjects\code\BossZhiPin\myvenv\lib\site-packages\pandas\core\apply.py", line 981, in apply_series_generator
results[i] = self.func(v, *self.args, **self.kwargs)
File "D:\PycharmProjects\code\BossZhiPin\myvenv\lib\site-packages\sklearn\preprocessing\_label.py", line 137, in transform
return _encode(y, uniques=self.classes_)
File "D:\PycharmProjects\code\BossZhiPin\myvenv\lib\site-packages\sklearn\utils\_encode.py", line 227, in _encode
raise ValueError(f"y contains previously unseen labels: {str(e)}")
ValueError: y contains previously unseen labels: '广州'
保存模型和复用
使用joblib库进行模型的保存和复用
安装
pip install joblib
def save_model(model, dir='MODEL', MODEL_NAME='predictmodel.pkl'):
if not os.path.exists(dir):
os.mkdir(dir)
path = os.path.join(dir, MODEL_NAME)
joblib.dump(model,path)
def load_model(dir='MODEL', MODEL_NAME='predictmodel.pkl'):
path = os.path.join(dir, MODEL_NAME)
if not os.path.exists(path):
raise FileNotFoundError(f"{path} 模型不存在,请先训练模型!")
model = joblib.load(path)
return model
前端获取数据到后端,后端对得到的数据进行预测返回
def getpredictata(defaultcity,defaultedu,defaulttype,defaultworkexperience):
print(defaultcity,defaultedu,defaulttype,defaultworkexperience)
# 加载模型
model = load_model()
# 预测数据
input_data = pd.DataFrame({
'address': defaultcity,
'educational': defaultedu,
'type': defaulttype,
'workExperience': defaultworkexperience
},index=[0])
input_data_encoded = onehot_encoder.transform(input_data)
prediction = model.predict(input_data_encoded)
# print(prediction)、
# 保留两位小数
prediction = round(prediction[0],2)
return prediction
效果如下
暂时就写这么多,后面有时间得到话进行一个可视化展示。