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 神...