在熊猫DataFrame的每一行上,有没有更快的训练IsolationForest的方法?

时间:2019-05-23 09:52:00

标签: python pandas scikit-learn

我有一个Pandas DataFrame,其中包含30天内2000个终端的交易计数(列是一个月中的某天),DataFrame如下所示:

trx.head()
    TerminalID 8881 8882    8883    8884    8885    8886    ... 
0   11546   0.0 0.0 0.0 0.0 0.0 0.0 ... 
1   200002  0.0 0.0 0.0 0.0 0.0 0.0 ... 
2   200512  1.0 0.0 0.0 1.0 1.0 0.0 ...
3   202630  3.0 1.0 1.0 0.0 1.0 1.0 ...
4   207000  2.0 4.0 1.0 6.0 3.0 7.0 ...

我想使用IsolationForest对数据的每一行进行异常检测。

首先,我将每一行转换为一个新的DataFrame并在其上拟合数据,每一行一个接一个,然后将结果添加到列表中:

def find_anomaly(trx1,outliers_fraction):
    scaler = StandardScaler()
    np_scaled = scaler.fit_transform(trx1)
    data = pd.DataFrame(np_scaled)
    # train isolation forest
    model =  IsolationForest(contamination=outliers_fraction)
    model.fit(data) 
    trx1['anomaly'] = pd.Series(model.predict(data))
    return(trx1)
#This for is slow
list_terminal_trx = []
for i in range(0,len(trx)-1):
    trx1=trx.iloc[i,1:].reset_index()
    trx1.columns=['day','count']
    trx1['day']=trx1['day'].astype(float)
    list_terminal_trx.append(find_anomaly(trx1,outliers_fraction))
    print('Learning for record',i)

上面的代码工作正常,但是很慢,我想知道是否有更好的方法?

已编辑1:,感谢@AT_asks建议我将n_jobs = -1设置为1,现在速度更快了,但是我的for循环还有其他选择吗?

Edited2 :经过一些修改,我使用了@AT_asks建议使用的apply(),但没有任何性能差异: 对于版本需要3:29:00 应用版本需要3:25:28

Edited3 :使用iterrows()代替for会带来相同的结果: 每个循环3分钟16s±0 ns(平均±标准偏差,运行1次,每个循环1次)

1 个答案:

答案 0 :(得分:1)

如果添加此参数,您可能会得到一些改进

//Putting the hashed passwords to the data base


 session_start();
    require('connect.php');
    $hashedPwd = password_hash($dbcon, PASSWORD_DEFAULT);
    $con = mysqli_connect("****", "***", "***", "***"); 

    $dbcon = $_POST['dbcon'];
    mysqli_query($con,"INSERT INTO `epiz_22821280_codes`.`auth_code` 
    (`passcode`) VALUES ('$hashedPwd');");

//Password test if I inserted 123456 on dbcon POST field



session_start();
    require('connect.php');

    $input = "123456";
    $hashedPwdInDb = password_hash("$input", PASSWORD_DEFAULT);
    $query = "SELECT * FROM `auth_code` WHERE passcode='$input' ";
    $result = mysql_query($query);

    $hash = "$query";
    if(password_verify($input, $hash )){
    print('success');

    } else  {
    print('not success');

    }

此外,我们可以尝试一下。

model =  IsolationForest(contamination=outliers_fraction, n_jobs=-1)