CCF BDCI 返乡发展人群预测_返乡发展人群预测大赛报告-程序员宅基地

技术标签: 图神经网络  python  机器学习  人工智能  开发语言  

机缘

在网上找数据集的时候无意中看到了有这么个比赛,伴随着好奇的心里以及尝试的心态就参加试一试。这次比赛出现了一些让我意想不到的结果特此记录一下。

赛题内容

基于中国联通的大数据能力,通过使用对联通的信令数据、通话数据、互联网行为等数据进行建模,对个人是否会返乡工作进行判断。以上为官网的背景介绍。以论文的角度看应该是要参考一些人口流动预测的场景。
数据集介绍:

  1. train.csv:包含全量数据集的70%(dataNoLabel是训练集的一部分,选手可以自己决定是否使用)
  2. 位置类特特征:基于联通基站产生的用户信令数据;
  3. 互联网类特征:基于联通用户上网产生的上网行为数据;
  4. 通话类特征:基于联通用户日常通话、短信产生的数据;
  5. 评价指标:该问题作为一个二分类问题使用ROC曲线下面积AUC(Area Under Curve)作为评价指标,AUC越大,预测越准确。
  6. 赛题链接:返乡人群预测

Baseline

这个赛题已经有大佬在网上开源了baseline方案。大佬的解决方案的大致思路是:

  1. 先对原始特征进行暴力穷举:
train_data['f47'] = train_data['f1'] * 10 + train_data['f2']
test_data['f47'] = test_data['f1'] * 10 + test_data['f2']
loc_f = ['f1', 'f2', 'f4', 'f5', 'f6']
for df in [train_data, test_data]:
    for i in range(len(loc_f)):
        for j in range(i + 1, len(loc_f)):
            df[f'{
      loc_f[i]}+{
      loc_f[j]}'] = df[loc_f[i]] + df[loc_f[j]]
            df[f'{
      loc_f[i]}-{
      loc_f[j]}'] = df[loc_f[i]] - df[loc_f[j]]
            df[f'{
      loc_f[i]}*{
      loc_f[j]}'] = df[loc_f[i]] * df[loc_f[j]]
            df[f'{
      loc_f[i]}/{
      loc_f[j]}'] = df[loc_f[i]] / (df[loc_f[j]]+1)

com_f = ['f43', 'f44', 'f45', 'f46']
for df in [train_data, test_data]:
    for i in range(len(com_f)):
        for j in range(i + 1, len(com_f)):
            df[f'{
      com_f[i]}+{
      com_f[j]}'] = df[com_f[i]] + df[com_f[j]]
            df[f'{
      com_f[i]}-{
      com_f[j]}'] = df[com_f[i]] - df[com_f[j]]
            df[f'{
      com_f[i]}*{
      com_f[j]}'] = df[com_f[i]] * df[com_f[j]]
            df[f'{
      com_f[i]}/{
      com_f[j]}'] = df[com_f[i]] / (df[com_f[j]]+1)
cat_columns = ['f3']
data = pd.concat([train_data, test_data])

for col in cat_columns:
    lb = LabelEncoder()
    lb.fit(data[col])
    train_data[col] = lb.transform(train_data[col])
    test_data[col] = lb.transform(test_data[col])
num_columns = [ col for col in train_data.columns if col not in ['id', 'label', 'f3']]
feature_columns = num_columns + cat_columns
target = 'label'

train = train_data[feature_columns]
label = train_data[target]
test = test_data[feature_columns]
print(train.shape)
print(train)
  1. 采用了lgb的树模型和5折交叉验证来进行训练
features = [i for i in train.columns if i not in ['label',  'id']]
y = train['label']
KF = StratifiedKFold(n_splits=5, random_state=2021, shuffle=True)
feat_imp_df = pd.DataFrame({
    'feat': features, 'imp': 0})
params = {
    
    'objective': 'binary',
    'boosting_type': 'gbdt',
    'metric': 'auc',
    'n_jobs': 30,
    'learning_rate': 0.05,
    'num_leaves': 2 ** 6,
    'max_depth': 8,
    'tree_learner': 'serial',
    'colsample_bytree': 0.8,
    'subsample_freq': 1,
    'subsample': 0.8,
    'num_boost_round': 5000,
    'max_bin': 255,
    'verbose': -1,
    'seed': 2021,
    'bagging_seed': 2021,
    'feature_fraction_seed': 2021,
    'early_stopping_rounds': 100,

}

