python预测数量及QT混合编程--Apple的学习笔记

一,前言:

在我上一篇blog QChart任务数预测项目实战--Apple的学习笔记 中有一个python预测任务,今天完成了并且进行QT c++及python混合编程后的集成。

二,功能:

要进行预测每天会新学习多少项内容。然后继续按艾宾浩斯曲线来处理。

三,思路分析:

哪些先分析下数据有什么特征,就会发现每天学习数量几乎都少于10项。然后周末或周一新学习的数量会笔记多。周五新学习的数量会比较少。这是我的个人规律,周末不上班,所以学习数量可以多些,周五一般就想休息了。

四,数学建模:

这个不属于线性回归,属于数据分类问题。那么预测每天会新学习多少项内容的数学模型就简化为如下:
预测周一的学习数量,周二的学习数量一直到周日的学习数量,而且数组范围为【1,10】。
机器学习里面首先想到朴素贝叶斯,由于此模型都没有什么条件概率。所以又简化为了计算周一出现[0,10]中哪个概率最大,则预测出将来的周一新学习项的数量。同理去推导周二到周日新学习的数量。

python算法模拟实验

mylist1=[[5,1,4,1,0,5],  #周一
         [1,2,1,3,3,4]]  #周二
useValue=[0,0]

def forecast():
    for date in range(2):
        maxNum = 0
        for i in range(10,-1,-1):  # 10 to 0 开始遍历
            if (mylist1[date].count(i))>maxNum:   #select the first max value,if counter is the same,select the max one
                maxNum = mylist1[date].count(i)
                useValue[date] =i
    print (useValue)
    
if __name__ == '__main__':
    forecast()

输出结果
[5, 3]
代表周一预测新学习数量加5,周二加3。

五,总结

由于我是2019-10-01开始使用这套系统的,所以当前的训练数据就比较少,不准确。我的概率在某个星期n计算会发现都是一样的,在这样的情况下使用的是最大值就不太准。

六,遇到的问题记录

1.解决了python37_d无法打开的问题,自己再copy一个然后重命名为_d.lib即可。
2.Py_IsInitialized报错,需要按网上说的修改python的include中的一个头文件。
3.添加python模块lib的方法可以右击工程添加,也可以手工添加,最后用的是手工在pro文件中添加。

七,学到的技术总结

  1. QT c++和python的混合编程技能。
  2. 复习了机器学习中的朴素贝叶斯。
  3. QT Vector的copy用<<即可。
  4. 掌握了datetime的各种转换。
  5. 学习了python collections进行归类的字典输出。

八,github源码上传

https://github.com/AppleCai/taskForecast

九,运行效果图

结果.png

十,python源码

import sqlite3
from datetime import datetime
from collections import Counter

mydatelist=[
         [],  #周日
         [],  #周一
         [],  #周二
         [],  #周三
         [],  #周四
         [],  #周五
         [],  #周六
         ]
useValue=[0,0,0,0,0,0,0] # 周日,周一~周六每天新学的任务数

def connectUserDb():
    con = sqlite3.connect(r'D:\Djangoproj\myWebTest\db.sqlite3')
    return con

def queryUserRecords(con):
    mytemplist = []
    # 因为我的django工程师10月初做的,所以从2019年10月1日后的数据算是有效的。然后开始统计
    cursor = con.execute("SELECT modify_date FROM myfile_basicinfo WHERE  modify_date>='2019-10-01'")
    # 仅提取日期字符串,不需要时间
    for item in cursor:
        mytemplist.append(item[0][0:10])
    # 对每一相同日期归类,以字典显示{日期:出现次数}
    res = Counter(mytemplist)
    print(res)
    for key in res:
        # 先将str转成datatime格式后再转为周几
        anyday = datetime.strptime(key, '%Y-%m-%d').strftime("%w") # key为日期字符串,做处理
        tempnum = res[key]
        # 预测的每天新增学习数量(即出现次数)不超过10项,超过10则用10代表
        if (tempnum>10):
            tempnum = 10
        mydatelist[int(anyday)].append(tempnum)  # 将日期转为周几,并将出现次数copy到数组。

def forecast():
    for date in range(7):  # date 0 to 6
        maxNum = 0
        for i in range(10,-1,-1):  # i is from 10 to 0
            if (mydatelist[date].count(i))>maxNum:   # 若出现次数相同,则选择字数最大的值作为预测性学习数量
                maxNum = mydatelist[date].count(i)
                useValue[date] =i
    print (useValue)

def maintask():
    connect=connectUserDb()    # 连接数据库
    queryUserRecords(connect)  # 查询曾经学习的记录,并且处理数据获得每天(周一~周日)新学习的数量
    forecast()                 # 进行机器分类学习,在0-10之前出现最大的概率
    return useValue

if __name__ == '__main__':
    maintask()

十一,QT widget部分源码

#include "widget.h"
#include "ui_widget.h"



Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{

    pythonCode();
    ui->setupUi(this);
    //QDateTime curDateTime=QDateTime::currentDateTime();
    curDate=QDate::currentDate();
    lastDate = curDate.addDays(15);
    ui->txtDate->setText(curDate.toString("yyyy-MM-dd"));
    ui->cb_rangeselect->addItem("one week");
    ui->cb_rangeselect->addItem("two week");
    connectSQL();
    addmyForecast();
}

