virmach的黑五机器疯狂出现然后消失,对于各位主机爱好者来说随时查看vps当前价格并决定是否购买是个非常麻烦的问题,本文将通过sklearn的方法对黑五出现的机器配置做个清单,并通过机器学习的方法预测当前vps价格与实际价格,最后提醒mjj们当前vps是否相对来说便宜,话不多说,本文主要步骤如下:

  1. 获取vps详细配置与价格
  2. 处理数据生成格式化数据
  3. sklearn线性回归生成预测模型
  4. 获取当前机型配置并报警

获取vps详细配置与价格

这一步如果在黑五开始的时候就已经开始抓去json数据的话会比较方便,这里由于没有,我就找了个vps提醒群抓取,文本保存如下样式。 virmach,为方便重现,我就把我保存的txt文本上传了,地址为 virmach黑五文本数据 大家自行下载 文本数据并不规则,因为有个机器会缺少某项数据。

处理数据生成格式化数据

机器学习需要的是结构化的数据,因此从文本格式最终生成结构化数据是必须的。 这里我使用linux中的shell命令确认了几项特征数据长度是一致的,最终选用了这几项特征作为线性模型的最终特征。 他们分别是硬盘,流量,内存,位置,IP,cpu,输出为价格。 使用grep找到对应feature,比如获取机器的ip信息

import os
os.system('grep "^IP"  virmach.txt >ip')

然后使用python的re正则表达式找到行中关于配置的详细信息。

import re   #导入re模块
locatep = r"位置: (.+)"  #定义找位置的re模型的pattern
locate = re.findall(locatep,open("locate").read()) #通过pattern找出所有的vps位置并存储在list中

最后写入csv文件,代码如下

import re
import os

os.system('grep "^IP"  virmach.txt >ip')
os.system('grep "^价格"  virmach.txt >price')
os.system('grep "^CPU"  virmach.txt >cpu')
os.system('grep "^硬盘"  virmach.txt >disk')
os.system('grep "^流量"  virmach.txt >band')
os.system('grep "^内存"  virmach.txt >mem')
os.system('grep "^位置"  virmach.txt >locate')
#os.system('grep "^构架"  virmach.txt >kvm')
pricep = r"(\d+.\d+)"
locatep = r"位置: (.+)"
#kvmp = r"构架: (.+)"
diskp = r"硬盘: (\d+)"
cpup = r"\d+"
ipp = r"\d+"
memp = r"\d+"
bandp = r"\d+"

price = re.findall(pricep,open("price").read())
locate = re.findall(locatep,open("locate").read())
#kvm = re.findall(kvmp,open("kvm").read())
disk = re.findall(diskp,open("disk").read())
cpu = re.findall(cpup,open("cpu").read())
ip = re.findall(ipp,open("ip").read())
mem = re.findall(memp,open("mem").read())
band = re.findall(bandp,open("band").read())


fw = open("hei.csv",'w')
fw.write("price\tlocate\tdisk\tcpu\tip\tmemory\tband")
#fw.write("price\tlocate\tkvm\tdisk\tcpu\tip\tmemory\tband")
for i in range(len(price)):
    fw.write("\n"+"\t".join([price[i],locate[i],disk[i],cpu[i],ip[i],mem[i],band[i]]))

fw.close()


sklearn线性回归生成预测模型

最重要的一步,预测virmach当前配置vps对应价格,可以使用多种多种模型,多重线性模型和神经网络,由于数据并不多,直接使用多重线性模型回归。在python中,使用sklearn包进行机器学习真的是非常方便,直接上代码。

#### 导入相关包

import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
import statsmodels.formula.api as sm
import re
from sklearn.linear_model import LinearRegression
import matplotlib.pyplot as plt
from sklearn.metrics import mean_squared_error,r2_score
import os
from scipy import stats

###读入前面处理好的virmach结构化的数据
df =pd.read_csv("hei.csv",sep="\t")
df.locate = df.locate.str.split(",", n = 1, expand = True)[1]
df.replace('^\s+', '', regex=True, inplace=True)


###由于vps位置为category类型,不能直接用于机器学习,这里替换为对应数字

df.locate = df.locate.replace('CA', 1).replace('NY', 2).replace('GA', 3).replace('NJ', 4).replace('TX', 5).replace('WA', 6).replace('IL', 7)