oof_lgb = np.zeros(len(train))
predictions_lgb = np.zeros((len(test)))
# 模型训练
for fold_, (trn_idx, val_idx) in enumerate(KF.split(train.values, y.values)):
    print("fold n°{}".format(fold_))
    trn_data = lgb.Dataset(train.iloc[trn_idx][features], label=y.iloc[trn_idx])
    val_data = lgb.Dataset(train.iloc[val_idx][features], label=y.iloc[val_idx])
    num_round = 3000
    clf = lgb.train(
        params,
        trn_data,
        num_round,
        valid_sets=[trn_data, val_data],
        verbose_eval=100,
        early_stopping_rounds=50,
    )

    oof_lgb[val_idx] = clf.predict(train.iloc[val_idx][features], num_iteration=clf.best_iteration)
    predictions_lgb[:] += clf.predict(test[features], num_iteration=clf.best_iteration) / 5
    feat_imp_df['imp'] += clf.feature_importance() / 5

print("AUC score: {}".format(roc_auc_score(y, oof_lgb)))
print("F1 score: {}".format(f1_score(y, [1 if i >= 0.5 else 0 for i in oof_lgb])))
print("Precision score: {}".format(precision_score(y, [1 if i >= 0.5 else 0 for i in oof_lgb])))
print("Recall score: {}".format(recall_score(y, [1 if i >= 0.5 else 0 for i in oof_lgb])))

这里就不放完整的大佬代码了,有需要的可以去赛题的评论区里面自行获取。


自己的理解

以上是大佬们开源的解决方案,就我个人感觉方案存在一些小问题(虽然我的排名非常垃圾可是我依旧想这样说一下我的看法):

  1. 大佬们的解决方案没有使用那个未标注的数据集。
  2. 可以看到大佬们的特征构造是对原始特征的几个字段进行暴力穷举得到的新特征并没有使用全部的字段,那就有个问题为什么其他字段的特征就没有用呢?能不能有一种这样的方法可以自动发掘和构造这样的特征以及可以自主判断特征对于目标问题的重要程度呢?
  3. 而且大佬们采用了lgb模型没有考虑样本之间的关系。为什么我说样本之间可能是存在关系的呢?这里的意思并不是说会默认人的行为活动是相关的,就是说A的返乡行为一定会影响B。比如,如果A和B都是一个学校的学生,那么他俩会有影响。而是存在某种意义度量下样本之间存在一定的联系,具体为比如毕业季,不在同一个学校的两个互不认识的学生应该具有相同或者相似的行为比如毕业旅行、找工作、聚餐等等。这样就算两个人不认识,我觉得也可以根据特征上的相似度来构建样本之间的拓扑结构。从而聚合特征来消除类内之间样本的差异性和噪声得到比如返乡学生的一般性特征。这是我的想法,我觉得是有道理的。

解决方案

以上是我对场景的理解。也就是说我认为解决预测问题的需要一种可以自适应的挖掘出特征之间对目标的重要程度,并且可以使用未标注数据集,而且还可以自动挖掘出样本之间的相关性的模型。

  1. 针对第一个可以自动挖掘特征对目标的重要程度,换种说法也就是可以对特征进行自适应的加权。自然可以想到多头注意力机制。
  2. 而可以使用未标注数据集,而且还可以自动挖掘出样本之间的相关性这两个问题我们而然可以想到图模型。如果接触过图学习的可能知道图数据中有一个trainmask和testmask的参数。只要我们让那些未标注的数据的这两个参数全部等于false那也就是让这部分数据即不参与训练也不参与预测,只进行特征聚合。至于样本之间的联系我们知道图本身可以表示数据之间的联系。
  3. 经以上想法我们将样本中每个人的特征看成是图上的节点,将原始问题转化为图上的节点的二分类问题。通过多头注意力机制加图学习来进行预测。
  4. 但是以上想法存在问题,就是我们没有图上边的信息,我们该如何在没有先验知识的情况下构建图的邻接矩阵呢?我们采用KDD22上一篇癫痫病预测论文里面的方法:通过计算样本之间向量在映射到高维空间当中的余弦相似度,采用topk机制,选取前k个最大的值对应的样本作为该样本的一阶邻居这种方法让模型来自适应的学习出图的邻接矩阵。(论文名字我忘记了,我只记得是KDD22)

