使用Flask部署机器学习模型

机器学习是一个广泛用于预测的过程。在各种可用于预测的库中,有N种算法可用。在本文中,我们将使用不同的机器学习算法和分类器在历史数据上构建预测模型,绘制结果并在测试数据上计算模型的准确性。
在大型数据集上使用各种算法构建/训练模型是数据的一部分。但是在不同的应用程序中使用这些模型是在现实世界中部署机器学习的第二部分。
 
为了将其用于预测新数据,我们必须将其部署在Internet上,以便外界可以使用它。在本文中,我们将讨论如何训练机器学习模型,如何使用Flask在其上创建Web应用程序。
 
我们必须安装许多必需的库,这些库将在此模型中使用。使用pip命令安装所有库。
 
点安装熊猫
点安装numpy
点安装sklearn
决策树–
决策树是一种众所周知的监督型机器学习算法,因为它易于使用,具有弹性和灵活性。我已经在UCI机器学习存储库中的Adult数据集上实现了该算法。
 
获取数据–
您可以从此链接获取数据集。
 
获取数据集还没有结束。我们必须对数据进行预处理,这意味着我们需要清理数据集。数据集的清理包括不同类型的过程,例如删除缺失值,填充NA值等。
 
filter_none
亮度_4
# importing the dataset 
import pandas 
import numpy 
from sklearn import preprocessing 
  
df = pandas.read_csv('adult.csv')     
df.head() 
输出:
df.head()的输出 
 
预处理数据集-
它由14个属性和一个类别标签组成,该标签指示个人的收入是否少于一年或超过50K。这些属性的范围从人的年龄,工人阶级的标签到人际关系的状态以及人所属的种族。有关所有属性的信息可在此处找到。
 
首先,我们从数据中查找并删除所有缺失的值。我们在该列中用模式值替换了缺少的值。还有许多其他方法可以替换丢失的值,但是对于这种类型的数据集,它似乎是最佳的。
 
filter_none
亮度_4
df = df.drop(['fnlwgt', 'educational-num'], axis = 1) 
  
col_names = df.columns 
  
for c in col_names: 
    df = df.replace("?", numpy.NaN) 
df = df.apply(lambda x:x.fillna(x.value_counts().index[0])) 
机器学习算法无法处理分类数据值。它只能处理数值。
为了使数据适合预测模型,我们需要将分类值转换为数值。在此之前,我们将评估是否需要对分类列进行任何转换。
 
离散化-这是使分类数据更整洁和有意义的一种常用方法。我们在列marital_status 上应用了离散化,将其缩小到仅适用于已婚或未婚的价值观。稍后,我们将在其余数据列中应用标签编码器。另外,有两个冗余列{‘education’, ‘educational-num’},因此,我们删除了其中之一。
 
filter_none
亮度_4
df.replace(['Divorced', 'Married-AF-spouse',  
              'Married-civ-spouse', 'Married-spouse-absent',  
              'Never-married', 'Separated', 'Widowed'], 
             ['divorced', 'married', 'married', 'married', 
              'not married', 'not married', 'not married'], inplace = True) 
  
category_col =['workclass', 'race', 'education', 'marital-status', 'occupation', 
               'relationship', 'gender', 'native-country', 'income']  
labelEncoder = preprocessing.LabelEncoder() 
  
mapping_dict ={} 
for col in category_col: 
    df[col] = labelEncoder.fit_transform(df[col]) 
  
    le_name_mapping = dict(zip(labelEncoder.classes_, 
                        labelEncoder.transform(labelEncoder.classes_))) 
  
    mapping_dict[col]= le_name_mapping 
print(mapping_dict) 
输出:
 