void Widget::pythonCode()
{
    Py_Initialize();
    //如果初始化失败,返回
    if(!Py_IsInitialized())
    {
        qDebug()<<"Initlize error";
    }
    else
    {
        qDebug() << "inititalize success";
    }
    PyRun_SimpleString("import sys");
    PyRun_SimpleString("sys.path.append('./')");  //即exe运行目录下放入python文件
    PyObject* pModule =PyImport_ImportModule("forecast");
    if(!pModule)
    {
        qDebug()<<"can not open python file";
    }
    else
    {
        qDebug() << "Import success";
    }

    // 加载函数maintask()
    PyObject *pLoadFunc = PyObject_GetAttrString(pModule, "maintask");

    if (!pLoadFunc) {
        printf("get func failed!");
    }
    else {
        qDebug() << "get func success";
    }
    PyObject *retObjectX = PyObject_CallObject(pLoadFunc, nullptr); // 获得python脚本返回数据

    if (retObjectX == nullptr) {
        qDebug() << "no return value";
        return ;
    }

    int row = PyList_Size(retObjectX);
    for (int i = 0; i < row; ++i) {
        PyObject *singleItem = PyList_GetItem(retObjectX, i);
        int res = 0;
        PyArg_Parse(singleItem,"i",&res);//转换返回类型
        ForecastVect.push_back(res);
        //double item = PyFloat_AsDouble(singleItem);
        //tmpVect.push_back(item);
    }
    qDebug()<<"test start";
    qDebug()<append(set0);

    series->setLabelsPosition(QAbstractBarSeries::LabelsInsideEnd); // 设置数据系列标签的位置于数据柱内测上方
    series->setLabelsVisible(true); // 设置显示数据系列标签

    QChart *chart = new QChart();
    chart->addSeries(series);
    chart->setTitle("forecast task number");
    chart->setAnimationOptions(QChart::SeriesAnimations);

    QBarCategoryAxis *axisX = new QBarCategoryAxis();
    axisX->append(categories);
    chart->addAxis(axisX, Qt::AlignBottom);
    series->attachAxis(axisX);

    QValueAxis *axisY = new QValueAxis();
    chart->addAxis(axisY, Qt::AlignLeft);
    series->attachAxis(axisY);

    chart->legend()->setVisible(true);
    chart->legend()->setAlignment(Qt::AlignBottom);
    ui->widgetBar->setChart(chart);
}

void Widget::connectSQL()
{
   QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
    db.setDatabaseName("D:\\Djangoproj\\myWebTest\\db.sqlite3");
    if (!db.open())
    {
        qDebug() << "open error";
    }
    else
    {
         qDebug()<<"ok";
    }
    SQLhandler();
    db.close();
}

void Widget::SQLhandler()
{
    QSqlQuery sql_query;
    //qDebug()< week;
    week.insert("周日",0);
    week.insert("周一",1);
    week.insert("周二",2);
    week.insert("周三",3);
    week.insert("周四",4);
    week.insert("周五",5);
    week.insert("周六",6);
    //qDebug()<ck_ONOFF->font();
    font.setBold(checked);
    ui->ck_ONOFF->setFont(font);
    ui->pushButton->setEnabled(true);
    bl_addML = checked;
    qDebug()<pushButton->setEnabled(false);
    // 根据checkbox来选择带新增预测的数据或不带新增预测的数据
    if (bl_addML)
    {
        CalculateTaskNum(ReviewPhase,DateInfo);
    }
    else
    {
        CalculateTaskNum(ReviewPhasePrevCopy,DateInfoPrevCopy);
    }
    ShowBar();
}

void Widget::CalculateTaskNum(const QVector &vReviewPhase,const QVector &vDateInfo)
{
    int i;
    CalCnt.clear();
    for(i=0;i<14;i++)
    {
        CalCnt.append(0);
    }
    int index=0;
    for(auto iphase:vReviewPhase)
    {
        int diff = 0;
        int j=0;
        /* change Datetime string to Data */
        QDate tempDate = QDateTime::fromString(vDateInfo[index], "yyyy-MM-dd hh:mm:ss").date();

        diff = curDate.daysTo(tempDate);
        if(diff>=0 && diff<14)
        {
            /* add the default review date */
            CalCnt[diff]++;
            j=iphase+1;  /* TBD */
            /* accumulation for each phase while diff<15 */
            while(diff<14 && j<6)
            {

                    diff=diff+myRule[j++];
                    if(diff>=0 && diff<14)
                    {
                        CalCnt[diff]++;
                    }
            }
        }
        else
        {
            j=iphase++;
            /* some item didn't review on time, so is minus value */
            while(diff<14 && diff>=0 && j<6)
            {
                    diff=diff+myRule[j++];

                    if(diff>0 && diff<14)
                    {
                        CalCnt[diff]++;
                    }
            }
        }

        /* next item */
        index++;
    }
}

void Widget::on_cb_rangeselect_currentIndexChanged(const QString &arg1)
{
    //Q_UNUSED(arg1)
    if(arg1=="one week")
    {
        showdays = 7;
    }
    else
    {
        showdays = 14;
    }
    ui->pushButton->setEnabled(true);
}

你可能感兴趣的:(python预测数量及QT混合编程--Apple的学习笔记)