代码

引入库文件

import os
import numpy as np
import cv2
import matplotlib.pyplot as plt
import torch
from torch.utils.data import Dataset,DataLoader
import torch_geometric
import pandas as pd
import networkx as ntx
import torch
import numpy as np
import torch.nn as nn
import math
import torch.nn.functional as F
import torch.nn as nn
import torch.nn.functional as F
from torchmetrics import Accuracy
from torchmetrics import AUROC
#from torchmetrics.classification import BinaryAccuracy
import torch
import numpy as np
import torch.nn as nn
import math
import torch.nn.functional as F

引入数据集

batchsize=1024##batchsize直接和图的邻接矩阵的规模相关不能太小
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
class MyDataset(torch.utils.data.Dataset):
    def __init__(self, root,datatype,num=49858):
        name1= os.path.join(root,'dataTrain.csv')
        name2= os.path.join(root,'dataNoLabel.csv')
        name3 =os.path.join(root,'dataA.csv')  
        name=''
        if(datatype=='train'):
            name=name1
        else:
            name=name3
        df=pd.read_csv(name)
        df1=pd.read_csv(name1)
        df2=pd.read_csv(name2)
        df3=pd.read_csv(name3)
        self.data2=df2.insert(loc=df2.shape[1], column='label', value=2)
        self.data3=df3.insert(loc=df3.shape[1], column='label', value=3)
        data = pd.DataFrame(df,columns=['f3'])
        dummies = pd.get_dummies(data)
        for index,row in df.iteritems():
            if(index not in ['id','label','f3']):
                a=np.min(np.array(df1[[index]]))
                b=np.max(np.array(df1[[index]]))
                df[[index]]=df[[index]].apply(lambda x : (x-a)/(b-a))
        for index, row in dummies.iteritems():
        # print(index) 
        # print(dummies[index])
        # print(row)
            df.insert(loc=3, column=index, value=row.tolist())
        df=df.drop(columns='f3',inplace=False)##在里面f3字段是一个离散特征,我们将它转换为onehot编码
        print(df.shape)
        # self.traindata=df.sample(n=num, frac=None, replace=False, weights=None, random_state=None, axis=0)
        # print(self.traindata.shape)
        # self.testdata=df[~df.index.isin(self.traindata.index)]
        # print(self.testdata.shape)
        self.data=df
        self.datatype=datatype

    def getdata(self,index,df):
        a=df.iloc[index,1:49].values.tolist()
        b=df.iloc[index,49:].values.tolist()
        a = [float(i) for i in a]
        b = [float(i) for i in b]
        X=torch.tensor(a,dtype=torch.float32)
        # X=X.unsqueeze(-1)
        Y=torch.tensor(b,dtype=torch.float32)
        return X,Y

    def __getitem__(self, index):    
        samples, labels=self.getdata(index,self.data) 
        sample=[samples,labels]
        return sample

    def __len__(self):
        return self.data.shape[0]

traindata=MyDataset(root='./data/person/',datatype='train')
print(len(traindata))
testdata=MyDataset(root='./data/person/',datatype='test')
print(len(testdata))
train_size = int(len(traindata) * 0.9)
test_size = len(traindata) - train_size
train_dataset, test_dataset = torch.utils.data.random_split(traindata, [train_size, test_size])
train_loader = DataLoader(train_dataset, batch_size=batchsize, shuffle=False)
print(len(train_dataset))
print(len(test_dataset))
print(len(testdata))
#for step, (input,label) in enumerate(train_loader):
    #print(input.shape)
    #print(label.shape)
print('+++++++++++++++++++++test++++++++++++++++++++')
test_loader = DataLoader(test_dataset, batch_size=batchsize, shuffle=False)
#for step, (input,label) in enumerate(test_loader):
    #print(input.shape)
    #print(label.shape)

多头注意力机制