{'workclass':{'?':0,'Federal-gov':1,'Local-gov':2,'Never-worked':3,'Private':4,'Self-emp-inc': 5,“ Self-emp-not-inc”:6,“ State-gov”:7,“ Without-pay”:8},“ race”:{“ Amer-Indian-Eskimo”:0,“ Asian-Pac -Islander':1,'Black':2,'Other':3,'White':4},'education':{'10th':0,'11th':1,'12th':2,'1st -4th:3,'5th-6th':4,'7th-8th':5,'9th':6,'Assoc-acdm':7,'Assoc-voc':8,'学士':9, '博士学位':10,'高中毕业程度':11,'硕士':12,'学龄前':13,'专业学校':14,'某些大学':15},'婚姻状况':{ '离婚':0,'已婚AF配偶':1,'已婚Civ-配偶':2,'未婚配偶':3,'未婚':4,4,'分开':5, '寡妇':6},'职业':{'?':0,'副武装':1,'武装部队':2,'工艺修理':3,'执行经理':4, “农渔”:5'清洁工人':6,'机器操作检查':7,'其他服务':8,'私房服务':9,'专业教授':10,'防护服务': 11,'销售':12,'技术支持':13,'交通运输':14},'关系':{'丈夫':0,'非亲属':1,'其他亲戚':2,'自己的孩子':3,'未婚':4,4,'妻子':5},'性别':{'女':0,'男':1},'原住民':{ '?':0,'柬埔寨':1,'加拿大':2,'中国':3,'哥伦比亚':4,'古巴':5,'多米尼加共和国':6,6,厄瓜多尔:7, '萨尔瓦多':8,'英格兰':9,'法国':10,'德国':11,'希腊':12,'危地马拉':13,'海地':14,'霍兰-荷兰': 15,'洪都拉斯':16,'洪':17,'匈牙利':18,'印度':19,'伊朗':20,'爱尔兰':21,'意大利':22,'牙买加':23, '日本':24,'老挝':25,'墨西哥':26,'尼加拉瓜':27,'美国外围地区(关岛-USVI等)”:28,'秘鲁':29,'菲律宾':30,'波兰':31,'葡萄牙':32,'波多黎各':33,'苏格兰':34,'南':35,'台湾':36, '泰国':37,'特立尼达和多巴哥':38,'美国':39,'越南':40,'Yugos lavia':41},'收入':{'50K':1}}
 
拟合模型–
预处理数据后,就可以将数据提供给机器学习算法了。然后,我们将数据分割成带属性的标签。现在,我们将数据集分为两半,一个用于训练,另一个用于测试。这是通过使用train_test_split()sklearn的功能实现的。
 
filter_none
亮度_4
from sklearn.model_selection import train_test_split 
from sklearn.tree import DecisionTreeClassifier 
from sklearn.metrics import accuracy_score 
  
X = df.values[:, 0:12] 
Y = df.values[:, 12] 
我们在这里使用决策树分类器作为预测模型。我们输入了数据的训练部分来训练模型。
训练完成后,我们通过向模型提供部分数据测试来测试模型的准确性。
这样,我们可以达到约84%的精度。现在,为了将此模型与新的未知数据一起使用,我们需要保存模型,以便以后可以预测值。为此,我们利用Python中的pickle,这是用于序列化和反序列化Python对象结构的强大算法。
 
filter_none
亮度_4
X_train, X_test, y_train, y_test = train_test_split( 
           X, Y, test_size = 0.3, random_state = 100) 
  
dt_clf_gini = DecisionTreeClassifier(criterion = "gini", 
                                     random_state = 100, 
                                     max_depth = 5, 
                                     min_samples_leaf = 5) 
  
dt_clf_gini.fit(X_train, y_train) 
y_pred_gini = dt_clf_gini.predict(X_test) 
  
print ("Desicion Tree using Gini Index\nAccuracy is ", 
             accuracy_score(y_test, y_pred_gini)*100 ) 
输出:
 
使用基尼系数的决策树
准确性是83.13031016480704
现在,Flask –
Flask是基于Python的微框架,用于开发小型网站。Flask非常易于使用python来创建Restful API。到目前为止,我们已经开发了一个模型,即model.pkl可以基于数据的各种属性来预测数据的类别。类标签是Salary> = 50K或<50K。
现在,我们将设计一个Web应用程序,在该应用程序中,用户将输入所有属性值,并为数据提供模型,然后根据模型的训练,模型将预测其详细信息包含以下内容的人员的工资受够了。
 
HTML表单–
为了预测各种属性的收入,我们首先需要收集数据(新属性值),然后使用上面构建的决策树模型来预测收入是否大于或等于5万。因此,为了收集数据,我们创建了html表单,该表单将包含从每个属性中选择的所有不同选项。在这里,我们仅使用html创建了一个简单表单。如果要使表单更具交互性,也可以这样做。
 
filter_none
亮度_4
<html> 
<body> 
    <h3>Income Prediction Form</h3> 
  
<div> 
  <form action="/result" method="POST"> 
    <label for="age">Age</label> 
    <input type="text" id="age" name="age"> 
    <br> 
    <label for="w_class">Working Class</label> 
    <select id="w_class" name="w_class"> 
      <option value="0">Federal-gov</option> 
      <option value="1">Local-gov</option> 
      <option value="2">Never-worked</option> 
      <option value="3">Private</option> 
      <option value="4">Self-emp-inc</option> 
      <option value="5">Self-emp-not-inc</option> 
      <option value="6">State-gov</option> 
      <option value="7">Without-pay</option> 
    </select> 
    <br> 
    <label for="edu">Education</label> 
    <select id="edu" name="edu"> 
      <option value="0">10th</option> 
      <option value="1">11th</option> 
      <option value="2">12th</option> 
      <option value="3">1st-4th</option> 
      <option value="4">5th-6th</option> 
      <option value="5">7th-8th</option> 
      <option value="6">9th</option> 
      <option value="7">Assoc-acdm</option> 
      <option value="8">Assoc-voc</option> 
      <option value="9">Bachelors</option> 
      <option value="10">Doctorate</option> 
      <option value="11">HS-grad</option> 
      <option value="12">Masters</option> 
      <option value="13">Preschool</option> 
      <option value="14">Prof-school</option> 
      <option value="15">16 - Some-college</option> 
    </select> 
    <br> 
    <label for="martial_stat">Marital Status</label> 
    <select id="martial_stat" name="martial_stat"> 
      <option value="0">divorced</option> 
      <option value="1">married</option> 
      <option value="2">not married</option> 
    </select> 
    <br> 
    <label for="occup">Occupation</label> 
    <select id="occup" name="occup"> 
      <option value="0">Adm-clerical</option> 
      <option value="1">Armed-Forces</option> 
      <option value="2">Craft-repair</option> 
      <option value="3">Exec-managerial</option> 
      <option value="4">Farming-fishing</option> 
      <option value="5">Handlers-cleaners</option> 
      <option value="6">Machine-op-inspct</option> 
      <option value="7">Other-service</option> 
      <option value="8">Priv-house-serv</option> 
      <option value="9">Prof-specialty</option> 
      <option value="10">Protective-serv</option> 
      <option value="11">Sales</option> 
      <option value="12">Tech-support</option> 
      <option value="13">Transport-moving</option> 
    </select> 
    <br> 
    <label for="relation">Relationship</label> 
    <select id="relation" name="relation"> 
      <option value="0">Husband</option> 
      <option value="1">Not-in-family</option> 
      <option value="2">Other-relative</option> 
      <option value="3">Own-child</option> 
      <option value="4">Unmarried</option> 
      <option value="5">Wife</option> 
    </select> 
    <br> 
    <label for="race">Race</label> 
    <select id="race" name="race"> 
      <option value="0">Amer Indian Eskimo</option> 
      <option value="1">Asian Pac Islander</option> 
      <option value="2">Black</option> 
      <option value="3">Other</option> 
      <option value="4">White</option> 
    </select> 
    <br> 
    <label for="gender">Gender</label> 
    <select id="gender" name="gender"> 
      <option value="0">Female</option> 
      <option value="1">Male</option> 
    </select> 
    <br> 
    <label for="c_gain">Capital Gain </label> 
    <input type="text" id="c_gain" name="c_gain">btw:[0-99999] 
    <br> 
    <label for="c_loss">Capital Loss </label> 
    <input type="text" id="c_loss" name="c_loss">btw:[0-4356] 
    <br> 
    <label for="hours_per_week">Hours per Week </label> 
    <input type="text" id="hours_per_week" name="hours_per_week">btw:[1-99] 
    <br> 
    <label for="native-country">Native Country</label> 
    <select id="native-country" name="native-country"> 
      <option value="0">Cambodia</option> 
      <option value="1">Canada</option> 
      <option value="2">China</option> 
      <option value="3">Columbia</option> 
      <option value="4">Cuba</option> 
      <option value="5">Dominican Republic</option> 
      <option value="6">Ecuador</option> 
      <option value="7">El Salvadorr</option> 
      <option value="8">England</option> 
      <option value="9">France</option> 
      <option value="10">Germany</option> 
      <option value="11">Greece</option> 
      <option value="12">Guatemala</option> 
      <option value="13">Haiti</option> 
      <option value="14">Netherlands</option> 
      <option value="15">Honduras</option> 
      <option value="16">HongKong</option> 
      <option value="17">Hungary</option> 
      <option value="18">India</option> 
      <option value="19">Iran</option> 
      <option value="20">Ireland</option> 
      <option value="21">Italy</option> 
      <option value="22">Jamaica</option> 
      <option value="23">Japan</option> 
      <option value="24">Laos</option> 
      <option value="25">Mexico</option> 
      <option value="26">Nicaragua</option> 
      <option value="27">Outlying-US(Guam-USVI-etc)</option> 
      <option value="28">Peru</option> 
      <option value="29">Philippines</option> 
      <option value="30">Poland</option> 
      <option value="11">Portugal</option> 
      <option value="32">Puerto-Rico</option> 
      <option value="33">Scotland</option> 
      <option value="34">South</option> 
      <option value="35">Taiwan</option> 
      <option value="36">Thailand</option> 
      <option value="37">Trinadad&Tobago</option> 
      <option value="38">United States</option> 
      <option value="39">Vietnam</option> 
      <option value="40">Yugoslavia</option> 
    </select> 
    <br> 
    <input type="submit" value="Submit"> 
  </form> 
</div> 
</body> 
</html> 
输出:
input_data_form
 
注意:
为了正确预测数据,每个标签的对应值应与所选每个输入的值匹配。例如,在“关系”属性中,有6个类别值。它们被转换为数字,例如{'丈夫':0,'非家庭':1,'其他亲戚':2,'独生子女':3,'未婚':4,4,'妻子': 5}。因此,我们需要将相同的值添加到html表单中。
 
filter_none
亮度_4
# prediction function 
def ValuePredictor(to_predict_list): 
    to_predict = np.array(to_predict_list).reshape(1, 12) 
    loaded_model = pickle.load(open("model.pkl", "rb")) 
    result = loaded_model.predict(to_predict) 
    return result[0] 
  
@app.route('/result', methods = ['POST']) 
def result(): 
    if request.method == 'POST': 
        to_predict_list = request.form.to_dict() 
        to_predict_list = list(to_predict_list.values()) 
        to_predict_list = list(map(int, to_predict_list)) 
        result = ValuePredictor(to_predict_list)         
        if int(result)== 1: 
            prediction ='Income more than 50K'
        else: 
            prediction ='Income less that 50K'            
        return render_template("result.html", prediction = prediction) 
从表单发布数据后,应将数据提供给模型。
 
Flask脚本–
在开始编码部分之前,我们需要下载flask和其他一些库。在这里,我们利用虚拟环境来管理所有库,并简化了开发和部署工作。
 
这是使用虚拟环境运行代码的代码。
 
mkdir收入预测
cd收入预测
python3 -m venv venv
来源venv / bin / activate
现在让我们安装Flask。
 
点安装烧瓶
让我们创建文件夹模板。在您的应用程序中,您将使用模板来呈现HTML,这些HTML将显示在用户的浏览器中。此文件夹包含我们的html表单文件index.html。
 
mkdir模板
script.py 在项目文件夹中创建文件,然后复制以下代码。
 
在这里,我们导入库,然后使用app=Flask(__name__)我们创建flask的实例。@app.route('/')用来告诉flask哪些URL应该触发该函数,index()并且在函数索引中我们用于render_template('index.html')在浏览器中显示脚本index.html。
 
让我们运行该应用程序。
 
export FLASK_APP = script.py#此行将在Linux中工作
设置FLASK_APP = script.py#这是Windows的代码。
运行烧瓶
这应该运行该应用程序并启动一个简单的服务器。打开http://127.0.0.1:5000/以查看html表单。
 
预测收入值–
提交表单时,网页应显示收入的预测值。为此,我们需要model.pkl在同一项目文件夹中创建的模型文件()。
 
在此,提交表单后,表单值to_predict_list 以字典的形式存储在变量中。我们将其转换为字典值的列表,并将其作为ValuePredictor()函数的参数传递。在此函数中,我们加载model.pkl文件并预测新值并返回结果。
然后将此结果/预测(收入大于或小于50k)作为参数传递给模板引擎,并显示html页面。
 
创建以下result.html文件并将其添加到模板文件夹。
 
filter_none
亮度_4
<!doctype html> 
<html> 
   <body> 
       <h1> {{ prediction }}</h1> 
   </body> 
</html> 
输出:
Prediction_Model_Folder_structure
再次运行该应用程序,提交表单后它应该预测收入,并在结果页面上显示输出。
18215660330
179001057@qq.com