#####查看数据
df.head().append(df.tail())


###sklearn的线性回归模型部分
regressor = LinearRegression()
X = df.iloc[:,1:].values
y = df.iloc[:,0].values
#####训练集测试集1:2划分
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 1/3, random_state = 0)

####模型训练

regressor.fit(X_train, y_train)

# 使用训练好的模型进行预测
y_pred = regressor.predict(X_test)

模型评估

test_set_rmse = (np.sqrt(mean_squared_error(y_test, y_pred)))
test_set_r2 = r2_score(y_test, y_pred)
print(test_set_rmse)
#8.5790882402413
print(test_set_r2)
#0.878882928666751

模型参数查看

print(regressor.intercept_)
#7.599458793118405
print(regressor.coef_)
#[ 2.44111567e-01  2.46369652e-01  5.93846195e+00 -6.07453703e+00 2.12034498e-03  6.35691925e-04]

获取当前机型配置并报警

模型训练好后就可以使用训练好的参数进行价格预测并提醒当前价格是否合算,一旦实际价格低于预测价格进行提醒, 首先获取黑五机型json,使用javascript获取参数并使用上面的回归模型进行价格预测,并提示当前预测价格,用户最后与当前价格比较,作出购买选择。

最后可直接运行并查看到当前套餐状态的代码如下:



##此脚本可直接运行
import requests
import json
import re
import time
import pandas as pd
url = 'https://billing.virmach.com/modules/addons/blackfriday/new_plan.json'
dic_ori = {}
def get_location(locate):
    if "CA" in locate:
        return 1
    elif "NY" in locate:
        return 2
    elif "GA" in locate:
        return 3
    elif "NJ" in locate:
        return 4
    elif "TX" in locate:
        return 5        
    elif "WA" in locate:
        return 6    
    elif "IL" in locate:
        return 7
def format_print(jpd,price):
    
    model = pd.Series([2.44111567e-01,2.46369652e-01,5.93846195e+00,-6.07453703e+00,2.12034498e-03,6.35691925e-04])
    predicted_price = sum(model*j_pd)
    print(predicted_price)
    if predicted_price>float(price):
        print("当前价格:{}\n比预测{}低".format(price,predicted_price))
    else:
        print("当前价格:{}\n比预测{}高".format(price,predicted_price))
   
json_text = requests.get(url).text
dic = json.loads(json_text)
pf = '''
当前套餐:
LOCATION地点: {}
CPU CPU:{} vCORE
HDD 硬盘:{}GB SSD (RAID 10)
BANDWIDTH月流量: {} GB/月
RAM内存: {}MB RAM
IPs IP数:{} DEDICATED IPv4'''.format(dic["location"],int(dic["cpu"]),int(dic["hdd"]),int(dic["bw"]),int(dic["ram"]),int(dic["ips"]))
print(pf)
while True:
#    try:
    json_text = requests.get(url).text
    s+=1
    time.sleep(3)
    dic = json.loads(json_text)
   # print(dic)
    pp = r"\d+.\d+"

    
    j_pd = [get_location(dic["location"]),int(dic["hdd"]),int(dic["cpu"]),int(dic["ips"]),int(dic["ram"]),int(dic["bw"])]
    pf = '''
当前套餐:
LOCATION地点: {}
CPU CPU:{} vCORE
HDD 硬盘:{}GB SSD (RAID 10)
BANDWIDTH月流量: {} GB/月
RAM内存: {}MB RAM
IPs IP数:{} DEDICATED IPv4'''.format(dic["location"],int(dic["cpu"]),int(dic["hdd"]),int(dic["bw"]),int(dic["ram"]),int(dic["ips"]))
    
    price = re.findall(pp,str(dic["price"]))
    if price==[]:
        
        continue
    price = price[0]
    #print(price)
    if dic!=dic_ori:
        print(pf)
        format_print(j_pd,price)
        dic_ori = dic
        
        
#    except:
#        print("unexpected error")
    

运行结果结果查看 virmach

总结

本文使用python的sklearn包对virmach黑五所有的优惠机型建立线性回归模型,并对当前可买的机型进行价格预测,从而确认当前机器是否比优惠期内其他的机型更加优惠,来决定是否购买当前闪购。