class selfAttention(nn.Module) :
    def __init__(self, num_attention_heads, input_size, hidden_size):
        super(selfAttention, self).__init__()
        if hidden_size % num_attention_heads != 0 :
            raise ValueError(
                "the hidden size %d is not a multiple of the number of attention heads"
                "%d" % (hidden_size, num_attention_heads)
            )

        self.num_attention_heads = num_attention_heads
        self.attention_head_size = int(hidden_size / num_attention_heads)
        self.all_head_size = hidden_size

        self.key_layer = nn.Linear(input_size, hidden_size)
        self.query_layer = nn.Linear(input_size, hidden_size)
        self.value_layer = nn.Linear(input_size, hidden_size)

    def trans_to_multiple_heads(self, x):
        new_size = x.size()[ : -1] + (self.num_attention_heads, self.attention_head_size)
        x = x.view(new_size)
        return x.permute(0, 2, 1, 3)

    def forward(self, x):
        key = self.key_layer(x)
        query = self.query_layer(x)
        value = self.value_layer(x)#kqv

        key_heads = self.trans_to_multiple_heads(key)
        query_heads = self.trans_to_multiple_heads(query)
        value_heads = self.trans_to_multiple_heads(value)

        attention_scores = torch.matmul(query_heads, key_heads.permute(0, 1, 3, 2))
        attention_scores = attention_scores / math.sqrt(self.attention_head_size)

        attention_probs = F.softmax(attention_scores, dim = -1)

        context = torch.matmul(attention_probs, value_heads)
        context = context.permute(0, 2, 1, 3).contiguous()
        new_size = context.size()[ : -2] + (self.all_head_size , )
        context = context.view(*new_size)
        return context

图学习层

class attgraNet(nn.Module):
    def __init__(self,inputsize,batchsize,k):
        super(attgraNet, self).__init__()
        self.k=k
        self.batchsize=batchsize
        self.inputsize=inputsize
        self.fc1 = nn.Linear(inputsize,inputsize*10)
        self.att = selfAttention(4,10,48)
        #self.para = torch.nn.Parameter(torch.ones([2,batchsize]), requires_grad=True)
        #四层GAT
        self.gat1=torch_geometric.nn.GATConv(48*48,16,16,dropout=0.6)
        self.act1=nn.LeakyReLU(0.1)
        self.gat2=torch_geometric.nn.GATConv(256,8,8,dropout=0.6)
        self.act2=nn.LeakyReLU(0.1)
        self.gat3=torch_geometric.nn.GATConv(64,8,8,dropout=0.6)
        self.act3=nn.LeakyReLU(0.1)
        self.gat4=torch_geometric.nn.GATConv(64,16,16,dropout=0.6)
        self.act4=nn.LeakyReLU(0.1)
        self.fc2 = nn.Sequential(nn.Linear(16*16, 84),nn.LeakyReLU(0.1),nn.BatchNorm1d(84))
        self.fc3 = nn.Linear(84, 2)

    def forward(self, x):
        #print(x.size())
        print(x.device)
        x = self.fc1(x)
        x = x.unsqueeze(-1)
        x = x.reshape(-1,self.inputsize,10)
        #print(x.size())
        x = self.att(x)
        x = x.reshape(x.shape[0],-1,1)
        #print(x.size())
        a=x
        dim0, dim1,dim2 = a.shape
        #print(dim0)
        #print(dim1)
        #print(dim2)
        para = torch.ones([2,a.shape[0]],dtype=torch.long).to(device)
        #print(para.shape)
        for i in range(dim0):
            score=torch.zeros(dim0)
            for j in range(dim0):
                if(i!=j):
                    #print(a[i].shape)
                    score[j]=torch.abs(torch.cosine_similarity(a[i], a[j], dim=0))
            #print(score)
            #print(torch.argmax(score, dim=0))
            for j in range(self.k):
                idx=torch.argmax(score, dim=0)
                para.data[0][i]=i
                para.data[1][i]=idx
                score[idx]=0
        #构造邻接矩阵
        x = x.reshape(dim0,-1)
        data = torch_geometric.data.Data(x=x, edge_index=para.long()).to(device)
        #print(data.x.shape)
        #print(data.edge_index.shape)
        #print(data.x.is_cuda)
        #print(data.edge_index.is_cuda)
        x = self.gat1(data.x,data.edge_index)
        x = self.act1(x)
        #print(x.shape)
        #print(data.edge_index.shape)
        x = self.gat2(x,data.edge_index)
        #print(x.shape)
        #print(data.edge_index.shape)
        x = self.act2(x)
        x = self.gat3(x,data.edge_index)
        x = self.act3(x)
        x = self.gat4(x,data.edge_index)
        x = self.act4(x)
        x = self.fc2(x)
        x = F.dropout(x, training=self.training)
        x = self.fc3(x)
        return F.log_softmax(x,dim=1)

