Word2Vec裡實現Huffman樹

2021-06-29 02:44:39 字數 4128 閱讀 1262

word2vec裡是拿陣列實現word2vec,效率很高,在學校裡經常見到的是遞迴迭代實現huffman樹,這對於處理大量葉子節點的問題不是乙個最佳方法。

陣列法:

#include 

#include

#include

#define max_code_length 40//巨集定義沒有;

struct vocab_word

;long

long vocab_size,a,b,k,min1,min2,i;//詞彙表大小

struct vocab_word * vocab;

int vocabcompare(const

void *a,const

void *b)

int main()

long

long *count = (long

long *)calloc(vocab_size*2-1,sizeof(long

long));

long

long *binary = (long

long *)calloc(vocab_size*2-1,sizeof(long

long));

long

long *parent_node = (long

long *)calloc(vocab_size*2-1,sizeof(long

long));

long

long point[max_code_length];

char code[max_code_length];

for (i = 0; i < vocab_size; ++i)

//for (i = 0; i < vocab_size; ++i) printf("%lld ",count[i]);

for (i = vocab_size; i < vocab_size*2-1; ++i)

count[i]=1e15;

//sort

qsort(count,vocab_size,sizeof(long

long),vocabcompare);

//for (i = 0; i < vocab_size; ++i) printf("%lld ",count[i]);

for (i = 0; i < vocab_size; ++i)

vocab[i].cn=count[i];

//for (i = 0; i < vocab_size; ++i) printf("%lld ",vocab[i].cn);

long

long pos1 = vocab_size-1;

long

long pos2 = vocab_size;

for (a = 0; a < vocab_size-1; ++a)//迭代vocab_size-1次構造huffman樹

}else

if (pos1>=0)

}else

//printf("count[%lld]=%lld count[%lld]=%lld\n",min1,count[min1],min2,count[min2]);

count[vocab_size + a]=count[min1]+count[min2];

//printf("count[%lld]=%lld\n",vocab_size+a,count[vocab_size+a]);

parent_node[min1]=vocab_size+a;

parent_node[min2]=vocab_size+a;

binary[min2]=1;

//printf("binary[%lld]=%lld\n",min2,binary[min2]);

}//for (i = 0; i < 2*vocab_size-1; ++i) printf("%lld ",binary[i]);

//for (i = 0; i < 2*vocab_size-1; ++i) printf("i=%lld,parent_node:%lld\n",i,parent_node[i]);

for (a = 0; a < vocab_size; ++a)

vocab[a].codelen=k;//huffman編碼長度

vocab[a].point[0]=vocab_size*2-2;

for (b = 0; b < k; ++b)//逆序處理

//printf("vocab[%lld].cn=%lld\n",a,vocab[a].cn);

//printf("vocab[%lld].codelen=%d\n",a,vocab[a].codelen);

//for ( i = 0; i < k; ++i) printf("vocab[%lld].code=%d\n",a,vocab[a].code[i]);

//for ( i = 0; i < k+1; ++i) printf("vocab[%lld].point=%d\n",a,vocab[a].point[i]);

}free(count);

free(binary);

free(parent_node);

//output

for (a = 0; a < vocab_size; ++a)

}

迭代法:

#include 

#include

typedef

int elemtype;

struct btreenode

;//1、輸出二叉樹,可在前序遍歷的基礎上修改。採用廣義**式,元素型別為int

void printbtree_int(struct btreenode *bt)

}}//2、根據陣列 a 中 n 個權值建立一棵哈夫曼樹,返回樹根指標

struct btreenode * createhuffman(elemtype a,int n)

for (int i = 1; i < n; ++i)//進行 n-1 次迴圈建立哈夫曼樹

if (b[j]!=null)

}for (int j = k2; j < n; ++j)

else

if (b[j]->datadata)}}

//由最小權值樹和次最小權值樹建立一棵新樹,q指向樹根結點

q=(struct btreenode *)malloc(sizeof(struct btreenode));

q->data = b[k1]->data + b[k2]->data;

q->left = b[k1];

q->right =b[k2];

b[k1] = q;//將指向新樹的指標賦給b指標陣列中k1位置

b[k2] = null;//k2位置為空

}free(b);//刪除動態建立的陣列b

return q;//返回整個哈夫曼樹的樹根指標

}//3、求哈夫曼樹的帶權路徑長度

elemtype weightpathlength(struct btreenode * fbt,int len)//len初始值為0

else

}//4、哈夫曼編碼(可以根據哈夫曼樹帶權路徑長度的演算法基礎上進行修改)

void huffmancoding(struct btreenode *fbt,int len)//len初始值為0

else

}}//主函式

int main()

a=(elemtype *)malloc(n*sizeof(elemtype));

//printf("從鍵盤輸入%d個整數作為權值:", n);

for (int i = 0; i < n; ++i)

fbt = createhuffman(a,n);

printf("廣義表形式的哈夫曼樹:");

printbtree_int(fbt);

printf("\n");

printf("哈夫曼樹的帶權路徑長度:");

printf("%d\n",weightpathlength(fbt,0));

printf("樹中每個葉子結點的哈夫曼編碼:\n");

huffmancoding(fbt,0);

return

0;}

與word2vec 原來word2vec那麼簡單

說到word2vec,它可謂非結構化資料裡面的佼佼者,尤其是在推薦和nlp當中,足以體現它的優勢所在,並且多年一直備受工業界喜愛.那麼word2vec到底是怎麼個原理的,發現身邊總是有很多人問,確不能準確的說出為什麼是兩個矩陣,到底是怎麼自動反向傳播的,以及對於softmax之後那麼大的維度資料,是...

word2vec學習參考

最近看nlp的東西比較多。就拿現在google 基於神經網路做的 word2vec 作為部落格的開始吧,今後會陸陸續續補充內容。基本是分4塊內容 1.神經網路語言模型 2.語言模型分層優化 3.word2vec 原理 4.google word2vec 看一點寫一點,先扔些參考資料鏈接上去。附上在研...

Word2Vec知識總結

word2vec是乙個產生詞向量的模型,是乙個雙層的神經網路 非常善於找出詞彙的相似度,同時可用於處理之前的技術 像one hot編碼和wordnet 處理不了的語義關係。它可以利用神經網路從大量的無標註的文字中提取有用資訊。我們也可以將它看成是乙個工具,它裡面包含了三種重要的模型 1 nnlm 神...