训练

net = attgraNet(48,batchsize,5)
print(net)
net.to(device)
print(next(net.parameters()).device)
criterion = torch.nn.NLLLoss()
optimizer = torch.optim.Adam(net.parameters())
print(torch.cuda.is_available())
def train(epoch,model):        
    model.train()        
    running_loss = 0.0    
    for i,(X, y) in enumerate(train_loader):
        input = X.to(device)                     
        y=y.to(device)
        output = model.forward(input)          
        #print(output.shape)
        #print(y.squeeze(dim=1).shape)
        loss = criterion(output , y.squeeze(dim=1).long())
        print("[{}, {}] loss %{}':".format(epoch,i,loss))
        running_loss += loss.item()
 
        
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        
    epoch_loss_train = running_loss / (len(train_dataset)/batchsize)        
    print(epoch_loss_train)
    return epoch_loss_train

测试

def val(model):
    model.eval()        
    running_loss = 0.0 
    n=0
    result=0
    resauroc=0
    metric = Accuracy(top_k=1)    
    #auroc = AUROC(num_classes=2)
    #应该以AUC来评判,但是我如果使用torchmetric中的AUC汇报GPU资源不够的错误    
    with torch.no_grad():   
        for i, (data,y) in enumerate(test_loader):
            input = data.to(device)         
            y=y.to(device)
            optimizer.zero_grad()               
            output = model.forward(input)
            #print(y.squeeze(dim=1).long().shape)
            #print(output.shape)
            loss= criterion(output,y.squeeze(dim=1).long())
            print("[{}] loss %{}':".format(i,loss))
            n=n+1
            res=metric(output.cpu(),y.squeeze(dim=1).long().cpu())
            #res1=AUROC(output.cpu(),y.squeeze(dim=1).long().cpu())
            print("[{}] ACC %{}':".format(i,res))
            #print("[{}] AUROC %{}':".format(i,res1))
            result=res+result
            #resauroc=res1+resauroc
            running_loss += loss.item()
 
    epoch_loss_val = running_loss / (len(test_dataset)/batchsize)    
    print(epoch_loss_val)
    print(result/n)
    #print(resauroc/n)
    return epoch_loss_val
    
val(net)

其余代码

def main(model):
    min_loss = 100000000.0    
    loss_train = []        
    loss_val = []          
    epochs=200
    since = time.time()           
    for epoch in range(epochs):
        epoch_loss_train = train(epoch,model) 
        loss_train.append(epoch_loss_train)
        epoch_loss_val = val(model) 
        loss_val.append(epoch_loss_val)
 
        if epoch_loss_val < min_loss:
            min_loss = epoch_loss_val               
            best_model_wts = model.state_dict()
            #torch.save(best_model_wts,os.path.join(parameter_address, experiment_name + '.pkl'))  
            torch.save(model.state_dict(),'bestsaveBIG.pt')
        model_wts = model.state_dict()    
        #torch.save(model_wts,os.path.join(parameter_address, experiment_name + "_" + str(epoch) + '.pkl'))  
        time_elapsed = time.time() - since   
        #torch.save(model,str(epoch)+'.pt')
    torch.save(model.state_dict(),'lastsaveBIG.pt')
if __name__ == "__main__":
    main(net)
    print('train finish')

Tips

  1. 以上是我的想法,但是理想很丰满现实很骨干,精度在A榜上只有0.89,B榜上只有0.88.
  2. 大家应该看到我也没有使用未标注的nolabel数据,其实理论上使用起来非常简单,把那个nolabel数据变成tensor和每个batch的数据拼接在一起进行计算余弦相似度,然后设置一个与拼接在一起以后batch长度相等的布尔型的的tensor,让未标注的数据的batch对应的索引为false其他为true就可以了。但是我为什么说是理论上是很简单呢,因为我们在计算余弦相似度的时候算法的时间复杂度是batchsize的平方量级的,而那个未标注数据里面大概有四万多数据。如果拼接之前的话我们需要计算1024*1024时间复杂度,拼接后的时间复杂度就是四万的平方。我拼接过后发现这个程序到比赛结束连一个batch都没有跑完(我是10月25号发现这个比赛的)所以就果断放弃了。
  3. 哎没想到啊,我本来以为我的想法是很有道理的,同时也是十分相信GNN的模型预测能力。没想到是这种结果连开源的baseline的精度都没有超过。无法接受,我个人认为GNN的模型预测能力是毋庸置疑的,可能是因为本人能力不够同时对GNN理解程度才导致这样的结果。还是需要巩固基础,加强GNN调参的技巧。同时我也会参加更多这样的比赛。希望有一天我可以使用GNN得到一个不错的名次。
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_36154011/article/details/127885640

智能推荐

FTP命令字和返回码_ftp 登录返回230-程序员宅基地

文章浏览阅读3.5k次,点赞2次,收藏13次。为了从FTP服务器下载文件,需要要实现一个简单的FTP客户端。FTP(文件传输协议) 是 TCP/IP 协议组中的应用层协议。FTP协议使用字符串格式命令字,每条命令都是一行字符串,以“\r\n”结尾。客户端发送格式是:命令+空格+参数+"\r\n"的格式服务器返回格式是以:状态码+空格+提示字符串+"\r\n"的格式,代码只要解析状态码就可以了。读写文件需要登陆服务器,特殊用..._ftp 登录返回230

centos7安装rabbitmq3.6.5_centos7 安装rabbitmq3.6.5-程序员宅基地

文章浏览阅读648次。前提:systemctl stop firewalld 关闭防火墙关闭selinux查看getenforce临时关闭setenforce 0永久关闭sed-i'/SELINUX/s/enforcing/disabled/'/etc/selinux/configselinux的三种模式enforcing:强制模式,SELinux 运作中,且已经正确的开始限制..._centos7 安装rabbitmq3.6.5

idea导入android工程,idea怎样导入Android studio 项目?-程序员宅基地

文章浏览阅读5.8k次。满意答案s55f2avsx2017.09.05采纳率:46%等级:12已帮助:5646人新版Android Studio/IntelliJ IDEA可以直接导入eclipse项目,不再推荐使用eclipse导出gradle的方式2启动Android Studio/IntelliJ IDEA,选择 import project3选择eclipse 项目4选择 create project f..._android studio 项目导入idea 看不懂安卓项目

浅谈AI大模型技术:概念、发展和应用_ai大模型应用开发-程序员宅基地

文章浏览阅读860次,点赞2次,收藏6次。AI大模型技术已经在自然语言处理、计算机视觉、多模态交互等领域取得了显著的进展和成果,同时也引发了一系列新的挑战和问题,如数据质量、计算效率、知识可解释性、安全可靠性等。城市运维涉及到多个方面,如交通管理、环境监测、公共安全、社会治理等,它们需要处理和分析大量的多模态数据,如图像、视频、语音、文本等,并根据不同的场景和需求,提供合适的决策和响应。知识搜索有多种形式,如语义搜索、对话搜索、图像搜索、视频搜索等,它们可以根据用户的输入和意图,从海量的数据源中检索出最相关的信息,并以友好的方式呈现给用户。_ai大模型应用开发

非常详细的阻抗测试基础知识_阻抗实部和虚部-程序员宅基地

文章浏览阅读8.2k次,点赞12次,收藏121次。为什么要测量阻抗呢?阻抗能代表什么?阻抗测量的注意事项... ...很多人可能会带着一系列的问题来阅读本文。不管是数字电路工程师还是射频工程师,都在关注各类器件的阻抗,本文非常值得一读。全文13000多字,认真读完大概需要2小时。一、阻抗测试基本概念阻抗定义:阻抗是元器件或电路对周期的交流信号的总的反作用。AC 交流测试信号 (幅度和频率)。包括实部和虚部。​图1 阻抗的定义阻抗是评测电路、元件以及制作元件材料的重要参数。那么什么是阻抗呢?让我们先来看一下阻抗的定义。首先阻抗是一个矢量。通常,阻抗是_阻抗实部和虚部

小学生python游戏编程arcade----基本知识1_arcade语言 like-程序员宅基地

文章浏览阅读955次。前面章节分享试用了pyzero,pygame但随着想增加更丰富的游戏内容,好多还要进行自己编写类,从今天开始解绍一个新的python游戏库arcade模块。通过此次的《连连看》游戏实现,让我对swing的相关知识有了进一步的了解,对java这门语言也有了比以前更深刻的认识。java的一些基本语法,比如数据类型、运算符、程序流程控制和数组等,理解更加透彻。java最核心的核心就是面向对象思想,对于这一个概念,终于悟到了一些。_arcade语言 like

随便推点

【增强版短视频去水印源码】去水印微信小程序+去水印软件源码_去水印机要增强版-程序员宅基地

文章浏览阅读1.1k次。源码简介与安装说明:2021增强版短视频去水印源码 去水印微信小程序源码网站 去水印软件源码安装环境(需要材料):备案域名–服务器安装宝塔-安装 Nginx 或者 Apachephp5.6 以上-安装 sg11 插件小程序已自带解析接口,支持全网主流短视频平台,搭建好了就能用注:接口是公益的,那么多人用解析慢是肯定的,前段和后端源码已经打包,上传服务器之后在配置文件修改数据库密码。然后输入自己的域名,进入后台,创建小程序,输入自己的小程序配置即可安装说明:上传源码,修改data/_去水印机要增强版

verilog进阶语法-触发器原语_fdre #(.init(1'b0) // initial value of register (1-程序员宅基地

文章浏览阅读557次。1. 触发器是FPGA存储数据的基本单元2. 触发器作为时序逻辑的基本元件,官方提供了丰富的配置方式,以适应各种可能的应用场景。_fdre #(.init(1'b0) // initial value of register (1'b0 or 1'b1) ) fdce_osc (

嵌入式面试/笔试C相关总结_嵌入式面试笔试c语言知识点-程序员宅基地

文章浏览阅读560次。本该是不同编译器结果不同,但是尝试了g++ msvc都是先计算c,再计算b,最后得到a+b+c是经过赋值以后的b和c参与计算而不是6。由上表可知,将q复制到p数组可以表示为:*p++=*q++,*优先级高,先取到对应q数组的值,然后两个++都是在后面,该行运算完后执行++。在电脑端编译完后会分为text data bss三种,其中text为可执行程序,data为初始化过的ro+rw变量,bss为未初始化或初始化为0变量。_嵌入式面试笔试c语言知识点

57 Things I've Learned Founding 3 Tech Companies_mature-程序员宅基地

文章浏览阅读2.3k次。57 Things I've Learned Founding 3 Tech CompaniesJason Goldberg, Betashop | Oct. 29, 2010, 1:29 PMI’ve been founding andhelping run techn_mature

一个脚本搞定文件合并去重,大数据处理,可以合并几个G以上的文件_python 超大文本合并-程序员宅基地

文章浏览阅读1.9k次。问题:先讲下需求,有若干个文本文件(txt或者csv文件等),每行代表一条数据,现在希望能合并成 1 个文本文件,且需要去除重复行。分析:一向奉行简单原则,如无必要,绝不复杂。如果数据量不大,那么如下两条命令就可以搞定合并:cat a.txt >> new.txtcat b.txt >> new.txt……去重:cat new...._python 超大文本合并

支付宝小程序iOS端过渡页DFLoadingPageRootController分析_类似支付宝页面过度加载页-程序员宅基地

文章浏览阅读489次。这个过渡页是第一次打开小程序展示的,点击某个小程序前把手机的开发者->network link conditioner->enable & very bad network 就会在停在此页。比如《支付宝运动》这个小程序先看这个类的.h可以看到它继承于DTViewController点击左上角返回的方法- (void)back;#import "DTViewController.h"#import "APBaseLoadingV..._类似支付宝页面过度加载页

推荐文章

热门文章

相关标签